gles: Support the GL_EXT_texture_format_BGRA8888 extension

This extension allows an application to upload data in BGRA format. We
can use this to avoid a conversion in Cogl whenever it is given BGRA
data. This is quite useful when uploading data generated by Cairo
because at least on little-endian architectures that ends up as BGRA.

The patch just makes the pixel_format_to_gl implementation return
GL_BGRA_EXT for the data format and internal format whenever
COGL_PIXEL_FORMAT_BGRA_8888{,_PRE} is used.

A small caveat with this patch is that once a texture is created as
GL_BGRA, when later using glTexSubImage2D to update the texture it
must always be given data as GL_BGRA. Currently this just works out
because we store the internal format of a texture as a CoglPixelFormat
and we already swizzle the data if it does not match exactly on GLES.
However if we later switch to using a different enum for internal
formats then we might lose the ability to store the component ordering
so we'll have to think of another way to do this.
This commit is contained in:
Neil Roberts 2012-03-21 16:06:59 +00:00
parent d6ca75fbec
commit 21e304b339
3 changed files with 30 additions and 3 deletions

View File

@ -100,7 +100,8 @@ typedef enum
COGL_PRIVATE_FEATURE_PBOS = 1L<<5, COGL_PRIVATE_FEATURE_PBOS = 1L<<5,
COGL_PRIVATE_FEATURE_VBOS = 1L<<6, COGL_PRIVATE_FEATURE_VBOS = 1L<<6,
COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL = 1L<<7, COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL = 1L<<7,
COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL = 1L<<8 COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL = 1L<<8,
COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888 = 1L<<9
} CoglPrivateFeatureFlags; } CoglPrivateFeatureFlags;
/* Sometimes when evaluating pipelines, either during comparisons or /* Sometimes when evaluating pipelines, either during comparisons or

View File

@ -166,6 +166,15 @@ _cogl_texture_determine_internal_format (CoglPixelFormat src_format,
return src_format; return src_format;
} }
else else
/* XXX: It might be nice to make this match the component ordering
of the source format when the formats are otherwise the same
because on GL there is no way to specify the ordering of the
internal format. However when using GLES with the
GL_EXT_texture_format_BGRA8888 the order of the internal format
becomes important because it must exactly match the format of
the uploaded data. That means that if someone creates a texture
with some RGBA data and then later tries to upload BGRA data we
do actually have to swizzle the components */
return dst_format; return dst_format;
} }

View File

@ -69,6 +69,22 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
gltype = GL_UNSIGNED_BYTE; gltype = GL_UNSIGNED_BYTE;
break; break;
case COGL_PIXEL_FORMAT_BGRA_8888:
case COGL_PIXEL_FORMAT_BGRA_8888_PRE:
/* There is an extension to support this format */
if ((context->private_feature_flags &
COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888))
{
/* For some reason the extension says you have to specify
BGRA for the internal format too */
glintformat = GL_BGRA_EXT;
glformat = GL_BGRA_EXT;
gltype = GL_UNSIGNED_BYTE;
required_format = format;
break;
}
/* flow through */
/* Just one 24-bit ordering supported */ /* Just one 24-bit ordering supported */
case COGL_PIXEL_FORMAT_RGB_888: case COGL_PIXEL_FORMAT_RGB_888:
case COGL_PIXEL_FORMAT_BGR_888: case COGL_PIXEL_FORMAT_BGR_888:
@ -81,8 +97,6 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
/* Just one 32-bit ordering supported */ /* Just one 32-bit ordering supported */
case COGL_PIXEL_FORMAT_RGBA_8888: case COGL_PIXEL_FORMAT_RGBA_8888:
case COGL_PIXEL_FORMAT_RGBA_8888_PRE: case COGL_PIXEL_FORMAT_RGBA_8888_PRE:
case COGL_PIXEL_FORMAT_BGRA_8888:
case COGL_PIXEL_FORMAT_BGRA_8888_PRE:
case COGL_PIXEL_FORMAT_ARGB_8888: case COGL_PIXEL_FORMAT_ARGB_8888:
case COGL_PIXEL_FORMAT_ARGB_8888_PRE: case COGL_PIXEL_FORMAT_ARGB_8888_PRE:
case COGL_PIXEL_FORMAT_ABGR_8888: case COGL_PIXEL_FORMAT_ABGR_8888:
@ -276,6 +290,9 @@ _cogl_driver_update_features (CoglContext *context,
if (_cogl_check_extension ("GL_OES_packed_depth_stencil", gl_extensions)) if (_cogl_check_extension ("GL_OES_packed_depth_stencil", gl_extensions))
private_flags |= COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL; private_flags |= COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL;
if (_cogl_check_extension ("GL_EXT_texture_format_BGRA8888", gl_extensions))
private_flags |= COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888;
/* Cache features */ /* Cache features */
context->private_feature_flags |= private_flags; context->private_feature_flags |= private_flags;
context->feature_flags |= flags; context->feature_flags |= flags;