tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

0024-Bug-887318-fix-bgra-readback.patch (7820B)


      1 diff --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");
     53 diff --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 }
    192 diff --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;