Create swizzle table inside of glsl caps

BUG=skia:

Committed: https://skia.googlesource.com/skia/+/4036674952f341dab0695c3b054fefa5bb8cdec1

Review URL: https://codereview.chromium.org/1420033005
diff --git a/include/gpu/GrCaps.h b/include/gpu/GrCaps.h
index 6893dc7..9287556 100644
--- a/include/gpu/GrCaps.h
+++ b/include/gpu/GrCaps.h
@@ -100,6 +100,7 @@
     PrecisionInfo fFloatPrecisions[kGrShaderTypeCount][kGrSLPrecisionCount];
 
 private:
+    virtual void onApplyOptionsOverrides(const GrContextOptions&) {};
     typedef SkRefCnt INHERITED;
 };
 
@@ -274,6 +275,8 @@
     bool fConfigTextureSupport[kGrPixelConfigCnt];
 
 private:
+    virtual void onApplyOptionsOverrides(const GrContextOptions&) {};
+
     bool fSupressPrints : 1;
     bool fDrawPathMasksToCompressedTextureSupport : 1;
 
diff --git a/include/gpu/GrContextOptions.h b/include/gpu/GrContextOptions.h
index 5619e30..1e5897b 100644
--- a/include/gpu/GrContextOptions.h
+++ b/include/gpu/GrContextOptions.h
@@ -19,7 +19,8 @@
         , fSuppressDualSourceBlending(false)
         , fGeometryBufferMapThreshold(-1)
         , fUseDrawInsteadOfPartialRenderTargetWrite(false)
-        , fImmediateMode(false) {}
+        , fImmediateMode(false)
+        , fUseShaderSwizzling(false) {}
 
     // EXPERIMENTAL
     // May be removed in the future, or may become standard depending
@@ -50,6 +51,10 @@
     /** The GrContext operates in immedidate mode. It will issue all draws to the backend API
         immediately. Intended to ease debugging. */
     bool fImmediateMode;
+
+    /** Force us to do all swizzling manually in the shader and don't rely on extensions to do
+        swizzling. */
+    bool fUseShaderSwizzling;
 };
 
 #endif
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index 75cecdf..22f6a6d 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -77,6 +77,7 @@
 
 void GrShaderCaps::applyOptionsOverrides(const GrContextOptions& options) {
     fDualSourceBlendingSupport = fDualSourceBlendingSupport && !options.fSuppressDualSourceBlending;
+    this->onApplyOptionsOverrides(options);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -127,6 +128,7 @@
     } else {
         fMaxTileSize = options.fMaxTileSizeOverride;
     }
+    this->onApplyOptionsOverrides(options);
 }
 
 static SkString map_flags_to_string(uint32_t flags) {
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 1ce961e..0591f18 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -8,6 +8,7 @@
 
 #include "GrGLCaps.h"
 
+#include "GrContextOptions.h"
 #include "GrGLContext.h"
 #include "glsl/GrGLSLCaps.h"
 #include "SkTSearch.h"
@@ -27,7 +28,6 @@
     fMaxFragmentTextureUnits = 0;
     fRGBA8RenderbufferSupport = false;
     fBGRAIsInternalFormat = false;
-    fTextureSwizzleSupport = false;
     fUnpackRowLengthSupport = false;
     fUnpackFlipYSupport = false;
     fPackRowLengthSupport = false;
@@ -94,13 +94,6 @@
     }
 
     if (kGL_GrGLStandard == standard) {
-        fTextureSwizzleSupport = version >= GR_GL_VER(3,3) ||
-                                 ctxInfo.hasExtension("GL_ARB_texture_swizzle");
-    } else {
-        fTextureSwizzleSupport = version >= GR_GL_VER(3,0);
-    }
-
-    if (kGL_GrGLStandard == standard) {
         fUnpackRowLengthSupport = true;
         fUnpackFlipYSupport = false;
         fPackRowLengthSupport = true;
@@ -499,6 +492,8 @@
     this->initConfigTexturableTable(ctxInfo, gli, srgbSupport);
     this->initConfigRenderableTable(ctxInfo, srgbSupport);
     this->initShaderPrecisionTable(ctxInfo, gli, glslCaps);
+    // Requires fTexutreSwizzleSupport and fTextureRedSupport to be set before this point.
+    this->initConfigSwizzleTable(ctxInfo, glslCaps);
 
     this->applyOptionsOverrides(contextOptions);
     glslCaps->applyOptionsOverrides(contextOptions);
@@ -1177,7 +1172,6 @@
     r.appendf("Max Vertex Attributes: %d\n", fMaxVertexAttributes);
     r.appendf("Support RGBA8 Render Buffer: %s\n", (fRGBA8RenderbufferSupport ? "YES": "NO"));
     r.appendf("BGRA is an internal format: %s\n", (fBGRAIsInternalFormat ? "YES": "NO"));
-    r.appendf("Support texture swizzle: %s\n", (fTextureSwizzleSupport ? "YES": "NO"));
     r.appendf("Unpack Row length support: %s\n", (fUnpackRowLengthSupport ? "YES": "NO"));
     r.appendf("Unpack Flip Y support: %s\n", (fUnpackFlipYSupport ? "YES": "NO"));
     r.appendf("Pack Row length support: %s\n", (fPackRowLengthSupport ? "YES": "NO"));
@@ -1288,6 +1282,44 @@
     }
 }
 
