static CoglPixelFormat _cogl_sub_texture_get_format (CoglTexture *tex) { CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); return _cogl_texture_get_format (sub_tex->full_texture); }
static CoglPixelFormat _cogl_texture_pixmap_x11_get_format (CoglTexture *tex) { CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); /* Forward on to the child texture */ return _cogl_texture_get_format (child_tex); }
static CoglBool _cogl_sub_texture_allocate (CoglTexture *tex, CoglError **error) { CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); CoglBool status = cogl_texture_allocate (sub_tex->full_texture, error); _cogl_texture_set_allocated (tex, _cogl_texture_get_format (sub_tex->full_texture), tex->width, tex->height); return status; }
CoglSubTexture * cogl_sub_texture_new (CoglContext *ctx, CoglTexture *next_texture, int sub_x, int sub_y, int sub_width, int sub_height) { CoglTexture *full_texture; CoglSubTexture *sub_tex; CoglTexture *tex; unsigned int next_width, next_height; next_width = cogl_texture_get_width (next_texture); next_height = cogl_texture_get_height (next_texture); /* The region must specify a non-zero subset of the full texture */ _COGL_RETURN_VAL_IF_FAIL (sub_x >= 0 && sub_y >= 0, NULL); _COGL_RETURN_VAL_IF_FAIL (sub_width > 0 && sub_height > 0, NULL); _COGL_RETURN_VAL_IF_FAIL (sub_x + sub_width <= next_width, NULL); _COGL_RETURN_VAL_IF_FAIL (sub_y + sub_height <= next_height, NULL); sub_tex = g_new (CoglSubTexture, 1); tex = COGL_TEXTURE (sub_tex); _cogl_texture_init (tex, ctx, sub_width, sub_height, _cogl_texture_get_format (next_texture), NULL, /* no loader */ &cogl_sub_texture_vtable); /* If the next texture is also a sub texture we can avoid one level of indirection by referencing the full texture of that texture instead. */ if (cogl_is_sub_texture (next_texture)) { CoglSubTexture *other_sub_tex = COGL_SUB_TEXTURE (next_texture); full_texture = other_sub_tex->full_texture; sub_x += other_sub_tex->sub_x; sub_y += other_sub_tex->sub_y; } else full_texture = next_texture; sub_tex->next_texture = cogl_object_ref (next_texture); sub_tex->full_texture = cogl_object_ref (full_texture); sub_tex->sub_x = sub_x; sub_tex->sub_y = sub_y; return _cogl_sub_texture_object_new (sub_tex); }
static CoglBool _cogl_texture_rectangle_set_region (CoglTexture *tex, int src_x, int src_y, int dst_x, int dst_y, int dst_width, int dst_height, int level, CoglBitmap *bmp, CoglError **error) { CoglBitmap *upload_bmp; GLenum gl_format; GLenum gl_type; CoglContext *ctx = tex->context; CoglBool status; upload_bmp = _cogl_bitmap_convert_for_upload (bmp, _cogl_texture_get_format (tex), FALSE, /* can't convert in place */ error); if (upload_bmp == NULL) return FALSE; ctx->driver_vtable->pixel_format_to_gl (ctx, cogl_bitmap_get_format (upload_bmp), NULL, /* internal format */ &gl_format, &gl_type); /* Send data to GL */ status = ctx->texture_driver->upload_subregion_to_gl (ctx, tex, FALSE, src_x, src_y, dst_x, dst_y, dst_width, dst_height, level, upload_bmp, gl_format, gl_type, error); cogl_object_unref (upload_bmp); return status; }
gboolean _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d, int src_x, int src_y, int width, int height, CoglBitmap *bmp, int dst_x, int dst_y, int level, CoglError **error) { CoglTexture *tex = COGL_TEXTURE (tex_2d); CoglContext *ctx = tex->context; CoglBitmap *upload_bmp; CoglPixelFormat upload_format; GLenum gl_format; GLenum gl_type; gboolean status = TRUE; upload_bmp = _cogl_bitmap_convert_for_upload (bmp, _cogl_texture_get_format (tex), FALSE, /* can't 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 gl format */ &gl_format, &gl_type); /* If this touches the first pixel then we'll update our copy */ if (dst_x == 0 && dst_y == 0 && !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); CoglPixelFormat bpp = _cogl_pixel_format_get_bytes_per_pixel (upload_format); tex_2d->first_pixel.gl_format = gl_format; tex_2d->first_pixel.gl_type = gl_type; if (data) { memcpy (tex_2d->first_pixel.data, (data + cogl_bitmap_get_rowstride (upload_bmp) * src_y + bpp * src_x), bpp); _cogl_bitmap_unmap (bmp); } else { g_warning ("Failed to read first bitmap pixel for " "glGenerateMipmap fallback"); cogl_error_free (ignore); memset (tex_2d->first_pixel.data, 0, bpp); } } status = ctx->texture_driver->upload_subregion_to_gl (ctx, tex, FALSE, src_x, src_y, dst_x, dst_y, width, height, level, upload_bmp, gl_format, gl_type, error); cogl_object_unref (upload_bmp); _cogl_texture_gl_maybe_update_max_level (tex, level); return status; }
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; }