Transplanet: Bug 724094 - Use fTexImage2D instead of TexSubImage2D when uploading full width. r=ajuma
authorBenoit Girard <b56girard@gmail.com>
Mon, 06 Feb 2012 15:15:36 -0500
changeset 89102 d5b28b99b9e99319d959868183ac5e00f30aaf33
parent 89101 06a0f954ccc247b68ebd64860f499b50ddb15e77
child 89103 1cdaddcade2cf195a2ddd2701f8a45839d2471ee
push id7119
push usereakhgari@mozilla.com
push dateWed, 14 Mar 2012 17:40:57 +0000
treeherdermozilla-inbound@10d7baa4aff0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersajuma
bugs724094
milestone12.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
Transplanet: Bug 724094 - Use fTexImage2D instead of TexSubImage2D when uploading full width. r=ajuma
gfx/gl/GLContext.cpp
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -2117,19 +2117,19 @@ static GLint GetAddressAlignment(ptrdiff
     } else if (!(aAddress & 0x1)) {
         return 2;
     } else {
         return 1;
     }
 }
 
 void
-GLContext::TexImage2D(GLenum target, GLint level, GLint internalformat, 
+GLContext::TexImage2D(GLenum target, GLint level, GLint internalformat,
                       GLsizei width, GLsizei height, GLsizei stride,
-                      GLint pixelsize, GLint border, GLenum format, 
+                      GLint pixelsize, GLint border, GLenum format,
                       GLenum type, const GLvoid *pixels)
 {
 #ifdef USE_GLES2
 
     NS_ASSERTION(format == internalformat,
                  "format and internalformat not the same for glTexImage2D on GLES2");
 
     // Use GLES-specific workarounds for GL_UNPACK_ROW_LENGTH; these are
@@ -2150,17 +2150,17 @@ GLContext::TexImage2D(GLenum target, GLi
                   width,
                   height,
                   stride,
                   pixelsize,
                   format,
                   type,
                   pixels);
 #else
-    fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 
+    fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
                  NS_MIN(GetAddressAlignment((ptrdiff_t)pixels),
                         GetAddressAlignment((ptrdiff_t)stride)));
     int rowLength = stride/pixelsize;
     fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, rowLength);
     fTexImage2D(target,
                 level,
                 internalformat,
                 width,
@@ -2170,27 +2170,42 @@ GLContext::TexImage2D(GLenum target, GLi
                 type,
                 pixels);
     fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, 0);
     fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
 #endif
 }
 
 void
