diff options
author | Robert Bragg <robert@linux.intel.com> | 2013-06-08 18:52:20 +0100 |
---|---|---|
committer | Robert Bragg <robert@linux.intel.com> | 2013-07-11 21:05:53 +0100 |
commit | 218da8e1349d7658f45c6933b9736c0d32941b8b (patch) | |
tree | 985cdad2ff2d3ee541cb19ab80786bdc1cd6cbea | |
parent | 10e91aa513123ed277a8d45976f8d75445d7dc9c (diff) | |
download | cogl-218da8e1349d7658f45c6933b9736c0d32941b8b.tar.gz |
2d-sliced: add _new_from_file/data/bitmap apis
This adds cogl_texture_2d_sliced_new_from_bitmap/data/file apis in
preparation for removing the cogl_texture_new_from_bitmap/file apis that
are considered a bit too magic, but we don't want to loose the
convenience they have.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
-rw-r--r-- | cogl/cogl-auto-texture.c | 57 | ||||
-rw-r--r-- | cogl/cogl-texture-2d-sliced-private.h | 2 | ||||
-rw-r--r-- | cogl/cogl-texture-2d-sliced.c | 99 | ||||
-rw-r--r-- | cogl/cogl-texture-2d-sliced.h | 165 | ||||
-rw-r--r-- | doc/reference/cogl2/cogl2-sections.txt | 3 |
5 files changed, 289 insertions, 37 deletions
diff --git a/cogl/cogl-auto-texture.c b/cogl/cogl-auto-texture.c index 6ee5e5f2..476b2659 100644 --- a/cogl/cogl-auto-texture.c +++ b/cogl/cogl-auto-texture.c @@ -46,6 +46,16 @@ #include "cogl-sub-texture.h" #include "cogl-texture-2d-gl.h" +static void +set_auto_mipmap_cb (CoglTexture *sub_texture, + const float *sub_texture_coords, + const float *meta_coords, + void *user_data) +{ + cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (sub_texture), + FALSE); +} + CoglTexture * cogl_texture_new_with_size (CoglContext *ctx, int width, @@ -79,17 +89,10 @@ cogl_texture_new_with_size (CoglContext *ctx, 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 (!tex) { /* 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, @@ -97,6 +100,22 @@ cogl_texture_new_with_size (CoglContext *ctx, internal_format)); } + if (tex && + flags & COGL_TEXTURE_NO_AUTO_MIPMAP) + { + /* To be able to iterate the slices of a #CoglTexture2DSliced we + * need to ensure the texture is allocated... */ + if (!cogl_texture_allocate (tex, NULL)) + return NULL; + + 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; } @@ -181,22 +200,28 @@ _cogl_texture_new_from_bitmap (CoglBitmap *bitmap, 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 (!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, - flags, + max_waste, internal_format, can_convert_in_place, error)); } + 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; } diff --git a/cogl/cogl-texture-2d-sliced-private.h b/cogl/cogl-texture-2d-sliced-private.h index 2d5106f9..4ba30c51 100644 --- a/cogl/cogl-texture-2d-sliced-private.h +++ b/cogl/cogl-texture-2d-sliced-private.h @@ -54,7 +54,7 @@ _cogl_texture_2d_sliced_new_from_foreign (CoglContext *context, CoglTexture2DSliced * _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, - CoglTextureFlags flags, + int max_waste, CoglPixelFormat internal_format, CoglBool can_convert_in_place, CoglError **error); diff --git a/cogl/cogl-texture-2d-sliced.c b/cogl/cogl-texture-2d-sliced.c index 88e0553f..c2fdc853 100644 --- a/cogl/cogl-texture-2d-sliced.c +++ b/cogl/cogl-texture-2d-sliced.c @@ -956,7 +956,7 @@ _cogl_texture_2d_sliced_allocate (CoglTexture *tex, CoglTexture2DSliced * _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, - CoglTextureFlags flags, + int max_waste, CoglPixelFormat internal_format, CoglBool can_convert_in_place, CoglError **error) @@ -964,8 +964,7 @@ _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, CoglContext *ctx; CoglTexture2DSliced *tex_2ds; CoglBitmap *upload_bmp; - int width, height, max_waste; - int i; + int width, height; _COGL_RETURN_VAL_IF_FAIL (cogl_is_bitmap (bmp), NULL); @@ -977,11 +976,6 @@ _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, /* Create new texture and fill with loaded data */ tex_2ds = g_new0 (CoglTexture2DSliced, 1); - if (flags & COGL_TEXTURE_NO_SLICING) - max_waste = -1; - else - max_waste = COGL_TEXTURE_MAX_WASTE; - internal_format = _cogl_texture_determine_internal_format (cogl_bitmap_get_format (bmp), internal_format); @@ -1016,18 +1010,6 @@ _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, cogl_object_unref (upload_bmp); - if ((flags & COGL_TEXTURE_NO_AUTO_MIPMAP)) - for (i = 0; i < tex_2ds->slice_textures->len; i++) - { - CoglPrimitiveTexture *slice_tex; - - slice_tex = g_array_index (tex_2ds->slice_textures, - CoglPrimitiveTexture *, - i); - - cogl_primitive_texture_set_auto_mipmap (slice_tex, FALSE); - } - return _cogl_texture_2d_sliced_object_new (tex_2ds); error: @@ -1037,6 +1019,19 @@ _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, } CoglTexture2DSliced * +cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, + int max_waste, + CoglPixelFormat internal_format, + CoglError **error) +{ + return _cogl_texture_2d_sliced_new_from_bitmap (bmp, + max_waste, + internal_format, + FALSE, + error); +} + +CoglTexture2DSliced * _cogl_texture_2d_sliced_new_from_foreign (CoglContext *ctx, unsigned int gl_handle, unsigned int gl_target, @@ -1128,6 +1123,70 @@ _cogl_texture_2d_sliced_new_from_foreign (CoglContext *ctx, return _cogl_texture_2d_sliced_object_new (tex_2ds); } +CoglTexture2DSliced * +cogl_texture_2d_sliced_new_from_data (CoglContext *ctx, + int width, + int height, + int max_waste, + CoglPixelFormat format, + CoglPixelFormat internal_format, + int rowstride, + const uint8_t *data, + CoglError **error) +{ + CoglBitmap *bmp; + CoglTexture2DSliced *tex_2ds; + + _COGL_RETURN_VAL_IF_FAIL (format != COGL_PIXEL_FORMAT_ANY, NULL); + _COGL_RETURN_VAL_IF_FAIL (data != NULL, NULL); + + /* Rowstride from width if not given */ + if (rowstride == 0) + rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format); + + /* Wrap the data into a bitmap */ + bmp = cogl_bitmap_new_for_data (ctx, + width, height, + format, + rowstride, + (uint8_t *) data); + + tex_2ds = cogl_texture_2d_sliced_new_from_bitmap (bmp, max_waste, + internal_format, + error); + + cogl_object_unref (bmp); + + return tex_2ds; +} + +CoglTexture2DSliced * +cogl_texture_2d_sliced_new_from_file (CoglContext *ctx, + const char *filename, + int max_waste, + CoglPixelFormat internal_format, + CoglError **error) +{ + CoglBitmap *bmp; + CoglTexture2DSliced *tex_2ds = NULL; + + _COGL_RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, NULL); + + bmp = cogl_bitmap_new_from_file (ctx, filename, error); + if (bmp == NULL) + return NULL; + + tex_2ds = _cogl_texture_2d_sliced_new_from_bitmap (bmp, + max_waste, + internal_format, + TRUE, /* can convert in-place */ + error); + + cogl_object_unref (bmp); + + return tex_2ds; +} + static CoglBool _cogl_texture_2d_sliced_is_foreign (CoglTexture *tex) { diff --git a/cogl/cogl-texture-2d-sliced.h b/cogl/cogl-texture-2d-sliced.h index e26157e6..882bdd68 100644 --- a/cogl/cogl-texture-2d-sliced.h +++ b/cogl/cogl-texture-2d-sliced.h @@ -114,6 +114,171 @@ cogl_texture_2d_sliced_new_with_size (CoglContext *ctx, CoglPixelFormat internal_format); /** + * cogl_texture_2d_sliced_new_from_file: + * @ctx: A #CoglContext + * @filename: the file to load + * @max_waste: The threshold of how wide a strip of wasted texels + * are allowed along the right and bottom textures before + * they must be sliced to reduce the amount of waste. A + * negative can be passed to disable slicing. + * @internal_format: the #CoglPixelFormat to use for the GPU storage of the + * texture. If %COGL_PIXEL_FORMAT_ANY is given then a premultiplied + * format similar to the format of the source data will be used. The + * default blending equations of Cogl expect premultiplied color data; + * the main use of passing a non-premultiplied format here is if you + * have non-premultiplied source data and are going to adjust the blend + * mode (see cogl_material_set_blend()) or use the data for something + * other than straight blending. + * @error: A #CoglError to catch exceptional errors or %NULL + * + * Creates a #CoglTexture2DSliced from an image file. + * + * A #CoglTexture2DSliced may internally be comprised of 1 or more + * #CoglTexture2D textures depending on GPU limitations. For example + * if the GPU only supports power-of-two sized textures then a sliced + * texture will turn a non-power-of-two size into a combination of + * smaller power-of-two sized textures. If the requested texture size + * is larger than is supported by the hardware then the texture will + * be sliced into smaller textures that can be accessed by the + * hardware. + * + * @max_waste is used as a threshold for recursively slicing the + * right-most or bottom-most slices into smaller sizes until the + * wasted padding at the bottom and right of the textures is less than + * specified. A negative @max_waste will disable slicing. + * + * <note>It's possible for the allocation of a sliced texture to fail + * later due to impossible slicing constraints if a negative + * @max_waste value is given. If the given virtual texture size is + * larger than is supported by the hardware but slicing is disabled + * the texture size would be too large to handle.</note> + * + * Return value: A newly created #CoglTexture2DSliced or %NULL on + * failure and @error will be updated. + * + * Since: 1.16 + */ +CoglTexture2DSliced * +cogl_texture_2d_sliced_new_from_file (CoglContext *ctx, + const char *filename, + int max_waste, + CoglPixelFormat internal_format, + CoglError **error); + +/** + * cogl_texture_2d_sliced_new_from_data: + * @width: width of texture in pixels + * @height: height of texture in pixels + * @format: the #CoglPixelFormat the buffer is stored in in RAM + * @max_waste: The threshold of how wide a strip of wasted texels + * are allowed along the right and bottom textures before + * they must be sliced to reduce the amount of waste. A + * negative can be passed to disable slicing. + * @internal_format: the #CoglPixelFormat to use for the GPU storage of the + * texture. If %COGL_PIXEL_FORMAT_ANY is given then a premultiplied + * format similar to the format of the source data will be used. The + * default blending equations of Cogl expect premultiplied color data; + * the main use of passing a non-premultiplied format here is if you + * have non-premultiplied source data and are going to adjust the blend + * mode (see cogl_material_set_blend()) or use the data for something + * other than straight blending. + * @rowstride: the memory offset in bytes between the start of each + * row in @data. A value of 0 will make Cogl automatically + * calculate @rowstride from @width and @format. + * @data: pointer the memory region where the source buffer resides + * @error: A #CoglError to catch exceptional errors or %NULL + * + * Creates a new #CoglTexture2DSliced texture based on data residing + * in memory. + * + * A #CoglTexture2DSliced may internally be comprised of 1 or more + * #CoglTexture2D textures depending on GPU limitations. For example + * if the GPU only supports power-of-two sized textures then a sliced + * texture will turn a non-power-of-two size into a combination of + * smaller power-of-two sized textures. If the requested texture size + * is larger than is supported by the hardware then the texture will + * be sliced into smaller textures that can be accessed by the + * hardware. + * + * @max_waste is used as a threshold for recursively slicing the + * right-most or bottom-most slices into smaller sizes until the + * wasted padding at the bottom and right of the textures is less than + * specified. A negative @max_waste will disable slicing. + * + * <note>It's possible for the allocation of a sliced texture to fail + * later due to impossible slicing constraints if a negative + * @max_waste value is given. If the given virtual texture size is + * larger than is supported by the hardware but slicing is disabled + * the texture size would be too large to handle.</note> + * + * Return value: A newly created #CoglTexture2DSliced or %NULL on + * failure and @error will be updated. + * + * Since: 1.16 + */ +CoglTexture2DSliced * +cogl_texture_2d_sliced_new_from_data (CoglContext *ctx, + int width, + int height, + int max_waste, + CoglPixelFormat format, + CoglPixelFormat internal_format, + int rowstride, + const uint8_t *data, + CoglError **error); + +/** + * cogl_texture_2d_sliced_new_from_bitmap: + * @bitmap: A #CoglBitmap + * @max_waste: The threshold of how wide a strip of wasted texels + * are allowed along the right and bottom textures before + * they must be sliced to reduce the amount of waste. A + * negative can be passed to disable slicing. + * @internal_format: the #CoglPixelFormat to use for the GPU storage of the + * texture. If %COGL_PIXEL_FORMAT_ANY is given then a premultiplied + * format similar to the format of the source data will be used. The + * default blending equations of Cogl expect premultiplied color data; + * the main use of passing a non-premultiplied format here is if you + * have non-premultiplied source data and are going to adjust the blend + * mode (see cogl_material_set_blend()) or use the data for something + * other than straight blending. + * @error: A #CoglError to catch exceptional errors or %NULL + * + * Creates a new #CoglTexture2DSliced texture based on data residing + * in a bitmap. + * + * A #CoglTexture2DSliced may internally be comprised of 1 or more + * #CoglTexture2D textures depending on GPU limitations. For example + * if the GPU only supports power-of-two sized textures then a sliced + * texture will turn a non-power-of-two size into a combination of + * smaller power-of-two sized textures. If the requested texture size + * is larger than is supported by the hardware then the texture will + * be sliced into smaller textures that can be accessed by the + * hardware. + * + * @max_waste is used as a threshold for recursively slicing the + * right-most or bottom-most slices into smaller sizes until the + * wasted padding at the bottom and right of the textures is less than + * specified. A negative @max_waste will disable slicing. + * + * <note>It's possible for the allocation of a sliced texture to fail + * later due to impossible slicing constraints if a negative + * @max_waste value is given. If the given virtual texture size is + * larger than is supported by the hardware but slicing is disabled + * the texture size would be too large to handle.</note> + * + * Return value: A newly created #CoglTexture2DSliced or %NULL on + * failure and @error will be updated. + * + * Since: 1.16 + */ +CoglTexture2DSliced * +cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, + int max_waste, + CoglPixelFormat internal_format, + CoglError **error); + +/** * cogl_is_texture_2d_sliced: * @object: A #CoglObject pointer * diff --git a/doc/reference/cogl2/cogl2-sections.txt b/doc/reference/cogl2/cogl2-sections.txt index fe29a5ff..51fc7a5a 100644 --- a/doc/reference/cogl2/cogl2-sections.txt +++ b/doc/reference/cogl2/cogl2-sections.txt @@ -423,6 +423,9 @@ cogl_is_atlas_texture <TITLE>Sliced Textures</TITLE> CoglTexture2DSliced cogl_texture_2d_sliced_new_with_size +cogl_texture_2d_sliced_new_from_file +cogl_texture_2d_sliced_new_from_data +cogl_texture_2d_sliced_new_from_bitmap cogl_is_texture_2d_sliced </SECTION> |