gfx/skia/patches/0024-Bug-887318-fix-bgra-readback.patch

changeset 0
6474c204b198
     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;

mercurial