Bug 683514 - Add support for the GL_EXT_unpack_subimage extension. r=joe
authorChris Lord <chrislord.net@gmail.com>
Fri, 09 Sep 2011 10:41:11 +0100
changeset 76824 7a8399ef753513fd59f0753d08fc2ef5d1405b1c
parent 76823 b201507b95c7fb0e3c0e026f5520118af526d425
child 76825 694520af9b1847cc9c70e5deac135d419407eb53
child 76831 1af35a19b87ec67dd5897670bd9521f1a5ee34bb
push id21141
push usereakhgari@mozilla.com
push dateFri, 09 Sep 2011 14:06:30 +0000
treeherdermozilla-central@694520af9b18 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjoe
bugs683514
milestone9.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 683514 - Add support for the GL_EXT_unpack_subimage extension. r=joe A GLES 2.0 extension exists that allows us to use GL_UNPACK_ROW_LENGTH, amongst other variables. This really helps us when uploading sub-regions of a buffer that don't span the entire width of that buffer (for example, when scrolling horizontally). This extension is available on Android tablets, and possibly other Tegra 2 devices, so is very much worth taking advantage of. Details: http://www.khronos.org/registry/gles/extensions/EXT/GL_EXT_unpack_subimage.txt
gfx/thebes/GLContext.cpp
gfx/thebes/GLContext.h
--- a/gfx/thebes/GLContext.cpp
+++ b/gfx/thebes/GLContext.cpp
@@ -431,16 +431,17 @@ static const char *sExtensionNames[] = {
     "GL_IMG_read_format",
     "GL_EXT_read_format_bgra",
     "GL_APPLE_client_storage",
     "GL_ARB_texture_non_power_of_two",
     "GL_ARB_pixel_buffer_object",
     "GL_ARB_ES2_compatibility",
     "GL_OES_texture_float",
     "GL_ARB_texture_float",
+    "GL_EXT_unpack_subimage",
     NULL
 };
 
 void
 GLContext::InitExtensions()
 {
     MakeCurrent();
     const GLubyte *extensions = fGetString(LOCAL_GL_EXTENSIONS);
@@ -1834,19 +1835,33 @@ GLContext::TexImage2D(GLenum target, GLi
                       GLint pixelsize, GLint border, GLenum format, 
                       GLenum type, const GLvoid *pixels)
 {
     fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 
                  NS_MIN(GetAddressAlignment((ptrdiff_t)pixels),
                         GetAddressAlignment((ptrdiff_t)stride)));
 
 #ifndef USE_GLES2
-    fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, stride/pixelsize);
+    bool useUnpackRowLength = true;
 #else
-    if (stride != width * pixelsize) {
+    // A Khronos extension, GL_EXT_unpack_subimage, that restores support
+    // for GL_UNPACK_ROW_LENGTH, GL_UNPACK_SKIP_ROWS and GL_UNPACK_SKIP_PIXELS
+    // exists on Tegra 2 (and possibly other chipsets)
+    bool useUnpackRowLength = IsExtensionSupported(EXT_unpack_subimage);
+#endif
+
+    // Don't use UNPACK_ROW_LENGTH if the length would be greater than the
+    // maximum texture size
+    int rowLength = stride/pixelsize;
+    if (rowLength > mMaxTextureSize)
+      useUnpackRowLength = false;
+
+    if (useUnpackRowLength)
+        fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, rowLength);
+    else if (stride != width * pixelsize) {
         // Not using the whole row of texture data and GLES doesn't 
         // support GL_UNPACK_ROW_LENGTH. We need to upload each row
         // separately.
         fTexImage2D(target,
                     border,
                     internalformat,
                     width,
                     height,
@@ -1868,31 +1883,29 @@ GLContext::TexImage2D(GLenum target, GLi
                            row);
 
             row += stride;
         }
 
         fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
         return;
     }
-#endif
 
     fTexImage2D(target,
                 level,
                 internalformat,
                 width,
                 height,
                 border,
                 format,
                 type,
                 pixels);
 
-#ifndef USE_GLES2
-    fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, 0);
-#endif
+    if (useUnpackRowLength)
+        fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, 0);
     fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
 }
 
 void
 GLContext::TexSubImage2D(GLenum target, GLint level, 
                          GLint xoffset, GLint yoffset, 
                          GLsizei width, GLsizei height, GLsizei stride,
                          GLint pixelsize, GLenum format, 
--- a/gfx/thebes/GLContext.h
+++ b/gfx/thebes/GLContext.h
@@ -975,16 +975,17 @@ public:
         IMG_read_format,
         EXT_read_format_bgra,
         APPLE_client_storage,
         ARB_texture_non_power_of_two,
         ARB_pixel_buffer_object,
         ARB_ES2_compatibility,
         OES_texture_float,
         ARB_texture_float,
+        EXT_unpack_subimage,
         Extensions_Max
     };
 
     PRBool IsExtensionSupported(GLExtensions aKnownExtension) {
         return mAvailableExtensions[aKnownExtension];
     }
 
     // for unknown extensions