CoglTexture2D * _cogl_texture_2d_new_from_bitmap (CoglBitmap *bmp, CoglPixelFormat internal_format, CoglBool can_convert_in_place, CoglError **error) { CoglContext *ctx; _COGL_RETURN_VAL_IF_FAIL (bmp != NULL, NULL); ctx = _cogl_bitmap_get_context (bmp); internal_format = _cogl_texture_determine_internal_format (cogl_bitmap_get_format (bmp), internal_format); if (!_cogl_texture_2d_can_create (ctx, cogl_bitmap_get_width (bmp), cogl_bitmap_get_height (bmp), internal_format)) { _cogl_set_error (error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_SIZE, "Failed to create texture 2d due to size/format" " constraints"); return NULL; } return ctx->driver_vtable->texture_2d_new_from_bitmap (bmp, internal_format, can_convert_in_place, error); }
CoglTextureRectangle * cogl_texture_rectangle_new_from_bitmap (CoglBitmap *bmp) { CoglTextureLoader *loader; _COGL_RETURN_VAL_IF_FAIL (cogl_is_bitmap (bmp), NULL); loader = _cogl_texture_create_loader (); loader->src_type = COGL_TEXTURE_SOURCE_TYPE_BITMAP; loader->src.bitmap.bitmap = cogl_object_ref (bmp); loader->src.bitmap.can_convert_in_place = FALSE; /* TODO add api for this */ return _cogl_texture_rectangle_create_base (_cogl_bitmap_get_context (bmp), cogl_bitmap_get_width (bmp), cogl_bitmap_get_height (bmp), cogl_bitmap_get_format (bmp), loader); }
static CoglTexture2D * _cogl_texture_2d_new_from_bitmap (CoglBitmap *bmp, CoglBool can_convert_in_place) { CoglTextureLoader *loader; _COGL_RETURN_VAL_IF_FAIL (bmp != NULL, NULL); loader = _cogl_texture_create_loader (); loader->src_type = COGL_TEXTURE_SOURCE_TYPE_BITMAP; loader->src.bitmap.bitmap = cogl_object_ref (bmp); loader->src.bitmap.can_convert_in_place = can_convert_in_place; return _cogl_texture_2d_create_base (_cogl_bitmap_get_context (bmp), cogl_bitmap_get_width (bmp), cogl_bitmap_get_height (bmp), cogl_bitmap_get_format (bmp), loader); }
CoglTexture3D * cogl_texture_3d_new_from_bitmap (CoglBitmap *bmp, int height, int depth) { CoglTextureLoader *loader; _COGL_RETURN_VAL_IF_FAIL (bmp, NULL); loader = _cogl_texture_create_loader (); loader->src_type = COGL_TEXTURE_SOURCE_TYPE_BITMAP; loader->src.bitmap.bitmap = cogl_object_ref (bmp); loader->src.bitmap.height = height; loader->src.bitmap.depth = depth; loader->src.bitmap.can_convert_in_place = FALSE; /* TODO add api for this */ return _cogl_texture_3d_create_base (_cogl_bitmap_get_context (bmp), cogl_bitmap_get_width (bmp), height, depth, cogl_bitmap_get_format (bmp), loader); }
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 CoglTexture * _cogl_texture_new_from_bitmap (CoglBitmap *bitmap, CoglTextureFlags flags, CoglPixelFormat internal_format, CoglBool can_convert_in_place, CoglError **error) { CoglContext *ctx = _cogl_bitmap_get_context (bitmap); CoglTexture *tex; CoglError *internal_error = NULL; if (!flags && !COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_ATLAS)) { /* First try putting the texture in the atlas */ CoglAtlasTexture *atlas_tex = _cogl_atlas_texture_new_from_bitmap (bitmap, can_convert_in_place); _cogl_texture_set_internal_format (COGL_TEXTURE (atlas_tex), internal_format); if (cogl_texture_allocate (COGL_TEXTURE (atlas_tex), &internal_error)) return COGL_TEXTURE (atlas_tex); cogl_error_free (internal_error); internal_error = NULL; cogl_object_unref (atlas_tex); } /* If that doesn't work try a fast path 2D texture */ if ((_cogl_util_is_pot (bitmap->width) && _cogl_util_is_pot (bitmap->height)) || (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) && cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP))) { tex = COGL_TEXTURE (_cogl_texture_2d_new_from_bitmap (bitmap, can_convert_in_place)); _cogl_texture_set_internal_format (tex, internal_format); if (!cogl_texture_allocate (tex, &internal_error)) { cogl_error_free (internal_error); internal_error = NULL; cogl_object_unref (tex); tex = NULL; } } else tex = NULL; if (!tex) { /* Otherwise create a sliced texture */ int max_waste = flags & COGL_TEXTURE_NO_SLICING ? -1 : COGL_TEXTURE_MAX_WASTE; tex = COGL_TEXTURE (_cogl_texture_2d_sliced_new_from_bitmap (bitmap, max_waste, can_convert_in_place)); _cogl_texture_set_internal_format (tex, internal_format); if (!cogl_texture_allocate (tex, error)) { cogl_object_unref (tex); tex = 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; }
CoglTexture * cogl_texture_new_from_bitmap (CoglBitmap *bitmap, CoglTextureFlags flags, CoglPixelFormat internal_format, CoglError **error) { CoglContext *ctx = _cogl_bitmap_get_context (bitmap); CoglAtlasTexture *atlas_tex; CoglTexture *tex; CoglError *internal_error = NULL; /* First try putting the texture in the atlas */ if ((atlas_tex = _cogl_atlas_texture_new_from_bitmap (bitmap, flags, internal_format, &internal_error))) return COGL_TEXTURE (atlas_tex); if (cogl_error_matches (internal_error, COGL_SYSTEM_ERROR, COGL_SYSTEM_ERROR_NO_MEMORY)) { _cogl_propagate_error (error, internal_error); return NULL; } cogl_error_free (internal_error); internal_error = NULL; /* If that doesn't work try a fast path 2D texture */ if ((_cogl_util_is_pot (bitmap->width) && _cogl_util_is_pot (bitmap->height)) || (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_BASIC) && cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT_MIPMAP))) { tex = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmap, internal_format, &internal_error)); if (cogl_error_matches (internal_error, COGL_SYSTEM_ERROR, COGL_SYSTEM_ERROR_NO_MEMORY)) { _cogl_propagate_error (error, internal_error); return NULL; } if (!tex) { cogl_error_free (internal_error); internal_error = 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 { /* Otherwise create a sliced texture */ tex = COGL_TEXTURE (_cogl_texture_2d_sliced_new_from_bitmap (bitmap, flags, internal_format, error)); } return tex; }