+2014-10-16 Roger Fong <roger_fong@apple.com>
+
+ Calling glReadPixels with BGRA format on an NVIDIA machine with an opaque context returns the wrong alpha values.
+ https://bugs.webkit.org/show_bug.cgi?id=137793.
+ <rdar://problem/15408133>
+
+ Reviewed by Dean Jackson.
+
+ This fixes conformance test context/context-attribute-preserve-drawing-buffer.html.
+
+ * platform/graphics/opengl/GraphicsContext3DOpenGL.cpp:
+ (WebCore::GraphicsContext3D::readPixelsAndConvertToBGRAIfNecessary):
+ On an NVIDIA machine, when the context has alpha turned off, call glReadPixels with RGBA format and then convert to RGBA.
+
2014-10-17 Chris Dumez <cdumez@apple.com>
Use is<>() / downcast<>() for all SVG RenderObjects
#include <wtf/MainThread.h>
#include <wtf/text/CString.h>
+#if USE(ACCELERATE)
+#include <Accelerate/Accelerate.h>
+#endif
+
#if PLATFORM(IOS)
#import <OpenGLES/ES2/glext.h>
// From <OpenGLES/glext.h>
void GraphicsContext3D::readPixelsAndConvertToBGRAIfNecessary(int x, int y, int width, int height, unsigned char* pixels)
{
- ::glReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels);
+ // NVIDIA drivers have a bug where calling readPixels in BGRA can return the wrong values for the alpha channel when the alpha is off for the context.
+ if (!m_attrs.alpha && getExtensions()->isNVIDIA()) {
+ ::glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+#if USE(ACCELERATE)
+ vImage_Buffer src;
+ src.height = height;
+ src.width = width;
+ src.rowBytes = width*4;
+ src.data = pixels;
+
+ vImage_Buffer dest;
+ dest.height = height;
+ dest.width = width;
+ dest.rowBytes = width*4;
+ dest.data = pixels;
+
+ // Swap pixel channels from RGBA to BGRA.
+ const uint8_t map[4] = { 2, 1, 0, 3 };
+ vImagePermuteChannels_ARGB8888(&src, &dest, map, kvImageNoFlags);
+#else
+ int totalBytes = width * height * 4;
+ for (int i = 0; i < totalBytes; i += 4)
+ std::swap(pixels[i], pixels[i + 2]);
+#endif
+ } else
+ ::glReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels);
}
void GraphicsContext3D::validateAttributes()