sRGB support in Ganesh. Several pieces:
authorbrianosman <brianosman@google.com>
Mon, 21 Mar 2016 13:55:37 +0000 (06:55 -0700)
committerCommit bot <commit-bot@chromium.org>
Mon, 21 Mar 2016 13:55:37 +0000 (06:55 -0700)
sRGB support now also requires GL_EXT_texture_sRGB_decode, which allows
us to disable sRGB -> Linear conversion when reading textures. This gives
us an easy way to support "legacy" L32 mode. We disable decoding based on
the pixel config of the render target. Textures can override that behavior
(specifically for format-conversion draws where we want that behavior).

Added sBGRA pixel config, which is not-really-a-format. It's just sRGBA
internally, and the external format is BGR order, so TexImage calls will
swizzle correctly. This lets us interact with sRGB raster surfaces on BGR
platforms.

Devices without sRGB support behave like they always have: conversion from
color type and profile type ignores sRGB and always returns linear pixel
configs.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1789663002

Review URL: https://codereview.chromium.org/1789663002

28 files changed:
example/HelloWorld.cpp
include/gpu/GrCaps.h
include/gpu/GrColor.h
include/gpu/GrTextureParams.h
include/gpu/GrTypes.h
include/gpu/SkGr.h
samplecode/SampleApp.cpp
src/core/SkImageCacherator.cpp
src/core/SkSpecialImage.cpp
src/effects/SkGpuBlurUtils.cpp
src/effects/SkTableColorFilter.cpp
src/effects/gradients/SkGradientShader.cpp
src/gpu/GrCaps.cpp
src/gpu/SkGpuDevice.cpp
src/gpu/SkGr.cpp
src/gpu/SkGrPixelRef.cpp
src/gpu/SkGrPriv.h
src/gpu/effects/GrConfigConversionEffect.cpp
src/gpu/effects/GrTextureStripAtlas.cpp
src/gpu/gl/GrGLCaps.cpp
src/gpu/gl/GrGLCaps.h
src/gpu/gl/GrGLDefines.h
src/gpu/gl/GrGLGpu.cpp
src/gpu/gl/GrGLGpu.h
src/gpu/gl/GrGLTexture.h
src/image/SkImage_Gpu.cpp
src/views/SkWindow.cpp
tests/ReadPixelsTest.cpp

index bb29a0c3f53824f69e09085994e67ee33cd2a498..892dce1c805251a31abc956273b199872c3268b8 100644 (file)
@@ -157,7 +157,8 @@ void HelloWorldWindow::draw(SkCanvas* canvas) {
             fRenderTarget->writePixels(0, 0, snap->width(), snap->height(),
                                             SkImageInfo2GrPixelConfig(info.colorType(),
                                                                     info.alphaType(),
-                                                                    info.profileType()),
+                                                                    info.profileType(),
+                                                                    *fContext->caps()),
                                             pmap.addr(),
                                             pmap.rowBytes(),
                                             GrContext::kFlushWrites_PixelOp);
index 60f213950ebf1b843bc5d5fc48290a2f6d758e8a..b806dcbabc67aba5d589ce1cc6bd7c88453d539c 100644 (file)
@@ -137,6 +137,7 @@ public:
     /** To avoid as-yet-unnecessary complexity we don't allow any partial support of MIP Maps (e.g.
         only for POT textures) */
     bool mipMapSupport() const { return fMipMapSupport; }
+    bool srgbSupport() const { return fSRGBSupport; }
     bool twoSidedStencilSupport() const { return fTwoSidedStencilSupport; }
     bool stencilWrapOpsSupport() const { return  fStencilWrapOpsSupport; }
     bool discardRenderTargetSupport() const { return fDiscardRenderTargetSupport; }
@@ -268,6 +269,7 @@ protected:
 
     bool fNPOTTextureTileSupport                     : 1;
     bool fMipMapSupport                              : 1;
+    bool fSRGBSupport                                : 1;
     bool fTwoSidedStencilSupport                     : 1;
     bool fStencilWrapOpsSupport                      : 1;
     bool fDiscardRenderTargetSupport                 : 1;
