Allow GrGLEffects to produce variable length keys.

R=robertphillips@google.com, jvanverth@google.com

Author: bsalomon@google.com

Review URL: https://codereview.chromium.org/385713005
diff --git a/include/gpu/GrBackendEffectFactory.h b/include/gpu/GrBackendEffectFactory.h
index ef9e436..e636252 100644
--- a/include/gpu/GrBackendEffectFactory.h
+++ b/include/gpu/GrBackendEffectFactory.h
@@ -48,6 +48,31 @@
 };
 
 /**
+ * This class is used to pass the key that was created for a GrGLEffect back to it
+ * when it emits code. It may allow the emit step to skip calculations that were
+ * performed when computing the key.
+ */
+class GrEffectKey {
+public:
+    GrEffectKey(const uint32_t* key, int count) : fKey(key), fCount(count) {
+        SkASSERT(0 == reinterpret_cast<intptr_t>(key) % sizeof(uint32_t));
+    }
+
+    /** Gets the uint32_t values that the effect inserted into the key. */
+    uint32_t get32(int index) const {
+        SkASSERT(index >=0 && index < fCount);
+        return fKey[index];
+    }
+
+    /** Gets the number of uint32_t values that the effect inserted into the key. */
+    int count32() const { return fCount; }
+
+private:
+    const uint32_t* fKey;           // unowned ptr into the larger key.
+    int             fCount;         // number of uint32_ts inserted by the effect into its key.
+};
+
+/**
  * Given a GrEffect of a particular type, creates the corresponding graphics-backend-specific
  * effect object. It also tracks equivalence of shaders generated via a key. The factory for an
  * effect is accessed via GrEffect::getFactory(). Each factory instance is assigned an ID at
@@ -66,8 +91,6 @@
  */
 class GrBackendEffectFactory : SkNoncopyable {
 public:
-    typedef uint32_t EffectKey;
-
     /** 
      * Generates an effect's key. The key is based on the aspects of the GrEffect object's
      * configuration that affect GLSL code generation. Two GrEffect instances that would cause
diff --git a/include/gpu/GrEffect.h b/include/gpu/GrEffect.h
index 781a29d..8cb870e 100644
--- a/include/gpu/GrEffect.h
+++ b/include/gpu/GrEffect.h
@@ -71,9 +71,8 @@
         from getFactory()).
 
         A return value of true from isEqual() should not be used to test whether the effects would
-        generate the same shader code. To test for identical code generation use the EffectKey
-        computed by the GrBackendEffectFactory:
-            effectA.getFactory().glEffectKey(effectA) == effectB.getFactory().glEffectKey(effectB).
+        generate the same shader code. To test for identical code generation use the effects' keys
+        computed by the GrBackendEffectFactory.
      */
     bool isEqual(const GrEffect& other) const {
         if (&this->getFactory() != &other.getFactory()) {
diff --git a/include/gpu/GrTBackendEffectFactory.h b/include/gpu/GrTBackendEffectFactory.h
index 251e8c7..450eb68 100644
--- a/include/gpu/GrTBackendEffectFactory.h
+++ b/include/gpu/GrTBackendEffectFactory.h
@@ -49,8 +49,7 @@
     virtual void getGLEffectKey(const GrDrawEffect& drawEffect,
                                 const GrGLCaps& caps,
                                 GrEffectKeyBuilder* b) const SK_OVERRIDE {
-        EffectKey effectKey = GLEffect::GenKey(drawEffect, caps);
-        b->add32(effectKey);
+        GLEffect::GenKey(drawEffect, caps, b);
     }
 
     /** Returns a new instance of the appropriate *GL* implementation class
diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp
index d020857..0811808 100644
--- a/src/core/SkXfermode.cpp
+++ b/src/core/SkXfermode.cpp
@@ -823,7 +823,7 @@
         }
         virtual void emitCode(GrGLShaderBuilder* builder,
                               const GrDrawEffect& drawEffect,
-                              EffectKey key,
+                              const GrEffectKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray& coords,
@@ -969,11 +969,13 @@
             }
         }
 
-        static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+        static inline void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                                  GrEffectKeyBuilder* b) {
             // The background may come from the dst or from a texture.
-            int numTextures = drawEffect.effect()->numTextures();
-            SkASSERT(numTextures <= 1);
-            return (drawEffect.castEffect<XferEffect>().mode() << 1) | numTextures;
+            uint32_t key = drawEffect.effect()->numTextures();
+            SkASSERT(key <= 1);
+            key |= drawEffect.castEffect<XferEffect>().mode() << 1;
+            b->add32(key);
         }
 
     private:
diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp
index f8b8497..76e1bc8 100644
--- a/src/effects/SkAlphaThresholdFilter.cpp
+++ b/src/effects/SkAlphaThresholdFilter.cpp
@@ -118,7 +118,7 @@
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
@@ -140,7 +140,7 @@
 
 void GrGLAlphaThresholdEffect::emitCode(GrGLShaderBuilder* builder,
                                         const GrDrawEffect&,
-                                        EffectKey key,
+                                        const GrEffectKey& key,
                                         const char* outputColor,
                                         const char* inputColor,
                                         const TransformedCoordsArray& coords,
diff --git a/src/effects/SkArithmeticMode.cpp b/src/effects/SkArithmeticMode.cpp
index 6e01504..e43603a 100644
--- a/src/effects/SkArithmeticMode.cpp
+++ b/src/effects/SkArithmeticMode.cpp
@@ -242,7 +242,7 @@
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
@@ -250,7 +250,7 @@
 
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps);
+    static void GenKey(const GrDrawEffect&, const GrGLCaps& caps, GrEffectKeyBuilder* b);
 
 private:
     GrGLUniformManager::UniformHandle fKUni;
@@ -349,7 +349,7 @@
 
 void GrGLArithmeticEffect::emitCode(GrGLShaderBuilder* builder,
                                     const GrDrawEffect& drawEffect,
-                                    EffectKey key,
+                                    const GrEffectKey& key,
                                     const char* outputColor,
                                     const char* inputColor,
                                     const TransformedCoordsArray& coords,
@@ -401,14 +401,14 @@
     fEnforcePMColor = arith.enforcePMColor();
 }
 
-GrGLEffect::EffectKey GrGLArithmeticEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                   const GrGLCaps&) {
+void GrGLArithmeticEffect::GenKey(const GrDrawEffect& drawEffect,
+                                  const GrGLCaps&, GrEffectKeyBuilder* b) {
     const GrArithmeticEffect& arith = drawEffect.castEffect<GrArithmeticEffect>();
-    EffectKey key = arith.enforcePMColor() ? 1 : 0;
+    uint32_t key = arith.enforcePMColor() ? 1 : 0;
     if (arith.backgroundTexture()) {
         key |= 2;
     }
-    return key;
+    b->add32(key);
 }
 
 GrEffect* GrArithmeticEffect::TestCreate(SkRandom* rand,
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index 4ab9944..3c502f4 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -600,7 +600,7 @@
                       const GrDrawEffect&);
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
@@ -641,7 +641,7 @@
 
 void GrGLRectBlurEffect::emitCode(GrGLShaderBuilder* builder,
                                  const GrDrawEffect&,
-                                 EffectKey key,
+                                 const GrEffectKey& key,
                                  const char* outputColor,
                                  const char* inputColor,
                                  const TransformedCoordsArray& coords,
@@ -961,7 +961,7 @@
 
     virtual void emitCode(GrGLShaderBuilder* builder,
                           const GrDrawEffect& drawEffect,
-                          EffectKey key,
+                          const GrEffectKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
@@ -983,7 +983,7 @@
 
 void GrGLRRectBlurEffect::emitCode(GrGLShaderBuilder* builder,
                              const GrDrawEffect& drawEffect,
-                             EffectKey key,
+                             const GrEffectKey& key,
                              const char* outputColor,
                              const char* inputColor,
                              const TransformedCoordsArray&,
diff --git a/src/effects/SkColorFilters.cpp b/src/effects/SkColorFilters.cpp
index 0e2fd6c..43df215 100644
--- a/src/effects/SkColorFilters.cpp
+++ b/src/effects/SkColorFilters.cpp
@@ -228,7 +228,7 @@
 
         virtual void emitCode(GrGLShaderBuilder* builder,
                               const GrDrawEffect& drawEffect,
-                              EffectKey key,
+                              const GrEffectKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray& coords,
@@ -249,12 +249,12 @@
             builder->fsCodeAppendf("\t%s = %s;\n", outputColor, filter.c_str());
         }
 
-        static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+        static void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                           GrEffectKeyBuilder* b) {
             const ModeColorFilterEffect& colorModeFilter = drawEffect.castEffect<ModeColorFilterEffect>();
             // The SL code does not depend on filter color at the moment, so no need to represent it
             // in the key.
-            EffectKey modeKey = colorModeFilter.mode();
-            return modeKey;
+            b->add32(colorModeFilter.mode());
         }
 
         virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) SK_OVERRIDE {
diff --git a/src/effects/SkColorMatrixFilter.cpp b/src/effects/SkColorMatrixFilter.cpp
index c24a2b7..31a76ab 100644
--- a/src/effects/SkColorMatrixFilter.cpp
+++ b/src/effects/SkColorMatrixFilter.cpp
@@ -391,7 +391,7 @@
     class GLEffect : public GrGLEffect {
     public:
         // this class always generates the same code.
-        static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) { return 0; }
+        static void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder* b) {}
 
         GLEffect(const GrBackendEffectFactory& factory,
                  const GrDrawEffect&)
@@ -400,7 +400,7 @@
 
         virtual void emitCode(GrGLShaderBuilder* builder,
                               const GrDrawEffect&,
-                              EffectKey,
+                              const GrEffectKey&,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index a6897ea..55935b4 100644
--- a/src/effects/SkDisplacementMapEffect.cpp
+++ b/src/effects/SkDisplacementMapEffect.cpp
@@ -278,13 +278,13 @@
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
 
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
@@ -513,7 +513,7 @@
 
 void GrGLDisplacementMapEffect::emitCode(GrGLShaderBuilder* builder,
                                          const GrDrawEffect&,
-                                         EffectKey key,
+                                         const GrEffectKey& key,
                                          const char* outputColor,
                                          const char* inputColor,
                                          const TransformedCoordsArray& coords,
@@ -600,14 +600,14 @@
                SkScalarToFloat(scaleY) : SkScalarToFloat(-scaleY));
 }
 
-GrGLEffect::EffectKey GrGLDisplacementMapEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                        const GrGLCaps&) {
+void GrGLDisplacementMapEffect::GenKey(const GrDrawEffect& drawEffect,
+                                       const GrGLCaps&, GrEffectKeyBuilder* b) {
     const GrDisplacementMapEffect& displacementMap =
         drawEffect.castEffect<GrDisplacementMapEffect>();
 
-    EffectKey xKey = displacementMap.xChannelSelector();
-    EffectKey yKey = displacementMap.yChannelSelector() << kChannelSelectorKeyBits;
+    uint32_t xKey = displacementMap.xChannelSelector();
+    uint32_t yKey = displacementMap.yChannelSelector() << kChannelSelectorKeyBits;
 
-    return xKey | yKey;
+    b->add32(xKey | yKey);
 }
 #endif
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index 682f2ba..6e6828b 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -1131,13 +1131,13 @@
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder* b);
 
     /**
      * Subclasses of GrGLLightingEffect must call INHERITED::setData();
@@ -1266,7 +1266,7 @@
 
 void GrGLLightingEffect::emitCode(GrGLShaderBuilder* builder,
                                   const GrDrawEffect&,
-                                  EffectKey key,
+                                  const GrEffectKey& key,
                                   const char* outputColor,
                                   const char* inputColor,
                                   const TransformedCoordsArray& coords,
@@ -1360,9 +1360,9 @@
     builder->fsCodeAppend(modulate.c_str());
 }
 
-GrGLEffect::EffectKey GrGLLightingEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                 const GrGLCaps& caps) {
-    return drawEffect.castEffect<GrLightingEffect>().light()->type();
+void GrGLLightingEffect::GenKey(const GrDrawEffect& drawEffect,
+                                const GrGLCaps& caps, GrEffectKeyBuilder* b) {
+    b->add32(drawEffect.castEffect<GrLightingEffect>().light()->type());
 }
 
 void GrGLLightingEffect::setData(const GrGLUniformManager& uman,
diff --git a/src/effects/SkLumaColorFilter.cpp b/src/effects/SkLumaColorFilter.cpp
index 7564307..d33e5e8 100644
--- a/src/effects/SkLumaColorFilter.cpp
+++ b/src/effects/SkLumaColorFilter.cpp
@@ -86,14 +86,11 @@
         : INHERITED(factory) {
         }
 
-        static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) {
-            // this class always generates the same code.
-            return 0;
-        }
+        static void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder* b) {}
 
         virtual void emitCode(GrGLShaderBuilder* builder,
                               const GrDrawEffect&,
-                              EffectKey,
+                              const GrEffectKey&,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp
index 4a730c2..d3adf27 100644
--- a/src/effects/SkMagnifierImageFilter.cpp
+++ b/src/effects/SkMagnifierImageFilter.cpp
@@ -97,7 +97,7 @@
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
@@ -119,7 +119,7 @@
 
 void GrGLMagnifierEffect::emitCode(GrGLShaderBuilder* builder,
                                    const GrDrawEffect&,
-                                   EffectKey key,
+                                   const GrEffectKey& key,
                                    const char* outputColor,
                                    const char* inputColor,
                                    const TransformedCoordsArray& coords,
diff --git a/src/effects/SkMatrixConvolutionImageFilter.cpp b/src/effects/SkMatrixConvolutionImageFilter.cpp
index fa7d205..676cab7 100644
--- a/src/effects/SkMatrixConvolutionImageFilter.cpp
+++ b/src/effects/SkMatrixConvolutionImageFilter.cpp
@@ -405,13 +405,13 @@
                                 const GrDrawEffect& effect);
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
 
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
@@ -465,7 +465,7 @@
 
 void GrGLMatrixConvolutionEffect::emitCode(GrGLShaderBuilder* builder,
                                            const GrDrawEffect&,
-                                           EffectKey key,
+                                           const GrEffectKey& key,
                                            const char* outputColor,
                                            const char* inputColor,
                                            const TransformedCoordsArray& coords,
@@ -537,13 +537,13 @@
 
 };
 
-GrGLEffect::EffectKey GrGLMatrixConvolutionEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                          const GrGLCaps&) {
+void GrGLMatrixConvolutionEffect::GenKey(const GrDrawEffect& drawEffect,
+                                         const GrGLCaps&, GrEffectKeyBuilder* b) {
     const GrMatrixConvolutionEffect& m = drawEffect.castEffect<GrMatrixConvolutionEffect>();
-    EffectKey key = encodeXY(m.kernelSize().width(), m.kernelSize().height());
+    uint32_t key = encodeXY(m.kernelSize().width(), m.kernelSize().height());
     key |= m.tileMode() << 7;
     key |= m.convolveAlpha() ? 1 << 9 : 0;
-    return key;
+    b->add32(key);
 }
 
 void GrGLMatrixConvolutionEffect::setData(const GrGLUniformManager& uman,
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index 10c6fe5..7be4435 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -316,13 +316,13 @@
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder* b);
 
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
@@ -346,7 +346,7 @@
 
 void GrGLMorphologyEffect::emitCode(GrGLShaderBuilder* builder,
                                     const GrDrawEffect&,
-                                    EffectKey key,
+                                    const GrEffectKey& key,
                                     const char* outputColor,
                                     const char* inputColor,
                                     const TransformedCoordsArray& coords,
@@ -384,12 +384,12 @@
     builder->fsCodeAppend(modulate.c_str());
 }
 
-GrGLEffect::EffectKey GrGLMorphologyEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                   const GrGLCaps&) {
+void GrGLMorphologyEffect::GenKey(const GrDrawEffect& drawEffect,
+                                  const GrGLCaps&, GrEffectKeyBuilder* b) {
     const GrMorphologyEffect& m = drawEffect.castEffect<GrMorphologyEffect>();
-    EffectKey key = static_cast<EffectKey>(m.radius());
+    uint32_t key = static_cast<uint32_t>(m.radius());
     key |= (m.type() << 8);
-    return key;
+    b->add32(key);
 }
 
 void GrGLMorphologyEffect::setData(const GrGLUniformManager& uman,
diff --git a/src/effects/SkPerlinNoiseShader.cpp b/src/effects/SkPerlinNoiseShader.cpp
index e481162..f0b9f67 100644
--- a/src/effects/SkPerlinNoiseShader.cpp
+++ b/src/effects/SkPerlinNoiseShader.cpp
@@ -499,7 +499,7 @@
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
@@ -507,7 +507,7 @@
 
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder* b);
 
 private:
 
@@ -647,7 +647,7 @@
 
 void GrGLPerlinNoise::emitCode(GrGLShaderBuilder* builder,
                                const GrDrawEffect&,
-                               EffectKey key,
+                               const GrEffectKey& key,
                                const char* outputColor,
                                const char* inputColor,
                                const TransformedCoordsArray& coords,
@@ -900,10 +900,10 @@
                   outputColor, outputColor, outputColor, outputColor);
 }
 
-GrGLEffect::EffectKey GrGLPerlinNoise::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+void GrGLPerlinNoise::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&, GrEffectKeyBuilder* b) {
     const GrPerlinNoiseEffect& turbulence = drawEffect.castEffect<GrPerlinNoiseEffect>();
 
-    EffectKey key = turbulence.numOctaves();
+    uint32_t key = turbulence.numOctaves();
 
     key = key << 3; // Make room for next 3 bits
 
@@ -923,7 +923,7 @@
         key |= 0x4; // Flip the 3rd bit if tile stitching is on
     }
 
-    return key;
+    b->add32(key);
 }
 
 void GrGLPerlinNoise::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp
index 4cf0987..e9ce20f 100644
--- a/src/effects/SkTableColorFilter.cpp
+++ b/src/effects/SkTableColorFilter.cpp
@@ -270,7 +270,7 @@
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
@@ -278,7 +278,7 @@
 
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
 
-    static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder* b) {}
 
 private:
 
@@ -291,7 +291,7 @@
 
 void GLColorTableEffect::emitCode(GrGLShaderBuilder* builder,
                                   const GrDrawEffect&,
-                                  EffectKey,
+                                  const GrEffectKey&,
                                   const char* outputColor,
                                   const char* inputColor,
                                   const TransformedCoordsArray&,
@@ -333,10 +333,6 @@
     builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
 }
 
-GrGLEffect::EffectKey GLColorTableEffect::GenKey(const GrDrawEffect&, const GrGLCaps&) {
-    return 0;
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 
 ColorTableEffect::ColorTableEffect(GrTexture* texture, unsigned flags)
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index fb8a7e5..5014c35 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -862,15 +862,15 @@
 
 GrGLGradientEffect::~GrGLGradientEffect() { }
 
-void GrGLGradientEffect::emitUniforms(GrGLShaderBuilder* builder, EffectKey key) {
+void GrGLGradientEffect::emitUniforms(GrGLShaderBuilder* builder, uint32_t baseKey) {
 
-    if (SkGradientShaderBase::kTwo_GpuColorType == ColorTypeFromKey(key)) { // 2 Color case
+    if (SkGradientShaderBase::kTwo_GpuColorType == ColorTypeFromKey(baseKey)) { // 2 Color case
         fColorStartUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
                                              kVec4f_GrSLType, "GradientStartColor");
         fColorEndUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
                                            kVec4f_GrSLType, "GradientEndColor");
 
-    } else if (SkGradientShaderBase::kThree_GpuColorType == ColorTypeFromKey(key)){ // 3 Color Case
+    } else if (SkGradientShaderBase::kThree_GpuColorType == ColorTypeFromKey(baseKey)){ // 3 Color Case
         fColorStartUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
                                              kVec4f_GrSLType, "GradientStartColor");
         fColorMidUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
@@ -944,10 +944,10 @@
 }
 
 
-GrGLEffect::EffectKey GrGLGradientEffect::GenBaseGradientKey(const GrDrawEffect& drawEffect) {
+uint32_t GrGLGradientEffect::GenBaseGradientKey(const GrDrawEffect& drawEffect) {
     const GrGradientEffect& e = drawEffect.castEffect<GrGradientEffect>();
 
-    EffectKey key = 0;
+    uint32_t key = 0;
 
     if (SkGradientShaderBase::kTwo_GpuColorType == e.getColorType()) {
         key |= kTwoColorKey;
@@ -964,11 +964,11 @@
 
 void GrGLGradientEffect::emitColor(GrGLShaderBuilder* builder,
                                    const char* gradientTValue,
-                                   EffectKey key,
+                                   uint32_t baseKey,
                                    const char* outputColor,
                                    const char* inputColor,
                                    const TextureSamplerArray& samplers) {
-    if (SkGradientShaderBase::kTwo_GpuColorType == ColorTypeFromKey(key)){
+    if (SkGradientShaderBase::kTwo_GpuColorType == ColorTypeFromKey(baseKey)){
         builder->fsCodeAppendf("\tvec4 colorTemp = mix(%s, %s, clamp(%s, 0.0, 1.0));\n",
                                builder->getUniformVariable(fColorStartUni).c_str(),
                                builder->getUniformVariable(fColorEndUni).c_str(),
@@ -978,13 +978,13 @@
         // The gradient SkShader reporting opaque is more restrictive than necessary in the two pt
         // case. Make sure the key reflects this optimization (and note that it can use the same
         // shader as thekBeforeIterp case). This same optimization applies to the 3 color case below.
-        if (GrGradientEffect::kAfterInterp_PremulType == PremulTypeFromKey(key)) {
+        if (GrGradientEffect::kAfterInterp_PremulType == PremulTypeFromKey(baseKey)) {
             builder->fsCodeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
         }
 
         builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
                                (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str());
-    } else if (SkGradientShaderBase::kThree_GpuColorType == ColorTypeFromKey(key)){
+    } else if (SkGradientShaderBase::kThree_GpuColorType == ColorTypeFromKey(baseKey)){
         builder->fsCodeAppendf("\tfloat oneMinus2t = 1.0 - (2.0 * (%s));\n",
                                gradientTValue);
         builder->fsCodeAppendf("\tvec4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) * %s;\n",
@@ -1002,7 +1002,7 @@
         }
         builder->fsCodeAppendf("\tcolorTemp += clamp(-oneMinus2t, 0.0, 1.0) * %s;\n",
                                builder->getUniformVariable(fColorEndUni).c_str());
-        if (GrGradientEffect::kAfterInterp_PremulType == PremulTypeFromKey(key)) {
+        if (GrGradientEffect::kAfterInterp_PremulType == PremulTypeFromKey(baseKey)) {
             builder->fsCodeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
         }
 
diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h
index 9613537..61acf3c 100644
--- a/src/effects/gradients/SkGradientShaderPriv.h
+++ b/src/effects/gradients/SkGradientShaderPriv.h
@@ -379,6 +379,29 @@
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
 protected:
+    /**
+     * Subclasses must call this. It will return a key for the part of the shader code controlled
+     * by the base class. The subclasses must stick it in their key and then pass it to the below
+     * emit* functions from their emitCode function.
+     */
+    static uint32_t GenBaseGradientKey(const GrDrawEffect&);
+
+    // Emits the uniform used as the y-coord to texture samples in derived classes. Subclasses
+    // should call this method from their emitCode().
+    void emitUniforms(GrGLShaderBuilder* builder, uint32_t baseKey);
+
+
+    // emit code that gets a fragment's color from an expression for t; Has branches for 3 separate
+    // control flows inside -- 2 color gradients, 3 color symmetric gradients (both using
+    // native GLSL mix), and 4+ color gradients that use the traditional texture lookup.
+    void emitColor(GrGLShaderBuilder* builder,
+                   const char* gradientTValue,
+                   uint32_t baseKey,
+                   const char* outputColor,
+                   const char* inputColor,
+                   const TextureSamplerArray& samplers);
+
+private:
     enum {
         kPremulTypeKeyBitCnt = 1,
         kPremulTypeMask = 1,
@@ -393,45 +416,24 @@
         // and combine with the result of GenBaseGradientKey.
         kBaseKeyBitCnt = (kPremulTypeKeyBitCnt + kColorKeyBitCnt)
     };
+    GR_STATIC_ASSERT(kBaseKeyBitCnt <= 32);
 
-    static SkGradientShaderBase::GpuColorType ColorTypeFromKey(EffectKey key){
-        if (kTwoColorKey == (key & kColorKeyMask)) {
+    static SkGradientShaderBase::GpuColorType ColorTypeFromKey(uint32_t baseKey){
+        if (kTwoColorKey == (baseKey & kColorKeyMask)) {
             return SkGradientShaderBase::kTwo_GpuColorType;
-        } else if (kThreeColorKey == (key & kColorKeyMask)) {
+        } else if (kThreeColorKey == (baseKey & kColorKeyMask)) {
             return SkGradientShaderBase::kThree_GpuColorType;
         } else {return SkGradientShaderBase::kTexture_GpuColorType;}
     }
 
-    static GrGradientEffect::PremulType PremulTypeFromKey(EffectKey key){
-        if (kPremulBeforeInterpKey == (key & kPremulTypeMask)) {
+    static GrGradientEffect::PremulType PremulTypeFromKey(uint32_t baseKey){
+        if (kPremulBeforeInterpKey == (baseKey & kPremulTypeMask)) {
             return GrGradientEffect::kBeforeInterp_PremulType;
         } else {
             return GrGradientEffect::kAfterInterp_PremulType;
         }
     }
 
-    /**
-     * Subclasses must call this. It will return a value restricted to the lower kBaseKeyBitCnt
-     * bits.
-     */
-    static EffectKey GenBaseGradientKey(const GrDrawEffect&);
-
-    // Emits the uniform used as the y-coord to texture samples in derived classes. Subclasses
-    // should call this method from their emitCode().
-    void emitUniforms(GrGLShaderBuilder* builder, EffectKey key);
-
-
-    // emit code that gets a fragment's color from an expression for t; Has branches for 3 separate
-    // control flows inside -- 2 color gradients, 3 color symmetric gradients (both using
-    // native GLSL mix), and 4+ color gradients that use the traditional texture lookup.
-    void emitColor(GrGLShaderBuilder* builder,
-                   const char* gradientTValue,
-                   EffectKey key,
-                   const char* outputColor,
-                   const char* inputColor,
-                   const TextureSamplerArray& samplers);
-
-private:
     SkScalar fCachedYCoord;
     GrGLUniformManager::UniformHandle fFSYUni;
     GrGLUniformManager::UniformHandle fColorStartUni;
diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp
index 332c9b4..9de4591 100644
--- a/src/effects/gradients/SkLinearGradient.cpp
+++ b/src/effects/gradients/SkLinearGradient.cpp
@@ -461,14 +461,14 @@
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-        return GenBaseGradientKey(drawEffect);
+    static void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&, GrEffectKeyBuilder* b) {
+        b->add32(GenBaseGradientKey(drawEffect));
     }
 
 private:
@@ -538,15 +538,16 @@
 
 void GrGLLinearGradient::emitCode(GrGLShaderBuilder* builder,
                                   const GrDrawEffect&,
-                                  EffectKey key,
+                                  const GrEffectKey& key,
                                   const char* outputColor,
                                   const char* inputColor,
                                   const TransformedCoordsArray& coords,
                                   const TextureSamplerArray& samplers) {
-    this->emitUniforms(builder, key);
+    uint32_t baseKey = key.get32(0);
+    this->emitUniforms(builder, baseKey);
     SkString t = builder->ensureFSCoords2D(coords, 0);
     t.append(".x");
-    this->emitColor(builder, t.c_str(), key, outputColor, inputColor, samplers);
+    this->emitColor(builder, t.c_str(), baseKey, outputColor, inputColor, samplers);
 }
 
 /////////////////////////////////////////////////////////////////////
diff --git a/src/effects/gradients/SkRadialGradient.cpp b/src/effects/gradients/SkRadialGradient.cpp
index e3aaea3..8a378aa 100644
--- a/src/effects/gradients/SkRadialGradient.cpp
+++ b/src/effects/gradients/SkRadialGradient.cpp
@@ -470,14 +470,14 @@
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-        return GenBaseGradientKey(drawEffect);
+    static void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&, GrEffectKeyBuilder* b) {
+        b->add32(GenBaseGradientKey(drawEffect));
     }
 
 private:
@@ -549,16 +549,17 @@
 
 void GrGLRadialGradient::emitCode(GrGLShaderBuilder* builder,
                                   const GrDrawEffect&,
-                                  EffectKey key,
+                                  const GrEffectKey& key,
                                   const char* outputColor,
                                   const char* inputColor,
                                   const TransformedCoordsArray& coords,
                                   const TextureSamplerArray& samplers) {
-    this->emitUniforms(builder, key);
+    uint32_t baseKey = key.get32(0);
+    this->emitUniforms(builder, baseKey);
     SkString t("length(");
     t.append(builder->ensureFSCoords2D(coords, 0));
     t.append(")");
-    this->emitColor(builder, t.c_str(), key, outputColor, inputColor, samplers);
+    this->emitColor(builder, t.c_str(), baseKey, outputColor, inputColor, samplers);
 }
 
 /////////////////////////////////////////////////////////////////////
diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp
index bb9d628..66e755a 100644
--- a/src/effects/gradients/SkSweepGradient.cpp
+++ b/src/effects/gradients/SkSweepGradient.cpp
@@ -186,14 +186,14 @@
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-        return GenBaseGradientKey(drawEffect);
+    static void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&, GrEffectKeyBuilder* b) {
+        b->add32(GenBaseGradientKey(drawEffect));
     }
 
 private:
@@ -256,12 +256,13 @@
 
 void GrGLSweepGradient::emitCode(GrGLShaderBuilder* builder,
                                  const GrDrawEffect&,
-                                 EffectKey key,
+                                 const GrEffectKey& key,
                                  const char* outputColor,
                                  const char* inputColor,
                                  const TransformedCoordsArray& coords,
                                  const TextureSamplerArray& samplers) {
-    this->emitUniforms(builder, key);
+    uint32_t baseKey = key.get32(0);
+    this->emitUniforms(builder, baseKey);
     SkString coords2D = builder->ensureFSCoords2D(coords, 0);
     const GrGLContextInfo ctxInfo = builder->ctxInfo();
     SkString t;
@@ -275,8 +276,7 @@
         t.printf("atan(- %s.y, -1.0 * %s.x) * 0.1591549430918 + 0.5",
                  coords2D.c_str(), coords2D.c_str());
     }
-    this->emitColor(builder, t.c_str(), key,
-                          outputColor, inputColor, samplers);
+    this->emitColor(builder, t.c_str(), baseKey, outputColor, inputColor, samplers);
 }
 
 /////////////////////////////////////////////////////////////////////
diff --git a/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp b/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp
index 8beb6fb..76f9a49 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp
+++ b/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp
@@ -139,14 +139,14 @@
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps);
+    static void GenKey(const GrDrawEffect&, const GrGLCaps& caps, GrEffectKeyBuilder* b);
 
 protected:
     UniformHandle fParamUni;
@@ -219,12 +219,13 @@
 
 void GLEdge2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
                                       const GrDrawEffect&,
-                                      EffectKey key,
+                                      const GrEffectKey& key,
                                       const char* outputColor,
                                       const char* inputColor,
                                       const TransformedCoordsArray& coords,
                                       const TextureSamplerArray& samplers) {
-    this->emitUniforms(builder, key);
+    uint32_t baseKey = key.get32(0);
+    this->emitUniforms(builder, baseKey);
     fParamUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility,
                                          kFloat_GrSLType, "Conical2FSParams", 3);
 
@@ -268,7 +269,7 @@
     builder->fsCodeAppendf("\tif (%s * %s + %s > 0.0) {\n", tName.c_str(),
                            p2.c_str(), p0.c_str());
     builder->fsCodeAppend("\t");
-    this->emitColor(builder, tName.c_str(), key, outputColor, inputColor, samplers);
+    this->emitColor(builder, tName.c_str(), baseKey, outputColor, inputColor, samplers);
     builder->fsCodeAppend("\t}\n");
 }
 
