/* 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 gboolean shm_buffer_attach (MetaWaylandBuffer *buffer, CoglTexture **texture, gboolean *changed_texture, GError **error) { MetaBackend *backend = meta_get_backend (); ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); struct wl_shm_buffer *shm_buffer; int stride, width, height; CoglPixelFormat format; CoglTextureComponents components; CoglBitmap *bitmap; CoglTexture *new_texture; shm_buffer = wl_shm_buffer_get (buffer->resource); stride = wl_shm_buffer_get_stride (shm_buffer); width = wl_shm_buffer_get_width (shm_buffer); height = wl_shm_buffer_get_height (shm_buffer); shm_buffer_get_cogl_pixel_format (shm_buffer, &format, &components); if (*texture && cogl_texture_get_width (*texture) == width && cogl_texture_get_height (*texture) == height && cogl_texture_get_components (*texture) == components && _cogl_texture_get_format (*texture) == format) { buffer->is_y_inverted = TRUE; *changed_texture = FALSE; return TRUE; } cogl_clear_object (texture); wl_shm_buffer_begin_access (shm_buffer); bitmap = cogl_bitmap_new_for_data (cogl_context, width, height, format, stride, wl_shm_buffer_get_data (shm_buffer)); new_texture = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmap)); cogl_texture_set_components (new_texture, components); if (!cogl_texture_allocate (new_texture, error)) { g_clear_pointer (&new_texture, cogl_object_unref); if (g_error_matches (*error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_SIZE)) { CoglTexture2DSliced *texture_sliced; g_clear_error (error); texture_sliced = cogl_texture_2d_sliced_new_from_bitmap (bitmap, COGL_TEXTURE_MAX_WASTE); new_texture = COGL_TEXTURE (texture_sliced); cogl_texture_set_components (new_texture, components); if (!cogl_texture_allocate (new_texture, error)) g_clear_pointer (&new_texture, cogl_object_unref); } } cogl_object_unref (bitmap); wl_shm_buffer_end_access (shm_buffer); if (!new_texture) return FALSE; *texture = new_texture; *changed_texture = TRUE; buffer->is_y_inverted = TRUE; return TRUE; }