cogl-texture: Split out _cogl_texture_prepare_for_upload

The Cogl atlas code was using _cogl_texture_prepare_for_upload with a
NULL pointer for the dst_bmp to determine the internal format of the
texture without converting the bitmap. It needs to do this to decide
whether the texture will go in the atlas before wasting time on the
conversion. This use of the function is a little confusing so that
part of it has been split out into a new function called
_cogl_texture_determine_internal_format. The code to decide whether a
premult conversion is needed has also been split out.
This commit is contained in:
Neil Roberts 2010-02-03 22:54:44 +00:00
parent 5063f4669c
commit 59198b8ab8
3 changed files with 57 additions and 42 deletions

View File

@ -949,15 +949,8 @@ _cogl_atlas_texture_new_from_bitmap (CoglHandle bmp_handle,
COGL_NOTE (ATLAS, "Adding texture of size %ix%i", bmp->width, bmp->height);
if (!_cogl_texture_prepare_for_upload (bmp,
internal_format,
&internal_format,
NULL,
NULL,
&gl_intformat,
&gl_format,
&gl_type))
return COGL_INVALID_HANDLE;
internal_format = _cogl_texture_determine_internal_format (bmp->format,
internal_format);
/* If the texture is in a strange format then we can't use it */
if (internal_format != COGL_PIXEL_FORMAT_RGB_888 &&

View File

@ -150,6 +150,13 @@ _cogl_texture_ensure_mipmaps (CoglHandle handle);
void
_cogl_texture_ensure_non_quad_rendering (CoglHandle handle);
/* Utility function to determine which pixel format to use when
dst_format is COGL_PIXEL_FORMAT_ANY. If dst_format is not ANY then
it will just be returned directly */
CoglPixelFormat
_cogl_texture_determine_internal_format (CoglPixelFormat src_format,
CoglPixelFormat dst_format);
/* Utility function to help uploading a bitmap. If the bitmap needs
premult conversion then it will be copied and *copied_bitmap will
be set to TRUE. Otherwise dst_bmp will be set to a shallow copy of

View File

@ -100,6 +100,36 @@ cogl_texture_unref (CoglHandle handle)
cogl_handle_unref (handle);
}
static gboolean
_cogl_texture_needs_premult_conversion (CoglPixelFormat src_format,
CoglPixelFormat dst_format)
{
return ((src_format & COGL_A_BIT) &&
src_format != COGL_PIXEL_FORMAT_A_8 &&
(src_format & COGL_PREMULT_BIT) !=
(dst_format & COGL_PREMULT_BIT));
}
CoglPixelFormat
_cogl_texture_determine_internal_format (CoglPixelFormat src_format,
CoglPixelFormat dst_format)
{
/* If the application hasn't specified a specific format then we'll
* pick the most appropriate. By default Cogl will use a
* premultiplied internal format. Later we will add control over
* this. */
if (dst_format == COGL_PIXEL_FORMAT_ANY)
{
if ((src_format & COGL_A_BIT) &&
src_format != COGL_PIXEL_FORMAT_A_8)
return src_format | COGL_PREMULT_BIT;
else
return src_format;
}
else
return dst_format;
}
gboolean
_cogl_texture_prepare_for_upload (CoglBitmap *src_bmp,
CoglPixelFormat dst_format,
@ -110,42 +140,27 @@ _cogl_texture_prepare_for_upload (CoglBitmap *src_bmp,
GLenum *out_glformat,
GLenum *out_gltype)
{
/* If the application hasn't specified a specific format then we'll
* pick the most appropriate. By default Cogl will use a
* premultiplied internal format. Later we will add control over
* this. */
if (dst_format == COGL_PIXEL_FORMAT_ANY)
{
if ((src_bmp->format & COGL_A_BIT) &&
src_bmp->format != COGL_PIXEL_FORMAT_A_8)
dst_format = src_bmp->format | COGL_PREMULT_BIT;
else
dst_format = src_bmp->format;
}
dst_format = _cogl_texture_determine_internal_format (src_bmp->format,
dst_format);
if (dst_bmp)
{
*copied_bitmap = FALSE;
*dst_bmp = *src_bmp;
*copied_bitmap = FALSE;
*dst_bmp = *src_bmp;
/* If the source format does not have the same premult flag as the
dst format then we need to copy and convert it */
if ((src_bmp->format & COGL_A_BIT) &&
src_bmp->format != COGL_PIXEL_FORMAT_A_8 &&
(src_bmp->format & COGL_PREMULT_BIT) !=
(dst_format & COGL_PREMULT_BIT))
/* If the source format does not have the same premult flag as the
dst format then we need to copy and convert it */
if (_cogl_texture_needs_premult_conversion (src_bmp->format,
dst_format))
{
dst_bmp->data = g_memdup (dst_bmp->data,
dst_bmp->height * dst_bmp->rowstride);
*copied_bitmap = TRUE;
if (!_cogl_bitmap_convert_premult_status (dst_bmp,
src_bmp->format ^
COGL_PREMULT_BIT))
{
dst_bmp->data = g_memdup (dst_bmp->data,
dst_bmp->height * dst_bmp->rowstride);
*copied_bitmap = TRUE;
if (!_cogl_bitmap_convert_premult_status (dst_bmp,
src_bmp->format ^
COGL_PREMULT_BIT))
{
g_free (dst_bmp->data);
return FALSE;
}
g_free (dst_bmp->data);
return FALSE;
}
}