1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/patches/0024-Bug-887318-fix-bgra-readback.patch Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,217 @@ 1.4 +diff --git a/gfx/gl/GLContextSkia.cpp b/gfx/gl/GLContextSkia.cpp 1.5 +--- a/gfx/gl/GLContextSkia.cpp 1.6 ++++ b/gfx/gl/GLContextSkia.cpp 1.7 +@@ -303,39 +303,47 @@ const GLubyte* glGetString_mozilla(GrGLe 1.8 + if (name == LOCAL_GL_VERSION) { 1.9 + if (sGLContext.get()->IsGLES2()) { 1.10 + return reinterpret_cast<const GLubyte*>("OpenGL ES 2.0"); 1.11 + } else { 1.12 + return reinterpret_cast<const GLubyte*>("2.0"); 1.13 + } 1.14 + } else if (name == LOCAL_GL_EXTENSIONS) { 1.15 + // Only expose the bare minimum extensions we want to support to ensure a functional Ganesh 1.16 + // as GLContext only exposes certain extensions 1.17 + static bool extensionsStringBuilt = false; 1.18 +- static char extensionsString[120]; 1.19 ++ static char extensionsString[256]; 1.20 + 1.21 + if (!extensionsStringBuilt) { 1.22 + if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_texture_format_BGRA8888)) { 1.23 + strcpy(extensionsString, "GL_EXT_texture_format_BGRA8888 "); 1.24 + } 1.25 + 1.26 + if (sGLContext.get()->IsExtensionSupported(GLContext::OES_packed_depth_stencil)) { 1.27 + strcat(extensionsString, "GL_OES_packed_depth_stencil "); 1.28 + } 1.29 + 1.30 + if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_packed_depth_stencil)) { 1.31 + strcat(extensionsString, "GL_EXT_packed_depth_stencil "); 1.32 + } 1.33 + 1.34 + if (sGLContext.get()->IsExtensionSupported(GLContext::OES_rgb8_rgba8)) { 1.35 + strcat(extensionsString, "GL_OES_rgb8_rgba8 "); 1.36 + } 1.37 + 1.38 ++ if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_bgra)) { 1.39 ++ strcat(extensionsString, "GL_EXT_bgra "); 1.40 ++ } 1.41 ++ 1.42 ++ if (sGLContext.get()->IsExtensionSupported(GLContext::EXT_read_format_bgra)) { 1.43 ++ strcat(extensionsString, "GL_EXT_read_format_bgra "); 1.44 ++ } 1.45 ++ 1.46 + extensionsStringBuilt = true; 1.47 + } 1.48 + 1.49 + return reinterpret_cast<const GLubyte*>(extensionsString); 1.50 + 1.51 + } else if (name == LOCAL_GL_SHADING_LANGUAGE_VERSION) { 1.52 + if (sGLContext.get()->IsGLES2()) { 1.53 + return reinterpret_cast<const GLubyte*>("OpenGL ES GLSL ES 1.0"); 1.54 + } else { 1.55 + return reinterpret_cast<const GLubyte*>("1.10"); 1.56 +diff --git a/gfx/skia/src/gpu/gl/GrGpuGL.cpp b/gfx/skia/src/gpu/gl/GrGpuGL.cpp 1.57 +--- a/gfx/skia/src/gpu/gl/GrGpuGL.cpp 1.58 ++++ b/gfx/skia/src/gpu/gl/GrGpuGL.cpp 1.59 +@@ -1,18 +1,18 @@ 1.60 + /* 1.61 + * Copyright 2011 Google Inc. 1.62 + * 1.63 + * Use of this source code is governed by a BSD-style license that can be 1.64 + * found in the LICENSE file. 1.65 + */ 1.66 + 1.67 +- 1.68 ++#include <algorithm> 1.69 + #include "GrGpuGL.h" 1.70 + #include "GrGLStencilBuffer.h" 1.71 + #include "GrGLPath.h" 1.72 + #include "GrGLShaderBuilder.h" 1.73 + #include "GrTemplates.h" 1.74 + #include "GrTypes.h" 1.75 + #include "SkTemplates.h" 1.76 + 1.77 + static const GrGLuint GR_MAX_GLUINT = ~0U; 1.78 + static const GrGLint GR_INVAL_GLINT = ~0; 1.79 +@@ -1381,29 +1381,67 @@ bool GrGpuGL::readPixelsWillPayForYFlip( 1.80 + // Note the rowBytes might be tight to the passed in data, but if data 1.81 + // gets clipped in x to the target the rowBytes will no longer be tight. 1.82 + if (left >= 0 && (left + width) < renderTarget->width()) { 1.83 + return 0 == rowBytes || 1.84 + GrBytesPerPixel(config) * width == rowBytes; 1.85 + } else { 1.86 + return false; 1.87 + } 1.88 + } 1.89 + 1.90 ++static void swizzleRow(void* buffer, int byteLen) { 1.91 ++ uint8_t* src = (uint8_t*)buffer; 1.92 ++ uint8_t* end = src + byteLen; 1.93 ++ 1.94 ++ GrAssert((end - src) % 4 == 0); 1.95 ++ 1.96 ++ for (; src != end; src += 4) { 1.97 ++ std::swap(src[0], src[2]); 1.98 ++ } 1.99 ++} 1.100 ++ 1.101 ++bool GrGpuGL::canReadBGRA() const 1.102 ++{ 1.103 ++ if (kDesktop_GrGLBinding == this->glBinding() || 1.104 ++ this->hasExtension("GL_EXT_bgra")) 1.105 ++ return true; 1.106 ++ 1.107 ++ if (this->hasExtension("GL_EXT_read_format_bgra")) { 1.108 ++ GrGLint readFormat = 0; 1.109 ++ GrGLint readType = 0; 1.110 ++ 1.111 ++ GL_CALL(GetIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat)); 1.112 ++ GL_CALL(GetIntegerv(GR_GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType)); 1.113 ++ 1.114 ++ return readFormat == GR_GL_BGRA && readType == GR_GL_UNSIGNED_BYTE; 1.115 ++ } 1.116 ++ 1.117 ++ return false; 1.118 ++} 1.119 ++ 1.120 + bool GrGpuGL::onReadPixels(GrRenderTarget* target, 1.121 + int left, int top, 1.122 + int width, int height, 1.123 + GrPixelConfig config, 1.124 + void* buffer, 1.125 + size_t rowBytes) { 1.126 + GrGLenum format; 1.127 + GrGLenum type; 1.128 + bool flipY = kBottomLeft_GrSurfaceOrigin == target->origin(); 1.129 ++ bool needSwizzle = false; 1.130 ++ 1.131 ++ if (kBGRA_8888_GrPixelConfig == config && !this->canReadBGRA()) { 1.132 ++ // Read RGBA and swizzle after 1.133 ++ config = kRGBA_8888_GrPixelConfig; 1.134 ++ needSwizzle = true; 1.135 ++ } 1.136 ++ 1.137 + if (!this->configToGLFormats(config, false, NULL, &format, &type)) { 1.138 + return false; 1.139 + } 1.140 + size_t bpp = GrBytesPerPixel(config); 1.141 + if (!adjust_pixel_ops_params(target->width(), target->height(), bpp, 1.142 + &left, &top, &width, &height, 1.143 + const_cast<const void**>(&buffer), 1.144 + &rowBytes)) { 1.145 + return false; 1.146 + } 1.147 +@@ -1478,35 +1516,46 @@ bool GrGpuGL::onReadPixels(GrRenderTarge 1.148 + scratch.reset(tightRowBytes); 1.149 + void* tmpRow = scratch.get(); 1.150 + // flip y in-place by rows 1.151 + const int halfY = height >> 1; 1.152 + char* top = reinterpret_cast<char*>(buffer); 1.153 + char* bottom = top + (height - 1) * rowBytes; 1.154 + for (int y = 0; y < halfY; y++) { 1.155 + memcpy(tmpRow, top, tightRowBytes); 1.156 + memcpy(top, bottom, tightRowBytes); 1.157 + memcpy(bottom, tmpRow, tightRowBytes); 1.158 ++ 1.159 ++ if (needSwizzle) { 1.160 ++ swizzleRow(top, tightRowBytes); 1.161 ++ swizzleRow(bottom, tightRowBytes); 1.162 ++ } 1.163 ++ 1.164 + top += rowBytes; 1.165 + bottom -= rowBytes; 1.166 + } 1.167 + } 1.168 + } else { 1.169 +- GrAssert(readDst != buffer); GrAssert(rowBytes != tightRowBytes); 1.170 ++ GrAssert(readDst != buffer); 1.171 ++ GrAssert(rowBytes != tightRowBytes); 1.172 + // copy from readDst to buffer while flipping y 1.173 + // const int halfY = height >> 1; 1.174 + const char* src = reinterpret_cast<const char*>(readDst); 1.175 + char* dst = reinterpret_cast<char*>(buffer); 1.176 + if (flipY) { 1.177 + dst += (height-1) * rowBytes; 1.178 + } 1.179 + for (int y = 0; y < height; y++) { 1.180 + memcpy(dst, src, tightRowBytes); 1.181 ++ if (needSwizzle) { 1.182 ++ swizzleRow(dst, tightRowBytes); 1.183 ++ } 1.184 ++ 1.185 + src += readDstRowBytes; 1.186 + if (!flipY) { 1.187 + dst += rowBytes; 1.188 + } else { 1.189 + dst -= rowBytes; 1.190 + } 1.191 + } 1.192 + } 1.193 + return true; 1.194 + } 1.195 +diff --git a/gfx/skia/src/gpu/gl/GrGpuGL.h b/gfx/skia/src/gpu/gl/GrGpuGL.h 1.196 +--- a/gfx/skia/src/gpu/gl/GrGpuGL.h 1.197 ++++ b/gfx/skia/src/gpu/gl/GrGpuGL.h 1.198 +@@ -243,20 +243,22 @@ private: 1.199 + GrPixelConfig dataConfig, 1.200 + const void* data, 1.201 + size_t rowBytes); 1.202 + 1.203 + bool createRenderTargetObjects(int width, int height, 1.204 + GrGLuint texID, 1.205 + GrGLRenderTarget::Desc* desc); 1.206 + 1.207 + void fillInConfigRenderableTable(); 1.208 + 1.209 ++ bool canReadBGRA() const; 1.210 ++ 1.211 + GrGLContext fGLContext; 1.212 + 1.213 + // GL program-related state 1.214 + ProgramCache* fProgramCache; 1.215 + SkAutoTUnref<GrGLProgram> fCurrentProgram; 1.216 + 1.217 + /////////////////////////////////////////////////////////////////////////// 1.218 + ///@name Caching of GL State 1.219 + ///@{ 1.220 + int fHWActiveTextureUnitIdx;