this looks good to me.<div><br></div><div>the only thing is, like your last patch, it adds use of _COGL_GET_CONTEXT() which could be nice to avoid if at all possible.</div><div><br></div><div>kind regards,</div><div>- Robert<br>
<br><div class="gmail_quote">On Wed, Mar 21, 2012 at 6:13 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 lets you upload texture data from a subregion of a<br>
buffer by passing GL_UNPACK_ROW_LENGTH, GL_UNPACK_SKIP_PIXELS and<br>
GL_UNPACK_SKIP_ROWS to glPixelStore. When this extension is available<br>
the GLES texture driver will now avoid making a copy of the bitmap<br>
when a subregion is used.<br>
<br>
Note that Mesa doesn&#39;t currently advertise this extension but I&#39;ve<br>
made a patch to propose it:<br>
<br>
<a href="http://lists.freedesktop.org/archives/mesa-dev/2012-March/020191.html" target="_blank">http://lists.freedesktop.org/archives/mesa-dev/2012-March/020191.html</a><br>
---<br>
 cogl/cogl-internal.h                        |    3 +-<br>
 cogl/driver/gles/cogl-gles.c                |    3 +<br>
 cogl/driver/gles/cogl-texture-driver-gles.c |   60 +++++++++++++++++++++++----<br>
 3 files changed, 57 insertions(+), 9 deletions(-)<br>
<br>
diff --git a/cogl/cogl-internal.h b/cogl/cogl-internal.h<br>
index 4f53cc3..284fc97 100644<br>
--- a/cogl/cogl-internal.h<br>
+++ b/cogl/cogl-internal.h<br>
@@ -101,7 +101,8 @@ typedef enum<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_TEXTURE_FORMAT_BGRA8888 = 1L&lt;&lt;9<br>
+  COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888 = 1L&lt;&lt;9,<br>
+  COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE = 1L&lt;&lt;10<br>
 } CoglPrivateFeatureFlags;<br>
<br>
 /* Sometimes when evaluating pipelines, either during comparisons or<br>
diff --git a/cogl/driver/gles/cogl-gles.c b/cogl/driver/gles/cogl-gles.c<br>
index e0f6500..464ddc6 100644<br>
--- a/cogl/driver/gles/cogl-gles.c<br>
+++ b/cogl/driver/gles/cogl-gles.c<br>
@@ -169,6 +169,9 @@ _cogl_gles_update_features (CoglContext *context,<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>
+  if (_cogl_check_extension (&quot;GL_EXT_unpack_subimage&quot;, gl_extensions))<br>
+    private_flags |= COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE;<br>
+<br>
   /* Cache features */<br>
   context-&gt;private_feature_flags |= private_flags;<br>
   context-&gt;feature_flags |= flags;<br>
diff --git a/cogl/driver/gles/cogl-texture-driver-gles.c b/cogl/driver/gles/cogl-texture-driver-gles.c<br>
index 62a65ee..fc18376 100644<br>
--- a/cogl/driver/gles/cogl-texture-driver-gles.c<br>
+++ b/cogl/driver/gles/cogl-texture-driver-gles.c<br>
@@ -52,6 +52,18 @@<br>
 #define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073<br>
 #endif<br>