+void GrGLCaps::initConfigSwizzleTable(const GrGLContextInfo& ctxInfo, GrGLSLCaps* glslCaps) {
+    GrGLStandard standard = ctxInfo.standard();
+    GrGLVersion version = ctxInfo.version();
 
+    glslCaps->fMustSwizzleInShader = true;
+    if (kGL_GrGLStandard == standard) {
+        if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
+            glslCaps->fMustSwizzleInShader = false;
+        }
+    } else {
+        if (version >= GR_GL_VER(3,0)) {
+            glslCaps->fMustSwizzleInShader = false;
+        }
+    }
+
+    glslCaps->fConfigSwizzle[kUnknown_GrPixelConfig] = nullptr;
+    if (fTextureRedSupport) {
+        glslCaps->fConfigSwizzle[kAlpha_8_GrPixelConfig] = "rrrr";
+        glslCaps->fConfigSwizzle[kAlpha_half_GrPixelConfig] = "rrrr";
+    } else {
+        glslCaps->fConfigSwizzle[kAlpha_8_GrPixelConfig] = "aaaa";
+        glslCaps->fConfigSwizzle[kAlpha_half_GrPixelConfig] = "aaaa";
+    }
+    glslCaps->fConfigSwizzle[kIndex_8_GrPixelConfig] = "rgba";
+    glslCaps->fConfigSwizzle[kRGB_565_GrPixelConfig] = "rgba";
+    glslCaps->fConfigSwizzle[kRGBA_4444_GrPixelConfig] = "rgba";
+    glslCaps->fConfigSwizzle[kRGBA_8888_GrPixelConfig] = "rgba";
+    glslCaps->fConfigSwizzle[kBGRA_8888_GrPixelConfig] = "rgba";
+    glslCaps->fConfigSwizzle[kSRGBA_8888_GrPixelConfig] = "rgba";
+    glslCaps->fConfigSwizzle[kETC1_GrPixelConfig] = "rgba";
+    glslCaps->fConfigSwizzle[kLATC_GrPixelConfig] = "rrrr";
+    glslCaps->fConfigSwizzle[kR11_EAC_GrPixelConfig] = "rrrr";
+    glslCaps->fConfigSwizzle[kASTC_12x12_GrPixelConfig] = "rgba";
+    glslCaps->fConfigSwizzle[kRGBA_float_GrPixelConfig] = "rgba";
+    glslCaps->fConfigSwizzle[kRGBA_half_GrPixelConfig] = "rgba";
+
+}
+
+void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {}
 
 
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 2ad5827..10d62b0 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -171,9 +171,6 @@
      */
     bool bgraIsInternalFormat() const { return fBGRAIsInternalFormat; }
 
-    /// GL_ARB_texture_swizzle support
-    bool textureSwizzleSupport() const { return fTextureSwizzleSupport; }
-
     /// Is there support for GL_UNPACK_ROW_LENGTH
     bool unpackRowLengthSupport() const { return fUnpackRowLengthSupport; }
 
