1diff --git a/gfx/gl/GLContextSkia.cpp b/gfx/gl/GLContextSkia.cpp 2--- a/gfx/gl/GLContextSkia.cpp 3+++ b/gfx/gl/GLContextSkia.cpp 4@@ -303,39 +303,47 @@ const GLubyte* glGetString_mozilla(GrGLe 5 if (name == LOCAL_GL_VERSION) { 6 if (sGLContext.get()->IsGLES2()) { 7 return reinterpret_cast<const GLubyte*>("OpenGL ES 2.0"); 8 } else { 9 return reinterpret_cast<const GLubyte*>("2.0"); 10 } 11 } else if (name == LOCAL_GL_EXTENSIONS) { 12 // Only expose the bare minimum extensions we want to support to ensure a functional Ganesh 13 // as GLContext only exposes certain extensions 14 static bool extensionsStringBuilt = false; 15- static char extensionsString[120]; 16+ static char extensionsString[256]; 17 18 if (!extensionsStringBuilt) { 19 if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_texture_format_BGRA8888)) { 20 strcpy(extensionsString, "GL_EXT_texture_format_BGRA8888 "); 21 } 22 23 if (sGLContext.get()->IsExtensionSupported(GLContext::OES_packed_depth_stencil)) { 24 strcat(extensionsString, "GL_OES_packed_depth_stencil "); 25 } 26 27 if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_packed_depth_stencil)) { 28 strcat(extensionsString, "GL_EXT_packed_depth_stencil "); 29 } 30 31 if (sGLContext.get()->IsExtensionSupported(GLContext::OES_rgb8_rgba8)) { 32 strcat(extensionsString, "GL_OES_rgb8_rgba8 "); 33 } 34 35+ if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_bgra)) { 36+ strcat(extensionsString, "GL_EXT_bgra "); 37+ } 38+ 39+ if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_read_format_bgra)) { 40+ strcat(extensionsString, "GL_EXT_read_format_bgra "); 41+ } 42+ 43 extensionsStringBuilt = true; 44 } 45 46 return reinterpret_cast<const GLubyte*>(extensionsString); 47 48 } else if (name == LOCAL_GL_SHADING_LANGUAGE_VERSION) { 49 if (sGLContext.get()->IsGLES2()) { 50 return reinterpret_cast<const GLubyte*>("OpenGL ES GLSL ES 1.0"); 51 } else { 52 return reinterpret_cast<const GLubyte*>("1.10"); 53diff --git a/gfx/skia/src/gpu/gl/GrGpuGL.cpp b/gfx/skia/src/gpu/gl/GrGpuGL.cpp 54--- a/gfx/skia/src/gpu/gl/GrGpuGL.cpp 55+++ b/gfx/skia/src/gpu/gl/GrGpuGL.cpp 56@@ -1,18 +1,18 @@ 57 /* 58 * Copyright 2011 Google Inc. 59 * 60 * Use of this source code is governed by a BSD-style license that can be 61 * found in the LICENSE file. 62 */ 63 64- 65+#include <algorithm> 66 #include "GrGpuGL.h" 67 #include "GrGLStencilBuffer.h" 68 #include "GrGLPath.h" 69 #include "GrGLShaderBuilder.h" 70 #include "GrTemplates.h" 71 #include "GrTypes.h" 72 #include "SkTemplates.h" 73 74 static const GrGLuint GR_MAX_GLUINT = ~0U; 75 static const GrGLint GR_INVAL_GLINT = ~0; 76@@ -1381,29 +1381,67 @@ bool GrGpuGL::readPixelsWillPayForYFlip( 77 // Note the rowBytes might be tight to the passed in data, but if data 78 // gets clipped in x to the target the rowBytes will no longer be tight. 79 if (left >= 0 && (left + width) < renderTarget->width()) { 80 return 0 == rowBytes || 81 GrBytesPerPixel(config) * width == rowBytes; 82 } else { 83 return false; 84 } 85 } 86 87+static void swizzleRow(void* buffer, int byteLen) { 88+ uint8_t* src = (uint8_t*)buffer; 89+ uint8_t* end = src + byteLen; 90+ 91+ GrAssert((end - src) % 4 == 0); 92+ 93+ for (; src != end; src += 4) { 94+ std::swap(src[0], src[2]); 95+ } 96+} 97+ 98+bool GrGpuGL::canReadBGRA() const 99+{ 100+ if (kDesktop_GrGLBinding == this->glBinding() || 101+ this->hasExtension("GL_EXT_bgra")) 102+ return true; 103+ 104+ if (this->hasExtension("GL_EXT_read_format_bgra")) { 105+ GrGLint readFormat = 0; 106+ GrGLint readType = 0; 107+ 108+ GL_CALL(GetIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat)); 109+ GL_CALL(GetIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType)); 110+ 111+ return readFormat == GR_GL_BGRA && readType == GR_GL_UNSIGNED_BYTE; 112+ } 113+ 114+ return false; 115+} 116+ 117 bool GrGpuGL::onReadPixels(GrRenderTarget* target, 118 int left, int top, 119 int width, int height, 120 GrPixelConfig config, 121 void* buffer, 122 size_t rowBytes) { 123 GrGLenum format; 124 GrGLenum type; 125 bool flipY = kBottomLeft_GrSurfaceOrigin == target->origin(); 126+ bool needSwizzle = false; 127+ 128+ if (kBGRA_8888_GrPixelConfig == config && !this->canReadBGRA()) { 129+ // Read RGBA and swizzle after 130+ config = kRGBA_8888_GrPixelConfig; 131+ needSwizzle = true; 132+ } 133+ 134 if (!this->configToGLFormats(config, false, NULL, &format, &type)) { 135 return false; 136 } 137 size_t bpp = GrBytesPerPixel(config); 138 if (!adjust_pixel_ops_params(target->width(), target->height(), bpp, 139 &left, &top, &width, &height, 140 const_cast<const void**>(&buffer), 141 &rowBytes)) { 142 return false; 143 } 144@@ -1478,35 +1516,46 @@ bool GrGpuGL::onReadPixels(GrRenderTarge 145 scratch.reset(tightRowBytes); 146 void* tmpRow = scratch.get(); 147 // flip y in-place by rows 148 const int halfY = height >> 1; 149 char* top = reinterpret_cast<char*>(buffer); 150 char* bottom = top + (height - 1) * rowBytes; 151 for (int y = 0; y < halfY; y++) { 152 memcpy(tmpRow, top, tightRowBytes); 153 memcpy(top, bottom, tightRowBytes); 154 memcpy(bottom, tmpRow, tightRowBytes); 155+ 156+ if (needSwizzle) { 157+ swizzleRow(top, tightRowBytes); 158+ swizzleRow(bottom, tightRowBytes); 159+ } 160+ 161 top += rowBytes; 162 bottom -= rowBytes; 163 } 164 } 165 } else { 166- GrAssert(readDst != buffer); GrAssert(rowBytes != tightRowBytes); 167+ GrAssert(readDst != buffer); 168+ GrAssert(rowBytes != tightRowBytes); 169 // copy from readDst to buffer while flipping y 170 // const int halfY = height >> 1; 171 const char* src = reinterpret_cast<const char*>(readDst); 172 char* dst = reinterpret_cast<char*>(buffer); 173 if (flipY) { 174 dst += (height-1) * rowBytes; 175 } 176 for (int y = 0; y < height; y++) { 177 memcpy(dst, src, tightRowBytes); 178+ if (needSwizzle) { 179+ swizzleRow(dst, tightRowBytes); 180+ } 181+ 182 src += readDstRowBytes; 183 if (!flipY) { 184 dst += rowBytes; 185 } else { 186 dst -= rowBytes; 187 } 188 } 189 } 190 return true; 191 } 192diff --git a/gfx/skia/src/gpu/gl/GrGpuGL.h b/gfx/skia/src/gpu/gl/GrGpuGL.h 193--- a/gfx/skia/src/gpu/gl/GrGpuGL.h 194+++ b/gfx/skia/src/gpu/gl/GrGpuGL.h 195@@ -243,20 +243,22 @@ private: 196 GrPixelConfig dataConfig, 197 const void* data, 198 size_t rowBytes); 199 200 bool createRenderTargetObjects(int width, int height, 201 GrGLuint texID, 202 GrGLRenderTarget::Desc* desc); 203 204 void fillInConfigRenderableTable(); 205 206+ bool canReadBGRA() const; 207+ 208 GrGLContext fGLContext; 209 210 // GL program-related state 211 ProgramCache* fProgramCache; 212 SkAutoTUnref<GrGLProgram> fCurrentProgram; 213 214 /////////////////////////////////////////////////////////////////////////// 215 ///@name Caching of GL State 216 ///@{ 217 int fHWActiveTextureUnitIdx; 218