<br>
+/* This extension isn&#39;t available for GLES 1.1 so these won&#39;t be<br>
+   defined */<br>
+#ifndef GL_UNPACK_ROW_LENGTH<br>
+#define GL_UNPACK_ROW_LENGTH 0x0CF2<br>
+#endif<br>
+#ifndef GL_UNPACK_SKIP_ROWS<br>
+#define GL_UNPACK_SKIP_ROWS 0x0CF3<br>
+#endif<br>
+#ifndef GL_UNPACK_SKIP_PIXELS<br>
+#define GL_UNPACK_SKIP_PIXELS 0x0CF4<br>
+#endif<br>
+<br>
 static void<br>
 _cogl_texture_driver_gen (GLenum   gl_target,<br>
                           GLsizei  n,<br>
@@ -84,10 +96,37 @@ _cogl_texture_driver_gen (GLenum   gl_target,<br>
 }<br>
<br>
 static void<br>
+prep_gl_for_pixels_upload_full (int pixels_rowstride,<br>
+                                int pixels_src_x,<br>
+                                int pixels_src_y,<br>
+                                int pixels_bpp)<br>
+{<br>
+  _COGL_GET_CONTEXT (ctx, NO_RETVAL);<br>
+<br>
+  if ((ctx-&gt;private_feature_flags &amp; COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE))<br>
+    {<br>
+      GE( ctx, glPixelStorei (GL_UNPACK_ROW_LENGTH,<br>
+                              pixels_rowstride / pixels_bpp) );<br>
+<br>
+      GE( ctx, glPixelStorei (GL_UNPACK_SKIP_PIXELS, pixels_src_x) );<br>
+      GE( ctx, glPixelStorei (GL_UNPACK_SKIP_ROWS, pixels_src_y) );<br>
+    }<br>
+  else<br>
+    {<br>
+      g_assert (pixels_src_x == 0);<br>
+      g_assert (pixels_src_y == 0);<br>
+    }<br>
+<br>
+  _cogl_texture_prep_gl_alignment_for_pixels_upload (pixels_rowstride);<br>
+}<br>
+<br>
+static void<br>
 _cogl_texture_driver_prep_gl_for_pixels_upload (int pixels_rowstride,<br>
                                                 int pixels_bpp)<br>
 {<br>
-  _cogl_texture_prep_gl_alignment_for_pixels_upload (pixels_rowstride);<br>
+  prep_gl_for_pixels_upload_full (pixels_rowstride,<br>
+                                  0, 0, /* src_x/y */<br>
+                                  pixels_bpp);<br>
 }<br>
<br>
 static void<br>
@@ -106,7 +145,10 @@ prepare_bitmap_alignment_for_upload (CoglBitmap *src_bmp)<br>
   int width = cogl_bitmap_get_width (src_bmp);<br>
   int alignment = 1;<br>
<br>
-  if (src_rowstride == 0)<br>
+  _COGL_GET_CONTEXT (ctx, NULL);<br>
+<br>
+  if ((ctx-&gt;private_feature_flags &amp; COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE) ||<br>
+      src_rowstride == 0)<br>
     return cogl_object_ref (src_bmp);<br>
<br>
   /* Work out the alignment of the source rowstride */<br>
@@ -145,11 +187,13 @@ _cogl_texture_driver_upload_subregion_to_gl (GLenum       gl_target,<br>
<br>
   _COGL_GET_CONTEXT (ctx, NO_RETVAL);<br>
<br>
-  /* If we are copying a sub region of the source bitmap then we need<br>
-     to copy it because GLES does not support GL_UNPACK_ROW_LENGTH */<br>
-  if (src_x != 0 || src_y != 0 ||<br>
-      width != cogl_bitmap_get_width (source_bmp) ||<br>
-      height != cogl_bitmap_get_height (source_bmp))<br>
+  /* If we have the GL_EXT_unpack_subimage extension then we can<br>
+     upload from subregions directly. Otherwise we may need to copy<br>
+     the bitmap */<br>
+  if (!(ctx-&gt;private_feature_flags &amp; COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE) &amp;&amp;<br>
+      (src_x != 0 || src_y != 0 ||<br>
+       width != cogl_bitmap_get_width (source_bmp) ||<br>
+       height != cogl_bitmap_get_height (source_bmp)))<br>
     {<br>
       slice_bmp =<br>
         _cogl_bitmap_new_with_malloc_buffer (ctx,<br>
@@ -167,7 +211,7 @@ _cogl_texture_driver_upload_subregion_to_gl (GLenum       gl_target,<br>
   rowstride = cogl_bitmap_get_rowstride (slice_bmp);<br>
<br>
   /* Setup gl alignment to match rowstride and top-left corner */<br>
-  _cogl_texture_driver_prep_gl_for_pixels_upload (rowstride, bpp);<br>
+  prep_gl_for_pixels_upload_full (rowstride, src_x, src_y, bpp);<br>
<br>
   data = _cogl_bitmap_bind (slice_bmp, COGL_BUFFER_ACCESS_READ, 0);<br>
<span class="HOEnZb"><font color="#888888"><br>
--<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></div>