@@ -273,6 +270,8 @@
     void initGLSL(const GrGLContextInfo&);
     bool hasPathRenderingSupport(const GrGLContextInfo&, const GrGLInterface*);
 
+    void onApplyOptionsOverrides(const GrContextOptions& options) override;
+
     /**
      * Maintains a bit per GrPixelConfig. It is used to avoid redundantly
      * performing glCheckFrameBufferStatus for the same config.
@@ -323,6 +322,8 @@
                                   const GrGLInterface* intf,
                                   GrGLSLCaps* glslCaps);
 
+    void initConfigSwizzleTable(const GrGLContextInfo& ctxInfo, GrGLSLCaps* glslCaps);
+
     // tracks configs that have been verified to pass the FBO completeness when
     // used as a color attachment
     VerifiedColorConfigs fVerifiedColorConfigs;
@@ -340,7 +341,6 @@
 
     bool fRGBA8RenderbufferSupport : 1;
     bool fBGRAIsInternalFormat : 1;
-    bool fTextureSwizzleSupport : 1;
     bool fUnpackRowLengthSupport : 1;
     bool fUnpackFlipYSupport : 1;
     bool fPackRowLengthSupport : 1;
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 0e9aa0d..4dde4af 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -2404,19 +2404,30 @@
     return gWrapModes[tm];
 }
 
-const GrGLenum* GrGLGpu::GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps) {
-    if (caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(config)) {
-        if (caps.textureRedSupport()) {
-            static const GrGLenum gRedSmear[] = { GR_GL_RED, GR_GL_RED, GR_GL_RED, GR_GL_RED };
-            return gRedSmear;
-        } else {
-            static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA,
-                                                    GR_GL_ALPHA, GR_GL_ALPHA };
-            return gAlphaSmear;
-        }
-    } else {
-        static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE, GR_GL_ALPHA };
-        return gStraight;
+static GrGLenum get_component_enum_from_char(char component) {
+    switch (component) {
+        case 'r':
+           return GR_GL_RED;
+        case 'g':
+           return GR_GL_GREEN;
+        case 'b':
+           return GR_GL_BLUE;
+        case 'a':
+           return GR_GL_ALPHA;
+        default:
+            SkFAIL("Unsupported component");
+            return 0;
+    }
+}
+
+/** If texture swizzling is available using tex parameters then it is preferred over mangling
+  the generated shader code. This potentially allows greater reuse of cached shaders. */
+static void get_tex_param_swizzle(GrPixelConfig config,
+                                  const GrGLSLCaps& caps,
+                                  GrGLenum* glSwizzle) {
+    const char* swizzle = caps.getSwizzleMap(config);
+    for (int i = 0; i < 4; ++i) {
+        glSwizzle[i] = get_component_enum_from_char(swizzle[i]);
     }
 }
 
@@ -2485,9 +2496,7 @@
 
     newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX());
     newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY());
-    memcpy(newTexParams.fSwizzleRGBA,
-           GetTexParamSwizzle(texture->config(), this->glCaps()),
-           sizeof(newTexParams.fSwizzleRGBA));
+    get_tex_param_swizzle(texture->config(), *this->glCaps().glslCaps(), newTexParams.fSwizzleRGBA);
     if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) {
         this->setTextureUnit(unitIdx);
         GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, newTexParams.fMagFilter));
@@ -2504,7 +2513,7 @@
         this->setTextureUnit(unitIdx);
         GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_T, newTexParams.fWrapT));
     }
