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