Bug 735932 - Fix no-alpha ReadPixels on Mac+nVidia - r=bjacob
authorJeff Gilbert <jgilbert@mozilla.com>
Fri, 31 Aug 2012 16:47:03 -0700
changeset 104079 7f57250ac7d15ce624a58fc40a4c06d03f1b4c14
parent 104078 fb8074886fb098f62fadfa65a71056437288eabe
child 104084 62bfaa4500ca758ee2ffa4acafb1f74ea9985a74
push id14326
push userjgilbert@mozilla.com
push dateFri, 31 Aug 2012 23:47:17 +0000
treeherdermozilla-inbound@7f57250ac7d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbjacob
bugs735932
milestone18.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 735932 - Fix no-alpha ReadPixels on Mac+nVidia - r=bjacob
gfx/gl/GLContext.cpp
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -2034,24 +2034,53 @@ GLContext::ReadPixelsIntoImageSurface(gf
     GLint currentPackAlignment = 0;
     fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, &currentPackAlignment);
 
     if (currentPackAlignment != 4)
         fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, 4);
 
     GLenum format;
     GLenum datatype;
-
     GetOptimalReadFormats(this, format, datatype);
 
+    GLsizei width = dest->Width();
+    GLsizei height = dest->Height();
+
     fReadPixels(0, 0,
-                dest->Width(), dest->Height(),
+                width, height,
                 format, datatype,
                 dest->Data());
 
+    // Check if GL is giving back 1.0 alpha for
+    // RGBA reads to RGBA images from no-alpha buffers.
+#ifdef XP_MACOSX
+    if (WorkAroundDriverBugs() &&
+        mVendor == VendorNVIDIA &&
+        dest->Format() == gfxASurface::ImageFormatARGB32 &&
+        width && height)
+    {
+        GLint alphaBits = 0;
+        fGetIntegerv(LOCAL_GL_ALPHA_BITS, &alphaBits);
+        if (!alphaBits) {
+            const uint32_t alphaMask = GFX_PACKED_PIXEL_NO_PREMULTIPLY(0xff,0,0,0);
+
+            uint32_t* itr = (uint32_t*)dest->Data();
+            uint32_t testPixel = *itr;
+            if ((testPixel & alphaMask) != alphaMask) {
+                // We need to set the alpha channel to 1.0 manually.
+                uint32_t* itrEnd = itr + width*height;  // Stride is guaranteed to be width*4.
+
+                for (; itr != itrEnd; itr++) {
+                    *itr |= alphaMask;
+                }
+            }
+        }
+    }
+#endif
+
     // Output should be in BGRA, so swap if RGBA.
     if (format == LOCAL_GL_RGBA) {
         SwapRAndBComponents(dest);
     }
 
     if (currentPackAlignment != 4)
         fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, currentPackAlignment);
 }