@@ -294,9 +295,9 @@
     }
 }
 
-GrGLEffect::EffectKey GLEdge2PtConicalEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                     const GrGLCaps&) {
-    return GenBaseGradientKey(drawEffect);
+void GLEdge2PtConicalEffect::GenKey(const GrDrawEffect& drawEffect,
+                                    const GrGLCaps&, GrEffectKeyBuilder* b) {
+    b->add32(GenBaseGradientKey(drawEffect));
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -414,14 +415,14 @@
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps);
+    static void GenKey(const GrDrawEffect&, const GrGLCaps& caps, GrEffectKeyBuilder* b);
 
 protected:
     UniformHandle fParamUni;
@@ -494,12 +495,13 @@
 
 void GLFocalOutside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
                                               const GrDrawEffect&,
-                                              EffectKey key,
+                                              const GrEffectKey& key,
                                               const char* outputColor,
                                               const char* inputColor,
                                               const TransformedCoordsArray& coords,
                                               const TextureSamplerArray& samplers) {
-    this->emitUniforms(builder, key);
+    uint32_t baseKey = key.get32(0);
+    this->emitUniforms(builder, baseKey);
     fParamUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility,
                                          kFloat_GrSLType, "Conical2FSParams", 2);
     SkString tName("t");
@@ -535,7 +537,7 @@
 
     builder->fsCodeAppendf("\tif (%s >= 0.0 && d >= 0.0) {\n", tName.c_str());
     builder->fsCodeAppend("\t\t");