-GLContext::TexSubImage2D(GLenum target, GLint level, 
-                         GLint xoffset, GLint yoffset, 
+GLContext::TexSubImage2D(GLenum target, GLint level,
+                         GLint xoffset, GLint yoffset,
                          GLsizei width, GLsizei height, GLsizei stride,
-                         GLint pixelsize, GLenum format, 
+                         GLint pixelsize, GLenum format,
                          GLenum type, const GLvoid* pixels)
 {
 #ifdef USE_GLES2
-  if (IsExtensionSupported(EXT_unpack_subimage)) {
+    if (stride == width * pixelsize) {
+        fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
+                 NS_MIN(GetAddressAlignment((ptrdiff_t)pixels),
+                        GetAddressAlignment((ptrdiff_t)stride)));
+        fTexSubImage2D(target,
+                       level,
+                       xoffset,
+                       yoffset,
+                       width,
+                       height,
+                       format,
+                       type,
+                       pixels);
+        fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
+    } else if (IsExtensionSupported(EXT_unpack_subimage)) {
         TexSubImage2DWithUnpackSubimageGLES(target, level, xoffset, yoffset,
                                             width, height, stride,
                                             pixelsize, format, type, pixels);
+
     } else {
         TexSubImage2DWithoutUnpackSubimage(target, level, xoffset, yoffset,
                                            width, height, stride,
                                            pixelsize, format, type, pixels);
     }
 #else
     fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
                  NS_MIN(GetAddressAlignment((ptrdiff_t)pixels),
@@ -2217,108 +2232,80 @@ GLContext::TexSubImage2DWithUnpackSubima
                                                GLsizei width, GLsizei height,
                                                GLsizei stride, GLint pixelsize,
                                                GLenum format, GLenum type,
                                                const GLvoid* pixels)
 {
     fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
                  NS_MIN(GetAddressAlignment((ptrdiff_t)pixels),
                         GetAddressAlignment((ptrdiff_t)stride)));
-    if (stride == width * pixelsize) {
-        // No need to use GL_UNPACK_ROW_LENGTH.
-        fTexSubImage2D(target,
-                       level,
-                       xoffset,
-                       yoffset,
-                       width,
-                       height,
-                       format,
-                       type,
-                       pixels);
-    } else {
-        // When using GL_UNPACK_ROW_LENGTH, we need to work around a Tegra
-        // driver crash where the driver apparently tries to read
-        // (stride - width * pixelsize) bytes past the end of the last input
-        // row. We only upload the first height-1 rows using GL_UNPACK_ROW_LENGTH,
-        // and then we upload the final row separately. See bug 697990.
-        int rowLength = stride/pixelsize;
-        fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, rowLength);
-        fTexSubImage2D(target,
-                       level,
-                       xoffset,
-                       yoffset,
-                       width,
-                       height-1,
-                       format,
-                       type,
-                       pixels);
-        fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, 0);
-        fTexSubImage2D(target,
-                       level,
-                       xoffset,
-                       yoffset+height-1,
-                       width,
-                       1,
-                       format,
-                       type,
-                       (const unsigned char *)pixels+(height-1)*stride);
-    }
+    // When using GL_UNPACK_ROW_LENGTH, we need to work around a Tegra
+    // driver crash where the driver apparently tries to read
+    // (stride - width * pixelsize) bytes past the end of the last input
+    // row. We only upload the first height-1 rows using GL_UNPACK_ROW_LENGTH,
+    // and then we upload the final row separately. See bug 697990.
+    int rowLength = stride/pixelsize;
+    fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, rowLength);
+    fTexSubImage2D(target,
+                    level,
+                    xoffset,
+                    yoffset,
+                    width,
+                    height-1,
+                    format,
+                    type,
+                    pixels);
+    fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, 0);
+    fTexSubImage2D(target,
+                    level,
+                    xoffset,
+                    yoffset+height-1,
+                    width,
+                    1,
+                    format,
+                    type,
+                    (const unsigned char *)pixels+(height-1)*stride);
     fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
 }
 
 void
 GLContext::TexSubImage2DWithoutUnpackSubimage(GLenum target, GLint level,
                                               GLint xoffset, GLint yoffset,
                                               GLsizei width, GLsizei height,
                                               GLsizei stride, GLint pixelsize,
                                               GLenum format, GLenum type,
                                               const GLvoid* pixels)
 {
-    if (stride == width * pixelsize) {
-        fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
-                     NS_MIN(GetAddressAlignment((ptrdiff_t)pixels),
-                            GetAddressAlignment((ptrdiff_t)stride)));
-        fTexSubImage2D(target,
-                       level,
-                       xoffset,
-                       yoffset,
-                       width,
-                       height,
-                       format,
-                       type,
-                       pixels);
-    } else {
-        // Not using the whole row of texture data and GL_UNPACK_ROW_LENGTH
-        // isn't supported. We make a copy of the texture data we're using,
-        // such that we're using the whole row of data in the copy. This turns
-        // out to be more efficient than uploading row-by-row; see bug 698197.
-        unsigned char *newPixels = new unsigned char[width*height*pixelsize];
-        unsigned char *rowDest = newPixels;
-        const unsigned char *rowSource = (const unsigned char *)pixels;
-        for (int h = 0; h < height; h++) {
+    // Not using the whole row of texture data and GL_UNPACK_ROW_LENGTH
+    // isn't supported. We make a copy of the texture data we're using,
+    // such that we're using the whole row of data in the copy. This turns
+    // out to be more efficient than uploading row-by-row; see bug 698197.
+    unsigned char *newPixels = new unsigned char[width*height*pixelsize];
+    unsigned char *rowDest = newPixels;
+    const unsigned char *rowSource = (const unsigned char *)pixels;
+    for (int h = 0; h < height; h++) {
             memcpy(rowDest, rowSource, width*pixelsize);
             rowDest += width*pixelsize;
             rowSource += stride;
-        }
-
-        stride = width*pixelsize;
-        fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
-                     NS_MIN(GetAddressAlignment((ptrdiff_t)newPixels),
+    }
+
+    stride = width*pixelsize;
+    fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT,
+                    NS_MIN(GetAddressAlignment((ptrdiff_t)newPixels),
                             GetAddressAlignment((ptrdiff_t)stride)));
-        fTexSubImage2D(target,
-                       level,
-                       xoffset,
-                       yoffset,
-                       width,
-                       height,
-                       format,
-                       type,
-                       newPixels);
-        delete [] newPixels;
-    }
+    fTexSubImage2D(target,
+                    level,
+                    xoffset,
+                    yoffset,
+                    width,
+                    height,
+                    format,
+                    type,
+                    newPixels);
+    delete [] newPixels;
     fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
 }
 
 void
 GLContext::RectTriangles::addRect(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1,
                                   GLfloat tx0, GLfloat ty0, GLfloat tx1, GLfloat ty1)
 {
     vert_coord v;