CoglTexture * st_cogl_texture_new_with_size_wrapper (int width, int height, CoglTextureFlags flags, CoglPixelFormat internal_format) { CoglTexture *texture = NULL; if (hardware_supports_npot_sizes ()) { texture = COGL_TEXTURE (cogl_texture_2d_new_with_size (cogl_context, width, height #if COGL_VERSION < COGL_VERSION_ENCODE (1, 18, 0) ,CLUTTER_CAIRO_FORMAT_ARGB32 #endif )); } else { texture = cogl_texture_new_with_size (width, height, flags, internal_format); } return texture; }
static void create_gles2_context (CoglTexture **offscreen_texture, CoglOffscreen **offscreen, CoglPipeline **pipeline, CoglGLES2Context **gles2_ctx, const CoglGLES2Vtable **gles2) { GError *error = NULL; *offscreen_texture = COGL_TEXTURE ( cogl_texture_2d_new_with_size (test_ctx, cogl_framebuffer_get_width (test_fb), cogl_framebuffer_get_height (test_fb), COGL_PIXEL_FORMAT_ANY, NULL)); *offscreen = cogl_offscreen_new_to_texture (*offscreen_texture); *pipeline = cogl_pipeline_new (test_ctx); cogl_pipeline_set_layer_texture (*pipeline, 0, *offscreen_texture); *gles2_ctx = cogl_gles2_context_new (test_ctx, NULL); if (!*gles2_ctx) g_error ("Failed to create GLES2 context: %s\n", error->message); *gles2 = cogl_gles2_context_get_vtable (*gles2_ctx); }
static CoglTexture2D * _cogl_atlas_create_texture (CoglAtlas *atlas, int width, int height) { CoglTexture2D *tex; CoglError *ignore_error = NULL; _COGL_GET_CONTEXT (ctx, NULL); if ((atlas->flags & COGL_ATLAS_CLEAR_TEXTURE)) { uint8_t *clear_data; CoglBitmap *clear_bmp; int bpp = _cogl_pixel_format_get_bytes_per_pixel (atlas->texture_format); /* Create a buffer of zeroes to initially clear the texture */ clear_data = g_malloc0 (width * height * bpp); clear_bmp = cogl_bitmap_new_for_data (ctx, width, height, atlas->texture_format, width * bpp, clear_data); tex = cogl_texture_2d_new_from_bitmap (clear_bmp); _cogl_texture_set_internal_format (COGL_TEXTURE (tex), atlas->texture_format); if (!cogl_texture_allocate (COGL_TEXTURE (tex), &ignore_error)) { cogl_error_free (ignore_error); cogl_object_unref (tex); tex = NULL; } cogl_object_unref (clear_bmp); g_free (clear_data); } else { tex = cogl_texture_2d_new_with_size (ctx, width, height); _cogl_texture_set_internal_format (COGL_TEXTURE (tex), atlas->texture_format); if (!cogl_texture_allocate (COGL_TEXTURE (tex), &ignore_error)) { cogl_error_free (ignore_error); cogl_object_unref (tex); tex = NULL; } } return tex; }
CoglTexture * cogl_texture_new_with_size (CoglContext *ctx, int width, int height, CoglTextureFlags flags, CoglPixelFormat internal_format) { CoglTexture *tex; CoglError *skip_error = NULL; if ((_cogl_util_is_pot (width) && _cogl_util_is_pot (height)) || (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) && cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP))) { /* First try creating a fast-path non-sliced texture */ tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, width, height, internal_format)); /* TODO: instead of allocating storage here it would be better * if we had some api that let us just check that the size is * supported by the hardware so storage could be allocated * lazily when uploading data. */ if (!cogl_texture_allocate (tex, &skip_error)) { cogl_error_free (skip_error); cogl_object_unref (tex); tex = NULL; } } else tex = NULL; if (tex) { CoglBool auto_mipmap = !(flags & COGL_TEXTURE_NO_AUTO_MIPMAP); cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (tex), auto_mipmap); } else { /* If it fails resort to sliced textures */ int max_waste = flags & COGL_TEXTURE_NO_SLICING ? -1 : COGL_TEXTURE_MAX_WASTE; cogl_error_free (skip_error); tex = COGL_TEXTURE (cogl_texture_2d_sliced_new_with_size (ctx, width, height, max_waste, internal_format)); } return tex; }
static CoglTexture * create_migration_texture (CoglContext *ctx, int width, int height, CoglPixelFormat internal_format) { CoglTexture *tex; CoglError *skip_error = NULL; if ((_cogl_util_is_pot (width) && _cogl_util_is_pot (height)) || (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) && cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP))) { /* First try creating a fast-path non-sliced texture */ tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, width, height)); _cogl_texture_set_internal_format (tex, internal_format); /* TODO: instead of allocating storage here it would be better * if we had some api that let us just check that the size is * supported by the hardware so storage could be allocated * lazily when uploading data. */ if (!cogl_texture_allocate (tex, &skip_error)) { cogl_error_free (skip_error); cogl_object_unref (tex); tex = NULL; } } else tex = NULL; if (!tex) { CoglTexture2DSliced *tex_2ds = cogl_texture_2d_sliced_new_with_size (ctx, width, height, COGL_TEXTURE_MAX_WASTE); _cogl_texture_set_internal_format (COGL_TEXTURE (tex_2ds), internal_format); tex = COGL_TEXTURE (tex_2ds); } return tex; }
static CoglTexture * test_texture_new_with_size(CoglContext *ctx, int width, int height, CoglTextureComponents components) { CoglTexture *tex; CoglError *skip_error = NULL; tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, width, height)); cogl_texture_set_components(tex, components); cogl_primitive_texture_set_auto_mipmap(tex, TRUE); if (!cogl_texture_allocate(tex, &skip_error)) { cogl_error_free(skip_error); cogl_object_unref(tex); return NULL; } return tex; }
static void init() { CoglError *error = NULL; CoglDisplay *display; CoglRenderer *renderer; CoglBool missing_requirement; //g_setenv ("COGL_X11_SYNC", "1", 0); test_ctx = cogl_context_new (NULL, &error); if (!test_ctx) { g_message ("Failed to create a CoglContext: %s", error->message); exit(1); } display = cogl_context_get_display (test_ctx); renderer = cogl_display_get_renderer (display); if (!check_flags (renderer)) { g_message ("WARNING: Missing required feature[s] for this test\n"); exit(1); } { //TODO: get all monitors size to test CoglOffscreen *offscreen; CoglTexture2D *tex = cogl_texture_2d_new_with_size (test_ctx, FB_WIDTH, FB_HEIGHT); offscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (tex)); test_fb = COGL_FRAMEBUFFER (offscreen); } if (!cogl_framebuffer_allocate (test_fb, &error)) { g_message ("Failed to allocate framebuffer: %s", error->message); exit(1); } cogl_framebuffer_clear4f (test_fb, COGL_BUFFER_BIT_COLOR | COGL_BUFFER_BIT_DEPTH | COGL_BUFFER_BIT_STENCIL, 0, 0, 0, 1); }
void test_texture_no_allocate (void) { uint8_t *tex_data; CoglTexture *texture; CoglTexture2D *texture_2d; CoglError *error = NULL; tex_data = g_malloc (BIG_TEX_WIDTH * BIG_TEX_HEIGHT * 4); /* NB: if we make the atlas and sliced texture APIs public then this * could changed to explicitly use that instead of the magic texture * API */ /* Try to create an atlas texture that is too big so it will * internally be freed without allocating */ texture = cogl_atlas_texture_new_from_data (test_ctx, BIG_TEX_WIDTH, BIG_TEX_HEIGHT, /* format */ COGL_PIXEL_FORMAT_RGBA_8888_PRE, /* rowstride */ BIG_TEX_WIDTH * 4, tex_data, &error); g_free (tex_data); /* It's ok if this causes an error, we just don't want it to * crash */ if (texture == NULL) cogl_error_free (error); else cogl_object_unref (texture); /* Try to create a sliced texture without allocating it */ texture = cogl_texture_2d_sliced_new_with_size (test_ctx, BIG_TEX_WIDTH, BIG_TEX_HEIGHT, COGL_TEXTURE_MAX_WASTE); cogl_object_unref (texture); /* 2D texture */ texture_2d = cogl_texture_2d_new_with_size (test_ctx, 64, 64); cogl_object_unref (texture_2d); /* 3D texture */ if (cogl_has_feature (test_ctx, COGL_FEATURE_ID_TEXTURE_3D)) { CoglTexture3D *texture_3d = cogl_texture_3d_new_with_size (test_ctx, 64, 64, 64); cogl_object_unref (texture_3d); } /* Rectangle texture */ if (cogl_has_feature (test_ctx, COGL_FEATURE_ID_TEXTURE_RECTANGLE)) { CoglTextureRectangle *texture_rect = cogl_texture_rectangle_new_with_size (test_ctx, 64, 64); cogl_object_unref (texture_rect); } }
CoglTexture * cogl_texture_new_with_size (unsigned int width, unsigned int height, CoglTextureFlags flags, CoglPixelFormat internal_format) { CoglTexture *tex; CoglError *skip_error = NULL; _COGL_GET_CONTEXT (ctx, NULL); if ((_cogl_util_is_pot (width) && _cogl_util_is_pot (height)) || (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) && cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP))) { /* First try creating a fast-path non-sliced texture */ tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, width, height)); _cogl_texture_set_internal_format (tex, internal_format); if (!cogl_texture_allocate (tex, &skip_error)) { cogl_error_free (skip_error); cogl_object_unref (tex); tex = NULL; } } else tex = NULL; if (!tex) { /* If it fails resort to sliced textures */ int max_waste = flags & COGL_TEXTURE_NO_SLICING ? -1 : COGL_TEXTURE_MAX_WASTE; tex = COGL_TEXTURE (cogl_texture_2d_sliced_new_with_size (ctx, width, height, max_waste)); _cogl_texture_set_internal_format (tex, internal_format); } /* NB: This api existed before Cogl introduced lazy allocation of * textures and so we maintain its original synchronous allocation * semantics and return NULL if allocation fails... */ if (!cogl_texture_allocate (tex, &skip_error)) { cogl_error_free (skip_error); cogl_object_unref (tex); return NULL; } if (tex && flags & COGL_TEXTURE_NO_AUTO_MIPMAP) { cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (tex), 0, 0, 1, 1, COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE, COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE, set_auto_mipmap_cb, NULL); } return tex; }
int main (int argc, char **argv) { Data data; CoglOnscreen *onscreen; CoglError *error = NULL; CoglVertexP2C4 triangle_vertices[] = { {0, 0.7, 0xff, 0x00, 0x00, 0xff}, {-0.7, -0.7, 0x00, 0xff, 0x00, 0xff}, {0.7, -0.7, 0x00, 0x00, 0xff, 0xff} }; GSource *cogl_source; GMainLoop *loop; CoglRenderer *renderer; CoglDisplay *display; renderer = cogl_renderer_new (); cogl_renderer_add_constraint (renderer, COGL_RENDERER_CONSTRAINT_SUPPORTS_COGL_GLES2); display = cogl_display_new (renderer, NULL); data.ctx = cogl_context_new (display, NULL); onscreen = cogl_onscreen_new (data.ctx, 640, 480); cogl_onscreen_show (onscreen); data.fb = COGL_FRAMEBUFFER (onscreen); /* Prepare onscreen primitive */ data.triangle = cogl_primitive_new_p2c4 (data.ctx, COGL_VERTICES_MODE_TRIANGLES, 3, triangle_vertices); data.pipeline = cogl_pipeline_new (data.ctx); data.offscreen_texture = COGL_TEXTURE ( cogl_texture_2d_new_with_size (data.ctx, OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT, COGL_PIXEL_FORMAT_ANY)); data.offscreen = cogl_offscreen_new_to_texture (data.offscreen_texture); data.gles2_ctx = cogl_gles2_context_new (data.ctx, &error); if (!data.gles2_ctx) { g_error ("Failed to create GLES2 context: %s\n", error->message); } data.gles2_vtable = cogl_gles2_context_get_vtable (data.gles2_ctx); /* Draw scene with GLES2 */ if (!cogl_push_gles2_context (data.ctx, data.gles2_ctx, data.fb, data.fb, &error)) { g_error ("Failed to push gles2 context: %s\n", error->message); } cogl_pop_gles2_context (data.ctx); cogl_source = cogl_glib_source_new (data.ctx, G_PRIORITY_DEFAULT); g_source_attach (cogl_source, NULL); cogl_onscreen_add_frame_callback (COGL_ONSCREEN (data.fb), frame_event_cb, &data, NULL); /* destroy notify */ g_idle_add (paint_cb, &data); loop = g_main_loop_new (NULL, TRUE); g_main_loop_run (loop); return 0; }
CoglTexture * rut_gaussian_blurrer_blur (RutGaussianBlurrer *blurrer, CoglTexture *source) { unsigned int src_w, src_h; CoglPixelFormat format; CoglOffscreen *offscreen; /* create the first FBO to render the x pass */ src_w = cogl_texture_get_width (source); src_h = cogl_texture_get_height (source); format = cogl_texture_get_format (source); if (blurrer->width != src_w || blurrer->height != src_h || blurrer->format != format) { _rut_gaussian_blurrer_free_buffers (blurrer); } if (!blurrer->x_pass) { CoglError *error = NULL; CoglTexture2D *texture_2d = cogl_texture_2d_new_with_size (blurrer->ctx->cogl_context, src_w, src_h, format); if (error) { g_warning ("blurrer: could not create x pass texture: %s", error->message); } blurrer->x_pass = COGL_TEXTURE (texture_2d); blurrer->width = src_w; blurrer->height = src_h; blurrer->format = format; offscreen = cogl_offscreen_new_to_texture (blurrer->x_pass); blurrer->x_pass_fb = COGL_FRAMEBUFFER (offscreen); cogl_framebuffer_orthographic (blurrer->x_pass_fb, 0, 0, src_w, src_h, -1, 100); } if (!blurrer->y_pass) { /* create the second FBO (final destination) to render the y pass */ CoglTexture2D *texture_2d = cogl_texture_2d_new_with_size (blurrer->ctx->cogl_context, src_w, src_h, format); blurrer->destination = COGL_TEXTURE (texture_2d); blurrer->y_pass = blurrer->destination; offscreen = cogl_offscreen_new_to_texture (blurrer->destination); blurrer->y_pass_fb = COGL_FRAMEBUFFER (offscreen); cogl_framebuffer_orthographic (blurrer->y_pass_fb, 0, 0, src_w, src_h, -1, 100); } set_blurrer_pipeline_texture (blurrer->x_pass_pipeline, source, 1.0f / src_w, 0); set_blurrer_pipeline_texture (blurrer->y_pass_pipeline, blurrer->x_pass, 0, 1.0f / src_h); /* x pass */ cogl_framebuffer_draw_rectangle (blurrer->x_pass_fb, blurrer->x_pass_pipeline, 0, 0, blurrer->width, blurrer->height); /* y pass */ cogl_framebuffer_draw_rectangle (blurrer->y_pass_fb, blurrer->y_pass_pipeline, 0, 0, blurrer->width, blurrer->height); return cogl_object_ref (blurrer->destination); }
static gboolean setup_framebuffers (StThemeNodeTransition *transition, const ClutterActorBox *allocation) { ClutterBackend *backend = clutter_get_default_backend (); CoglContext *ctx = clutter_backend_get_cogl_context (backend); StThemeNodeTransitionPrivate *priv = transition->priv; CoglColor clear_color = { 0, 0, 0, 0 }; guint width, height; /* template material to avoid unnecessary shader compilation */ static CoglHandle material_template = COGL_INVALID_HANDLE; width = priv->offscreen_box.x2 - priv->offscreen_box.x1; height = priv->offscreen_box.y2 - priv->offscreen_box.y1; g_return_val_if_fail (width > 0, FALSE); g_return_val_if_fail (height > 0, FALSE); if (priv->old_texture) cogl_handle_unref (priv->old_texture); priv->old_texture = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, width, height #if COGL_VERSION < COGL_VERSION_ENCODE (1, 18, 0) ,COGL_PIXEL_FORMAT_ANY #endif )); if (priv->new_texture) cogl_handle_unref (priv->new_texture); priv->new_texture = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, width, height #if COGL_VERSION < COGL_VERSION_ENCODE (1, 18, 0) ,COGL_PIXEL_FORMAT_ANY #endif )); g_return_val_if_fail (priv->old_texture != COGL_INVALID_HANDLE, FALSE); g_return_val_if_fail (priv->new_texture != COGL_INVALID_HANDLE, FALSE); if (priv->old_offscreen) cogl_handle_unref (priv->old_offscreen); priv->old_offscreen = cogl_offscreen_new_to_texture (priv->old_texture); if (priv->new_offscreen) cogl_handle_unref (priv->new_offscreen); priv->new_offscreen = cogl_offscreen_new_to_texture (priv->new_texture); g_return_val_if_fail (priv->old_offscreen != COGL_INVALID_HANDLE, FALSE); g_return_val_if_fail (priv->new_offscreen != COGL_INVALID_HANDLE, FALSE); if (priv->material == NULL) { if (G_UNLIKELY (material_template == COGL_INVALID_HANDLE)) { material_template = cogl_material_new (); cogl_material_set_layer_combine (material_template, 0, "RGBA = REPLACE (TEXTURE)", NULL); cogl_material_set_layer_combine (material_template, 1, "RGBA = INTERPOLATE (PREVIOUS, " "TEXTURE, " "CONSTANT[A])", NULL); cogl_material_set_layer_combine (material_template, 2, "RGBA = MODULATE (PREVIOUS, " "PRIMARY)", NULL); } priv->material = cogl_material_copy (material_template); } cogl_material_set_layer (priv->material, 0, priv->new_texture); cogl_material_set_layer (priv->material, 1, priv->old_texture); cogl_push_framebuffer (priv->old_offscreen); cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR); cogl_ortho (priv->offscreen_box.x1, priv->offscreen_box.x2, priv->offscreen_box.y2, priv->offscreen_box.y1, 0.0, 1.0); st_theme_node_paint (priv->old_theme_node, allocation, 255); cogl_pop_framebuffer (); cogl_push_framebuffer (priv->new_offscreen); cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR); cogl_ortho (priv->offscreen_box.x1, priv->offscreen_box.x2, priv->offscreen_box.y2, priv->offscreen_box.y1, 0.0, 1.0); st_theme_node_paint (priv->new_theme_node, allocation, 255); cogl_pop_framebuffer (); return TRUE; }
static void test_push_pop_single_context (void) { CoglTexture *offscreen_texture; CoglOffscreen *offscreen; CoglPipeline *pipeline; CoglGLES2Context *gles2_ctx; const CoglGLES2Vtable *gles2; GError *error = NULL; offscreen_texture = COGL_TEXTURE ( cogl_texture_2d_new_with_size (test_ctx, cogl_framebuffer_get_width (test_fb), cogl_framebuffer_get_height (test_fb), COGL_PIXEL_FORMAT_ANY, NULL)); offscreen = cogl_offscreen_new_to_texture (offscreen_texture); pipeline = cogl_pipeline_new (test_ctx); cogl_pipeline_set_layer_texture (pipeline, 0, offscreen_texture); gles2_ctx = cogl_gles2_context_new (test_ctx, &error); if (!gles2_ctx) g_error ("Failed to create GLES2 context: %s\n", error->message); gles2 = cogl_gles2_context_get_vtable (gles2_ctx); /* Clear onscreen to 0xffff00 using GLES2 */ if (!cogl_push_gles2_context (test_ctx, gles2_ctx, test_fb, test_fb, &error)) { g_error ("Failed to push gles2 context: %s\n", error->message); } gles2->glClearColor (1, 1, 0, 1); gles2->glClear (GL_COLOR_BUFFER_BIT); cogl_pop_gles2_context (test_ctx); test_utils_check_pixel (test_fb, 0, 0, 0xffff00ff); /* Clear offscreen to 0xff0000 using GLES2 and then copy the result * onscreen. * * If we fail to bind the new context here then we'd probably end up * clearing onscreen to 0xff0000 and copying 0xffff00 to onscreen * instead. */ if (!cogl_push_gles2_context (test_ctx, gles2_ctx, COGL_FRAMEBUFFER (offscreen), COGL_FRAMEBUFFER (offscreen), &error)) { g_error ("Failed to push gles2 context: %s\n", error->message); } gles2->glClearColor (1, 0, 0, 1); gles2->glClear (GL_COLOR_BUFFER_BIT); cogl_pop_gles2_context (test_ctx); cogl_framebuffer_draw_rectangle (test_fb, pipeline, -1, 1, 1, -1); /* NB: Cogl doesn't automatically support mid-scene modifications * of textures and so we explicitly flush the drawn rectangle to the * framebuffer now otherwise it may be batched until after the * offscreen texture has been modified again. */ cogl_flush (); /* Clear the offscreen framebuffer to blue using GLES2 before * reading back from the onscreen framebuffer in case we mistakenly * read from the offscreen framebuffer and get a false positive */ if (!cogl_push_gles2_context (test_ctx, gles2_ctx, COGL_FRAMEBUFFER (offscreen), COGL_FRAMEBUFFER (offscreen), &error)) { g_error ("Failed to push gles2 context: %s\n", error->message); } gles2->glClearColor (0, 0, 1, 1); gles2->glClear (GL_COLOR_BUFFER_BIT); cogl_pop_gles2_context (test_ctx); test_utils_check_pixel (test_fb, 0, 0, 0xff0000ff); /* Now copy the offscreen blue clear to the onscreen framebufer and * check that too */ cogl_framebuffer_draw_rectangle (test_fb, pipeline, -1, 1, 1, -1); test_utils_check_pixel (test_fb, 0, 0, 0x0000ffff); if (!cogl_push_gles2_context (test_ctx, gles2_ctx, test_fb, test_fb, &error)) { g_error ("Failed to push gles2 context: %s\n", error->message); } gles2->glClearColor (1, 0, 1, 1); gles2->glClear (GL_COLOR_BUFFER_BIT); cogl_pop_gles2_context (test_ctx); test_utils_check_pixel (test_fb, 0, 0, 0xff00ffff); cogl_object_unref (gles2_ctx); cogl_object_unref (pipeline); }