-    this->emitColor(builder, tName.c_str(), key, outputColor, inputColor, samplers);
+    this->emitColor(builder, tName.c_str(), baseKey, outputColor, inputColor, samplers);
     builder->fsCodeAppend("\t}\n");
 }
 
@@ -559,18 +561,11 @@
     }
 }
 
-GrGLEffect::EffectKey GLFocalOutside2PtConicalEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                             const GrGLCaps&) {
-    enum {
-        kIsFlipped = 1 << kBaseKeyBitCnt,
-    };
-
-    EffectKey key = GenBaseGradientKey(drawEffect);
-
-    if (drawEffect.castEffect<FocalOutside2PtConicalEffect>().isFlipped()) {
-        key |= kIsFlipped;
-    }
-    return key;
+void GLFocalOutside2PtConicalEffect::GenKey(const GrDrawEffect& drawEffect,
+                                            const GrGLCaps&, GrEffectKeyBuilder* b) {
+    uint32_t* key = b->add32n(2);
+    key[0] = GenBaseGradientKey(drawEffect);
+    key[1] = drawEffect.castEffect<FocalOutside2PtConicalEffect>().isFlipped();
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -625,14 +620,14 @@
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps);
+    static void GenKey(const GrDrawEffect&, const GrGLCaps& caps, GrEffectKeyBuilder* b);
 
 protected:
     UniformHandle fFocalUni;
@@ -702,12 +697,13 @@
 
 void GLFocalInside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
                                              const GrDrawEffect&,
-                                             EffectKey key,
+                                             const GrEffectKey& key,
                                              const char* outputColor,
                                              const char* inputColor,
                                              const TransformedCoordsArray& coords,
                                              const TextureSamplerArray& samplers) {
-    this->emitUniforms(builder, key);
+    uint32_t baseKey = key.get32(0);
+    this->emitUniforms(builder, baseKey);
     fFocalUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
                                     kFloat_GrSLType, "Conical2FSParams");
     SkString tName("t");
