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; }
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; }
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 allocate_from_bitmap (CoglTexture2D *tex_2d, CoglTextureLoader *loader, CoglError **error) { CoglTexture *tex = COGL_TEXTURE (tex_2d); CoglBitmap *bmp = loader->src.bitmap.bitmap; CoglContext *ctx = _cogl_bitmap_get_context (bmp); CoglPixelFormat internal_format; int width = cogl_bitmap_get_width (bmp); int height = cogl_bitmap_get_height (bmp); gboolean can_convert_in_place = loader->src.bitmap.can_convert_in_place; CoglBitmap *upload_bmp; GLenum gl_intformat; GLenum gl_format; GLenum gl_type; internal_format = _cogl_texture_determine_internal_format (tex, cogl_bitmap_get_format (bmp)); if (!_cogl_texture_2d_gl_can_create (ctx, width, height, internal_format)) { _cogl_set_error (error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_SIZE, "Failed to create texture 2d due to size/format" " constraints"); return FALSE; } upload_bmp = _cogl_bitmap_convert_for_upload (bmp, internal_format, can_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); 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); CoglPixelFormat format = cogl_bitmap_get_format (upload_bmp); 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_pixel_format_get_bytes_per_pixel (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_2d->first_pixel.data, 0, _cogl_pixel_format_get_bytes_per_pixel (format)); } } tex_2d->gl_texture = ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, internal_format); if (!ctx->texture_driver->upload_to_gl (ctx, GL_TEXTURE_2D, tex_2d->gl_texture, FALSE, upload_bmp, gl_intformat, gl_format, gl_type, error)) { cogl_object_unref (upload_bmp); return FALSE; } tex_2d->gl_internal_format = gl_intformat; cogl_object_unref (upload_bmp); tex_2d->internal_format = internal_format; _cogl_texture_set_allocated (tex, internal_format, width, height); return TRUE; }
static CoglBool allocate_from_bitmap (CoglTextureRectangle *tex_rect, CoglTextureLoader *loader, CoglError **error) { CoglTexture *tex = COGL_TEXTURE (tex_rect); CoglContext *ctx = tex->context; CoglPixelFormat internal_format; CoglBitmap *bmp = loader->src.bitmap.bitmap; int width = cogl_bitmap_get_width (bmp); int height = cogl_bitmap_get_height (bmp); CoglBool can_convert_in_place = loader->src.bitmap.can_convert_in_place; CoglBitmap *upload_bmp; GLenum gl_intformat; GLenum gl_format; GLenum gl_type; internal_format = _cogl_texture_determine_internal_format (tex, cogl_bitmap_get_format (bmp)); if (!_cogl_texture_rectangle_can_create (ctx, width, height, 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; ctx->driver_vtable->pixel_format_to_gl (ctx, cogl_bitmap_get_format (upload_bmp), NULL, /* internal format */ &gl_format, &gl_type); ctx->driver_vtable->pixel_format_to_gl (ctx, internal_format, &gl_intformat, NULL, NULL); tex_rect->gl_texture = ctx->texture_driver->gen (ctx, GL_TEXTURE_RECTANGLE_ARB, internal_format); if (!ctx->texture_driver->upload_to_gl (ctx, GL_TEXTURE_RECTANGLE_ARB, tex_rect->gl_texture, FALSE, upload_bmp, gl_intformat, gl_format, gl_type, error)) { cogl_object_unref (upload_bmp); return FALSE; } tex_rect->gl_format = gl_intformat; tex_rect->internal_format = internal_format; cogl_object_unref (upload_bmp); _cogl_texture_set_allocated (COGL_TEXTURE (tex_rect), internal_format, width, height); return TRUE; }