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>

(cherry picked from commit 218da8e1349d7658f45c6933b9736c0d32941b8b)

Conflicts:
	cogl/cogl-auto-texture.c
This commit is contained in:
Robert Bragg 2013-06-08 18:52:20 +01:00 committed by Neil Roberts
parent aa92110f83
commit 061240ef2a
5 changed files with 289 additions and 36 deletions

View File

@ -54,6 +54,16 @@ _cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
CoglBool can_convert_in_place, CoglBool can_convert_in_place,
CoglError **error); CoglError **error);
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 * CoglTexture *
cogl_texture_new_with_size (unsigned int width, cogl_texture_new_with_size (unsigned int width,
unsigned int height, unsigned int height,
@ -88,13 +98,7 @@ cogl_texture_new_with_size (unsigned int width,
else else
tex = NULL; tex = NULL;
if (tex) 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 it fails resort to sliced textures */ /* If it fails resort to sliced textures */
int max_waste = flags & COGL_TEXTURE_NO_SLICING ? -1 : COGL_TEXTURE_MAX_WASTE; int max_waste = flags & COGL_TEXTURE_NO_SLICING ? -1 : COGL_TEXTURE_MAX_WASTE;
@ -105,6 +109,22 @@ cogl_texture_new_with_size (unsigned int width,
internal_format)); 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; return tex;
} }
@ -219,22 +239,28 @@ _cogl_texture_new_from_bitmap (CoglBitmap *bitmap,
else else
tex = NULL; tex = NULL;
if (tex) 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 */ /* 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, tex = COGL_TEXTURE (_cogl_texture_2d_sliced_new_from_bitmap (bitmap,
flags, max_waste,
internal_format, internal_format,
can_convert_in_place, can_convert_in_place,
error)); 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; return tex;
} }

View File

@ -54,7 +54,7 @@ _cogl_texture_2d_sliced_new_from_foreign (CoglContext *context,
CoglTexture2DSliced * CoglTexture2DSliced *
_cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
CoglTextureFlags flags, int max_waste,
CoglPixelFormat internal_format, CoglPixelFormat internal_format,
CoglBool can_convert_in_place, CoglBool can_convert_in_place,
CoglError **error); CoglError **error);

View File

@ -956,7 +956,7 @@ _cogl_texture_2d_sliced_allocate (CoglTexture *tex,
CoglTexture2DSliced * CoglTexture2DSliced *
_cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
CoglTextureFlags flags, int max_waste,
CoglPixelFormat internal_format, CoglPixelFormat internal_format,
CoglBool can_convert_in_place, CoglBool can_convert_in_place,
CoglError **error) CoglError **error)
@ -964,8 +964,7 @@ _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
CoglContext *ctx; CoglContext *ctx;
CoglTexture2DSliced *tex_2ds; CoglTexture2DSliced *tex_2ds;
CoglBitmap *upload_bmp; CoglBitmap *upload_bmp;
int width, height, max_waste; int width, height;
int i;
_COGL_RETURN_VAL_IF_FAIL (cogl_is_bitmap (bmp), NULL); _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 */ /* Create new texture and fill with loaded data */
tex_2ds = g_new0 (CoglTexture2DSliced, 1); tex_2ds = g_new0 (CoglTexture2DSliced, 1);
if (flags & COGL_TEXTURE_NO_SLICING)
max_waste = -1;
else
max_waste = COGL_TEXTURE_MAX_WASTE;
internal_format = internal_format =
_cogl_texture_determine_internal_format (cogl_bitmap_get_format (bmp), _cogl_texture_determine_internal_format (cogl_bitmap_get_format (bmp),
internal_format); internal_format);
@ -1016,18 +1010,6 @@ _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
cogl_object_unref (upload_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); return _cogl_texture_2d_sliced_object_new (tex_2ds);
error: error:
@ -1036,6 +1018,19 @@ _cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp,
return NULL; return NULL;
} }
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 * CoglTexture2DSliced *
_cogl_texture_2d_sliced_new_from_foreign (CoglContext *ctx, _cogl_texture_2d_sliced_new_from_foreign (CoglContext *ctx,
unsigned int gl_handle, unsigned int gl_handle,
@ -1128,6 +1123,70 @@ _cogl_texture_2d_sliced_new_from_foreign (CoglContext *ctx,
return _cogl_texture_2d_sliced_object_new (tex_2ds); 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_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 static CoglBool
_cogl_texture_2d_sliced_is_foreign (CoglTexture *tex) _cogl_texture_2d_sliced_is_foreign (CoglTexture *tex)
{ {

View File

@ -113,6 +113,171 @@ cogl_texture_2d_sliced_new_with_size (CoglContext *ctx,
int max_waste, int max_waste,
CoglPixelFormat internal_format); 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: * cogl_is_texture_2d_sliced:
* @object: A #CoglObject pointer * @object: A #CoglObject pointer

View File

@ -483,6 +483,9 @@ cogl_is_atlas_texture
<TITLE>Sliced Textures</TITLE> <TITLE>Sliced Textures</TITLE>
CoglTexture2DSliced CoglTexture2DSliced
cogl_texture_2d_sliced_new_with_size 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 cogl_is_texture_2d_sliced
</SECTION> </SECTION>