@@ -724,7 +720,7 @@
     builder->fsCodeAppendf("\tfloat %s = %s.x * %s  + length(%s);\n", tName.c_str(),
                            coords2D, focal.c_str(), coords2D);
 
-    this->emitColor(builder, tName.c_str(), key, outputColor, inputColor, samplers);
+    this->emitColor(builder, tName.c_str(), baseKey, outputColor, inputColor, samplers);
 }
 
 void GLFocalInside2PtConicalEffect::setData(const GrGLUniformManager& uman,
@@ -739,9 +735,9 @@
     }
 }
 
-GrGLEffect::EffectKey GLFocalInside2PtConicalEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                            const GrGLCaps&) {
-    return GenBaseGradientKey(drawEffect);
+void GLFocalInside2PtConicalEffect::GenKey(const GrDrawEffect& drawEffect,
+                                           const GrGLCaps&, GrEffectKeyBuilder* b) {
+    b->add32(GenBaseGradientKey(drawEffect));
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -865,14 +861,14 @@
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps);
+    static void GenKey(const GrDrawEffect&, const GrGLCaps& caps, GrEffectKeyBuilder* b);
 
 protected:
     UniformHandle fCenterUni;
@@ -950,12 +946,13 @@
 
 void GLCircleInside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
                                               const GrDrawEffect&,
-                                              EffectKey key,
+                                              const GrEffectKey& key,
                                               const char* outputColor,
                                               const char* inputColor,
                                               const TransformedCoordsArray& coords,
                                               const TextureSamplerArray& samplers) {
-    this->emitUniforms(builder, key);
+    uint32_t baseKey = key.get32(0);
+    this->emitUniforms(builder, baseKey);
     fCenterUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
                                      kVec2f_GrSLType, "Conical2FSCenter");
     fParamUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
@@ -985,7 +982,7 @@
     builder->fsCodeAppendf("\tfloat %s = d + sqrt(d * d - %s.x * pDotp + %s.z);\n",
                            tName.c_str(), params.c_str(), params.c_str());
 
-    this->emitColor(builder, tName.c_str(), key, outputColor, inputColor, samplers);
+    this->emitColor(builder, tName.c_str(), baseKey, outputColor, inputColor, samplers);
 }
 
 void GLCircleInside2PtConicalEffect::setData(const GrGLUniformManager& uman,
@@ -1012,10 +1009,9 @@
     }
 }
 
-GrGLEffect::EffectKey GLCircleInside2PtConicalEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                             const GrGLCaps&) {
-    EffectKey key = GenBaseGradientKey(drawEffect);
-    return key;
+void GLCircleInside2PtConicalEffect::GenKey(const GrDrawEffect& drawEffect,
+                                            const GrGLCaps&, GrEffectKeyBuilder* b) {
+    b->add32(GenBaseGradientKey(drawEffect));
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -1091,14 +1087,14 @@
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps);
+    static void GenKey(const GrDrawEffect&, const GrGLCaps& caps, GrEffectKeyBuilder* b);
 
 protected:
     UniformHandle fCenterUni;
@@ -1184,12 +1180,13 @@
 
 void GLCircleOutside2PtConicalEffect::emitCode(GrGLShaderBuilder* builder,
                                                const GrDrawEffect&,
-                                               EffectKey key,
+                                               const GrEffectKey& key,
                                                const char* outputColor,
                                                const char* inputColor,
                                                const TransformedCoordsArray& coords,
                                                const TextureSamplerArray& samplers) {
-    this->emitUniforms(builder, key);
+    uint32_t baseKey = key.get32(0);
+    this->emitUniforms(builder, baseKey);
     fCenterUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
                                      kVec2f_GrSLType, "Conical2FSCenter");
     fParamUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
@@ -1233,7 +1230,7 @@
 
     builder->fsCodeAppendf("\tif (%s >= %s.w && deter >= 0.0) {\n", tName.c_str(), params.c_str());
     builder->fsCodeAppend("\t\t");
-    this->emitColor(builder, tName.c_str(), key, outputColor, inputColor, samplers);
+    this->emitColor(builder, tName.c_str(), baseKey, outputColor, inputColor, samplers);
     builder->fsCodeAppend("\t}\n");
 }
 
@@ -1265,18 +1262,11 @@
     }
 }
 
-GrGLEffect::EffectKey GLCircleOutside2PtConicalEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                              const GrGLCaps&) {
-    enum {
-        kIsFlipped = 1 << kBaseKeyBitCnt,
-    };
-
-    EffectKey key = GenBaseGradientKey(drawEffect);
-
-    if (drawEffect.castEffect<CircleOutside2PtConicalEffect>().isFlipped()) {
-        key |= kIsFlipped;
-    }
-    return key;
+void GLCircleOutside2PtConicalEffect::GenKey(const GrDrawEffect& drawEffect,
+                                             const GrGLCaps&, GrEffectKeyBuilder* b) {
+    uint32_t* key = b->add32n(2);
+    key[0] = GenBaseGradientKey(drawEffect);
+    key[1] = drawEffect.castEffect<CircleOutside2PtConicalEffect>().isFlipped();
 }
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/src/effects/gradients/SkTwoPointRadialGradient.cpp b/src/effects/gradients/SkTwoPointRadialGradient.cpp
index a97cc0c..5015274 100644
--- a/src/effects/gradients/SkTwoPointRadialGradient.cpp
+++ b/src/effects/gradients/SkTwoPointRadialGradient.cpp
@@ -398,14 +398,14 @@
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
-    static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps);
+    static void GenKey(const GrDrawEffect&, const GrGLCaps& caps, GrEffectKeyBuilder* b);
 
 protected:
 
@@ -554,13 +554,13 @@
 
 void GrGLRadial2Gradient::emitCode(GrGLShaderBuilder* builder,
                                    const GrDrawEffect& drawEffect,
-                                   EffectKey key,
+                                   const GrEffectKey& key,
                                    const char* outputColor,
                                    const char* inputColor,
                                    const TransformedCoordsArray& coords,
                                    const TextureSamplerArray& samplers) {
-
-    this->emitUniforms(builder, key);
+    uint32_t baseKey = key.get32(0);
+    this->emitUniforms(builder, baseKey);
     fParamUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility,
                                          kFloat_GrSLType, "Radial2FSParams", 6);
 
@@ -622,7 +622,7 @@
         t.printf("-%s / %s", cName.c_str(), bVar.c_str());
     }
 
-    this->emitColor(builder, t.c_str(), key, outputColor, inputColor, samplers);
+    this->emitColor(builder, t.c_str(), baseKey, outputColor, inputColor, samplers);
 }
 
 void GrGLRadial2Gradient::setData(const GrGLUniformManager& uman,
@@ -659,17 +659,11 @@
     }
 }
 
-GrGLEffect::EffectKey GrGLRadial2Gradient::GenKey(const GrDrawEffect& drawEffect,
-                                                  const GrGLCaps&) {
-    enum {
-        kIsDegenerate = 1 << kBaseKeyBitCnt,
-    };
-
-    EffectKey key = GenBaseGradientKey(drawEffect);
-    if (drawEffect.castEffect<GrRadial2Gradient>().isDegenerate()) {
-        key |= kIsDegenerate;
-    }
-    return key;
+void GrGLRadial2Gradient::GenKey(const GrDrawEffect& drawEffect,
+                                 const GrGLCaps&, GrEffectKeyBuilder* b) {
+    uint32_t* key = b->add32n(2);
+    key[0] = GenBaseGradientKey(drawEffect);
+    key[1] = drawEffect.castEffect<GrRadial2Gradient>().isDegenerate();
 }
 
 /////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp
index 3116712..afcb987 100644
--- a/src/gpu/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/GrAAConvexPathRenderer.cpp
@@ -533,7 +533,7 @@
 
         virtual void emitCode(GrGLFullShaderBuilder* builder,
                               const GrDrawEffect& drawEffect,
-                              EffectKey key,
+                              const GrEffectKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
@@ -570,9 +570,7 @@
             builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str());
         }
 