index 6b83237626ae590746757ac28ce22b9a5c22a3f8..77f1a6cb0841aa84d1f073ea7265d28438cc2b02 100644 (file)
@@ -208,7 +208,6 @@ static inline char GrColorComponentFlagToChar(GrColorComponentFlags component) {
 }
 
 static inline uint32_t GrPixelConfigComponentMask(GrPixelConfig config) {
-    SkASSERT(config >= 0 && config < kGrPixelConfigCnt);
     static const uint32_t kFlags[] = {
         0,                              // kUnknown_GrPixelConfig
         kA_GrColorComponentFlag,        // kAlpha_8_GrPixelConfig
@@ -218,6 +217,7 @@ static inline uint32_t GrPixelConfigComponentMask(GrPixelConfig config) {
         kRGBA_GrColorComponentFlags,    // kRGBA_8888_GrPixelConfig
         kRGBA_GrColorComponentFlags,    // kBGRA_8888_GrPixelConfig
         kRGBA_GrColorComponentFlags,    // kSRGBA_8888_GrPixelConfig
+        kRGBA_GrColorComponentFlags,    // kSBGRA_8888_GrPixelConfig
         kRGB_GrColorComponentFlags,     // kETC1_GrPixelConfig
         kA_GrColorComponentFlag,        // kLATC_GrPixelConfig
         kA_GrColorComponentFlag,        // kR11_EAC_GrPixelConfig
@@ -236,13 +236,14 @@ static inline uint32_t GrPixelConfigComponentMask(GrPixelConfig config) {
     GR_STATIC_ASSERT(5  == kRGBA_8888_GrPixelConfig);
     GR_STATIC_ASSERT(6  == kBGRA_8888_GrPixelConfig);
     GR_STATIC_ASSERT(7  == kSRGBA_8888_GrPixelConfig);
-    GR_STATIC_ASSERT(8  == kETC1_GrPixelConfig);
-    GR_STATIC_ASSERT(9  == kLATC_GrPixelConfig);
-    GR_STATIC_ASSERT(10  == kR11_EAC_GrPixelConfig);
-    GR_STATIC_ASSERT(11 == kASTC_12x12_GrPixelConfig);
-    GR_STATIC_ASSERT(12 == kRGBA_float_GrPixelConfig);
-    GR_STATIC_ASSERT(13 == kAlpha_half_GrPixelConfig);
-    GR_STATIC_ASSERT(14 == kRGBA_half_GrPixelConfig);
+    GR_STATIC_ASSERT(8  == kSBGRA_8888_GrPixelConfig);
+    GR_STATIC_ASSERT(9  == kETC1_GrPixelConfig);
+    GR_STATIC_ASSERT(10  == kLATC_GrPixelConfig);
+    GR_STATIC_ASSERT(11  == kR11_EAC_GrPixelConfig);
+    GR_STATIC_ASSERT(12 == kASTC_12x12_GrPixelConfig);
+    GR_STATIC_ASSERT(13 == kRGBA_float_GrPixelConfig);
+    GR_STATIC_ASSERT(14 == kAlpha_half_GrPixelConfig);
+    GR_STATIC_ASSERT(15 == kRGBA_half_GrPixelConfig);
     GR_STATIC_ASSERT(SK_ARRAY_COUNT(kFlags) == kGrPixelConfigCnt);
 }
 
index 3186b1b027186b29df31361e7fd80eb6055d52f8..40d9ac5375049327d66f5513c9a3927de4aaeb8e 100644 (file)
@@ -24,6 +24,11 @@ public:
         static const GrTextureParams gParams(SkShader::kClamp_TileMode, kBilerp_FilterMode);
         return gParams;
     }
+    static const GrTextureParams& ClampNoFilterForceAllowSRGB() {
+        static const GrTextureParams gParams(SkShader::kClamp_TileMode, kNone_FilterMode,
+                                             kForceAllowSRGB_SRGBMode);
+        return gParams;
+    }
 
     GrTextureParams() {
         this->reset();
@@ -35,10 +40,19 @@ public:
         kMipMap_FilterMode
     };
 
+    enum SRGBMode {
+        kRespectDestination_SRGBMode,
+        kForceAllowSRGB_SRGBMode,
+    };
+
     GrTextureParams(SkShader::TileMode tileXAndY, FilterMode filterMode) {
         this->reset(tileXAndY, filterMode);
     }
 
+    GrTextureParams(SkShader::TileMode tileXandY, FilterMode filterMode, SRGBMode srgbMode) {
+        this->reset(tileXandY, filterMode, srgbMode);
+    }
+
     GrTextureParams(const SkShader::TileMode tileModes[2], FilterMode filterMode) {
         this->reset(tileModes, filterMode);
     }
@@ -51,6 +65,7 @@ public:
         fTileModes[0] = params.fTileModes[0];
         fTileModes[1] = params.fTileModes[1];
         fFilterMode = params.fFilterMode;
+        fSRGBMode = params.fSRGBMode;
         return *this;
     }
 
@@ -61,12 +76,20 @@ public:
     void reset(SkShader::TileMode tileXAndY, FilterMode filterMode) {
         fTileModes[0] = fTileModes[1] = tileXAndY;
         fFilterMode = filterMode;
+        fSRGBMode = kRespectDestination_SRGBMode;
+    }
+
+    void reset(SkShader::TileMode tileXandY, FilterMode filterMode, SRGBMode srgbMode) {
+        fTileModes[0] = fTileModes[1] = tileXandY;
+        fFilterMode = filterMode;
+        fSRGBMode = srgbMode;
     }
 
     void reset(const SkShader::TileMode tileModes[2], FilterMode filterMode) {
         fTileModes[0] = tileModes[0];
         fTileModes[1] = tileModes[1];
         fFilterMode = filterMode;
+        fSRGBMode = kRespectDestination_SRGBMode;
     }
 
     void setClampNoFilter() {
@@ -84,6 +107,8 @@ public:
     void setTileModeY(const SkShader::TileMode tm) { fTileModes[1] = tm; }
     void setTileModeXAndY(const SkShader::TileMode tm) { fTileModes[0] = fTileModes[1] = tm; }
 
+    void setSRGBMode(SRGBMode srgbMode) { fSRGBMode = srgbMode; }
+
     SkShader::TileMode getTileModeX() const { return fTileModes[0]; }
 
     SkShader::TileMode getTileModeY() const { return fTileModes[1]; }
@@ -95,10 +120,13 @@ public:
 
     FilterMode filterMode() const { return fFilterMode; }
 
+    SRGBMode srgbMode() const { return fSRGBMode; }
+
     bool operator== (const GrTextureParams& other) const {
         return fTileModes[0] == other.fTileModes[0] &&
                fTileModes[1] == other.fTileModes[1] &&
-               fFilterMode == other.fFilterMode;
+               fFilterMode == other.fFilterMode &&
+               fSRGBMode == other.fSRGBMode;
     }
 
     bool operator!= (const GrTextureParams& other) const { return !(*this == other); }
@@ -106,5 +134,6 @@ public:
 private:
     SkShader::TileMode fTileModes[2];
     FilterMode         fFilterMode;
+    SRGBMode           fSRGBMode;
 };
 #endif
index 3def9aaa993df434948afe15cf8263d655f42776..9be500d3b2206e004a9fbed3bc176365bae51d0a 100644 (file)
@@ -217,6 +217,10 @@ enum GrPixelConfig {
      * Premultiplied and sRGB. Byte order is r,g,b,a.
      */
     kSRGBA_8888_GrPixelConfig,
+    /**
+     * Premultiplied and sRGB. Byte order is b,g,r,a.
+     */
+    kSBGRA_8888_GrPixelConfig,
     /**
      * ETC1 Compressed Data
      */
@@ -268,8 +272,10 @@ static const int kGrPixelConfigCnt = kLast_GrPixelConfig + 1;
 #endif
 #if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
     static const GrPixelConfig kSkia8888_GrPixelConfig = kBGRA_8888_GrPixelConfig;
+    static const GrPixelConfig kSkiaGamma8888_GrPixelConfig = kSBGRA_8888_GrPixelConfig;
 #elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
     static const GrPixelConfig kSkia8888_GrPixelConfig = kRGBA_8888_GrPixelConfig;
+    static const GrPixelConfig kSkiaGamma8888_GrPixelConfig = kSRGBA_8888_GrPixelConfig;
 #else
     #error "SK_*32_SHIFT values must correspond to GL_BGRA or GL_RGBA format."
 #endif
@@ -311,6 +317,7 @@ static inline bool GrPixelConfigIs8888(GrPixelConfig config) {
         case kRGBA_8888_GrPixelConfig:
         case kBGRA_8888_GrPixelConfig:
         case kSRGBA_8888_GrPixelConfig:
+        case kSBGRA_8888_GrPixelConfig:
             return true;
         default:
             return false;
@@ -322,6 +329,7 @@ static inline bool GrPixelConfigIs8888(GrPixelConfig config) {
 static inline bool GrPixelConfigIsSRGB(GrPixelConfig config) {
     switch (config) {
         case kSRGBA_8888_GrPixelConfig:
+        case kSBGRA_8888_GrPixelConfig:
             return true;
         default:
             return false;
@@ -336,6 +344,10 @@ static inline GrPixelConfig GrPixelConfigSwapRAndB(GrPixelConfig config) {
             return kRGBA_8888_GrPixelConfig;
         case kRGBA_8888_GrPixelConfig:
             return kBGRA_8888_GrPixelConfig;
+        case kSBGRA_8888_GrPixelConfig:
+            return kSRGBA_8888_GrPixelConfig;
+        case kSRGBA_8888_GrPixelConfig:
+            return kSBGRA_8888_GrPixelConfig;
         default:
             return kUnknown_GrPixelConfig;
     }
@@ -353,6 +365,7 @@ static inline size_t GrBytesPerPixel(GrPixelConfig config) {
         case kRGBA_8888_GrPixelConfig:
         case kBGRA_8888_GrPixelConfig:
         case kSRGBA_8888_GrPixelConfig:
+        case kSBGRA_8888_GrPixelConfig:
             return 4;
         case kRGBA_half_GrPixelConfig:
             return 8;
@@ -386,6 +399,16 @@ static inline bool GrPixelConfigIsAlphaOnly(GrPixelConfig config) {
     }
 }
 
+static inline bool GrAllowSRGBForDestinationPixelConfig(GrPixelConfig config) {
+    switch (config) {
+        case kRGBA_8888_GrPixelConfig:
+        case kBGRA_8888_GrPixelConfig:
+            return false;
+        default:
+            return true;
+    }
+}
+
 /**
  * Optional bitfield flags that can be set on GrSurfaceDesc (below).
  */
index aacc5d25db20f40815d5ed6278058306e12c318b..6a73636c69047e26e70dbcd39127f378bd88c658 100644 (file)
@@ -15,6 +15,7 @@
 #include "SkFilterQuality.h"
 #include "SkImageInfo.h"
 
+class GrCaps;
 class GrContext;
 class GrTexture;
 class GrTextureParams;
@@ -70,10 +71,10 @@ static inline GrColor SkPMColorToGrColor(SkPMColor c) {
 GrTexture* GrRefCachedBitmapTexture(GrContext*, const SkBitmap&, const GrTextureParams&);
 
 // TODO: Move SkImageInfo2GrPixelConfig to SkGrPriv.h (requires cleanup to SkWindow its subclasses).
-GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType, SkAlphaType, SkColorProfileType);
+GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType, SkAlphaType, SkColorProfileType, const GrCaps&);
 
-static inline GrPixelConfig SkImageInfo2GrPixelConfig(const SkImageInfo& info) {
-    return SkImageInfo2GrPixelConfig(info.colorType(), info.alphaType(), info.profileType());
+static inline GrPixelConfig SkImageInfo2GrPixelConfig(const SkImageInfo& info, const GrCaps& caps) {
+    return SkImageInfo2GrPixelConfig(info.colorType(), info.alphaType(), info.profileType(), caps);
 }
 
 GrTextureParams::FilterMode GrSkFilterQualityToGrFilterMode(SkFilterQuality paintFilterQuality,
index 05d6ce0f7dc5fac6beb216c7ffa65417605bcbb5..afd942bf1f5fc2dc7885d4599242a2eea0e768de 100644 (file)
@@ -310,7 +310,8 @@ public:
                 fCurRenderTarget->writePixels(0, 0, bm.width(), bm.height(),
                                              SkImageInfo2GrPixelConfig(bm.colorType(),
                                                                        bm.alphaType(),
-                                                                       bm.profileType()),
+                                                                       bm.profileType(),
+                                                                       *fCurContext->caps()),
                                              bm.getPixels(),
                                              bm.rowBytes(),
                                              GrContext::kFlushWrites_PixelOp);
index 12c09cbe0ae7107658350379635c5881eea9a010..bb389e986b4e4d831ddd5d66bead22324729b824 100644 (file)
@@ -171,7 +171,8 @@ bool SkImageCacherator::lockAsBitmap(SkBitmap* bitmap, const SkImage* client,
     }
 
     const uint32_t pixelOpsFlags = 0;
-    if (!tex->readPixels(0, 0, bitmap->width(), bitmap->height(), SkImageInfo2GrPixelConfig(fInfo),
+    if (!tex->readPixels(0, 0, bitmap->width(), bitmap->height(),
+                         SkImageInfo2GrPixelConfig(fInfo, *tex->getContext()->caps()),
                          bitmap->getPixels(), bitmap->rowBytes(), pixelOpsFlags)) {
         bitmap->reset();
         return false;
@@ -273,7 +274,7 @@ GrTexture* SkImageCacherator::lockTexture(GrContext* ctx, const GrUniqueKey& key
         }
     }
 
-    const GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(fInfo);
+    const GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(fInfo, *ctx->caps());
 
     // 3. Ask the generator to return a compressed form that the GPU might support
     SkAutoTUnref<SkData> data(this->refEncoded(ctx));
index 991e16351586674ad01272215071f043c72d8408..426a44ebff26ed4a4a8059f3f34a79ad8a4ea90f 100644 (file)
@@ -136,6 +136,7 @@ SkImageFilter::Proxy* SkSpecialImage::internal_getProxy() const {
 ///////////////////////////////////////////////////////////////////////////////
 #include "SkImage.h"
 #if SK_SUPPORT_GPU
+#include "GrContext.h"
 #include "SkGrPriv.h"
 #endif
 
@@ -206,7 +207,7 @@ public:
 #if SK_SUPPORT_GPU
         GrTexture* texture = as_IB(fImage.get())->peekTexture();
         if (texture) {
-            GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(info);
+            GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(info, *texture->getContext()->caps());
             desc.fFlags = kRenderTarget_GrSurfaceFlag;
 
             return SkSpecialSurface::MakeRenderTarget(this->proxy(), texture->getContext(), desc);
@@ -430,7 +431,7 @@ public:
     }
 
     sk_sp<SkSpecialSurface> onMakeSurface(const SkImageInfo& info) const override {
-        GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(info);
+        GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(info, *fTexture->getContext()->caps());
         desc.fFlags = kRenderTarget_GrSurfaceFlag;
 
         return SkSpecialSurface::MakeRenderTarget(this->proxy(), fTexture->getContext(), desc);
index 77a850187788874df96455265709d922d66a0bcb..7fac2a6b2c09c1328f1e2cc51219e7a55b003539 100644 (file)
@@ -198,6 +198,8 @@ GrTexture* GaussianBlur(GrContext* context,
 
     SkASSERT(kBGRA_8888_GrPixelConfig == srcTexture->config() ||
              kRGBA_8888_GrPixelConfig == srcTexture->config() ||
+             kSRGBA_8888_GrPixelConfig == srcTexture->config() ||
+             kSBGRA_8888_GrPixelConfig == srcTexture->config() ||
              kAlpha_8_GrPixelConfig == srcTexture->config());
 
     GrSurfaceDesc desc;
index 3a6c070fab80c0f400613636f6e0f07dd03e28ca..5ae175ffca7822f43c40c83206d11465249950c5 100644 (file)
@@ -331,6 +331,7 @@ SkColorFilter* SkTable_ColorFilter::newComposed(const SkColorFilter* innerFilter
 
 #if SK_SUPPORT_GPU
 
+#include "GrContext.h"
 #include "GrFragmentProcessor.h"
 #include "GrInvariantOutput.h"
 #include "SkGr.h"
@@ -466,7 +467,7 @@ const GrFragmentProcessor* ColorTableEffect::Create(GrContext* context, SkBitmap
     desc.fHeight = 128;
     desc.fRowHeight = bitmap.height();
     desc.fContext = context;
-    desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info());
+    desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *context->caps());
     GrTextureStripAtlas* atlas = GrTextureStripAtlas::GetAtlas(desc);
     int row = atlas->lockRow(bitmap);
     SkAutoTUnref<GrTexture> texture;
index 9fe6c91a018ebcdcad364c344914dfc0c77631ff..e305a73a35fd6d74e822490b9acfba5ce70edaea 100644 (file)
@@ -905,6 +905,7 @@ SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
 #if SK_SUPPORT_GPU
 
 #include "effects/GrTextureStripAtlas.h"
+#include "GrContext.h"
 #include "GrInvariantOutput.h"
 #include "gl/GrGLContext.h"
 #include "glsl/GrGLSLFragmentShaderBuilder.h"
@@ -1117,7 +1118,7 @@ GrGradientEffect::GrGradientEffect(GrContext* ctx,
         desc.fHeight = 32;
         desc.fRowHeight = bitmap.height();
         desc.fContext = ctx;
-        desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info());
+        desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *ctx->caps());
         fAtlas = GrTextureStripAtlas::GetAtlas(desc);
         SkASSERT(fAtlas);
 
index c544d6ef772fa979ba2bb01e402c54ba7e217c82..000f90c6a628a9e3cb61b7938aeb6084d35de40c 100644 (file)
@@ -83,6 +83,7 @@ void GrShaderCaps::applyOptionsOverrides(const GrContextOptions& options) {
 GrCaps::GrCaps(const GrContextOptions& options) {
     fMipMapSupport = false;
     fNPOTTextureTileSupport = false;
+    fSRGBSupport = false;
     fTwoSidedStencilSupport = false;
     fStencilWrapOpsSupport = false;
     fDiscardRenderTargetSupport = false;
@@ -157,6 +158,7 @@ SkString GrCaps::dump() const {
     static const char* gNY[] = {"NO", "YES"};
     r.appendf("MIP Map Support                    : %s\n", gNY[fMipMapSupport]);
     r.appendf("NPOT Texture Tile Support          : %s\n", gNY[fNPOTTextureTileSupport]);
+    r.appendf("sRGB Support                       : %s\n", gNY[fSRGBSupport]);
     r.appendf("Two Sided Stencil Support          : %s\n", gNY[fTwoSidedStencilSupport]);
     r.appendf("Stencil Wrap Ops  Support          : %s\n", gNY[fStencilWrapOpsSupport]);
     r.appendf("Discard Render Target Support      : %s\n", gNY[fDiscardRenderTargetSupport]);
@@ -210,6 +212,7 @@ SkString GrCaps::dump() const {
         "RGBA8888", // kRGBA_8888_GrPixelConfig,
         "BGRA8888", // kBGRA_8888_GrPixelConfig,
         "SRGBA8888",// kSRGBA_8888_GrPixelConfig,
+        "SBGRA8888",// kSBGRA_8888_GrPixelConfig,
         "ETC1",     // kETC1_GrPixelConfig,
         "LATC",     // kLATC_GrPixelConfig,
         "R11EAC",   // kR11_EAC_GrPixelConfig,
@@ -226,13 +229,14 @@ SkString GrCaps::dump() const {
     GR_STATIC_ASSERT(5  == kRGBA_8888_GrPixelConfig);
     GR_STATIC_ASSERT(6  == kBGRA_8888_GrPixelConfig);
     GR_STATIC_ASSERT(7  == kSRGBA_8888_GrPixelConfig);
-    GR_STATIC_ASSERT(8  == kETC1_GrPixelConfig);
-    GR_STATIC_ASSERT(9  == kLATC_GrPixelConfig);
-    GR_STATIC_ASSERT(10  == kR11_EAC_GrPixelConfig);
-    GR_STATIC_ASSERT(11 == kASTC_12x12_GrPixelConfig);
-    GR_STATIC_ASSERT(12 == kRGBA_float_GrPixelConfig);
-    GR_STATIC_ASSERT(13 == kAlpha_half_GrPixelConfig);
-    GR_STATIC_ASSERT(14 == kRGBA_half_GrPixelConfig);
+    GR_STATIC_ASSERT(8  == kSBGRA_8888_GrPixelConfig);
+    GR_STATIC_ASSERT(9  == kETC1_GrPixelConfig);
+    GR_STATIC_ASSERT(10  == kLATC_GrPixelConfig);
+    GR_STATIC_ASSERT(11  == kR11_EAC_GrPixelConfig);
+    GR_STATIC_ASSERT(12 == kASTC_12x12_GrPixelConfig);
+    GR_STATIC_ASSERT(13 == kRGBA_float_GrPixelConfig);
+    GR_STATIC_ASSERT(14 == kAlpha_half_GrPixelConfig);
+    GR_STATIC_ASSERT(15 == kRGBA_half_GrPixelConfig);
     GR_STATIC_ASSERT(SK_ARRAY_COUNT(kConfigNames) == kGrPixelConfigCnt);
 
     SkASSERT(!this->isConfigRenderable(kUnknown_GrPixelConfig, false));
index c2d8bdad325adc8ab5b09008ec5d7a9e90784568..823e9b84ff88de04b09e82417477f4d9e044be76 100644 (file)
@@ -193,6 +193,7 @@ GrRenderTarget* SkGpuDevice::CreateRenderTarget(
 
     SkColorType ct = origInfo.colorType();
     SkAlphaType at = origInfo.alphaType();
+    SkColorProfileType pt = origInfo.profileType();
     if (kRGB_565_SkColorType == ct) {
         at = kOpaque_SkAlphaType;  // force this setting
     } else if (ct != kBGRA_8888_SkColorType && ct != kRGBA_8888_SkColorType) {
@@ -202,13 +203,13 @@ GrRenderTarget* SkGpuDevice::CreateRenderTarget(
     if (kOpaque_SkAlphaType != at) {
         at = kPremul_SkAlphaType;  // force this setting
     }
-    const SkImageInfo info = SkImageInfo::Make(origInfo.width(), origInfo.height(), ct, at);
+    const SkImageInfo info = SkImageInfo::Make(origInfo.width(), origInfo.height(), ct, at, pt);
 
     GrSurfaceDesc desc;
     desc.fFlags = kRenderTarget_GrSurfaceFlag;
     desc.fWidth = info.width();
     desc.fHeight = info.height();
-    desc.fConfig = SkImageInfo2GrPixelConfig(info);
+    desc.fConfig = SkImageInfo2GrPixelConfig(info, *context->caps());
     desc.fSampleCnt = sampleCount;
     desc.fTextureStorageAllocator = textureStorageAllocator;
     desc.fIsMipMapped = false;
@@ -227,7 +228,7 @@ bool SkGpuDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size
     ASSERT_SINGLE_OWNER
 
     // TODO: teach fRenderTarget to take ImageInfo directly to specify the src pixels
-    GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo);
+    GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo, *fContext->caps());
     if (kUnknown_GrPixelConfig == config) {
         return false;
     }
@@ -244,7 +245,7 @@ bool SkGpuDevice::onWritePixels(const SkImageInfo& info, const void* pixels, siz
                                 int x, int y) {
     ASSERT_SINGLE_OWNER
     // TODO: teach fRenderTarget to take ImageInfo directly to specify the src pixels
-    GrPixelConfig config = SkImageInfo2GrPixelConfig(info);
+    GrPixelConfig config = SkImageInfo2GrPixelConfig(info, *fContext->caps());
     if (kUnknown_GrPixelConfig == config) {
         return false;
     }
index 9ab8843386cd385a6e34ce724d6250866ef8a6fc..61ab4b402a67f020a48658a5297b2d62d31a1ff3 100644 (file)
 #  include "etc1.h"
 #endif
 
-GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info) {
+GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info, const GrCaps& caps) {
     GrSurfaceDesc desc;
     desc.fFlags = kNone_GrSurfaceFlags;
     desc.fWidth = info.width();
     desc.fHeight = info.height();
-    desc.fConfig = SkImageInfo2GrPixelConfig(info);
+    desc.fConfig = SkImageInfo2GrPixelConfig(info, caps);
     desc.fSampleCnt = 0;
     return desc;
 }
@@ -213,7 +213,7 @@ static GrTexture* load_etc1_texture(GrContext* ctx, const SkBitmap &bm, GrSurfac
 }
 
 GrTexture* GrUploadBitmapToTexture(GrContext* ctx, const SkBitmap& bitmap) {
-    GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap.info());
+    GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap.info(), *ctx->caps());
     if (GrTexture *texture = load_etc1_texture(ctx, bitmap, desc)) {
         return texture;
     }
@@ -238,10 +238,34 @@ GrTexture* GrUploadPixmapToTexture(GrContext* ctx, const SkPixmap& pixmap, SkBud
     SkPixmap tmpPixmap;
     SkBitmap tmpBitmap;
 
-    GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(pixmap.info());
     const GrCaps* caps = ctx->caps();
-
-    if (kIndex_8_SkColorType == pixmap.colorType()) {
+    GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(pixmap.info(), *caps);
+
+    if (caps->srgbSupport() && !GrPixelConfigIsSRGB(desc.fConfig) &&
+        kSRGB_SkColorProfileType == pixmap.info().profileType()) {
+        // We we supplied sRGB as the profile type, but we don't have a suitable pixel config.
+        // Convert to 8888 sRGB so we can handle the data correctly. The raster backend doesn't
+        // handle sRGB Index8 -> sRGB 8888 correctly (yet), so lie about both the source and
+        // destination (claim they're linear):
+        SkImageInfo linSrcInfo = SkImageInfo::Make(pixmap.width(), pixmap.height(),
+                                                   pixmap.colorType(), pixmap.alphaType());
+        SkPixmap linSrcPixmap(linSrcInfo, pixmap.addr(), pixmap.rowBytes(), pixmap.ctable());
+
+        SkImageInfo dstInfo = SkImageInfo::MakeN32Premul(pixmap.width(), pixmap.height(),
+                                                         kSRGB_SkColorProfileType);
+        tmpBitmap.allocPixels(dstInfo);
+
+        SkImageInfo linDstInfo = SkImageInfo::MakeN32Premul(pixmap.width(), pixmap.height());
+        if (!linSrcPixmap.readPixels(linDstInfo, tmpBitmap.getPixels(), tmpBitmap.rowBytes())) {
+            return nullptr;
+        }
+        if (!tmpBitmap.peekPixels(&tmpPixmap)) {
+            return nullptr;
+        }
+        pmap = &tmpPixmap;
+        // must rebuild desc, since we've forced the info to be N32
+        desc = GrImageInfoToSurfaceDesc(pmap->info(), *caps);
+    } else if (kIndex_8_SkColorType == pixmap.colorType()) {
         if (caps->isConfigTexturable(kIndex_8_GrPixelConfig)) {
             size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig,
                                                           pixmap.width(), pixmap.height());
@@ -263,7 +287,7 @@ GrTexture* GrUploadPixmapToTexture(GrContext* ctx, const SkPixmap& pixmap, SkBud
             }
             pmap = &tmpPixmap;
             // must rebuild desc, since we've forced the info to be N32
-            desc = GrImageInfoToSurfaceDesc(pmap->info());
+            desc = GrImageInfoToSurfaceDesc(pmap->info(), *caps);
         }
     }
 
@@ -289,7 +313,7 @@ void GrInstallBitmapUniqueKeyInvalidator(const GrUniqueKey& key, SkPixelRef* pix
 
 GrTexture* GrGenerateMipMapsAndUploadToTexture(GrContext* ctx, const SkBitmap& bitmap)
 {
-    GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap.info());
+    GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap.info(), *ctx->caps());
     if (kIndex_8_SkColorType != bitmap.colorType() && !bitmap.readyToDraw()) {
         GrTexture* texture = load_etc1_texture(ctx, bitmap, desc);
         if (texture) {
@@ -358,7 +382,10 @@ GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap,
 
 // alphatype is ignore for now, but if GrPixelConfig is expanded to encompass
 // alpha info, that will be considered.
-GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProfileType pt) {
+GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProfileType pt,
+                                        const GrCaps& caps) {
+    // We intentionally ignore profile type for non-8888 formats. Anything we can't support
+    // in hardware will be expanded to sRGB 8888 in GrUploadPixmapToTexture.
     switch (ct) {
         case kUnknown_SkColorType:
             return kUnknown_GrPixelConfig;
@@ -369,12 +396,11 @@ GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType, SkColorProf
         case kARGB_4444_SkColorType:
             return kRGBA_4444_GrPixelConfig;
         case kRGBA_8888_SkColorType:
-            //if (kSRGB_SkColorProfileType == pt) {
-            //    return kSRGBA_8888_GrPixelConfig;
-            //}
-            return kRGBA_8888_GrPixelConfig;
+            return (kSRGB_SkColorProfileType == pt && caps.srgbSupport())
+                   ? kSRGBA_8888_GrPixelConfig : kRGBA_8888_GrPixelConfig;
         case kBGRA_8888_SkColorType:
-            return kBGRA_8888_GrPixelConfig;
+            return (kSRGB_SkColorProfileType == pt && caps.srgbSupport())
+                   ? kSBGRA_8888_GrPixelConfig : kBGRA_8888_GrPixelConfig;
         case kIndex_8_SkColorType:
             return kIndex_8_GrPixelConfig;
         case kGray_8_SkColorType:
@@ -413,6 +439,10 @@ bool GrPixelConfig2ColorAndProfileType(GrPixelConfig config, SkColorType* ctOut,
             ct = kRGBA_8888_SkColorType;
             pt = kSRGB_SkColorProfileType;
             break;
+        case kSBGRA_8888_GrPixelConfig:
+            ct = kBGRA_8888_SkColorType;
+            pt = kSRGB_SkColorProfileType;
+            break;
         default:
             return false;
     }
index f61d92e1863b1d58e4854023f59a7f54dfe1df6c..e21d3b9d6ddd5e2d46863d15a6d5d7c73bd75d5c 100644 (file)
@@ -75,7 +75,7 @@ static SkGrPixelRef* copy_to_new_texture_pixelref(GrTexture* texture, SkColorTyp
         srcRect = *subset;
     }
     desc.fFlags = kRenderTarget_GrSurfaceFlag;
-    desc.fConfig = SkImageInfo2GrPixelConfig(dstCT, kPremul_SkAlphaType, dstPT);
+    desc.fConfig = SkImageInfo2GrPixelConfig(dstCT, kPremul_SkAlphaType, dstPT, *context->caps());
     desc.fTextureStorageAllocator = texture->desc().fTextureStorageAllocator;
     desc.fIsMipMapped = false;
 
index 75f4000ba47f978e548e61f519a1f112d5966999..f43a4e9595486e2892f25a2e3deedde488a713ea 100644 (file)
@@ -95,7 +95,7 @@ bool SkPaintToGrPaintWithTexture(GrContext* context,
 
 //////////////////////////////////////////////////////////////////////////////
 
-GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo&);
+GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo&, const GrCaps&);
 
 bool GrPixelConfig2ColorAndProfileType(GrPixelConfig, SkColorType*, SkColorProfileType*);
 
index dc41203406ae8924a1dcabbe531bb50017cccaa7..bedcc78370e642daaaadc523bfa1c33f37eec45b 100644 (file)
@@ -98,7 +98,7 @@ GrConfigConversionEffect::GrConfigConversionEffect(GrTexture* texture,
                                                    const GrSwizzle& swizzle,
                                                    PMConversion pmConversion,
                                                    const SkMatrix& matrix)
-    : INHERITED(texture, matrix)
+    : INHERITED(texture, matrix, GrTextureParams::ClampNoFilterForceAllowSRGB())
     , fSwizzle(swizzle)
     , fPMConversion(pmConversion) {
     this->initClassID<GrConfigConversionEffect>();
@@ -296,7 +296,8 @@ const GrFragmentProcessor* GrConfigConversionEffect::Create(GrTexture* texture,
         // If we returned a GrConfigConversionEffect that was equivalent to a GrSimpleTextureEffect
         // then we may pollute our texture cache with redundant shaders. So in the case that no
         // conversions were requested we instead return a GrSimpleTextureEffect.
-        return GrSimpleTextureEffect::Create(texture, matrix);
+        return GrSimpleTextureEffect::Create(texture, matrix,
+                                             GrTextureParams::ClampNoFilterForceAllowSRGB());
     } else {
         if (kRGBA_8888_GrPixelConfig != texture->config() &&
             kBGRA_8888_GrPixelConfig != texture->config() &&
index 1ac3dab2aaded6a33f49d28ec04f2d0a25443929..1543a2e9dbed65129e21a2b78083f1c3378b3ad6 100644 (file)
@@ -158,7 +158,7 @@ int GrTextureStripAtlas::lockRow(const SkBitmap& data) {
         // that is not currently in use
         fTexture->writePixels(0,  rowNumber * fDesc.fRowHeight,
                               fDesc.fWidth, fDesc.fRowHeight,
-                              SkImageInfo2GrPixelConfig(data.info()),
+                              SkImageInfo2GrPixelConfig(data.info(), *this->getContext()->caps()),
                               data.getPixels(),
                               data.rowBytes(),
                               GrContext::kDontFlush_PixelOpsFlag);
index 40885359fba40b43d51aba8a8752f0e96f56ce5b..af31480ba74d80db4716ccffaf3aad370f9d4c0a 100644 (file)
@@ -1435,27 +1435,31 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
     }
     fConfigTable[kBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
 
-    // We only enable srgb support if both textures and FBOs support srgb.
-    bool srgbSupport = false;
+    // We only enable srgb support if both textures and FBOs support srgb,
+    // *and* we can disable sRGB decode-on-read, to support "legacy" mode.
     if (kGL_GrGLStandard == standard) {
         if (ctxInfo.version() >= GR_GL_VER(3,0)) {
-            srgbSupport = true;
+            fSRGBSupport = true;
         } else if (ctxInfo.hasExtension("GL_EXT_texture_sRGB")) {
             if (ctxInfo.hasExtension("GL_ARB_framebuffer_sRGB") ||
                 ctxInfo.hasExtension("GL_EXT_framebuffer_sRGB")) {
-                srgbSupport = true;
+                fSRGBSupport = true;
             }
         }
         // All the above srgb extensions support toggling srgb writes
-        fSRGBWriteControl = srgbSupport;
+        fSRGBWriteControl = fSRGBSupport;
     } else {
         // See https://bug.skia.org/4148 for PowerVR issue.
-        srgbSupport = kPowerVRRogue_GrGLRenderer != ctxInfo.renderer() &&
+        fSRGBSupport = kPowerVRRogue_GrGLRenderer != ctxInfo.renderer() &&
             (ctxInfo.version() >= GR_GL_VER(3,0) || ctxInfo.hasExtension("GL_EXT_sRGB"));
         // ES through 3.1 requires EXT_srgb_write_control to support toggling
         // sRGB writing for destinations.
         fSRGBWriteControl = ctxInfo.hasExtension("GL_EXT_sRGB_write_control");
     }
+    if (!ctxInfo.hasExtension("GL_EXT_texture_sRGB_decode")) {
+        // To support "legacy" L32 mode, we require the ability to turn off sRGB decode:
+        fSRGBSupport = false;
+    }
     fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
     fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
     // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
@@ -1464,7 +1468,7 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
         GR_GL_RGBA;
     fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
     fConfigTable[kSRGBA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
-    if (srgbSupport) {
+    if (fSRGBSupport) {
         fConfigTable[kSRGBA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
                                                          allRenderFlags;
     }
@@ -1473,6 +1477,26 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
     }
     fConfigTable[kSRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
 
+    // sBGRA is not a "real" thing in OpenGL, but GPUs support it, and on platforms where
+    // kN32 == BGRA, we need some way to work with it. (The default framebuffer on Windows
+    // is in this format, for example).
+    fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_SRGB_ALPHA;
+    fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_SRGB8_ALPHA8;
+    // GL does not do srgb<->rgb conversions when transferring between cpu and gpu. Thus, the
+    // external format is GL_BGRA.
+    fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] =
+        GR_GL_BGRA;
+    fConfigTable[kSBGRA_8888_GrPixelConfig].fFormats.fExternalType = GR_GL_UNSIGNED_BYTE;
+    fConfigTable[kSBGRA_8888_GrPixelConfig].fFormatType = kNormalizedFixedPoint_FormatType;
+    if (fSRGBSupport) {
+        fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag |
+            allRenderFlags;
+    }
+    if (texStorageSupported) {
+        fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag;
+    }
+    fConfigTable[kSBGRA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA();
+
     fConfigTable[kRGB_565_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_RGB;
     if (this->ES2CompatibilitySupport()) {
         fConfigTable[kRGB_565_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_RGB565;
@@ -1792,6 +1816,11 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
     if (ctxInfo.standard() == kGLES_GrGLStandard && ctxInfo.version() == GR_GL_VER(2,0)) {
         fConfigTable[kSRGBA_8888_GrPixelConfig].fFormats.fExternalFormat[kTexImage_ExternalFormatUsage] =
             GR_GL_SRGB_ALPHA;
+
+        // Additionally, because we had to "invent" sBGRA, there is no way to make it work
+        // in ES 2.0, because there is no <internalFormat> we can use. So just make that format
+        // unsupported. (If we have no sRGB support at all, this will get overwritten below).
+        fConfigTable[kSBGRA_8888_GrPixelConfig].fFlags = 0;
     }
 
     // If BGRA is supported as an internal format it must always be specified to glTex[Sub]Image
index 376610d8b0d9636c299f0a4fee95174c89f3634f..ed673e7ce73cd507a1cc96d5545431bd5029a322 100644 (file)
@@ -120,12 +120,10 @@ public:
              const GrGLInterface* glInterface);
 
     bool isConfigTexturable(GrPixelConfig config) const override {
-        SkASSERT(kGrPixelConfigCnt > config);
         return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kTextureable_Flag);
     }
 
     bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const override {
-        SkASSERT(kGrPixelConfigCnt > config);
         if (withMSAA) {
             return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kRenderableWithMSAA_Flag);
         } else {
@@ -134,7 +132,6 @@ public:
     }
 
     bool isConfigTexSupportEnabled(GrPixelConfig config) const {
-        SkASSERT(kGrPixelConfigCnt > config);
         return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kCanUseTexStorage_Flag);
     }
 
index cd73be401b4abe3a5c2a9734a130310039e823c2..ff4c4572500a4bf009e23537effd8d7e567c2672 100644 (file)
 /* TextureUsage */
 #define GR_GL_FRAMEBUFFER_ATTACHMENT         0x93A3
 
+/* TextureSRGBDecode */
+#define GR_GL_DECODE_EXT                     0x8A49
+#define GR_GL_SKIP_DECODE_EXT                0x8A4A
+
 /* TextureParameterName */
 #define GR_GL_TEXTURE_MAG_FILTER             0x2800
 #define GR_GL_TEXTURE_MIN_FILTER             0x2801
 #define GR_GL_TEXTURE_WRAP_S                 0x2802
 #define GR_GL_TEXTURE_WRAP_T                 0x2803
 #define GR_GL_TEXTURE_USAGE                  0x93A2
+#define GR_GL_TEXTURE_SRGB_DECODE_EXT        0x8A48
 
 /* TextureTarget */
 /*      GL_TEXTURE_2D */
index 76cb1a068a2bc3dee7ae2df28bc167d1eda2aad9..62baf7900283a90101d5607acd5ccad86d688d09 100644 (file)
@@ -898,6 +898,7 @@ static inline GrGLint config_alignment(GrPixelConfig config) {
         case kRGBA_8888_GrPixelConfig:
         case kBGRA_8888_GrPixelConfig:
         case kSRGBA_8888_GrPixelConfig:
+        case kSBGRA_8888_GrPixelConfig:
         case kRGBA_float_GrPixelConfig:
             return 4;
         default:
@@ -2100,13 +2101,15 @@ bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcesso
     SkSTArray<8, const GrTextureAccess*> textureAccesses;
     program->setData(primProc, pipeline, &textureAccesses);
 
+    GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTarget());
+    bool allowSRGB = GrAllowSRGBForDestinationPixelConfig(glRT->config());
+
     int numTextureAccesses = textureAccesses.count();
     for (int i = 0; i < numTextureAccesses; i++) {
-        this->bindTexture(i, textureAccesses[i]->getParams(),
+        this->bindTexture(i, textureAccesses[i]->getParams(), allowSRGB,
                           static_cast<GrGLTexture*>(textureAccesses[i]->getTexture()));
     }
 
-    GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTarget());
     this->flushStencil(pipeline.getStencil());
     this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->origin());
     this->flushHWAAState(glRT, pipeline.isHWAntialiasState(), !pipeline.getStencil().isDisabled());
@@ -2607,6 +2610,16 @@ bool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height,
             tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
             tempDrawInfo->fReadConfig = kRGBA_8888_GrPixelConfig;
             ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
+        } else if (readConfig == kSBGRA_8888_GrPixelConfig &&
+            this->glCaps().isConfigRenderable(kSRGBA_8888_GrPixelConfig, false) &&
+            this->readPixelsSupported(kSRGBA_8888_GrPixelConfig, kSRGBA_8888_GrPixelConfig)) {
+            // We're trying to read sBGRA but it's not supported. If sRGBA is renderable and
+            // we can read it back, then do a swizzling draw to a sRGBA and read it back (which
+            // will effectively be sBGRA).
+            tempDrawInfo->fTempSurfaceDesc.fConfig = kSRGBA_8888_GrPixelConfig;
+            tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
+            tempDrawInfo->fReadConfig = kSRGBA_8888_GrPixelConfig;
+            ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
         } else if (readConfig == kAlpha_8_GrPixelConfig) {
             // onReadPixels implements a fallback for cases where we are want to read kAlpha_8,
             // it's unsupported, but 32bit RGBA reads are supported.
@@ -3311,7 +3324,8 @@ static void get_tex_param_swizzle(GrPixelConfig config,
     }
 }
 
-void GrGLGpu::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture) {
+void GrGLGpu::bindTexture(int unitIdx, const GrTextureParams& params, bool dstConfigAllowsSRGB,
+                          GrGLTexture* texture) {
     SkASSERT(texture);
 
 #ifdef SK_DEBUG
@@ -3347,6 +3361,19 @@ void GrGLGpu::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTextur
     bool setAll = timestamp < this->getResetTimestamp();
     GrGLTexture::TexParams newTexParams;
 
+    if (this->caps()->srgbSupport()) {
+        // By default, the decision to allow SRGB decode is based on the destination config.
+        // A texture can override that by specifying a value in GrTextureParams.
+        newTexParams.fSRGBDecode =
+            (dstConfigAllowsSRGB || GrTextureParams::kForceAllowSRGB_SRGBMode == params.srgbMode())
+            ? GR_GL_DECODE_EXT : GR_GL_SKIP_DECODE_EXT;
+
+        if (setAll || newTexParams.fSRGBDecode != oldTexParams.fSRGBDecode) {
+            this->setTextureUnit(unitIdx);
+            GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SRGB_DECODE_EXT, newTexParams.fSRGBDecode));
+        }
+    }
+
     static GrGLenum glMinFilterModes[] = {
         GR_GL_NEAREST,
         GR_GL_LINEAR,
@@ -4014,7 +4041,7 @@ void GrGLGpu::copySurfaceAsDraw(GrSurface* dst,
 
     GrGLTexture* srcTex = static_cast<GrGLTexture*>(src->asTexture());
     GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kNone_FilterMode);
-    this->bindTexture(0, params, srcTex);
+    this->bindTexture(0, params, true, srcTex);
 
     GrGLIRect dstVP;
     this->bindSurfaceFBOForCopy(dst, GR_GL_FRAMEBUFFER, &dstVP, kDst_TempFBOTarget);
index e365601e1fddada89ca9ba9817eaf722f13ba065..a3582739e76d3de16bd0d95c70657e5e92360209 100644 (file)
@@ -59,7 +59,8 @@ public:
     void discard(GrRenderTarget*) override;
 
     // Used by GrGLProgram to configure OpenGL state.
-    void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture);
+    void bindTexture(int unitIdx, const GrTextureParams& params, bool dstConfigAllowsSRGB,
+                     GrGLTexture* texture);
 
     bool onGetReadPixelsInfo(GrSurface* srcSurface, int readWidth, int readHeight, size_t rowBytes,
                              GrPixelConfig readConfig, DrawPreference*,
index 937b8be13edd0b3d0a3e998be62aec19fb65b1e1..6ee8dcfe2b6eefa5ef35cba7f9496df124938edf 100644 (file)
@@ -25,6 +25,7 @@ public:
         GrGLenum fWrapT;
         GrGLenum fMaxMipMapLevel;
         GrGLenum fSwizzleRGBA[4];
+        GrGLenum fSRGBDecode;
         void invalidate() { memset(this, 0xff, sizeof(TexParams)); }
     };
 
index 79fe72b09ec9ab46872eaf4aaa7b4e2b7b53187e..7a99dfeaa5d1187135c021c6679e35968b821870 100644 (file)
@@ -111,7 +111,8 @@ static void apply_premul(const SkImageInfo& info, void* pixels, size_t rowBytes)
 bool SkImage_Gpu::onReadPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
                                int srcX, int srcY, CachingHint) const {
     GrPixelConfig config = SkImageInfo2GrPixelConfig(info.colorType(), info.alphaType(),
-                                                     info.profileType());
+                                                     info.profileType(),
+                                                     *fTexture->getContext()->caps());
     uint32_t flags = 0;
     if (kUnpremul_SkAlphaType == info.alphaType() && kPremul_SkAlphaType == fAlphaType) {
         // let the GPU perform this transformation for us
index 82c1a43c0a5599475a7747ebfe5bce28e54d2296..056b3eab5098ee3c96fd4d5c0337753e3ba37c5b 100644 (file)
@@ -329,9 +329,13 @@ GrRenderTarget* SkWindow::renderTarget(const AttachmentInfo& attachmentInfo,
     // TODO: Query the actual framebuffer for sRGB capable. However, to
     // preserve old (fake-linear) behavior, we don't do this. Instead, rely
     // on the flag (currently driven via 'C' mode in SampleApp).
-    desc.fConfig = (info().profileType() == kSRGB_SkColorProfileType ||
+    //
+    // Also, we may not have real sRGB support (ANGLE, in particular), so check for
+    // that, and fall back to L32:
+    desc.fConfig = grContext->caps()->srgbSupport() &&
+                   (info().profileType() == kSRGB_SkColorProfileType ||
                     info().colorType() == kRGBA_F16_SkColorType)
-        ? kSRGBA_8888_GrPixelConfig // This may not be the right byte-order
+        ? kSkiaGamma8888_GrPixelConfig
         : kSkia8888_GrPixelConfig;
     desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
     desc.fSampleCnt = attachmentInfo.fSampleCount;
index 77a11e5f8bd379262fcc1698d0dbb12f8ae43b9f..87e51163da6bde89c6eb94981ae611a562b47dca 100644 (file)
@@ -424,7 +424,8 @@ static void test_readpixels_texture(skiatest::Reporter* reporter, GrTexture* tex
                     GrPixelConfig dstConfig =
                             SkImageInfo2GrPixelConfig(gReadPixelsConfigs[c].fColorType,
                                                       gReadPixelsConfigs[c].fAlphaType,
-                                                      kLinear_SkColorProfileType);
+                                                      kLinear_SkColorProfileType,
+                                                      *texture->getContext()->caps());
                     uint32_t flags = 0;
                     if (gReadPixelsConfigs[c].fAlphaType == kUnpremul_SkAlphaType) {
                         flags = GrContext::kUnpremul_PixelOpsFlag;