Bug 1003027 - Use temp surface for bad strides. - r=mattwoodrow
authorJeff Gilbert <jgilbert@mozilla.com>
Fri, 02 May 2014 13:22:07 -0700
changeset 181778 b3a88dc52da78d6de5a31eca1d0a4512f2481979
parent 181777 e66519a652242d04e288f33683616b1605398e41
child 181779 f8497c9757f136708aea52f06e2d0efce18fdab9
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersmattwoodrow
bugs1003027
milestone32.0a1
Bug 1003027 - Use temp surface for bad strides. - r=mattwoodrow
gfx/gl/GLReadTexImageHelper.cpp
--- a/gfx/gl/GLReadTexImageHelper.cpp
+++ b/gfx/gl/GLReadTexImageHelper.cpp
@@ -296,37 +296,37 @@ static void CopyDataSourceSurface(DataSo
 
     srcRow += srcRowHole;
     destRow += destRowHole;
     --rows;
   }
 }
 
 static int
-CalcStride(int width, int pixelSize, int alignment)
+CalcRowStride(int width, int pixelSize, int alignment)
 {
     MOZ_ASSERT(alignment);
 
-    int stride = width * pixelSize;
-    if (stride % alignment) { // Extra at the end of the line?
-        int alignmentCount = stride / alignment;
-        stride = (alignmentCount+1) * alignment;
+    int rowStride = width * pixelSize;
+    if (rowStride % alignment) { // Extra at the end of the line?
+        int alignmentCount = rowStride / alignment;
+        rowStride = (alignmentCount+1) * alignment;
     }
-    return stride;
+    return rowStride;
 }
 
 static int
-GuessAlignment(int width, int pixelSize, int stride)
+GuessAlignment(int width, int pixelSize, int rowStride)
 {
     int alignment = 8; // Max GLES allows.
-    while (CalcStride(width, pixelSize, alignment) != stride) {
+    while (CalcRowStride(width, pixelSize, alignment) != rowStride) {
         alignment /= 2;
         if (!alignment) {
-            MOZ_ASSERT(alignment);
-            return 1;
+            NS_WARNING("Bad alignment for GLES. Will use temp surf for readback.");
+            return 0;
         }
     }
     return alignment;
 }
 
 void
 ReadPixelsIntoImageSurface(GLContext* gl, gfxImageSurface* dest) {
     gl->MakeCurrent();
@@ -370,18 +370,28 @@ ReadPixelsIntoImageSurface(GLContext* gl
     GLenum readFormat = destFormat;
     GLenum readType = destType;
     bool needsTempSurf = !GetActualReadFormats(gl,
                                                destFormat, destType,
                                                readFormat, readType);
 
     nsAutoPtr<gfxImageSurface> tempSurf;
     gfxImageSurface* readSurf = nullptr;
-    int readAlignment = 0;
-    if (needsTempSurf) {
+
+    // Figure out alignment. We don't need to know why, we just need it
+    // to be valid.
+    int readAlignment = GuessAlignment(dest->Width(),
+                                       destPixelSize,
+                                       dest->Stride());
+    if (!readAlignment) // Couldn't calculate a valid alignment.
+        needsTempSurf = true;
+
+    if (!needsTempSurf) {
+        readSurf = dest;
+    } else {
         if (gl->DebugMode()) {
             NS_WARNING("Needing intermediary surface for ReadPixels. This will be slow!");
         }
         SurfaceFormat readFormatGFX;
 
         switch (readFormat) {
             case LOCAL_GL_RGBA:
             case LOCAL_GL_BGRA: {
@@ -420,23 +430,16 @@ ReadPixelsIntoImageSurface(GLContext* gl
                 MOZ_CRASH("Bad read type.");
             }
         }
 
         tempSurf = new gfxImageSurface(dest->GetSize(),
                                        SurfaceFormatToImageFormat(readFormatGFX),
                                        false);
         readSurf = tempSurf;
-    } else {
-        // Figure out alignment. We don't need to know why, we just need it
-        // to be valid.
-        readAlignment = GuessAlignment(dest->Width(),
-                                       destPixelSize,
-                                       dest->Stride());
-        readSurf = dest;
     }
     MOZ_ASSERT(readAlignment);
 
     GLint currentPackAlignment = 0;
     gl->fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, &currentPackAlignment);
 
     if (currentPackAlignment != readAlignment)
         gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, readAlignment);