-    if (this->glCaps().textureSwizzleSupport() &&
+    if (!this->glCaps().glslCaps()->mustSwizzleInShader() &&
         (setAll || memcmp(newTexParams.fSwizzleRGBA,
                           oldTexParams.fSwizzleRGBA,
                           sizeof(newTexParams.fSwizzleRGBA)))) {
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index c10d79e..396d488 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -128,11 +128,6 @@
     bool isTestingOnlyBackendTexture(GrBackendObject id) const override;
     void deleteTestingOnlyBackendTexture(GrBackendObject id) const override;
 
-    /** If texture swizzling is available using tex parameters then it is preferred over mangling
-        the generated shader code. This potentially allows greater reuse of cached shaders. */
-    static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps);
-
-
 private:
     GrGLGpu(GrGLContext* ctx, GrContext* context);
 
diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp
index a232a63..8ff2557 100644
--- a/src/gpu/gl/GrGLProgramDesc.cpp
+++ b/src/gpu/gl/GrGLProgramDesc.cpp
@@ -18,26 +18,14 @@
  * present in the texture's config. swizzleComponentMask indicates the channels present in the
  * shader swizzle.
  */
-static bool swizzle_requires_alpha_remapping(const GrGLCaps& caps,
-                                             uint32_t configComponentMask,
-                                             uint32_t swizzleComponentMask) {
-    if (caps.textureSwizzleSupport()) {
+static bool swizzle_requires_alpha_remapping(const GrGLSLCaps& caps, GrPixelConfig config) {
+    if (!caps.mustSwizzleInShader()) {
         // Any remapping is handled using texture swizzling not shader modifications.
         return false;
     }
-    // check if the texture is alpha-only
-    if (kA_GrColorComponentFlag == configComponentMask) {
-        if (caps.textureRedSupport() && (kA_GrColorComponentFlag & swizzleComponentMask)) {
-            // we must map the swizzle 'a's to 'r'.
-            return true;
-        }
-        if (kRGB_GrColorComponentFlags & swizzleComponentMask) {
-            // The 'r', 'g', and/or 'b's must be mapped to 'a' according to our semantics that
-            // alpha-only textures smear alpha across all four channels when read.
-            return true;
-        }
-    }
-    return false;
+    const char* swizzleMap = caps.getSwizzleMap(config);
+    
+    return SkToBool(memcmp(swizzleMap, "rgba", 4));
 }
 
 static uint32_t gen_texture_key(const GrProcessor& proc, const GrGLCaps& caps) {
@@ -45,8 +33,7 @@
     int numTextures = proc.numTextures();
     for (int t = 0; t < numTextures; ++t) {
         const GrTextureAccess& access = proc.textureAccess(t);
-        uint32_t configComponentMask = GrPixelConfigComponentMask(access.getTexture()->config());
-        if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.swizzleMask())) {
+        if (swizzle_requires_alpha_remapping(*caps.glslCaps(), access.getTexture()->config())) {
             key |= 1 << t;
         }
     }
diff --git a/src/gpu/gl/builders/GrGLShaderBuilder.cpp b/src/gpu/gl/builders/GrGLShaderBuilder.cpp
index 03dc166..2c00baf 100644
--- a/src/gpu/gl/builders/GrGLShaderBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLShaderBuilder.cpp
@@ -6,47 +6,68 @@
  */
 
 #include "GrGLShaderBuilder.h"
-#include "gl/GrGLGpu.h"
 #include "gl/builders/GrGLProgramBuilder.h"
 #include "glsl/GrGLSLCaps.h"
 #include "glsl/GrGLSLShaderVar.h"
 #include "glsl/GrGLSLTextureSampler.h"
 
-namespace {
-void append_texture_lookup(SkString* out,
-                           GrGLGpu* gpu,
-                           const char* samplerName,
-                           const char* coordName,
-                           uint32_t configComponentMask,
-                           const char* swizzle,
-                           GrSLType varyingType = kVec2f_GrSLType) {
+static void map_swizzle(const char* swizzleMap, const char* swizzle, char* mangledSwizzle) {
+    int i;
+    for (i = 0; '\0' != swizzle[i]; ++i) {
+        switch (swizzle[i]) {
+            case 'r':
+                mangledSwizzle[i] = swizzleMap[0];
+                break;
+            case 'g':
+                mangledSwizzle[i] = swizzleMap[1];
+                break;
+            case 'b':
+                mangledSwizzle[i] = swizzleMap[2];
+                break;
+            case 'a':
+                mangledSwizzle[i] = swizzleMap[3];
+                break;
+            default:
+                SkFAIL("Unsupported swizzle");
+        }
+    }
+    mangledSwizzle[i] ='\0';
+}
+
+static void append_texture_lookup(SkString* out,
+                                  const GrGLSLCaps* glslCaps,
+                                  const char* samplerName,
+                                  const char* coordName,
+                                  GrPixelConfig config,
+                                  const char* swizzle,
+                                  GrSLType varyingType = kVec2f_GrSLType) {
     SkASSERT(coordName);
 
     out->appendf("%s(%s, %s)",
-                 GrGLSLTexture2DFunctionName(varyingType, gpu->glslGeneration()),
+                 GrGLSLTexture2DFunctionName(varyingType, glslCaps->generation()),
                  samplerName,
                  coordName);
 
     char mangledSwizzle[5];
 
-    // The swizzling occurs using texture params instead of shader-mangling if ARB_texture_swizzle
-    // is available.
-    if (!gpu->glCaps().textureSwizzleSupport() &&
-        (kA_GrColorComponentFlag == configComponentMask)) {
-        char alphaChar = gpu->glCaps().textureRedSupport() ? 'r' : 'a';
-        int i;
-        for (i = 0; '\0' != swizzle[i]; ++i) {
-            mangledSwizzle[i] = alphaChar;
+    // This refers to any swizzling we may need to get from some backend internal format to the
+    // format used in GrPixelConfig. Some backends will automatically do the sizzling for us.
+    if (glslCaps->mustSwizzleInShader()) {
+        const char* swizzleMap = glslCaps->getSwizzleMap(config);
+        // if the map is simply 'rgba' then we don't need to do any manual swizzling to get us to
+        // a GrPixelConfig format.
+        if (memcmp(swizzleMap, "rgba", 4)) {
+            // Manually 'swizzle' the swizzle using our mapping
+            map_swizzle(swizzleMap, swizzle, mangledSwizzle);
+            swizzle = mangledSwizzle;
         }
-        mangledSwizzle[i] ='\0';
-        swizzle = mangledSwizzle;
     }
+
     // For shader prettiness we omit the swizzle rather than appending ".rgba".
     if (memcmp(swizzle, "rgba", 4)) {
         out->appendf(".%s", swizzle);
     }
 }
-}
 
 GrGLShaderBuilder::GrGLShaderBuilder(GrGLProgramBuilder* program)
     : fProgramBuilder(program)
@@ -97,10 +118,10 @@
                                             const char* coordName,
                                             GrSLType varyingType) const {
     append_texture_lookup(out,
-                          fProgramBuilder->gpu(),
+                          fProgramBuilder->glslCaps(),
                           fProgramBuilder->getUniformCStr(sampler.fSamplerUniform),
                           coordName,
-                          sampler.configComponentMask(),
+                          sampler.config(),
                           sampler.swizzle(),
                           varyingType);
 }
@@ -134,19 +155,6 @@
     }
 }
 
-void GrGLShaderBuilder::appendTextureLookup(const char* samplerName,
-                                            const char* coordName,
-                                            uint32_t configComponentMask,
-                                            const char* swizzle) {
-    append_texture_lookup(&this->code(),
-                          fProgramBuilder->gpu(),
-                          samplerName,
-                          coordName,
-                          configComponentMask,
-                          swizzle,
-                          kVec2f_GrSLType);
-}
-
 void GrGLShaderBuilder::addLayoutQualifier(const char* param, InterfaceQualifier interface) {
     SkASSERT(fProgramBuilder->glslCaps()->generation() >= k330_GrGLSLGeneration ||
              fProgramBuilder->glslCaps()->mustEnableAdvBlendEqs());
diff --git a/src/gpu/gl/builders/GrGLShaderBuilder.h b/src/gpu/gl/builders/GrGLShaderBuilder.h
index 2daea15..d63a679 100644
--- a/src/gpu/gl/builders/GrGLShaderBuilder.h
+++ b/src/gpu/gl/builders/GrGLShaderBuilder.h
@@ -126,14 +126,6 @@
     void appendDecls(const VarArray& vars, SkString* out) const;
 
     /*
-     * this super low level function is just for use internally to builders
-     */
-    void appendTextureLookup(const char* samplerName,
-                             const char* coordName,
-                             uint32_t configComponentMask,
-                             const char* swizzle);
-
-    /*
      * A general function which enables an extension in a shader if the feature bit is not present
      */
     void addFeature(uint32_t featureBit, const char* extensionName);
diff --git a/src/gpu/glsl/GrGLSLCaps.cpp b/src/gpu/glsl/GrGLSLCaps.cpp
index 54d041e..140cb11 100755
--- a/src/gpu/glsl/GrGLSLCaps.cpp
+++ b/src/gpu/glsl/GrGLSLCaps.cpp
@@ -8,6 +8,8 @@
 
 #include "GrGLSLCaps.h"
 
+#include "GrContextOptions.h"
+
 ////////////////////////////////////////////////////////////////////////////////////////////
 
 GrGLSLCaps::GrGLSLCaps(const GrContextOptions& options) {
@@ -25,6 +27,9 @@
     fFBFetchColorName = nullptr;
     fFBFetchExtensionString = nullptr;
     fAdvBlendEqInteraction = kNotSupported_AdvBlendEqInteraction;
+
+    fMustSwizzleInShader = false;
+    memset(fConfigSwizzle, 0, sizeof(fConfigSwizzle));
 }
 
 SkString GrGLSLCaps::dump() const {
@@ -56,3 +61,9 @@
     return r;
 }
 
+void GrGLSLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
+    if (options.fUseShaderSwizzling) {
+        fMustSwizzleInShader = true;
+    }
+}
+
diff --git a/src/gpu/glsl/GrGLSLCaps.h b/src/gpu/glsl/GrGLSLCaps.h
index f93ef27..e703fb8 100755
--- a/src/gpu/glsl/GrGLSLCaps.h
+++ b/src/gpu/glsl/GrGLSLCaps.h
@@ -82,6 +82,15 @@
         return fShaderDerivativeExtensionString;
     }
 
+    bool mustSwizzleInShader() const { return fMustSwizzleInShader; }
+
+    /**
+     * Returns a string which represents how to map from an internal GLFormat to a given
+     * GrPixelConfig. The function mustSwizzleInShader determines whether this swizzle is applied
+     * in the generated shader code or using sample state in the 3D API.
+     */
+    const char* getSwizzleMap(GrPixelConfig config) const { return fConfigSwizzle[config]; }
+
     GrGLSLGeneration generation() const { return fGLSLGeneration; }
 
     /**
@@ -90,6 +99,8 @@
     SkString dump() const override;
 
 private:
+    void onApplyOptionsOverrides(const GrContextOptions& options) override;
+
     GrGLSLGeneration fGLSLGeneration;
     
     bool fDropsTileOnZeroDivide : 1;
@@ -109,6 +120,9 @@
 
     AdvBlendEqInteraction fAdvBlendEqInteraction;
 
+    bool        fMustSwizzleInShader;
+    const char* fConfigSwizzle[kGrPixelConfigCnt];
+
     friend class GrGLCaps;  // For initialization.
 
     typedef GrShaderCaps INHERITED;
diff --git a/src/gpu/glsl/GrGLSLTextureSampler.h b/src/gpu/glsl/GrGLSLTextureSampler.h
index 2f14cd1..2de0431 100644
--- a/src/gpu/glsl/GrGLSLTextureSampler.h
+++ b/src/gpu/glsl/GrGLSLTextureSampler.h
@@ -19,19 +19,18 @@
 
     GrGLSLTextureSampler(UniformHandle uniform, const GrTextureAccess& access)
         : fSamplerUniform(uniform)
-        , fConfigComponentMask(GrPixelConfigComponentMask(access.getTexture()->config())) {
-        SkASSERT(0 != fConfigComponentMask);
+        , fConfig(access.getTexture()->config()) {
+        SkASSERT(kUnknown_GrPixelConfig != fConfig);
         memcpy(fSwizzle, access.getSwizzle(), 5);
     }
 
-    // bitfield of GrColorComponentFlags present in the texture's config.
-    uint32_t configComponentMask() const { return fConfigComponentMask; }
+    GrPixelConfig config() const { return fConfig; }
     // this is .abcd
     const char* swizzle() const { return fSwizzle; }
 
 private:
     UniformHandle fSamplerUniform;
-    uint32_t      fConfigComponentMask;
+    GrPixelConfig fConfig;
     char          fSwizzle[5];
 
     friend class GrGLShaderBuilder;