Reviewed-by: Robert Bragg &lt;<a href="mailto:robert@linux.intel.com">robert@linux.intel.com</a>&gt;<br><br><div class="gmail_quote">On Thu, Mar 22, 2012 at 5:32 PM, Neil Roberts <span dir="ltr">&lt;<a href="mailto:neil@linux.intel.com">neil@linux.intel.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This extension allows an application to upload data in BGRA format. We<br>
can use this to avoid a conversion in Cogl whenever it is given BGRA<br>
data. This is quite useful when uploading data generated by Cairo<br>
because at least on little-endian architectures that ends up as BGRA.<br>
<br>
The patch just makes the pixel_format_to_gl implementation return<br>
GL_BGRA_EXT for the data format and internal format whenever<br>
COGL_PIXEL_FORMAT_BGRA_8888{,_PRE} is used.<br>
<br>
A small caveat with this patch is that once a texture is created as<br>
GL_BGRA, when later using glTexSubImage2D to update the texture it<br>
must always be given data as GL_BGRA. Currently this just works out<br>
because we store the internal format of a texture as a CoglPixelFormat<br>
and we already swizzle the data if it does not match exactly on GLES.<br>
However if we later switch to using a different enum for internal<br>
formats then we might lose the ability to store the component ordering<br>
so we&#39;ll have to think of another way to do this.<br>
---<br>
 cogl/cogl-internal.h         |    3 ++-<br>
 cogl/cogl-texture.c          |    9 +++++++++<br>
 cogl/driver/gles/cogl-gles.c |   21 +++++++++++++++++++--<br>
 3 files changed, 30 insertions(+), 3 deletions(-)<br>
<br>
diff --git a/cogl/cogl-internal.h b/cogl/cogl-internal.h<br>
index 9019859..4f53cc3 100644<br>
--- a/cogl/cogl-internal.h<br>
+++ b/cogl/cogl-internal.h<br>
@@ -100,7 +100,8 @@ typedef enum<br>
   COGL_PRIVATE_FEATURE_PBOS = 1L&lt;&lt;5,<br>
   COGL_PRIVATE_FEATURE_VBOS = 1L&lt;&lt;6,<br>
   COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL = 1L&lt;&lt;7,<br>
-  COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL = 1L&lt;&lt;8<br>
+  COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL = 1L&lt;&lt;8,<br>
+  COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888 = 1L&lt;&lt;9<br>
 } CoglPrivateFeatureFlags;<br>
<br>
 /* Sometimes when evaluating pipelines, either during comparisons or<br>
diff --git a/cogl/cogl-texture.c b/cogl/cogl-texture.c<br>
index 27cbb64..ab07f91 100644<br>
--- a/cogl/cogl-texture.c<br>
+++ b/cogl/cogl-texture.c<br>
@@ -166,6 +166,15 @@ _cogl_texture_determine_internal_format (CoglPixelFormat src_format,<br>
         return src_format;<br>
     }<br>
   else<br>
+    /* XXX: It might be nice to make this match the component ordering<br>
+       of the source format when the formats are otherwise the same<br>
+       because on GL there is no way to specify the ordering of the<br>
+       internal format. However when using GLES with the<br>
+       GL_EXT_texture_format_BGRA8888 the order of the internal format<br>
+       becomes important because it must exactly match the format of<br>
+       the uploaded data. That means that if someone creates a texture<br>
+       with some RGBA data and then later tries to upload BGRA data we<br>
+       do actually have to swizzle the components */<br>
     return dst_format;<br>
 }<br>
<br>
diff --git a/cogl/driver/gles/cogl-gles.c b/cogl/driver/gles/cogl-gles.c<br>
index d4c5968..102a19f 100644<br>
--- a/cogl/driver/gles/cogl-gles.c<br>
+++ b/cogl/driver/gles/cogl-gles.c<br>
@@ -69,6 +69,22 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,<br>
       gltype = GL_UNSIGNED_BYTE;<br>
       break;<br>
<br>
+    case COGL_PIXEL_FORMAT_BGRA_8888:<br>
+    case COGL_PIXEL_FORMAT_BGRA_8888_PRE:<br>
+      /* There is an extension to support this format */<br>
+      if ((context-&gt;private_feature_flags &amp;<br>
+           COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888))<br>
+        {<br>
+          /* For some reason the extension says you have to specify<br>
+             BGRA for the internal format too */<br>
+          glintformat = GL_BGRA_EXT;<br>
+          glformat = GL_BGRA_EXT;<br>
+          gltype = GL_UNSIGNED_BYTE;<br>
+          required_format = format;<br>
+          break;<br>
+        }<br>
+      /* flow through */<br>
+<br>
       /* Just one 24-bit ordering supported */<br>
     case COGL_PIXEL_FORMAT_RGB_888:<br>
     case COGL_PIXEL_FORMAT_BGR_888:<br>
@@ -81,8 +97,6 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,<br>
       /* Just one 32-bit ordering supported */<br>
     case COGL_PIXEL_FORMAT_RGBA_8888:<br>
     case COGL_PIXEL_FORMAT_RGBA_8888_PRE:<br>
-    case COGL_PIXEL_FORMAT_BGRA_8888:<br>
-    case COGL_PIXEL_FORMAT_BGRA_8888_PRE:<br>
     case COGL_PIXEL_FORMAT_ARGB_8888:<br>
     case COGL_PIXEL_FORMAT_ARGB_8888_PRE:<br>
     case COGL_PIXEL_FORMAT_ABGR_8888:<br>
@@ -276,6 +290,9 @@ _cogl_driver_update_features (CoglContext *context,<br>
   if (_cogl_check_extension (&quot;GL_OES_packed_depth_stencil&quot;, gl_extensions))<br>
     private_flags |= COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL;<br>
<br>
+  if (_cogl_check_extension (&quot;GL_EXT_texture_format_BGRA8888&quot;, gl_extensions))<br>
+    private_flags |= COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888;<br>
+<br>
   /* Cache features */<br>
   context-&gt;private_feature_flags |= private_flags;<br>
   context-&gt;feature_flags |= flags;<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.7.3.16.g9464b<br>
<br>
_______________________________________________<br>
Cogl mailing list<br>
<a href="mailto:Cogl@lists.freedesktop.org">Cogl@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/cogl" target="_blank">http://lists.freedesktop.org/mailman/listinfo/cogl</a><br>
</font></span></blockquote></div><br>