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; }
CoglTexture * cogl_texture_new_from_data (int width, int height, CoglTextureFlags flags, CoglPixelFormat format, CoglPixelFormat internal_format, int rowstride, const uint8_t *data) { CoglError *ignore_error = NULL; CoglTexture *tex; _COGL_GET_CONTEXT (ctx, NULL); tex = _cogl_texture_new_from_data (ctx, width, height, flags, format, internal_format, rowstride, data, &ignore_error); if (!tex) cogl_error_free (ignore_error); return tex; }
CoglTexture * st_cogl_texture_new_from_file_wrapper (const char *filename, CoglTextureFlags flags, CoglPixelFormat internal_format) { CoglTexture *texture = NULL; CoglError *error = NULL; if (hardware_supports_npot_sizes ()) { texture = COGL_TEXTURE (cogl_texture_2d_new_from_file (cogl_context, filename, #if COGL_VERSION < COGL_VERSION_ENCODE (1, 18, 0) COGL_PIXEL_FORMAT_ANY, #endif &error)); } else { texture = cogl_texture_new_from_file (filename, flags, internal_format, &error); } if (error) { g_debug ("cogl_texture_(2d)_new_from_file failed: %s\n", error->message); cogl_error_free (error); } return texture; }
static CoglBool connect_custom_winsys (CoglRenderer *renderer, CoglError **error) { const CoglWinsysVtable *winsys = renderer->custom_winsys_vtable_getter(); CoglError *tmp_error = NULL; GString *error_message; renderer->winsys_vtable = winsys; error_message = g_string_new (""); if (!winsys->renderer_connect (renderer, &tmp_error)) { g_string_append_c (error_message, '\n'); g_string_append (error_message, tmp_error->message); cogl_error_free (tmp_error); } else { renderer->connected = TRUE; g_string_free (error_message, TRUE); return TRUE; } renderer->winsys_vtable = NULL; _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_INIT, "Failed to connected to any renderer: %s", error_message->str); g_string_free (error_message, TRUE); return FALSE; }
CoglTexture * _cogl_atlas_copy_rectangle (CoglAtlas *atlas, int x, int y, int width, int height, CoglPixelFormat internal_format) { CoglTexture *tex; CoglBlitData blit_data; CoglError *ignore_error = NULL; _COGL_GET_CONTEXT (ctx, NULL); /* Create a new texture at the right size */ tex = create_migration_texture (ctx, width, height, internal_format); if (!cogl_texture_allocate (tex, &ignore_error)) { cogl_error_free (ignore_error); cogl_object_unref (tex); return NULL; } /* Blit the data out of the atlas to the new texture. If FBOs aren't available this will end up having to copy the entire atlas texture */ _cogl_blit_begin (&blit_data, tex, atlas->texture); _cogl_blit (&blit_data, x, y, 0, 0, width, height); _cogl_blit_end (&blit_data); return tex; }
CoglIndices * cogl_indices_new (CoglContext *context, CoglIndicesType type, const void *indices_data, int n_indices) { size_t buffer_bytes = sizeof_indices_type (type) * n_indices; CoglIndexBuffer *index_buffer = cogl_index_buffer_new (context, buffer_bytes); CoglBuffer *buffer = COGL_BUFFER (index_buffer); CoglIndices *indices; CoglError *ignore_error = NULL; cogl_buffer_set_data (buffer, 0, indices_data, buffer_bytes, &ignore_error); if (ignore_error) { cogl_error_free (ignore_error); cogl_object_unref (index_buffer); return NULL; } indices = cogl_indices_new_for_buffer (type, index_buffer, 0); cogl_object_unref (index_buffer); return indices; }
static void file_loaded (GObject *source_object, GAsyncResult *result, gpointer user_data) { MetaBackgroundImage *image = META_BACKGROUND_IMAGE (source_object); GError *error = NULL; CoglError *catch_error = NULL; GTask *task; CoglTexture *texture; GdkPixbuf *pixbuf; int width, height, row_stride; guchar *pixels; gboolean has_alpha; task = G_TASK (result); pixbuf = g_task_propagate_pointer (task, &error); if (pixbuf == NULL) { char *uri = g_file_get_uri (image->file); g_warning ("Failed to load background '%s': %s", uri, error->message); g_clear_error (&error); g_free (uri); goto out; } width = gdk_pixbuf_get_width (pixbuf); height = gdk_pixbuf_get_height (pixbuf); row_stride = gdk_pixbuf_get_rowstride (pixbuf); pixels = gdk_pixbuf_get_pixels (pixbuf); has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); texture = meta_create_texture (width, height, has_alpha ? COGL_TEXTURE_COMPONENTS_RGBA : COGL_TEXTURE_COMPONENTS_RGB, META_TEXTURE_ALLOW_SLICING); if (!cogl_texture_set_data (texture, has_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888, row_stride, pixels, 0, &catch_error)) { g_warning ("Failed to create texture for background"); cogl_error_free (catch_error); cogl_object_unref (texture); } image->texture = texture; out: if (pixbuf != NULL) g_object_unref (pixbuf); image->loaded = TRUE; g_signal_emit (image, signals[LOADED], 0); }
int _cogl_blend_string_test (void) { struct _TestString strings[] = { {" A = MODULATE ( TEXTURE[RGB], PREVIOUS[A], PREVIOUS[A] ) ", COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE }, {" RGB = MODULATE ( TEXTURE[RGB], PREVIOUS[A] ) ", COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE }, {"A=ADD(TEXTURE[A],PREVIOUS[RGB])", COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE }, {"A=ADD(TEXTURE[A],PREVIOUS[RGB])", COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE }, {"RGBA = ADD(SRC_COLOR*(SRC_COLOR[A]), DST_COLOR*(1-SRC_COLOR[A]))", COGL_BLEND_STRING_CONTEXT_BLENDING }, {"RGB = ADD(SRC_COLOR, DST_COLOR*(0))", COGL_BLEND_STRING_CONTEXT_BLENDING }, {"RGB = ADD(SRC_COLOR, 0)", COGL_BLEND_STRING_CONTEXT_BLENDING }, {"RGB = ADD()", COGL_BLEND_STRING_CONTEXT_BLENDING }, {"RGB = ADD(SRC_COLOR, 0, DST_COLOR)", COGL_BLEND_STRING_CONTEXT_BLENDING }, {NULL} }; int i; CoglError *error = NULL; for (i = 0; strings[i].string; i++) { CoglBlendStringStatement statements[2]; int count = _cogl_blend_string_compile (strings[i].string, strings[i].context, statements, &error); if (!count) { g_print ("Failed to parse string:\n%s\n%s\n", strings[i].string, error->message); cogl_error_free (error); error = NULL; continue; } g_print ("Original:\n"); g_print ("%s\n", strings[i].string); if (count > 0) print_statement (0, &statements[0]); if (count > 1) print_statement (1, &statements[1]); } return 0; }
CoglBool cogl_buffer_set_data (CoglBuffer *buffer, size_t offset, const void *data, size_t size) { CoglError *ignore_error = NULL; CoglBool status = _cogl_buffer_set_data (buffer, offset, data, size, &ignore_error); if (!status) cogl_error_free (ignore_error); return status; }
void * cogl_buffer_map (CoglBuffer *buffer, CoglBufferAccess access, CoglBufferMapHint hints) { CoglError *ignore_error = NULL; void *ptr = cogl_buffer_map_range (buffer, 0, buffer->size, access, hints, &ignore_error); if (!ptr) cogl_error_free (ignore_error); return ptr; }
/* This first tries to upload the texture to a CoglTexture2D, but * if that's not possible it falls back to a CoglTexture2DSliced. * * Auto-mipmapping of any uploaded texture is disabled */ static CoglTexture * video_texture_new_from_data (CoglContext *ctx, int width, int height, CoglPixelFormat format, CoglPixelFormat internal_format, int rowstride, const uint8_t *data, CoglError **error) { CoglBitmap *bitmap; CoglTexture *tex; CoglError *internal_error = NULL; bitmap = cogl_bitmap_new_for_data (ctx, width, height, format, rowstride, (uint8_t *) data); if ((is_pot (cogl_bitmap_get_width (bitmap)) && is_pot (cogl_bitmap_get_height (bitmap))) || cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC)) { tex = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmap, internal_format, &internal_error)); if (!tex) { cogl_error_free (internal_error); internal_error = NULL; } } else tex = NULL; if (!tex) { /* Otherwise create a sliced texture */ CoglTexture2DSliced *tex_2ds = cogl_texture_2d_sliced_new_from_bitmap (bitmap, -1, /* no maximum waste */ internal_format, error); tex = COGL_TEXTURE (tex_2ds); } cogl_object_unref (bitmap); return tex; }
static void texture_tower_revalidate_fbo (MetaTextureTower *tower, int level) { CoglTexture *source_texture = tower->textures[level - 1]; int source_texture_width = cogl_texture_get_width (source_texture); int source_texture_height = cogl_texture_get_height (source_texture); CoglTexture *dest_texture = tower->textures[level]; int dest_texture_width = cogl_texture_get_width (dest_texture); int dest_texture_height = cogl_texture_get_height (dest_texture); Box *invalid = &tower->invalid[level]; CoglFramebuffer *fb; CoglError *catch_error = NULL; CoglPipeline *pipeline; if (tower->fbos[level] == NULL) tower->fbos[level] = cogl_offscreen_new_with_texture (dest_texture); fb = COGL_FRAMEBUFFER (tower->fbos[level]); if (!cogl_framebuffer_allocate (fb, &catch_error)) { cogl_error_free (catch_error); return; } cogl_framebuffer_orthographic (fb, 0, 0, dest_texture_width, dest_texture_height, -1., 1.); if (!tower->pipeline_template) { CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); tower->pipeline_template = cogl_pipeline_new (ctx); cogl_pipeline_set_blend (tower->pipeline_template, "RGBA = ADD (SRC_COLOR, 0)", NULL); } pipeline = cogl_pipeline_copy (tower->pipeline_template); cogl_pipeline_set_layer_texture (pipeline, 0, tower->textures[level - 1]); cogl_framebuffer_draw_textured_rectangle (fb, pipeline, invalid->x1, invalid->y1, invalid->x2, invalid->y2, (2. * invalid->x1) / source_texture_width, (2. * invalid->y1) / source_texture_height, (2. * invalid->x2) / source_texture_width, (2. * invalid->y2) / source_texture_height); cogl_object_unref (pipeline); }
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 gboolean cogl_pango_glyph_cache_add_to_global_atlas (CoglPangoGlyphCache *cache, PangoFont *font, PangoGlyph glyph, CoglPangoGlyphCacheValue *value) { CoglAtlasTexture *texture; CoglError *ignore_error = NULL; if (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SHARED_ATLAS)) return FALSE; /* If the cache is using mipmapping then we can't use the global atlas because it would just get migrated back out */ if (cache->use_mipmapping) return FALSE; texture = cogl_atlas_texture_new_with_size (cache->ctx, value->draw_width, value->draw_height); if (!cogl_texture_allocate (COGL_TEXTURE (texture), &ignore_error)) { cogl_error_free (ignore_error); return FALSE; } value->texture = COGL_TEXTURE (texture); value->tx1 = 0; value->ty1 = 0; value->tx2 = 1; value->ty2 = 1; value->tx_pixel = 0; value->ty_pixel = 0; /* The first time we store a texture in the global atlas we'll register for notifications when the global atlas is reorganized so we can forward the notification on as a glyph reorganization */ if (!cache->using_global_atlas) { _cogl_atlas_texture_add_reorganize_callback (cache->ctx, cogl_pango_glyph_cache_reorganize_cb, cache); cache->using_global_atlas = TRUE; } return TRUE; }
CoglTexture * cogl_texture_new_from_bitmap (CoglBitmap *bitmap, CoglTextureFlags flags, CoglPixelFormat internal_format) { CoglError *ignore_error = NULL; CoglTexture *tex = _cogl_texture_new_from_bitmap (bitmap, flags, internal_format, FALSE, /* can't convert in-place */ &ignore_error); if (!tex) cogl_error_free (ignore_error); return tex; }
CoglContext * _cogl_context_get_default (void) { CoglError *error = NULL; /* Create if doesn't exist yet */ if (_cogl_context == NULL) { _cogl_context = cogl_context_new (NULL, &error); if (!_cogl_context) { g_warning ("Failed to create default context: %s", error->message); cogl_error_free (error); } } return _cogl_context; }
static void st_texture_cache_reset_texture (StTextureCachePropertyBind *bind, const char *propname) { cairo_surface_t *surface; CoglTexture *texdata; ClutterBackend *backend = clutter_get_default_backend (); CoglContext *ctx = clutter_backend_get_cogl_context (backend); g_object_get (bind->source, propname, &surface, NULL); if (surface != NULL && cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_IMAGE && (cairo_image_surface_get_format (surface) == CAIRO_FORMAT_ARGB32 || cairo_image_surface_get_format (surface) == CAIRO_FORMAT_RGB24)) { CoglError *error = NULL; texdata = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface), cairo_image_surface_get_format (surface) == CAIRO_FORMAT_ARGB32 ? COGL_PIXEL_FORMAT_BGRA_8888 : COGL_PIXEL_FORMAT_BGR_888, cairo_image_surface_get_stride (surface), cairo_image_surface_get_data (surface), &error)); if (texdata) { clutter_texture_set_cogl_texture (bind->texture, texdata); cogl_object_unref (texdata); } else if (error) { g_warning ("Failed to allocate texture: %s", error->message); cogl_error_free (error); } clutter_actor_set_opacity (CLUTTER_ACTOR (bind->texture), 255); } else clutter_actor_set_opacity (CLUTTER_ACTOR (bind->texture), 0); }
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; }
CoglTexture * st_cogl_texture_new_from_data_wrapper (int width, int height, CoglTextureFlags flags, CoglPixelFormat format, CoglPixelFormat internal_format, int rowstride, const uint8_t *data) { CoglTexture *texture = NULL; if (hardware_supports_npot_sizes ()) { CoglError *error = NULL; texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (cogl_context, width, height, format, #if COGL_VERSION < COGL_VERSION_ENCODE (1, 18, 0) COGL_PIXEL_FORMAT_ANY, #endif rowstride, data, &error)); if (error) { g_debug ("(st) cogl_texture_2d_new_from_data failed: %s\n", error->message); cogl_error_free (error); } } else { texture = cogl_texture_new_from_data (width, height, flags, format, internal_format, rowstride, data); } return texture; }
void _clutter_backend_reset_cogl_framebuffer (ClutterBackend *backend) { if (backend->dummy_onscreen == COGL_INVALID_HANDLE) { CoglError *internal_error = NULL; backend->dummy_onscreen = cogl_onscreen_new (backend->cogl_context, 1, 1); if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (backend->dummy_onscreen), &internal_error)) { g_critical ("Unable to create dummy onscreen: %s", internal_error->message); cogl_error_free (internal_error); return; } } cogl_set_framebuffer (COGL_FRAMEBUFFER (backend->dummy_onscreen)); }
static CoglTexture * pixbuf_to_cogl_texture (GdkPixbuf *pixbuf) { ClutterBackend *backend = clutter_get_default_backend (); CoglContext *ctx = clutter_backend_get_cogl_context (backend); CoglError *error = NULL; CoglTexture2D *texture; texture = cogl_texture_2d_new_from_data (ctx, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), gdk_pixbuf_get_has_alpha (pixbuf) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888, gdk_pixbuf_get_rowstride (pixbuf), gdk_pixbuf_get_pixels (pixbuf), &error); if (error) { g_warning ("Failed to allocate texture: %s", error->message); cogl_error_free (error); } return texture ? COGL_TEXTURE (texture) : NULL; }
void * _cogl_buffer_map_range_for_fill_or_fallback (CoglBuffer *buffer, size_t offset, size_t size) { CoglContext *ctx = buffer->context; void *ret; CoglError *ignore_error = NULL; _COGL_RETURN_VAL_IF_FAIL (!ctx->buffer_map_fallback_in_use, NULL); ctx->buffer_map_fallback_in_use = TRUE; ret = cogl_buffer_map_range (buffer, offset, size, COGL_BUFFER_ACCESS_WRITE, COGL_BUFFER_MAP_HINT_DISCARD, &ignore_error); if (ret) return ret; cogl_error_free (ignore_error); /* If the map fails then we'll use a temporary buffer to fill the data and then upload it using cogl_buffer_set_data when the buffer is unmapped. The temporary buffer is shared to avoid reallocating it every time */ g_byte_array_set_size (ctx->buffer_map_fallback_array, size); ctx->buffer_map_fallback_offset = offset; buffer->flags |= COGL_BUFFER_FLAG_MAPPED_FALLBACK; return ctx->buffer_map_fallback_array->data; }
int main (int argc, char **argv) { CoglOnscreenTemplate *onscreen_template; CoglDisplay *display; CoglContext *ctx; CoglOnscreen *onscreen; CoglFramebuffer *fb; CoglError *error = NULL; CoglVertexP2C4 triangle_vertices[] = { {0, 0.7, 0xff, 0x00, 0x00, 0x80}, {-0.7, -0.7, 0x00, 0xff, 0x00, 0xff}, {0.7, -0.7, 0x00, 0x00, 0xff, 0xff} }; CoglPrimitive *triangle; CoglTexture *tex; CoglOffscreen *offscreen; CoglFramebuffer *offscreen_fb; CoglPipeline *pipeline; onscreen_template = cogl_onscreen_template_new (NULL); cogl_onscreen_template_set_samples_per_pixel (onscreen_template, 4); display = cogl_display_new (NULL, onscreen_template); if (!cogl_display_setup (display, &error)) { fprintf (stderr, "Platform doesn't support onscreen 4x msaa rendering: %s\n", error->message); return 1; } ctx = cogl_context_new (display, &error); if (!ctx) { fprintf (stderr, "Failed to create context: %s\n", error->message); return 1; } onscreen = cogl_onscreen_new (ctx, 640, 480); fb = COGL_FRAMEBUFFER (onscreen); cogl_framebuffer_set_samples_per_pixel (fb, 4); if (!cogl_framebuffer_allocate (fb, &error)) { fprintf (stderr, "Failed to allocate 4x msaa offscreen framebuffer, " "disabling msaa for onscreen rendering: %s\n", error->message); cogl_error_free (error); cogl_framebuffer_set_samples_per_pixel (fb, 0); error = NULL; if (!cogl_framebuffer_allocate (fb, &error)) { fprintf (stderr, "Failed to allocate framebuffer: %s\n", error->message); return 1; } } cogl_onscreen_show (onscreen); tex = cogl_texture_new_with_size (ctx, 320, 480, COGL_TEXTURE_NO_SLICING, COGL_PIXEL_FORMAT_ANY); offscreen = cogl_offscreen_new_to_texture (tex); offscreen_fb = COGL_FRAMEBUFFER (offscreen); cogl_framebuffer_set_samples_per_pixel (offscreen_fb, 4); if (!cogl_framebuffer_allocate (offscreen_fb, &error)) { cogl_error_free (error); error = NULL; fprintf (stderr, "Failed to allocate 4x msaa offscreen framebuffer, " "disabling msaa for offscreen rendering"); cogl_framebuffer_set_samples_per_pixel (offscreen_fb, 0); } triangle = cogl_primitive_new_p2c4 (ctx, COGL_VERTICES_MODE_TRIANGLES, 3, triangle_vertices); pipeline = cogl_pipeline_new (ctx); for (;;) { CoglPollFD *poll_fds; int n_poll_fds; int64_t timeout; CoglPipeline *texture_pipeline; cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1); cogl_framebuffer_push_matrix (fb); cogl_framebuffer_scale (fb, 0.5, 1, 1); cogl_framebuffer_translate (fb, -1, 0, 0); cogl_framebuffer_draw_primitive (fb, pipeline, triangle); cogl_framebuffer_pop_matrix (fb); cogl_framebuffer_draw_primitive (fb, pipeline, triangle); cogl_framebuffer_resolve_samples (offscreen_fb); texture_pipeline = cogl_pipeline_new (ctx); cogl_pipeline_set_layer_texture (texture_pipeline, 0, tex); cogl_framebuffer_draw_rectangle (fb, texture_pipeline, 0, 1, 1, -1); cogl_object_unref (texture_pipeline); cogl_onscreen_swap_buffers (onscreen); cogl_poll_get_info (ctx, &poll_fds, &n_poll_fds, &timeout); g_poll ((GPollFD *) poll_fds, n_poll_fds, 0); cogl_poll_dispatch (ctx, poll_fds, n_poll_fds); } return 0; }
static void cogland_surface_commit (struct wl_client *client, struct wl_resource *resource) { CoglandSurface *surface = wl_resource_get_user_data (resource); CoglandCompositor *compositor = surface->compositor; /* wl_surface.attach */ if (surface->pending.newly_attached && surface->buffer_ref.buffer != surface->pending.buffer) { CoglError *error = NULL; if (surface->texture) { cogl_object_unref (surface->texture); surface->texture = NULL; } cogland_buffer_reference (&surface->buffer_ref, surface->pending.buffer); if (surface->pending.buffer) { struct wl_resource *buffer_resource = surface->pending.buffer->resource; surface->texture = cogl_wayland_texture_2d_new_from_buffer (compositor->cogl_context, buffer_resource, &error); if (!surface->texture) { g_error ("Failed to create texture_2d from wayland buffer: %s", error->message); cogl_error_free (error); } } } if (surface->pending.buffer) { wl_list_remove (&surface->pending.buffer_destroy_listener.link); surface->pending.buffer = NULL; } surface->pending.sx = 0; surface->pending.sy = 0; surface->pending.newly_attached = FALSE; /* wl_surface.damage */ if (surface->buffer_ref.buffer && surface->texture && !region_is_empty (&surface->pending.damage)) { CoglandRegion *region = &surface->pending.damage; CoglTexture *texture = surface->texture; if (region->x2 > cogl_texture_get_width (texture)) region->x2 = cogl_texture_get_width (texture); if (region->y2 > cogl_texture_get_height (texture)) region->y2 = cogl_texture_get_height (texture); if (region->x1 < 0) region->x1 = 0; if (region->y1 < 0) region->y1 = 0; surface_damaged (surface, region->x1, region->y1, region->x2 - region->x1, region->y2 - region->y1); } region_init (&surface->pending.damage); /* wl_surface.frame */ wl_list_insert_list (&compositor->frame_callbacks, &surface->pending.frame_callback_list); wl_list_init (&surface->pending.frame_callback_list); }
int main (int argc, char **argv) { CoglandCompositor compositor; GMainLoop *loop; CoglError *error = NULL; GError *gerror = 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; if (!process_arguments (&argc, &argv, &gerror)) { fprintf (stderr, "%s\n", gerror->message); return EXIT_FAILURE; } memset (&compositor, 0, sizeof (compositor)); compositor.wayland_display = wl_display_create (); if (compositor.wayland_display == NULL) g_error ("failed to create wayland display"); wl_list_init (&compositor.frame_callbacks); if (!wl_display_add_global (compositor.wayland_display, &wl_compositor_interface, &compositor, compositor_bind)) g_error ("Failed to register wayland compositor object"); wl_display_init_shm (compositor.wayland_display); loop = g_main_loop_new (NULL, FALSE); compositor.wayland_loop = wl_display_get_event_loop (compositor.wayland_display); compositor.wayland_event_source = wayland_event_source_new (compositor.wayland_display); g_source_attach (compositor.wayland_event_source, NULL); /* We want Cogl to use an EGL renderer because otherwise it won't * set up the wl_drm object and only SHM buffers will work. */ compositor.cogl_context = create_cogl_context (&compositor, TRUE /* use EGL constraint */, &error); if (compositor.cogl_context == NULL) { /* If we couldn't get an EGL context then try any type of * context */ cogl_error_free (error); error = NULL; compositor.cogl_context = create_cogl_context (&compositor, FALSE, /* don't set EGL constraint */ &error); if (compositor.cogl_context) g_warning ("Failed to create context with EGL constraint, " "falling back"); else g_error ("Failed to create a Cogl context: %s\n", error->message); } compositor.virtual_width = 800; compositor.virtual_height = 600; if (option_multiple_outputs) { int hw = compositor.virtual_width / 2; int hh = compositor.virtual_height / 2; /* Emulate compositing with multiple monitors... */ cogland_compositor_create_output (&compositor, 0, 0, hw, hh); cogland_compositor_create_output (&compositor, hw, 0, hw, hh); cogland_compositor_create_output (&compositor, 0, hh, hw, hh); cogland_compositor_create_output (&compositor, hw, hh, hw, hh); } else { cogland_compositor_create_output (&compositor, 0, 0, compositor.virtual_width, compositor.virtual_height); } if (wl_display_add_global (compositor.wayland_display, &wl_shell_interface, &compositor, bind_shell) == NULL) g_error ("Failed to register a global shell object"); if (wl_display_add_socket (compositor.wayland_display, "wayland-0")) g_error ("Failed to create socket"); compositor.triangle = cogl_primitive_new_p2c4 (compositor.cogl_context, COGL_VERTICES_MODE_TRIANGLES, 3, triangle_vertices); compositor.triangle_pipeline = cogl_pipeline_new (compositor.cogl_context); cogl_source = cogl_glib_source_new (compositor.cogl_context, G_PRIORITY_DEFAULT); g_source_attach (cogl_source, NULL); g_main_loop_run (loop); return 0; }
CoglPipeline * _st_create_shadow_pipeline_from_actor (StShadow *shadow_spec, ClutterActor *actor) { CoglPipeline *shadow_pipeline = NULL; if (CLUTTER_IS_TEXTURE (actor)) { CoglTexture *texture; texture = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (actor)); shadow_pipeline = _st_create_shadow_pipeline (shadow_spec, texture); } else { CoglTexture *buffer; CoglOffscreen *offscreen; CoglFramebuffer *fb; ClutterActorBox box; CoglColor clear_color; float width, height; CoglError *catch_error = NULL; clutter_actor_get_allocation_box (actor, &box); clutter_actor_box_get_size (&box, &width, &height); if (width == 0 || height == 0) return NULL; buffer = cogl_texture_new_with_size (width, height, COGL_TEXTURE_NO_SLICING, COGL_PIXEL_FORMAT_ANY); if (buffer == NULL) return NULL; offscreen = cogl_offscreen_new_with_texture (buffer); fb = COGL_FRAMEBUFFER (offscreen); if (!cogl_framebuffer_allocate (fb, &catch_error)) { cogl_error_free (catch_error); cogl_object_unref (buffer); return NULL; } cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 0); /* XXX: There's no way to render a ClutterActor to an offscreen * as it uses the implicit API. */ G_GNUC_BEGIN_IGNORE_DEPRECATIONS; cogl_push_framebuffer (fb); G_GNUC_END_IGNORE_DEPRECATIONS; cogl_framebuffer_clear (fb, COGL_BUFFER_BIT_COLOR, &clear_color); cogl_framebuffer_translate (fb, -box.x1, -box.y1, 0); cogl_framebuffer_orthographic (fb, 0, 0, width, height, 0, 1.0); clutter_actor_set_opacity_override (actor, 255); clutter_actor_paint (actor); clutter_actor_set_opacity_override (actor, -1); G_GNUC_BEGIN_IGNORE_DEPRECATIONS; cogl_pop_framebuffer (); G_GNUC_END_IGNORE_DEPRECATIONS; cogl_object_unref (fb); shadow_pipeline = _st_create_shadow_pipeline (shadow_spec, buffer); cogl_object_unref (buffer); } return shadow_pipeline; }
static void emit_vertex_buffer_geometry (CoglFramebuffer *fb, CoglPipeline *pipeline, CoglPangoDisplayListNode *node) { CoglContext *ctx = fb->context; /* It's expensive to go through the Cogl journal for large runs * of text in part because the journal transforms the quads in software * to avoid changing the modelview matrix. So for larger runs of text * we load the vertices into a VBO, and this has the added advantage * that if the text doesn't change from frame to frame the VBO can * be re-used avoiding the repeated cost of validating the data and * mapping it into the GPU... */ if (node->d.texture.primitive == NULL) { CoglAttributeBuffer *buffer; CoglVertexP2T2 *verts, *v; int n_verts; CoglBool allocated = FALSE; CoglAttribute *attributes[2]; CoglPrimitive *prim; int i; CoglError *ignore_error = NULL; n_verts = node->d.texture.rectangles->len * 4; buffer = cogl_attribute_buffer_new_with_size (ctx, n_verts * sizeof (CoglVertexP2T2)); if ((verts = cogl_buffer_map (COGL_BUFFER (buffer), COGL_BUFFER_ACCESS_WRITE, COGL_BUFFER_MAP_HINT_DISCARD, &ignore_error)) == NULL) { cogl_error_free (ignore_error); verts = g_new (CoglVertexP2T2, n_verts); allocated = TRUE; } v = verts; /* Copy the rectangles into the buffer and expand into four vertices instead of just two */ for (i = 0; i < node->d.texture.rectangles->len; i++) { const CoglPangoDisplayListRectangle *rectangle = &g_array_index (node->d.texture.rectangles, CoglPangoDisplayListRectangle, i); v->x = rectangle->x_1; v->y = rectangle->y_1; v->s = rectangle->s_1; v->t = rectangle->t_1; v++; v->x = rectangle->x_1; v->y = rectangle->y_2; v->s = rectangle->s_1; v->t = rectangle->t_2; v++; v->x = rectangle->x_2; v->y = rectangle->y_2; v->s = rectangle->s_2; v->t = rectangle->t_2; v++; v->x = rectangle->x_2; v->y = rectangle->y_1; v->s = rectangle->s_2; v->t = rectangle->t_1; v++; } if (allocated) { cogl_buffer_set_data (COGL_BUFFER (buffer), 0, /* offset */ verts, sizeof (CoglVertexP2T2) * n_verts, NULL); g_free (verts); } else cogl_buffer_unmap (COGL_BUFFER (buffer)); attributes[0] = cogl_attribute_new (buffer, "cogl_position_in", sizeof (CoglVertexP2T2), G_STRUCT_OFFSET (CoglVertexP2T2, x), 2, /* n_components */ COGL_ATTRIBUTE_TYPE_FLOAT); attributes[1] = cogl_attribute_new (buffer, "cogl_tex_coord0_in", sizeof (CoglVertexP2T2), G_STRUCT_OFFSET (CoglVertexP2T2, s), 2, /* n_components */ COGL_ATTRIBUTE_TYPE_FLOAT); prim = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES, n_verts, attributes, 2 /* n_attributes */); #ifdef CLUTTER_COGL_HAS_GL if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_QUADS)) cogl_primitive_set_mode (prim, GL_QUADS); else #endif { /* GLES doesn't support GL_QUADS so instead we use a VBO with indexed vertices to generate GL_TRIANGLES from the quads */ CoglIndices *indices = cogl_get_rectangle_indices (ctx, node->d.texture.rectangles->len); cogl_primitive_set_indices (prim, indices, node->d.texture.rectangles->len * 6); } node->d.texture.primitive = prim; cogl_object_unref (buffer); cogl_object_unref (attributes[0]); cogl_object_unref (attributes[1]); } cogl_primitive_draw (node->d.texture.primitive, fb, pipeline); }
static CoglBool allocate_from_bitmap (CoglTexture3D *tex_3d, CoglTextureLoader *loader, CoglError **error) { CoglTexture *tex = COGL_TEXTURE (tex_3d); CoglContext *ctx = tex->context; CoglPixelFormat internal_format; CoglBitmap *bmp = loader->src.bitmap.bitmap; int bmp_width = cogl_bitmap_get_width (bmp); int height = loader->src.bitmap.height; int depth = loader->src.bitmap.depth; CoglPixelFormat bmp_format = cogl_bitmap_get_format (bmp); CoglBool can_convert_in_place = loader->src.bitmap.can_convert_in_place; CoglBitmap *upload_bmp; CoglPixelFormat upload_format; GLenum gl_intformat; GLenum gl_format; GLenum gl_type; internal_format = _cogl_texture_determine_internal_format (tex, bmp_format); if (!_cogl_texture_3d_can_create (ctx, bmp_width, height, depth, internal_format, error)) return FALSE; upload_bmp = _cogl_bitmap_convert_for_upload (bmp, internal_format, can_convert_in_place, error); if (upload_bmp == NULL) return FALSE; upload_format = cogl_bitmap_get_format (upload_bmp); ctx->driver_vtable->pixel_format_to_gl (ctx, upload_format, NULL, /* internal format */ &gl_format, &gl_type); ctx->driver_vtable->pixel_format_to_gl (ctx, internal_format, &gl_intformat, NULL, NULL); /* Keep a copy of the first pixel so that if glGenerateMipmap isn't supported we can fallback to using GL_GENERATE_MIPMAP */ if (!cogl_has_feature (ctx, COGL_FEATURE_ID_OFFSCREEN)) { CoglError *ignore = NULL; uint8_t *data = _cogl_bitmap_map (upload_bmp, COGL_BUFFER_ACCESS_READ, 0, &ignore); tex_3d->first_pixel.gl_format = gl_format; tex_3d->first_pixel.gl_type = gl_type; if (data) { memcpy (tex_3d->first_pixel.data, data, _cogl_pixel_format_get_bytes_per_pixel (upload_format)); _cogl_bitmap_unmap (upload_bmp); } else { g_warning ("Failed to read first pixel of bitmap for " "glGenerateMipmap fallback"); cogl_error_free (ignore); memset (tex_3d->first_pixel.data, 0, _cogl_pixel_format_get_bytes_per_pixel (upload_format)); } } tex_3d->gl_texture = ctx->texture_driver->gen (ctx, GL_TEXTURE_3D, internal_format); if (!ctx->texture_driver->upload_to_gl_3d (ctx, GL_TEXTURE_3D, tex_3d->gl_texture, FALSE, /* is_foreign */ height, depth, upload_bmp, gl_intformat, gl_format, gl_type, error)) { cogl_object_unref (upload_bmp); return FALSE; } tex_3d->gl_format = gl_intformat; cogl_object_unref (upload_bmp); tex_3d->depth = loader->src.bitmap.depth; tex_3d->internal_format = internal_format; _cogl_texture_set_allocated (tex, internal_format, bmp_width, loader->src.bitmap.height); return TRUE; }
/* For reference: There was some deliberation over whether to have a * constructor that could throw an exception but looking at standard * practices with several high level OO languages including python, C++, * C# Java and Ruby they all support exceptions in constructors and the * general consensus appears to be that throwing an exception is neater * than successfully constructing with an internal error status that * would then have to be explicitly checked via some form of ::is_ok() * method. */ CoglContext * cogl_context_new (CoglDisplay *display, CoglError **error) { CoglContext *context; uint8_t white_pixel[] = { 0xff, 0xff, 0xff, 0xff }; CoglBitmap *white_pixel_bitmap; const CoglWinsysVtable *winsys; int i; CoglError *internal_error = NULL; _cogl_init (); #ifdef COGL_ENABLE_PROFILE /* We need to be absolutely sure that uprof has been initialized * before calling _cogl_uprof_init. uprof_init (NULL, NULL) * will be a NOP if it has been initialized but it will also * mean subsequent parsing of the UProf GOptionGroup will have no * affect. * * Sadly GOptionGroup based library initialization is extremely * fragile by design because GOptionGroups have no notion of * dependencies and so the order things are initialized isn't * currently under tight control. */ uprof_init (NULL, NULL); _cogl_uprof_init (); #endif /* Allocate context memory */ context = g_malloc0 (sizeof (CoglContext)); /* Convert the context into an object immediately in case any of the code below wants to verify that the context pointer is a valid object */ _cogl_context_object_new (context); /* XXX: Gross hack! * Currently everything in Cogl just assumes there is a default * context which it can access via _COGL_GET_CONTEXT() including * code used to construct a CoglContext. Until all of that code * has been updated to take an explicit context argument we have * to immediately make our pointer the default context. */ _cogl_context = context; /* Init default values */ memset (context->features, 0, sizeof (context->features)); context->feature_flags = 0; memset (context->private_features, 0, sizeof (context->private_features)); context->rectangle_state = COGL_WINSYS_RECTANGLE_STATE_UNKNOWN; memset (context->winsys_features, 0, sizeof (context->winsys_features)); if (!display) { CoglRenderer *renderer = cogl_renderer_new (); if (!cogl_renderer_connect (renderer, error)) { g_free (context); return NULL; } display = cogl_display_new (renderer, NULL); cogl_object_unref(renderer); } else cogl_object_ref (display); if (!cogl_display_setup (display, error)) { cogl_object_unref (display); g_free (context); return NULL; } context->display = display; /* This is duplicated data, but it's much more convenient to have the driver attached to the context and the value is accessed a lot throughout Cogl */ context->driver = display->renderer->driver; /* Again this is duplicated data, but it convenient to be able * access these from the context. */ context->driver_vtable = display->renderer->driver_vtable; context->texture_driver = display->renderer->texture_driver; for (i = 0; i < G_N_ELEMENTS (context->private_features); i++) context->private_features[i] |= display->renderer->private_features[i]; winsys = _cogl_context_get_winsys (context); if (!winsys->context_init (context, error)) { cogl_object_unref (display); g_free (context); return NULL; } context->attribute_name_states_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); context->attribute_name_index_map = NULL; context->n_attribute_names = 0; /* The "cogl_color_in" attribute needs a deterministic name_index * so we make sure it's the first attribute name we register */ _cogl_attribute_register_attribute_name (context, "cogl_color_in"); context->uniform_names = g_ptr_array_new_with_free_func ((GDestroyNotify) g_free); context->uniform_name_hash = g_hash_table_new (g_str_hash, g_str_equal); context->n_uniform_names = 0; /* Initialise the driver specific state */ _cogl_init_feature_overrides (context); /* XXX: ONGOING BUG: Intel viewport scissor * * Intel gen6 drivers don't currently correctly handle offset * viewports, since primitives aren't clipped within the bounds of * the viewport. To workaround this we push our own clip for the * viewport that will use scissoring to ensure we clip as expected. * * TODO: file a bug upstream! */ if (context->gpu.driver_package == COGL_GPU_INFO_DRIVER_PACKAGE_MESA && context->gpu.architecture == COGL_GPU_INFO_ARCHITECTURE_SANDYBRIDGE && !getenv ("COGL_DISABLE_INTEL_VIEWPORT_SCISSORT_WORKAROUND")) context->needs_viewport_scissor_workaround = TRUE; else context->needs_viewport_scissor_workaround = FALSE; context->sampler_cache = _cogl_sampler_cache_new (context); _cogl_pipeline_init_default_pipeline (); _cogl_pipeline_init_default_layers (); _cogl_pipeline_init_state_hash_functions (); _cogl_pipeline_init_layer_state_hash_functions (); context->current_clip_stack_valid = FALSE; context->current_clip_stack = NULL; context->legacy_backface_culling_enabled = FALSE; cogl_matrix_init_identity (&context->identity_matrix); cogl_matrix_init_identity (&context->y_flip_matrix); cogl_matrix_scale (&context->y_flip_matrix, 1, -1, 1); context->flushed_matrix_mode = COGL_MATRIX_MODELVIEW; context->texture_units = g_array_new (FALSE, FALSE, sizeof (CoglTextureUnit)); if (_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_ANY_GL)) { /* See cogl-pipeline.c for more details about why we leave texture unit 1 * active by default... */ context->active_texture_unit = 1; GE (context, glActiveTexture (GL_TEXTURE1)); } context->legacy_fog_state.enabled = FALSE; context->opaque_color_pipeline = cogl_pipeline_new (context); context->blended_color_pipeline = cogl_pipeline_new (context); context->texture_pipeline = cogl_pipeline_new (context); context->codegen_header_buffer = g_string_new (""); context->codegen_source_buffer = g_string_new (""); context->codegen_boilerplate_buffer = g_string_new (""); context->source_stack = NULL; context->legacy_state_set = 0; context->default_gl_texture_2d_tex = NULL; context->default_gl_texture_3d_tex = NULL; context->default_gl_texture_rect_tex = NULL; context->framebuffers = NULL; context->current_draw_buffer = NULL; context->current_read_buffer = NULL; context->current_draw_buffer_state_flushed = 0; context->current_draw_buffer_changes = COGL_FRAMEBUFFER_STATE_ALL; context->swap_callback_closures = g_hash_table_new (g_direct_hash, g_direct_equal); _cogl_list_init (&context->onscreen_events_queue); _cogl_list_init (&context->onscreen_dirty_queue); g_queue_init (&context->gles2_context_stack); context->journal_flush_attributes_array = g_array_new (TRUE, FALSE, sizeof (CoglAttribute *)); context->journal_clip_bounds = NULL; context->polygon_vertices = g_array_new (FALSE, FALSE, sizeof (float)); context->current_pipeline = NULL; context->current_pipeline_changes_since_flush = 0; context->current_pipeline_with_color_attrib = FALSE; _cogl_bitmask_init (&context->enabled_builtin_attributes); _cogl_bitmask_init (&context->enable_builtin_attributes_tmp); _cogl_bitmask_init (&context->enabled_texcoord_attributes); _cogl_bitmask_init (&context->enable_texcoord_attributes_tmp); _cogl_bitmask_init (&context->enabled_custom_attributes); _cogl_bitmask_init (&context->enable_custom_attributes_tmp); _cogl_bitmask_init (&context->changed_bits_tmp); context->max_texture_units = -1; context->max_activateable_texture_units = -1; context->current_fragment_program_type = COGL_PIPELINE_PROGRAM_TYPE_GLSL; context->current_vertex_program_type = COGL_PIPELINE_PROGRAM_TYPE_GLSL; context->current_gl_program = 0; context->current_gl_dither_enabled = TRUE; context->current_gl_color_mask = COGL_COLOR_MASK_ALL; context->gl_blend_enable_cache = FALSE; context->depth_test_enabled_cache = FALSE; context->depth_test_function_cache = COGL_DEPTH_TEST_FUNCTION_LESS; context->depth_writing_enabled_cache = TRUE; context->depth_range_near_cache = 0; context->depth_range_far_cache = 1; context->legacy_depth_test_enabled = FALSE; context->pipeline_cache = _cogl_pipeline_cache_new (); for (i = 0; i < COGL_BUFFER_BIND_TARGET_COUNT; i++) context->current_buffer[i] = NULL; context->window_buffer = NULL; context->framebuffer_stack = _cogl_create_framebuffer_stack (); /* XXX: In this case the Clutter backend is still responsible for * the OpenGL binding API and for creating onscreen framebuffers and * so we have to add a dummy framebuffer to represent the backend * owned window... */ if (_cogl_context_get_winsys (context) == _cogl_winsys_stub_get_vtable ()) { CoglOnscreen *window = _cogl_onscreen_new (); cogl_set_framebuffer (COGL_FRAMEBUFFER (window)); cogl_object_unref (COGL_FRAMEBUFFER (window)); } context->current_path = NULL; context->stencil_pipeline = cogl_pipeline_new (context); context->in_begin_gl_block = FALSE; context->quad_buffer_indices_byte = NULL; context->quad_buffer_indices = NULL; context->quad_buffer_indices_len = 0; context->rectangle_byte_indices = NULL; context->rectangle_short_indices = NULL; context->rectangle_short_indices_len = 0; context->texture_download_pipeline = NULL; context->blit_texture_pipeline = NULL; #ifdef HAVE_COGL_GL if (_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_ALPHA_TEST)) /* The default for GL_ALPHA_TEST is to always pass which is equivalent to * the test being disabled therefore we assume that for all drivers there * will be no performance impact if we always leave the test enabled which * makes things a bit simpler for us. Under GLES2 the alpha test is * implemented in the fragment shader so there is no enable for it */ GE (context, glEnable (GL_ALPHA_TEST)); if ((context->driver == COGL_DRIVER_GL3)) { GLuint vertex_array; /* In a forward compatible context, GL 3 doesn't support rendering * using the default vertex array object. Cogl doesn't use vertex * array objects yet so for now we just create a dummy array * object that we will use as our own default object. Eventually * it could be good to attach the vertex array objects to * CoglPrimitives */ context->glGenVertexArrays (1, &vertex_array); context->glBindVertexArray (vertex_array); } #endif context->current_modelview_entry = NULL; context->current_projection_entry = NULL; _cogl_matrix_entry_identity_init (&context->identity_entry); _cogl_matrix_entry_cache_init (&context->builtin_flushed_projection); _cogl_matrix_entry_cache_init (&context->builtin_flushed_modelview); /* Create default textures used for fall backs */ context->default_gl_texture_2d_tex = cogl_texture_2d_new_from_data (context, 1, 1, COGL_PIXEL_FORMAT_RGBA_8888_PRE, 0, /* rowstride */ white_pixel, NULL); /* abort on error */ /* If 3D or rectangle textures aren't supported then these will * return errors that we can simply ignore. */ internal_error = NULL; context->default_gl_texture_3d_tex = cogl_texture_3d_new_from_data (context, 1, 1, 1, /* width, height, depth */ COGL_PIXEL_FORMAT_RGBA_8888_PRE, 0, /* rowstride */ 0, /* image stride */ white_pixel, &internal_error); if (internal_error) cogl_error_free (internal_error); /* TODO: add cogl_texture_rectangle_new_from_data() */ white_pixel_bitmap = cogl_bitmap_new_for_data (context, 1, 1, /* width/height */ COGL_PIXEL_FORMAT_RGBA_8888_PRE, 4, /* rowstride */ white_pixel); internal_error = NULL; context->default_gl_texture_rect_tex = cogl_texture_rectangle_new_from_bitmap (white_pixel_bitmap); /* XXX: we need to allocate the texture now because the white_pixel * data is on the stack */ cogl_texture_allocate (COGL_TEXTURE (context->default_gl_texture_rect_tex), &internal_error); if (internal_error) cogl_error_free (internal_error); cogl_object_unref (white_pixel_bitmap); cogl_push_source (context->opaque_color_pipeline); context->atlases = NULL; g_hook_list_init (&context->atlas_reorganize_callbacks, sizeof (GHook)); context->buffer_map_fallback_array = g_byte_array_new (); context->buffer_map_fallback_in_use = FALSE; /* As far as I can tell, GL_POINT_SPRITE doesn't have any effect unless GL_COORD_REPLACE is enabled for an individual layer. Therefore it seems like it should be ok to just leave it enabled all the time instead of having to have a set property on each pipeline to track whether any layers have point sprite coords enabled. We don't need to do this for GL3 or GLES2 because point sprites are handled using a builtin varying in the shader. */ if (_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_GL_FIXED) && cogl_has_feature (context, COGL_FEATURE_ID_POINT_SPRITE)) GE (context, glEnable (GL_POINT_SPRITE)); _cogl_list_init (&context->fences); return context; }