-        static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-            return 0x0;
-        }
+        static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*) {}
 
         virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
 
diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp
index 761c63f..59e9b6f 100644
--- a/src/gpu/GrAARectRenderer.cpp
+++ b/src/gpu/GrAARectRenderer.cpp
@@ -46,7 +46,7 @@
 
         virtual void emitCode(GrGLFullShaderBuilder* builder,
                               const GrDrawEffect& drawEffect,
-                              EffectKey key,
+                              const GrEffectKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
@@ -88,9 +88,7 @@
                                    (GrGLSLExpr4(inputColor) * GrGLSLExpr1("coverage")).c_str());
         }
 
-        static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-            return 0;
-        }
+        static void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*) {}
 
         virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect&) SK_OVERRIDE {}
 
@@ -164,7 +162,7 @@
 
         virtual void emitCode(GrGLFullShaderBuilder* builder,
                               const GrDrawEffect& drawEffect,
-                              EffectKey key,
+                              const GrEffectKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
@@ -221,9 +219,7 @@
                                    (GrGLSLExpr4(inputColor) * GrGLSLExpr1("coverage")).c_str());
         }
 
-        static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-            return 0;
-        }
+        static void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*) {}
 
         virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect&) SK_OVERRIDE {}
 
diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp
index 648bc14..b604f02 100644
--- a/src/gpu/GrOvalRenderer.cpp
+++ b/src/gpu/GrOvalRenderer.cpp
@@ -97,7 +97,7 @@
 
         virtual void emitCode(GrGLFullShaderBuilder* builder,
                               const GrDrawEffect& drawEffect,
-                              EffectKey key,
+                              const GrEffectKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
@@ -121,10 +121,10 @@
                                    (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
         }
 
-        static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+        static void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                           GrEffectKeyBuilder* b) {
             const CircleEdgeEffect& circleEffect = drawEffect.castEffect<CircleEdgeEffect>();
-
-            return circleEffect.isStroked() ? 0x1 : 0x0;
+            b->add32(circleEffect.isStroked());
         }
 
         virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
@@ -208,7 +208,7 @@
 
         virtual void emitCode(GrGLFullShaderBuilder* builder,
                               const GrDrawEffect& drawEffect,
-                              EffectKey key,
+                              const GrEffectKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
@@ -251,10 +251,10 @@
                                    (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
         }
 
-        static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+        static void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                           GrEffectKeyBuilder* b) {
             const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<EllipseEdgeEffect>();
-
-            return ellipseEffect.isStroked() ? 0x1 : 0x0;
+            b->add32(ellipseEffect.isStroked());
         }
 
         virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {
@@ -346,7 +346,7 @@
 
         virtual void emitCode(GrGLFullShaderBuilder* builder,
                               const GrDrawEffect& drawEffect,
-                              EffectKey key,
+                              const GrEffectKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
@@ -407,10 +407,12 @@
                                    (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
         }
 
-        static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
-            const DIEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<DIEllipseEdgeEffect>();
+        static void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                           GrEffectKeyBuilder* b) {
+            const DIEllipseEdgeEffect& ellipseEffect =
+                drawEffect.castEffect<DIEllipseEdgeEffect>();
 
-            return ellipseEffect.getMode();
+            b->add32(ellipseEffect.getMode());
         }
 
         virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {
diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp
index d710c64..7337d8a 100644
--- a/src/gpu/effects/GrBezierEffect.cpp
+++ b/src/gpu/effects/GrBezierEffect.cpp
@@ -19,13 +19,13 @@
 
     virtual void emitCode(GrGLFullShaderBuilder* builder,
                           const GrDrawEffect& drawEffect,
-                          EffectKey key,
+                          const GrEffectKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
 
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
 
@@ -44,7 +44,7 @@
 
 void GrGLConicEffect::emitCode(GrGLFullShaderBuilder* builder,
                                const GrDrawEffect& drawEffect,
-                               EffectKey key,
+                               const GrEffectKey& key,
                                const char* outputColor,
                                const char* inputColor,
                                const TransformedCoordsArray&,
@@ -117,9 +117,11 @@
                            (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
 }
 
-GrGLEffect::EffectKey GrGLConicEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+void GrGLConicEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                             GrEffectKeyBuilder* b) {
     const GrConicEffect& ce = drawEffect.castEffect<GrConicEffect>();
-    return ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
+    uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
+    b->add32(key);
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -167,13 +169,13 @@
 
     virtual void emitCode(GrGLFullShaderBuilder* builder,
                           const GrDrawEffect& drawEffect,
-                          EffectKey key,
+                          const GrEffectKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
 
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
 
@@ -192,7 +194,7 @@
 
 void GrGLQuadEffect::emitCode(GrGLFullShaderBuilder* builder,
                               const GrDrawEffect& drawEffect,
-                              EffectKey key,
+                              const GrEffectKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
@@ -255,9 +257,11 @@
     builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str());
 }
 
-GrGLEffect::EffectKey GrGLQuadEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+void GrGLQuadEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                            GrEffectKeyBuilder* b) {
     const GrQuadEffect& ce = drawEffect.castEffect<GrQuadEffect>();
-    return ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
+    uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
+    b->add32(key);
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -305,13 +309,13 @@
 
     virtual void emitCode(GrGLFullShaderBuilder* builder,
                           const GrDrawEffect& drawEffect,
-                          EffectKey key,
+                          const GrEffectKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
 
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
 
@@ -330,7 +334,7 @@
 
 void GrGLCubicEffect::emitCode(GrGLFullShaderBuilder* builder,
                                const GrDrawEffect& drawEffect,
-                               EffectKey key,
+                               const GrEffectKey& key,
                                const char* outputColor,
                                const char* inputColor,
                                const TransformedCoordsArray&,
@@ -403,9 +407,11 @@
                            (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
 }
 
-GrGLEffect::EffectKey GrGLCubicEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+void GrGLCubicEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                             GrEffectKeyBuilder* b) {
     const GrCubicEffect& ce = drawEffect.castEffect<GrCubicEffect>();
-    return ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
+    uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
+    b->add32(key);
 }
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/effects/GrBicubicEffect.cpp b/src/gpu/effects/GrBicubicEffect.cpp
index 118efaf..2b819f6 100644
--- a/src/gpu/effects/GrBicubicEffect.cpp
+++ b/src/gpu/effects/GrBicubicEffect.cpp
@@ -26,7 +26,7 @@
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
@@ -34,9 +34,10 @@
 
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+    static inline void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                              GrEffectKeyBuilder* b) {
         const GrTextureDomain& domain = drawEffect.castEffect<GrBicubicEffect>().domain();
-        return GrTextureDomain::GLDomain::DomainKey(domain);
+        b->add32(GrTextureDomain::GLDomain::DomainKey(domain));
     }
 
 private:
@@ -55,7 +56,7 @@
 
 void GrGLBicubicEffect::emitCode(GrGLShaderBuilder* builder,
                                  const GrDrawEffect& drawEffect,
-                                 EffectKey key,
+                                 const GrEffectKey& key,
                                  const char* outputColor,
                                  const char* inputColor,
                                  const TransformedCoordsArray& coords,
diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp
index c421867..07529d0 100644
--- a/src/gpu/effects/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/GrConfigConversionEffect.cpp
@@ -25,7 +25,7 @@
 
     virtual void emitCode(GrGLShaderBuilder* builder,
                           const GrDrawEffect&,
-                          EffectKey key,
+                          const GrEffectKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray& coords,
@@ -71,9 +71,11 @@
         builder->fsCodeAppend(modulate.c_str());
     }
 
-    static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+    static inline void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                              GrEffectKeyBuilder* b) {
         const GrConfigConversionEffect& conv = drawEffect.castEffect<GrConfigConversionEffect>();
-        return static_cast<EffectKey>(conv.swapsRedAndBlue()) | (conv.pmConversion() << 1);
+        uint32_t key = (conv.swapsRedAndBlue() ? 0 : 1) | (conv.pmConversion() << 1);
+        b->add32(key);
     }
 
 private:
diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp
index dd104bd..11109f7 100644
--- a/src/gpu/effects/GrConvexPolyEffect.cpp
+++ b/src/gpu/effects/GrConvexPolyEffect.cpp
@@ -91,13 +91,13 @@
 
     virtual void emitCode(GrGLShaderBuilder* builder,
                           const GrDrawEffect& drawEffect,
-                          EffectKey key,
+                          const GrEffectKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
 
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
@@ -115,7 +115,7 @@
 
 void GLAARectEffect::emitCode(GrGLShaderBuilder* builder,
                               const GrDrawEffect& drawEffect,
-                              EffectKey key,
+                              const GrEffectKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
@@ -165,9 +165,10 @@
     }
 }
 
-GrGLEffect::EffectKey GLAARectEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+void GLAARectEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                            GrEffectKeyBuilder* b) {
     const AARectEffect& aare = drawEffect.castEffect<AARectEffect>();
-    return aare.getEdgeType();
+    b->add32(aare.getEdgeType());
 }
 
 const GrBackendEffectFactory& AARectEffect::getFactory() const {
@@ -182,13 +183,13 @@
 
     virtual void emitCode(GrGLShaderBuilder* builder,
                           const GrDrawEffect& drawEffect,
-                          EffectKey key,
+                          const GrEffectKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
 
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
@@ -206,7 +207,7 @@
 
 void GrGLConvexPolyEffect::emitCode(GrGLShaderBuilder* builder,
                                     const GrDrawEffect& drawEffect,
-                                    EffectKey key,
+                                    const GrEffectKey& key,
                                     const char* outputColor,
                                     const char* inputColor,
                                     const TransformedCoordsArray&,
@@ -254,11 +255,12 @@
     }
 }
 
-GrGLEffect::EffectKey GrGLConvexPolyEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                   const GrGLCaps&) {
+void GrGLConvexPolyEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                                  GrEffectKeyBuilder* b) {
     const GrConvexPolyEffect& cpe = drawEffect.castEffect<GrConvexPolyEffect>();
     GR_STATIC_ASSERT(kGrEffectEdgeTypeCnt <= 8);
-    return (cpe.getEdgeCount() << 3) | cpe.getEdgeType();
+    uint32_t key = (cpe.getEdgeCount() << 3) | cpe.getEdgeType();
+    b->add32(key);
 }
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/effects/GrConvolutionEffect.cpp b/src/gpu/effects/GrConvolutionEffect.cpp
index 43ef7e7..f20d1db 100644
--- a/src/gpu/effects/GrConvolutionEffect.cpp
+++ b/src/gpu/effects/GrConvolutionEffect.cpp
@@ -21,7 +21,7 @@
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
@@ -29,7 +29,7 @@
 
     virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
 
 private:
     int width() const { return Gr1DKernelEffect::WidthFromRadius(fRadius); }
@@ -57,7 +57,7 @@
 
 void GrGLConvolutionEffect::emitCode(GrGLShaderBuilder* builder,
                                      const GrDrawEffect&,
-                                     EffectKey key,
+                                     const GrEffectKey& key,
                                      const char* outputColor,
                                      const char* inputColor,
                                      const TransformedCoordsArray& coords,
@@ -134,16 +134,16 @@
     uman.set1fv(fKernelUni, this->width(), conv.kernel());
 }
 
-GrGLEffect::EffectKey GrGLConvolutionEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                    const GrGLCaps&) {
+void GrGLConvolutionEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                                   GrEffectKeyBuilder* b) {
     const GrConvolutionEffect& conv = drawEffect.castEffect<GrConvolutionEffect>();
-    EffectKey key = conv.radius();
+    uint32_t key = conv.radius();
     key <<= 2;
     if (conv.useBounds()) {
         key |= 0x2;
         key |= GrConvolutionEffect::kY_Direction == conv.direction() ? 0x1 : 0x0;
     }
-    return key;
+    b->add32(key);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/effects/GrCustomCoordsTextureEffect.cpp b/src/gpu/effects/GrCustomCoordsTextureEffect.cpp
index feb9d62..a24abf9 100644
--- a/src/gpu/effects/GrCustomCoordsTextureEffect.cpp
+++ b/src/gpu/effects/GrCustomCoordsTextureEffect.cpp
@@ -21,7 +21,7 @@
 
     virtual void emitCode(GrGLFullShaderBuilder* builder,
                           const GrDrawEffect& drawEffect,
-                          EffectKey key,
+                          const GrEffectKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp
index 488d1ba..9f6b77d 100644
--- a/src/gpu/effects/GrDashingEffect.cpp
+++ b/src/gpu/effects/GrDashingEffect.cpp
@@ -470,13 +470,13 @@
 
     virtual void emitCode(GrGLFullShaderBuilder* builder,
                           const GrDrawEffect& drawEffect,
-                          EffectKey key,
+                          const GrEffectKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
 
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
@@ -498,7 +498,7 @@
 
 void GLDashingCircleEffect::emitCode(GrGLFullShaderBuilder* builder,
                                     const GrDrawEffect& drawEffect,
-                                    EffectKey key,
+                                    const GrEffectKey& key,
                                     const char* outputColor,
                                     const char* inputColor,
                                     const TransformedCoordsArray&,
@@ -549,10 +549,10 @@
     }
 }
 
-GrGLEffect::EffectKey GLDashingCircleEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                const GrGLCaps&) {
+void GLDashingCircleEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                                   GrEffectKeyBuilder* b) {
     const DashingCircleEffect& dce = drawEffect.castEffect<DashingCircleEffect>();
-    return dce.getEdgeType();
+    b->add32(dce.getEdgeType());
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -675,13 +675,13 @@
 
     virtual void emitCode(GrGLFullShaderBuilder* builder,
                           const GrDrawEffect& drawEffect,
-                          EffectKey key,
+                          const GrEffectKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
 
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
@@ -702,7 +702,7 @@
 
 void GLDashingLineEffect::emitCode(GrGLFullShaderBuilder* builder,
                                     const GrDrawEffect& drawEffect,
-                                    EffectKey key,
+                                    const GrEffectKey& key,
                                     const char* outputColor,
                                     const char* inputColor,
                                     const TransformedCoordsArray&,
@@ -766,10 +766,10 @@
     }
 }
 
-GrGLEffect::EffectKey GLDashingLineEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                const GrGLCaps&) {
+void GLDashingLineEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                                 GrEffectKeyBuilder* b) {
     const DashingLineEffect& de = drawEffect.castEffect<DashingLineEffect>();
-    return de.getEdgeType();
+    b->add32(de.getEdgeType());
 }
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
index f69980d..0c0c1af 100755
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp
@@ -38,7 +38,7 @@
 
     virtual void emitCode(GrGLFullShaderBuilder* builder,
                           const GrDrawEffect& drawEffect,
-                          EffectKey key,
+                          const GrEffectKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
@@ -148,11 +148,12 @@
 #endif
     }
 
-    static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+    static inline void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                              GrEffectKeyBuilder* b) {
         const GrDistanceFieldTextureEffect& dfTexEffect =
                                               drawEffect.castEffect<GrDistanceFieldTextureEffect>();
 
-        return dfTexEffect.isSimilarity() ? 0x1 : 0x0;
+        b->add32(dfTexEffect.isSimilarity());
     }
 
 private:
@@ -255,7 +256,7 @@
 
     virtual void emitCode(GrGLFullShaderBuilder* builder,
                           const GrDrawEffect& drawEffect,
-                          EffectKey key,
+                          const GrEffectKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
@@ -412,11 +413,12 @@
         }
     }
 
-    static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
+    static inline void GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                              GrEffectKeyBuilder* b) {
         const GrDistanceFieldLCDTextureEffect& dfTexEffect =
                                            drawEffect.castEffect<GrDistanceFieldLCDTextureEffect>();
 
-        return dfTexEffect.isUniformScale() ? 0x01 : 0x00;;
+        b->add32(dfTexEffect.isUniformScale());
     }
 
 private:
diff --git a/src/gpu/effects/GrDitherEffect.cpp b/src/gpu/effects/GrDitherEffect.cpp
index 37354c6..a431897 100644
--- a/src/gpu/effects/GrDitherEffect.cpp
+++ b/src/gpu/effects/GrDitherEffect.cpp
@@ -72,7 +72,7 @@
 
     virtual void emitCode(GrGLShaderBuilder* builder,
                           const GrDrawEffect& drawEffect,
-                          EffectKey key,
+                          const GrEffectKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
@@ -89,7 +89,7 @@
 
 void GLDitherEffect::emitCode(GrGLShaderBuilder* builder,
                               const GrDrawEffect& drawEffect,
-                              EffectKey key,
+                              const GrEffectKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
diff --git a/src/gpu/effects/GrOvalEffect.cpp b/src/gpu/effects/GrOvalEffect.cpp
index a80b08d..ebeb288 100644
--- a/src/gpu/effects/GrOvalEffect.cpp
+++ b/src/gpu/effects/GrOvalEffect.cpp
@@ -102,13 +102,13 @@
 
     virtual void emitCode(GrGLShaderBuilder* builder,
                           const GrDrawEffect& drawEffect,
-                          EffectKey key,
+                          const GrEffectKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
 
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
@@ -128,7 +128,7 @@
 
 void GLCircleEffect::emitCode(GrGLShaderBuilder* builder,
                               const GrDrawEffect& drawEffect,
-                              EffectKey key,
+                              const GrEffectKey& key,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray&,
@@ -161,10 +161,10 @@
                            (GrGLSLExpr4(inputColor) * GrGLSLExpr1("d")).c_str());
 }
 
-GrGLEffect::EffectKey GLCircleEffect::GenKey(const GrDrawEffect& drawEffect,
-                                             const GrGLCaps&) {
+void GLCircleEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                            GrEffectKeyBuilder* b) {
     const CircleEffect& ce = drawEffect.castEffect<CircleEffect>();
-    return ce.getEdgeType();
+    b->add32(ce.getEdgeType());
 }
 
 void GLCircleEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
@@ -274,13 +274,13 @@
 
     virtual void emitCode(GrGLShaderBuilder* builder,
                           const GrDrawEffect& drawEffect,
-                          EffectKey key,
+                          const GrEffectKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
 
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
@@ -300,7 +300,7 @@
 
 void GLEllipseEffect::emitCode(GrGLShaderBuilder* builder,
                                const GrDrawEffect& drawEffect,
-                               EffectKey key,
+                               const GrEffectKey& key,
                                const char* outputColor,
                                const char* inputColor,
                                const TransformedCoordsArray&,
@@ -346,10 +346,10 @@
                            (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
 }
 
-GrGLEffect::EffectKey GLEllipseEffect::GenKey(const GrDrawEffect& drawEffect,
-                                              const GrGLCaps&) {
+void GLEllipseEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                             GrEffectKeyBuilder* b) {
     const EllipseEffect& ee = drawEffect.castEffect<EllipseEffect>();
-    return ee.getEdgeType();
+    b->add32(ee.getEdgeType());
 }
 
 void GLEllipseEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {
diff --git a/src/gpu/effects/GrRRectEffect.cpp b/src/gpu/effects/GrRRectEffect.cpp
index efad436..277f6df 100644
--- a/src/gpu/effects/GrRRectEffect.cpp
+++ b/src/gpu/effects/GrRRectEffect.cpp
@@ -136,13 +136,13 @@
 
     virtual void emitCode(GrGLShaderBuilder* builder,
                           const GrDrawEffect& drawEffect,
-                          EffectKey key,
+                          const GrEffectKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
 
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
@@ -161,7 +161,7 @@
 
 void GLCircularRRectEffect::emitCode(GrGLShaderBuilder* builder,
                              const GrDrawEffect& drawEffect,
-                             EffectKey key,
+                             const GrEffectKey& key,
                              const char* outputColor,
                              const char* inputColor,
                              const TransformedCoordsArray&,
@@ -291,11 +291,11 @@
                            (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
 }
 
-GrGLEffect::EffectKey GLCircularRRectEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                    const GrGLCaps&) {
+void GLCircularRRectEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                                   GrEffectKeyBuilder* b) {
     const CircularRRectEffect& crre = drawEffect.castEffect<CircularRRectEffect>();
     GR_STATIC_ASSERT(kGrEffectEdgeTypeCnt <= 8);
-    return (crre.getCircularCornerFlags() << 3) | crre.getEdgeType();
+    b->add32((crre.getCircularCornerFlags() << 3) | crre.getEdgeType());
 }
 
 void GLCircularRRectEffect::setData(const GrGLUniformManager& uman,
@@ -488,13 +488,13 @@
 
     virtual void emitCode(GrGLShaderBuilder* builder,
                           const GrDrawEffect& drawEffect,
-                          EffectKey key,
+                          const GrEffectKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
                           const TextureSamplerArray&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
 
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
@@ -513,7 +513,7 @@
 
 void GLEllipticalRRectEffect::emitCode(GrGLShaderBuilder* builder,
                                        const GrDrawEffect& drawEffect,
-                                       EffectKey key,
+                                       const GrEffectKey& key,
                                        const char* outputColor,
                                        const char* inputColor,
                                        const TransformedCoordsArray&,
@@ -586,11 +586,11 @@
                            (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str());
 }
 
-GrGLEffect::EffectKey GLEllipticalRRectEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                      const GrGLCaps&) {
+void GLEllipticalRRectEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                                     GrEffectKeyBuilder* b) {
     const EllipticalRRectEffect& erre = drawEffect.castEffect<EllipticalRRectEffect>();
     GR_STATIC_ASSERT(kLast_GrEffectEdgeType < (1 << 3));
-    return erre.getRRect().getType() | erre.getEdgeType() << 3;
+    b->add32(erre.getRRect().getType() | erre.getEdgeType() << 3);
 }
 
 void GLEllipticalRRectEffect::setData(const GrGLUniformManager& uman,
diff --git a/src/gpu/effects/GrSimpleTextureEffect.cpp b/src/gpu/effects/GrSimpleTextureEffect.cpp
index c93abf9..74926bc 100644
--- a/src/gpu/effects/GrSimpleTextureEffect.cpp
+++ b/src/gpu/effects/GrSimpleTextureEffect.cpp
@@ -21,7 +21,7 @@
 
     virtual void emitCode(GrGLShaderBuilder* builder,
                           const GrDrawEffect& drawEffect,
-                          EffectKey key,
+                          const GrEffectKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray& coords,
diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp
index 108ec78..5af5bc8 100644
--- a/src/gpu/effects/GrTextureDomain.cpp
+++ b/src/gpu/effects/GrTextureDomain.cpp
@@ -147,7 +147,7 @@
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrDrawEffect&,
-                          EffectKey,
+                          const GrEffectKey&,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray&,
@@ -155,7 +155,7 @@
 
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
+    static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*);
 
 private:
     GrTextureDomain::GLDomain         fGLDomain;
@@ -169,7 +169,7 @@
 
 void GrGLTextureDomainEffect::emitCode(GrGLShaderBuilder* builder,
                                        const GrDrawEffect& drawEffect,
-                                       EffectKey key,
+                                       const GrEffectKey& key,
                                        const char* outputColor,
                                        const char* inputColor,
                                        const TransformedCoordsArray& coords,
@@ -188,10 +188,10 @@
     fGLDomain.setData(uman, domain, effect.texture(0)->origin());
 }
 
-GrGLEffect::EffectKey GrGLTextureDomainEffect::GenKey(const GrDrawEffect& drawEffect,
-                                                      const GrGLCaps&) {
+void GrGLTextureDomainEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&,
+                                     GrEffectKeyBuilder* b) {
     const GrTextureDomain& domain = drawEffect.castEffect<GrTextureDomainEffect>().textureDomain();
-    return GrTextureDomain::GLDomain::DomainKey(domain);
+    b->add32(GrTextureDomain::GLDomain::DomainKey(domain));
 }
 
 
diff --git a/src/gpu/effects/GrTextureDomain.h b/src/gpu/effects/GrTextureDomain.h
index dc78187..80a617e 100644
--- a/src/gpu/effects/GrTextureDomain.h
+++ b/src/gpu/effects/GrTextureDomain.h
@@ -108,7 +108,7 @@
          * GrGLEffect::GenKey() must call this and include the returned value in it's computed key.
          * The returned will be limited to the lower kDomainKeyBits bits.
          */
-        static GrGLEffect::EffectKey DomainKey(const GrTextureDomain& domain) {
+        static uint32_t DomainKey(const GrTextureDomain& domain) {
             GR_STATIC_ASSERT(kModeCount <= 4);
             return domain.mode();
         }
diff --git a/src/gpu/effects/GrYUVtoRGBEffect.cpp b/src/gpu/effects/GrYUVtoRGBEffect.cpp
index 76b8581..15e51a2 100644
--- a/src/gpu/effects/GrYUVtoRGBEffect.cpp
+++ b/src/gpu/effects/GrYUVtoRGBEffect.cpp
@@ -37,7 +37,7 @@
     class GLEffect : public GrGLEffect {
     public:
         // this class always generates the same code.
-        static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) { return 0; }
+        static void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*) {}
 
         GLEffect(const GrBackendEffectFactory& factory,
                  const GrDrawEffect&)
@@ -46,7 +46,7 @@
 
         virtual void emitCode(GrGLShaderBuilder* builder,
                               const GrDrawEffect&,
-                              EffectKey,
+                              const GrEffectKey&,
                               const char* outputColor,
                               const char* inputColor,
                               const TransformedCoordsArray& coords,
diff --git a/src/gpu/gl/GrGLEffect.h b/src/gpu/gl/GrGLEffect.h
index 0727372..f9235db 100644
--- a/src/gpu/gl/GrGLEffect.h
+++ b/src/gpu/gl/GrGLEffect.h
@@ -20,7 +20,7 @@
     include/gpu/GrEffect.h. Objects of type GrGLEffect are responsible for emitting the
     GLSL code that implements a GrEffect and for uploading uniforms at draw time. If they don't
     always emit the same GLSL code, they must have a function:
-        static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&)
+        static inline void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*)
     that is used to implement a program cache. When two GrEffects produce the same key this means
     that their GrGLEffects would emit the same GLSL code.
 
@@ -39,7 +39,6 @@
 class GrGLEffect {
 
 public:
-    typedef GrBackendEffectFactory::EffectKey EffectKey;
     typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray;
     typedef GrGLProgramEffects::TextureSampler TextureSampler;
     typedef GrGLProgramEffects::TextureSamplerArray TextureSamplerArray;
@@ -58,8 +57,6 @@
         @param builder      Interface used to emit code in the shaders.
         @param drawEffect   A wrapper on the effect that generated this program stage.
         @param key          The key that was computed by GenKey() from the generating GrEffect.
-                            Only the bits indicated by GrBackendEffectFactory::kEffectKeyBits are
-                            guaranteed to match the value produced by GenKey();
         @param outputColor  A predefined vec4 in the FS in which the stage should place its output
                             color (or coverage).
         @param inputColor   A vec4 that holds the input color to the stage in the FS. This may be
@@ -73,24 +70,24 @@
         */
     virtual void emitCode(GrGLShaderBuilder* builder,
                           const GrDrawEffect& drawEffect,
-                          EffectKey key,
+                          const GrEffectKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray& coords,
                           const TextureSamplerArray& samplers) = 0;
 
     /** A GrGLEffect instance can be reused with any GrEffect that produces the same stage
-        key; this function reads data from a stage and uploads any uniform variables required
-        by the shaders created in emitCode(). The GrEffect installed in the GrEffectStage is
+        key; this function reads data from a GrEffect and uploads any uniform variables required
+        by the shaders created in emitCode(). The GrEffect installed in the GrDrawEffect is
         guaranteed to be of the same type that created this GrGLEffect and to have an identical
-        EffectKey as the one that created this GrGLEffect. Effects that use local coords have
+        effect key as the one that created this GrGLEffect. Effects that use local coords have
         to consider whether the GrEffectStage's coord change matrix should be used. When explicit
         local coordinates are used it can be ignored. */
     virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) {}
 
     const char* name() const { return fFactory.name(); }
 
-    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) { return 0; }
+    static void GenKey(const GrDrawEffect&, const GrGLCaps&, GrEffectKeyBuilder*) {}
 
     /** Used by the system when generating shader code, to see if this effect can be downcasted to
         the internal GrGLVertexEffect type */
diff --git a/src/gpu/gl/GrGLProgramDesc.h b/src/gpu/gl/GrGLProgramDesc.h
index c8aae19..a8d27ab 100644
--- a/src/gpu/gl/GrGLProgramDesc.h
+++ b/src/gpu/gl/GrGLProgramDesc.h
@@ -24,9 +24,7 @@
 
 
 /** This class describes a program to generate. It also serves as a program cache key. Very little
-    of this is GL-specific. There is the generation of GrGLEffect::EffectKeys and the dst-read part
-    of the key set by GrGLShaderBuilder. If the interfaces that set those portions were abstracted
-    to be API-neutral then so could this class. */
+    of this is GL-specific. The GL-specific parts could be factored out into a subclass. */
 class GrGLProgramDesc {
 public:
     GrGLProgramDesc() {}
@@ -196,8 +194,6 @@
         return reinterpret_cast<const T*>(reinterpret_cast<intptr_t>(fKey.begin()) + OFFSET);
     }
 
-    typedef GrBackendEffectFactory::EffectKey EffectKey;
-
     KeyHeader* header() { return this->atOffset<KeyHeader, kHeaderOffset>(); }
 
     // Shared code between setRandom() and Build().
@@ -227,13 +223,17 @@
             fBaseIndex = kColor_EffectType == type ? 0 : desc->numColorEffects();
         }
 
-        EffectKey get(int index) const {
-            const uint16_t* offsets = reinterpret_cast<const uint16_t*>(
+        GrEffectKey get(int index) const {
+            const uint16_t* offsetsAndLengths = reinterpret_cast<const uint16_t*>(
                 fDesc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset);
             // We store two uint16_ts per effect, one for the offset to the effect's key and one for
             // its length. Here we just need the offset.
-            uint16_t offset = offsets[2 * (fBaseIndex + index)];
-            return *reinterpret_cast<const EffectKey*>(fDesc->fKey.begin() + offset);
+            uint16_t offset = offsetsAndLengths[2 * (fBaseIndex + index) + 0];
+            uint16_t length = offsetsAndLengths[2 * (fBaseIndex + index) + 1];
+            // Currently effects must add to the key in units of uint32_t.
+            SkASSERT(0 == (length % sizeof(uint32_t)));
+            return GrEffectKey(reinterpret_cast<const uint32_t*>(fDesc->fKey.begin() + offset),
+                               length / sizeof(uint32_t));
         }
     private:
         const GrGLProgramDesc*  fDesc;
diff --git a/src/gpu/gl/GrGLProgramEffects.cpp b/src/gpu/gl/GrGLProgramEffects.cpp
index 9936aa5..05b1501 100644
--- a/src/gpu/gl/GrGLProgramEffects.cpp
+++ b/src/gpu/gl/GrGLProgramEffects.cpp
@@ -12,7 +12,6 @@
 #include "gl/GrGLVertexEffect.h"
 #include "gl/GrGpuGL.h"
 
-typedef GrGLProgramEffects::EffectKey EffectKey;
 typedef GrGLProgramEffects::TransformedCoords TransformedCoords;
 typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray;
 typedef GrGLProgramEffects::TextureSampler TextureSampler;
@@ -69,7 +68,7 @@
 /**
  * Retrieves the matrix type from transformKey for the transform at transformIdx.
  */
-MatrixType get_matrix_type(EffectKey transformKey, int transformIdx) {
+MatrixType get_matrix_type(uint32_t transformKey, int transformIdx) {
     return static_cast<MatrixType>(
                (transformKey >> (kTransformKeyBits * transformIdx)) & kMatrixTypeKeyMask);
 }
@@ -79,7 +78,7 @@
  * the same coordinate set as the original GrCoordTransform if the position and local coords are
  * identical for this program.
  */
-GrCoordSet get_source_coords(EffectKey transformKey, int transformIdx) {
+GrCoordSet get_source_coords(uint32_t transformKey, int transformIdx) {
     return (transformKey >> (kTransformKeyBits * transformIdx)) & kPositionCoords_Flag ?
                kPosition_GrCoordSet :
                kLocal_GrCoordSet;
@@ -117,9 +116,9 @@
 bool GrGLProgramEffects::GenEffectMetaKey(const GrDrawEffect& drawEffect, const GrGLCaps& caps,
                                           GrEffectKeyBuilder* b) {
 
-    EffectKey textureKey = GrGLProgramEffects::GenTextureKey(drawEffect, caps);
-    EffectKey transformKey = GrGLProgramEffects::GenTransformKey(drawEffect);
-    EffectKey attribKey = GrGLProgramEffects::GenAttribKey(drawEffect);
+    uint32_t textureKey = GrGLProgramEffects::GenTextureKey(drawEffect, caps);
+    uint32_t transformKey = GrGLProgramEffects::GenTransformKey(drawEffect);
+    uint32_t attribKey = GrGLProgramEffects::GenAttribKey(drawEffect);
     uint32_t classID = drawEffect.effect()->getFactory().effectClassID();
 
     // Currently we allow 16 bits for each of the above portions of the meta-key. Fail if they
@@ -135,24 +134,24 @@
     return true;
 }
 
-EffectKey GrGLProgramEffects::GenAttribKey(const GrDrawEffect& drawEffect) {
-    EffectKey key = 0;
+uint32_t GrGLProgramEffects::GenAttribKey(const GrDrawEffect& drawEffect) {
+    uint32_t key = 0;
     int numAttributes = drawEffect.getVertexAttribIndexCount();
     SkASSERT(numAttributes <= 2);
     const int* attributeIndices = drawEffect.getVertexAttribIndices();
     for (int a = 0; a < numAttributes; ++a) {
-        EffectKey value = attributeIndices[a] << 3 * a;
+        uint32_t value = attributeIndices[a] << 3 * a;
         SkASSERT(0 == (value & key)); // keys for each attribute ought not to overlap
         key |= value;
     }
     return key;
 }
 
-EffectKey GrGLProgramEffects::GenTransformKey(const GrDrawEffect& drawEffect) {
-    EffectKey totalKey = 0;
+uint32_t GrGLProgramEffects::GenTransformKey(const GrDrawEffect& drawEffect) {
+    uint32_t totalKey = 0;
     int numTransforms = drawEffect.effect()->numTransforms();
     for (int t = 0; t < numTransforms; ++t) {
-        EffectKey key = 0;
+        uint32_t key = 0;
         const GrCoordTransform& coordTransform = drawEffect.effect()->coordTransform(t);
         SkMatrix::TypeMask type0 = coordTransform.getMatrix().getType();
         SkMatrix::TypeMask type1;
@@ -182,8 +181,8 @@
     return totalKey;
 }
 
-EffectKey GrGLProgramEffects::GenTextureKey(const GrDrawEffect& drawEffect, const GrGLCaps& caps) {
-    EffectKey key = 0;
+uint32_t GrGLProgramEffects::GenTextureKey(const GrDrawEffect& drawEffect, const GrGLCaps& caps) {
+    uint32_t key = 0;
     int numTextures = drawEffect.effect()->numTextures();
     for (int t = 0; t < numTextures; ++t) {
         const GrTextureAccess& access = drawEffect.effect()->textureAccess(t);
@@ -250,7 +249,7 @@
 
 void GrGLVertexProgramEffects::emitEffect(GrGLFullShaderBuilder* builder,
                                           const GrEffectStage& stage,
-                                          EffectKey key,
+                                          const GrEffectKey& key,
                                           const char* outColor,
                                           const char* inColor,
                                           int stageIndex) {
@@ -301,7 +300,7 @@
                                               const GrDrawEffect& drawEffect,
                                               TransformedCoordsArray* outCoords) {
     SkTArray<Transform, true>& transforms = fTransforms.push_back();
-    EffectKey totalKey = GenTransformKey(drawEffect);
+    uint32_t totalKey = GenTransformKey(drawEffect);
     int numTransforms = drawEffect.effect()->numTransforms();
     transforms.push_back_n(numTransforms);
     for (int t = 0; t < numTransforms; t++) {
@@ -396,7 +395,7 @@
 }
 
 void GrGLVertexProgramEffectsBuilder::emitEffect(const GrEffectStage& stage,
-                                                 GrGLProgramEffects::EffectKey key,
+                                                 const GrEffectKey& key,
                                                  const char* outColor,
                                                  const char* inColor,
                                                  int stageIndex) {
@@ -408,7 +407,7 @@
 
 void GrGLPathTexGenProgramEffects::emitEffect(GrGLFragmentOnlyShaderBuilder* builder,
                                           const GrEffectStage& stage,
-                                          EffectKey key,
+                                          const GrEffectKey& key,
                                           const char* outColor,
                                           const char* inColor,
                                           int stageIndex) {
@@ -439,7 +438,7 @@
                                            const GrDrawEffect& drawEffect,
                                            TransformedCoordsArray* outCoords) {
     int numTransforms = drawEffect.effect()->numTransforms();
-    EffectKey totalKey = GenTransformKey(drawEffect);
+    uint32_t totalKey = GenTransformKey(drawEffect);
     int texCoordIndex = builder->addTexCoordSets(numTransforms);
     SkNEW_APPEND_TO_TARRAY(&fTransforms, Transforms, (totalKey, texCoordIndex));
     SkString name;
@@ -469,7 +468,7 @@
 void GrGLPathTexGenProgramEffects::setPathTexGenState(GrGpuGL* gpu,
                                               const GrDrawEffect& drawEffect,
                                               int effectIdx) {
-    EffectKey totalKey = fTransforms[effectIdx].fTransformKey;
+    uint32_t totalKey = fTransforms[effectIdx].fTransformKey;
     int texCoordIndex = fTransforms[effectIdx].fTexCoordIndex;
     int numTransforms = drawEffect.effect()->numTransforms();
     for (int t = 0; t < numTransforms; ++t) {
@@ -502,7 +501,7 @@
 }
 
 void GrGLPathTexGenProgramEffectsBuilder::emitEffect(const GrEffectStage& stage,
-                                                     GrGLProgramEffects::EffectKey key,
+                                                     const GrEffectKey& key,
                                                      const char* outColor,
                                                      const char* inColor,
                                                      int stageIndex) {
diff --git a/src/gpu/gl/GrGLProgramEffects.h b/src/gpu/gl/GrGLProgramEffects.h
index c4d8843..c9ba913 100644
--- a/src/gpu/gl/GrGLProgramEffects.h
+++ b/src/gpu/gl/GrGLProgramEffects.h
@@ -27,7 +27,6 @@
  */
 class GrGLProgramEffects : public SkRefCnt {
 public:
-    typedef GrBackendEffectFactory::EffectKey EffectKey;
     typedef GrGLUniformManager::UniformHandle UniformHandle;
 
     /**
@@ -104,9 +103,9 @@
     /**
      * Helpers for GenEffectMetaKey.
      */
-    static EffectKey GenAttribKey(const GrDrawEffect&);
-    static EffectKey GenTransformKey(const GrDrawEffect&);
-    static EffectKey GenTextureKey(const GrDrawEffect&, const GrGLCaps&);
+    static uint32_t GenAttribKey(const GrDrawEffect&);
+    static uint32_t GenTransformKey(const GrDrawEffect&);
+    static uint32_t GenTextureKey(const GrDrawEffect&, const GrGLCaps&);
 
     GrGLProgramEffects(int reserveCount)
         : fGLEffects(reserveCount)
@@ -149,7 +148,7 @@
      * Emits the effect's shader code, and stores the necessary uniforms internally.
      */
     virtual void emitEffect(const GrEffectStage&,
-                            GrGLProgramEffects::EffectKey,
+                            const GrEffectKey&,
                             const char* outColor,
                             const char* inColor,
                             int stageIndex) = 0;
@@ -181,7 +180,7 @@
      */
     void emitEffect(GrGLFullShaderBuilder*,
                     const GrEffectStage&,
-                    GrGLProgramEffects::EffectKey,
+                    const GrEffectKey&,
                     const char* outColor,
                     const char* inColor,
                     int stageIndex);
@@ -228,7 +227,7 @@
     virtual ~GrGLVertexProgramEffectsBuilder() { }
 
     virtual void emitEffect(const GrEffectStage&,
-                            GrGLProgramEffects::EffectKey,
+                            const GrEffectKey&,
                             const char* outColor,
                             const char* inColor,
                             int stageIndex) SK_OVERRIDE;
@@ -272,7 +271,7 @@
      */
     void emitEffect(GrGLFragmentOnlyShaderBuilder*,
                     const GrEffectStage&,
-                    GrGLProgramEffects::EffectKey,
+                    const GrEffectKey&,
                     const char* outColor,
                     const char* inColor,
                     int stageIndex);
@@ -295,10 +294,10 @@
     void setPathTexGenState(GrGpuGL*, const GrDrawEffect&, int effectIdx);
 
     struct Transforms {
-        Transforms(EffectKey transformKey, int texCoordIndex)
+        Transforms(uint32_t transformKey, int texCoordIndex)
             : fTransformKey(transformKey), fTexCoordIndex(texCoordIndex) {}
-        EffectKey fTransformKey;
-        int fTexCoordIndex;
+        uint32_t    fTransformKey;
+        int         fTexCoordIndex;
     };
 
     SkTArray<Transforms> fTransforms;
@@ -315,7 +314,7 @@
     virtual ~GrGLPathTexGenProgramEffectsBuilder() { }
 
     virtual void emitEffect(const GrEffectStage&,
-                            GrGLProgramEffects::EffectKey,
+                            const GrEffectKey&,
                             const char* outColor,
                             const char* inColor,
                             int stageIndex) SK_OVERRIDE;
diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h
index c28cd09..73e9a8f 100644
--- a/src/gpu/gl/GrGLShaderBuilder.h
+++ b/src/gpu/gl/GrGLShaderBuilder.h
@@ -31,7 +31,6 @@
 class GrGLShaderBuilder {
 public:
     typedef GrTAllocator<GrGLShaderVar> VarArray;
-    typedef GrBackendEffectFactory::EffectKey EffectKey;
     typedef GrGLProgramEffects::TextureSampler TextureSampler;
     typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray;
     typedef GrGLUniformManager::BuilderUniform BuilderUniform;
diff --git a/src/gpu/gl/GrGLVertexEffect.h b/src/gpu/gl/GrGLVertexEffect.h
index 40b4b34..eba1fbe 100644
--- a/src/gpu/gl/GrGLVertexEffect.h
+++ b/src/gpu/gl/GrGLVertexEffect.h
@@ -26,7 +26,7 @@
      */
     virtual void emitCode(GrGLFullShaderBuilder* builder,
                           const GrDrawEffect& drawEffect,
-                          EffectKey key,
+                          const GrEffectKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray& coords,
@@ -37,7 +37,7 @@
      */
     virtual void emitCode(GrGLShaderBuilder* builder,
                           const GrDrawEffect& drawEffect,
-                          EffectKey key,
+                          const GrEffectKey& key,
                           const char* outputColor,
                           const char* inputColor,
                           const TransformedCoordsArray& coords,