Let them eat GrEffectRef.

Changes the remaining existing code that operates on naked GrEffects to GrEffectRef.
Review URL: https://codereview.appspot.com/7124058

git-svn-id: http://skia.googlecode.com/svn/trunk@7321 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 9739199..077d246 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -200,10 +200,10 @@
     GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kReset_ASRInit);
     GrDrawState* drawState = target->drawState();
     drawState->setRenderTarget(rt);
-    SkAutoTUnref<GrEffectRef> conv(GrConvolutionEffect::Create(texture,
-                                                               direction,
-                                                               radius,
-                                                               sigma));
+    SkAutoTUnref<GrEffectRef> conv(GrConvolutionEffect::CreateGuassian(texture,
+                                                                       direction,
+                                                                       radius,
+                                                                       sigma));
     drawState->stage(0)->setEffect(conv);
     target->drawSimpleRect(rect, NULL);
 }
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index e7609d8..70fdff9 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -757,7 +757,7 @@
     GrAssert(NULL != drawState.getRenderTarget());
     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
         if (drawState.isStageEnabled(s)) {
-            const GrEffect* effect = drawState.getStage(s).getEffect();
+            const GrEffectRef& effect = *drawState.getStage(s).getEffect();
             int numTextures = effect->numTextures();
             for (int t = 0; t < numTextures; ++t) {
                 GrTexture* texture = effect->texture(t);
@@ -840,9 +840,9 @@
     // Run through the color stages
     int stageCnt = drawState.getFirstCoverageStage();
     for (int s = 0; s < stageCnt; ++s) {
-        const GrEffect* effect = drawState.getStage(s).getEffect();
+        const GrEffectRef* effect = drawState.getStage(s).getEffect();
         if (NULL != effect) {
-            effect->getConstantColorComponents(&color, &validComponentFlags);
+            (*effect)->getConstantColorComponents(&color, &validComponentFlags);
         }
     }
 
@@ -866,9 +866,9 @@
             }
         }
         for (int s = drawState.getFirstCoverageStage(); s < GrDrawState::kNumStages; ++s) {
-            const GrEffect* effect = drawState.getStage(s).getEffect();
+            const GrEffectRef* effect = drawState.getStage(s).getEffect();
             if (NULL != effect) {
-                effect->getConstantColorComponents(&color, &validComponentFlags);
+                (*effect)->getConstantColorComponents(&color, &validComponentFlags);
             }
         }
     }
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index cedb7d4..7ceefe8 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1520,7 +1520,7 @@
         return;
     }
 
-    GrTexture* devTex = grPaint.getColorStage(kBitmapTextureIdx).getEffect()->texture(0);
+    GrTexture* devTex = (*grPaint.getColorStage(kBitmapTextureIdx).getEffect())->texture(0);
     SkASSERT(NULL != devTex);
 
     SkImageFilter* filter = paint.getImageFilter();
diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp
index 309dcd8..2271b10 100644
--- a/src/gpu/effects/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/GrConfigConversionEffect.cpp
@@ -16,8 +16,8 @@
 class GrGLConfigConversionEffect : public GrGLEffect {
 public:
     GrGLConfigConversionEffect(const GrBackendEffectFactory& factory,
-                               const GrEffect& s) : INHERITED (factory) {
-        const GrConfigConversionEffect& effect = static_cast<const GrConfigConversionEffect&>(s);
+                               const GrEffectRef& s) : INHERITED (factory) {
+        const GrConfigConversionEffect& effect = CastEffect<GrConfigConversionEffect>(s);
         fSwapRedAndBlue = effect.swapsRedAndBlue();
         fPMConversion = effect.pmConversion();
     }
@@ -68,7 +68,7 @@
 
     void setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
         const GrConfigConversionEffect& effect =
-            static_cast<const GrConfigConversionEffect&>(*stage.getEffect());
+            GetEffectFromStage<GrConfigConversionEffect>(stage);
         fEffectMatrix.setData(uman,
                               effect.getMatrix(),
                               stage.getCoordChangeMatrix(),
@@ -76,8 +76,7 @@
     }
 
     static inline EffectKey GenKey(const GrEffectStage& s, const GrGLCaps&) {
-        const GrConfigConversionEffect& effect =
-            static_cast<const GrConfigConversionEffect&>(*s.getEffect());
+        const GrConfigConversionEffect& effect = GetEffectFromStage<GrConfigConversionEffect>(s);
         EffectKey key = static_cast<EffectKey>(effect.swapsRedAndBlue()) |
                         (effect.pmConversion() << 1);
         key <<= GrGLEffectMatrix::kKeyBits;
@@ -116,9 +115,9 @@
     return GrTBackendEffectFactory<GrConfigConversionEffect>::getInstance();
 }
 
-bool GrConfigConversionEffect::onIsEqual(const GrEffect& s) const {
-    const GrConfigConversionEffect& other = static_cast<const GrConfigConversionEffect&>(s);
-    return this->texture(0) == s.texture(0) &&
+bool GrConfigConversionEffect::onIsEqual(const GrEffectRef& s) const {
+    const GrConfigConversionEffect& other = CastEffect<GrConfigConversionEffect>(s);
+    return this->texture(0) == s->texture(0) &&
            other.fSwapRedAndBlue == fSwapRedAndBlue &&
            other.fPMConversion == fPMConversion;
 }
@@ -142,11 +141,11 @@
     } else {
         swapRB = random->nextBool();
     }
-    SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrConfigConversionEffect,
-                                             (textures[GrEffectUnitTest::kSkiaPMTextureIdx],
-                                              swapRB,
-                                              pmConv,
-                                              GrEffectUnitTest::TestMatrix(random))));
+    AutoEffectUnref effect(SkNEW_ARGS(GrConfigConversionEffect,
+                                      (textures[GrEffectUnitTest::kSkiaPMTextureIdx],
+                                       swapRB,
+                                       pmConv,
+                                       GrEffectUnitTest::TestMatrix(random))));
     return CreateEffectRef(effect);
 }
 
@@ -214,18 +213,18 @@
         // We then verify that two reads produced the same values.
 
         GrPaint paint;
-        SkAutoTUnref<GrEffect> pmToUPM1(SkNEW_ARGS(GrConfigConversionEffect, (dataTex,
-                                                                              false,
-                                                                              *pmToUPMRule,
-                                                                              SkMatrix::I())));
-        SkAutoTUnref<GrEffect> upmToPM(SkNEW_ARGS(GrConfigConversionEffect, (readTex,
-                                                                             false,
-                                                                             *upmToPMRule,
-                                                                             SkMatrix::I())));
-        SkAutoTUnref<GrEffect> pmToUPM2(SkNEW_ARGS(GrConfigConversionEffect, (tempTex,
-                                                                              false,
-                                                                              *pmToUPMRule,
-                                                                              SkMatrix::I())));
+        AutoEffectUnref pmToUPM1(SkNEW_ARGS(GrConfigConversionEffect, (dataTex,
+                                                                       false,
+                                                                       *pmToUPMRule,
+                                                                       SkMatrix::I())));
+        AutoEffectUnref upmToPM(SkNEW_ARGS(GrConfigConversionEffect, (readTex,
+                                                                      false,
+                                                                      *upmToPMRule,
+                                                                      SkMatrix::I())));
+        AutoEffectUnref pmToUPM2(SkNEW_ARGS(GrConfigConversionEffect, (tempTex,
+                                                                       false,
+                                                                       *pmToUPMRule,
+                                                                       SkMatrix::I())));
 
         SkAutoTUnref<GrEffectRef> pmToUPMEffect1(CreateEffectRef(pmToUPM1));
         SkAutoTUnref<GrEffectRef> upmToPMEffect(CreateEffectRef(upmToPM));
@@ -280,10 +279,10 @@
             // The PM conversions assume colors are 0..255
             return false;
         }
-        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrConfigConversionEffect, (texture,
-                                                                            swapRedAndBlue,
-                                                                            pmConversion,
-                                                                            matrix)));
+        AutoEffectUnref effect(SkNEW_ARGS(GrConfigConversionEffect, (texture,
+                                                                     swapRedAndBlue,
+                                                                     pmConversion,
+                                                                     matrix)));
         stage->setEffect(CreateEffectRef(effect))->unref();
         return true;
     }
diff --git a/src/gpu/effects/GrConfigConversionEffect.h b/src/gpu/effects/GrConfigConversionEffect.h
index 3845d32..08e5f71 100644
--- a/src/gpu/effects/GrConfigConversionEffect.h
+++ b/src/gpu/effects/GrConfigConversionEffect.h
@@ -66,7 +66,7 @@
                             PMConversion pmConversion,
                             const SkMatrix& matrix);
 
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrEffectRef&) const SK_OVERRIDE;
 
     bool            fSwapRedAndBlue;
     PMConversion    fPMConversion;
diff --git a/src/gpu/effects/GrConvolutionEffect.cpp b/src/gpu/effects/GrConvolutionEffect.cpp
index 82c908a..ffa5427 100644
--- a/src/gpu/effects/GrConvolutionEffect.cpp
+++ b/src/gpu/effects/GrConvolutionEffect.cpp
@@ -18,7 +18,7 @@
 
 class GrGLConvolutionEffect : public GrGLEffect {
 public:
-    GrGLConvolutionEffect(const GrBackendEffectFactory&, const GrEffect&);
+    GrGLConvolutionEffect(const GrBackendEffectFactory&, const GrEffectRef&);
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrEffectStage&,
@@ -44,12 +44,11 @@
 };
 
 GrGLConvolutionEffect::GrGLConvolutionEffect(const GrBackendEffectFactory& factory,
-                                             const GrEffect& effect)
+                                             const GrEffectRef& effect)
     : INHERITED(factory)
     , fKernelUni(kInvalidUniformHandle)
     , fImageIncrementUni(kInvalidUniformHandle) {
-    const GrConvolutionEffect& c =
-        static_cast<const GrConvolutionEffect&>(effect);
+    const GrConvolutionEffect& c = CastEffect<GrConvolutionEffect>(effect);
     fRadius = c.radius();
 }
 
@@ -91,7 +90,7 @@
 }
 
 void GrGLConvolutionEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
-    const GrConvolutionEffect& conv = static_cast<const GrConvolutionEffect&>(*stage.getEffect());
+    const GrConvolutionEffect& conv = GetEffectFromStage<GrConvolutionEffect>(stage);
     GrTexture& texture = *conv.texture(0);
     // the code we generated was for a specific kernel radius
     GrAssert(conv.radius() == fRadius);
@@ -112,8 +111,8 @@
 }
 
 GrGLEffect::EffectKey GrGLConvolutionEffect::GenKey(const GrEffectStage& s, const GrGLCaps&) {
-    const GrConvolutionEffect& conv = static_cast<const GrConvolutionEffect&>(*s.getEffect());
-    EffectKey key = static_cast<const GrConvolutionEffect&>(*s.getEffect()).radius();
+    const GrConvolutionEffect& conv = GetEffectFromStage<GrConvolutionEffect>(s);
+    EffectKey key = conv.radius();
     key <<= GrGLEffectMatrix::kKeyBits;
     EffectKey matrixKey = GrGLEffectMatrix::GenKey(conv.getMatrix(),
                                                    s.getCoordChangeMatrix(),
@@ -167,8 +166,8 @@
     return GrTBackendEffectFactory<GrConvolutionEffect>::getInstance();
 }
 
-bool GrConvolutionEffect::onIsEqual(const GrEffect& sBase) const {
-     const GrConvolutionEffect& s = static_cast<const GrConvolutionEffect&>(sBase);
+bool GrConvolutionEffect::onIsEqual(const GrEffectRef& sBase) const {
+    const GrConvolutionEffect& s = CastEffect<GrConvolutionEffect>(sBase);
     return (this->texture(0) == s.texture(0) &&
             this->radius() == s.radius() &&
             this->direction() == s.direction() &&
@@ -193,4 +192,3 @@
 
     return GrConvolutionEffect::Create(textures[texIdx], dir, radius,kernel);
 }
-
diff --git a/src/gpu/effects/GrConvolutionEffect.h b/src/gpu/effects/GrConvolutionEffect.h
index 944d34f..7345ae4 100644
--- a/src/gpu/effects/GrConvolutionEffect.h
+++ b/src/gpu/effects/GrConvolutionEffect.h
@@ -23,22 +23,22 @@
 
     /// Convolve with an arbitrary user-specified kernel
     static GrEffectRef* Create(GrTexture* tex, Direction dir, int halfWidth, const float* kernel) {
-        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrConvolutionEffect, (tex,
-                                                                       dir,
-                                                                       halfWidth,
-                                                                       kernel)));
+        AutoEffectUnref effect(SkNEW_ARGS(GrConvolutionEffect, (tex,
+                                                                dir,
+                                                                halfWidth,
+                                                                kernel)));
         return CreateEffectRef(effect);
     }
 
     /// Convolve with a Gaussian kernel
-    static GrEffectRef* Create(GrTexture* tex,
-                               Direction dir,
-                               int halfWidth,
-                               float gaussianSigma) {
-        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrConvolutionEffect, (tex,
-                                                                       dir,
-                                                                       halfWidth,
-                                                                       gaussianSigma)));
+    static GrEffectRef* CreateGuassian(GrTexture* tex,
+                                       Direction dir,
+                                       int halfWidth,
+                                       float gaussianSigma) {
+        AutoEffectUnref effect(SkNEW_ARGS(GrConvolutionEffect, (tex,
+                                                                dir,
+                                                                halfWidth,
+                                                                gaussianSigma)));
         return CreateEffectRef(effect);
     }
 
@@ -82,7 +82,7 @@
                         int halfWidth,
                         float gaussianSigma);
 
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrEffectRef&) const SK_OVERRIDE;
 
     GR_DECLARE_EFFECT_TEST;
 
diff --git a/src/gpu/effects/GrSimpleTextureEffect.cpp b/src/gpu/effects/GrSimpleTextureEffect.cpp
index 69ab13e..b674879 100644
--- a/src/gpu/effects/GrSimpleTextureEffect.cpp
+++ b/src/gpu/effects/GrSimpleTextureEffect.cpp
@@ -15,7 +15,7 @@
 
 class GrGLSimpleTextureEffect : public GrGLEffect {
 public:
-    GrGLSimpleTextureEffect(const GrBackendEffectFactory& factory, const GrEffect&)
+    GrGLSimpleTextureEffect(const GrBackendEffectFactory& factory, const GrEffectRef&)
     : INHERITED (factory) {}
 
     virtual void emitCode(GrGLShaderBuilder* builder,
@@ -37,16 +37,14 @@
     }
 
     static inline EffectKey GenKey(const GrEffectStage& stage, const GrGLCaps&) {
-        const GrSimpleTextureEffect& ste =
-            static_cast<const GrSimpleTextureEffect&>(*stage.getEffect());
+        const GrSimpleTextureEffect& ste = GetEffectFromStage<GrSimpleTextureEffect>(stage);
         return GrGLEffectMatrix::GenKey(ste.getMatrix(),
                                         stage.getCoordChangeMatrix(),
                                         ste.texture(0));
     }
 
     virtual void setData(const GrGLUniformManager& uman, const GrEffectStage& stage) SK_OVERRIDE {
-        const GrSimpleTextureEffect& ste =
-            static_cast<const GrSimpleTextureEffect&>(*stage.getEffect());
+        const GrSimpleTextureEffect& ste = GetEffectFromStage<GrSimpleTextureEffect>(stage);
         fEffectMatrix.setData(uman, ste.getMatrix(), stage.getCoordChangeMatrix(), ste.texture(0));
     }
 
diff --git a/src/gpu/effects/GrSimpleTextureEffect.h b/src/gpu/effects/GrSimpleTextureEffect.h
index 5ccbe33..b7466b4 100644
--- a/src/gpu/effects/GrSimpleTextureEffect.h
+++ b/src/gpu/effects/GrSimpleTextureEffect.h
@@ -21,18 +21,18 @@
 public:
     /* unfiltered, clamp mode */
     static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix) {
-        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix)));
+        AutoEffectUnref effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix)));
         return CreateEffectRef(effect);
     }
 
     /* clamp mode */
     static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix, bool bilerp) {
-        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, bilerp)));
+        AutoEffectUnref effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, bilerp)));
         return CreateEffectRef(effect);
     }
 
     static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix, const GrTextureParams& p) {
-        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, p)));
+        AutoEffectUnref effect(SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, p)));
         return CreateEffectRef(effect);
     }
 
@@ -54,8 +54,8 @@
     GrSimpleTextureEffect(GrTexture* texture, const SkMatrix& matrix, const GrTextureParams& params)
         : GrSingleTextureEffect(texture, matrix, params) {}
 
-    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
-        const GrSimpleTextureEffect& ste = static_cast<const GrSimpleTextureEffect&>(other);
+    virtual bool onIsEqual(const GrEffectRef& other) const SK_OVERRIDE {
+        const GrSimpleTextureEffect& ste = CastEffect<GrSimpleTextureEffect>(other);
         return this->hasSameTextureParamsAndMatrix(ste);
     }
 
diff --git a/src/gpu/effects/GrTextureDomainEffect.cpp b/src/gpu/effects/GrTextureDomainEffect.cpp
index c4a59d8..58c8b80 100644
--- a/src/gpu/effects/GrTextureDomainEffect.cpp
+++ b/src/gpu/effects/GrTextureDomainEffect.cpp
@@ -14,7 +14,7 @@
 
 class GrGLTextureDomainEffect : public GrGLEffect {
 public:
-    GrGLTextureDomainEffect(const GrBackendEffectFactory&, const GrEffect&);
+    GrGLTextureDomainEffect(const GrBackendEffectFactory&, const GrEffectRef&);
 
     virtual void emitCode(GrGLShaderBuilder*,
                           const GrEffectStage&,
@@ -37,7 +37,7 @@
 };
 
 GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrBackendEffectFactory& factory,
-                                                 const GrEffect&)
+                                                 const GrEffectRef&)
     : INHERITED(factory)
     , fNameUni(GrGLUniformManager::kInvalidUniformHandle) {
     fPrevDomain[0] = SK_FloatNaN;
@@ -50,8 +50,7 @@
                                        const char* outputColor,
                                        const char* inputColor,
                                        const TextureSamplerArray& samplers) {
-    const GrTextureDomainEffect& effect =
-        static_cast<const GrTextureDomainEffect&>(*stage.getEffect());
+    const GrTextureDomainEffect& effect = GetEffectFromStage<GrTextureDomainEffect>(stage);
 
     const char* coords;
     fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, vertexCoords, &coords);
@@ -81,8 +80,7 @@
 }
 
 void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
-    const GrTextureDomainEffect& effect =
-        static_cast<const GrTextureDomainEffect&>(*stage.getEffect());
+    const GrTextureDomainEffect& effect = GetEffectFromStage<GrTextureDomainEffect>(stage);
     const GrRect& domain = effect.domain();
 
     float values[4] = {
@@ -109,8 +107,7 @@
 }
 
 GrGLEffect::EffectKey GrGLTextureDomainEffect::GenKey(const GrEffectStage& stage, const GrGLCaps&) {
-    const GrTextureDomainEffect& effect =
-        static_cast<const GrTextureDomainEffect&>(*stage.getEffect());
+    const GrTextureDomainEffect& effect = GetEffectFromStage<GrTextureDomainEffect>(stage);
     EffectKey key = effect.wrapMode();
     key <<= GrGLEffectMatrix::kKeyBits;
     EffectKey matrixKey = GrGLEffectMatrix::GenKey(effect.getMatrix(),
@@ -144,11 +141,11 @@
         GrAssert(clippedDomain.fLeft <= clippedDomain.fRight);
         GrAssert(clippedDomain.fTop <= clippedDomain.fBottom);
 
-        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrTextureDomainEffect, (texture,
-                                                                         matrix,
-                                                                         clippedDomain,
-                                                                         wrapMode,
-                                                                         bilerp)));
+        AutoEffectUnref effect(SkNEW_ARGS(GrTextureDomainEffect, (texture,
+                                                                  matrix,
+                                                                  clippedDomain,
+                                                                  wrapMode,
+                                                                  bilerp)));
         return CreateEffectRef(effect);
 
     }
@@ -172,8 +169,8 @@
     return GrTBackendEffectFactory<GrTextureDomainEffect>::getInstance();
 }
 
-bool GrTextureDomainEffect::onIsEqual(const GrEffect& sBase) const {
-    const GrTextureDomainEffect& s = static_cast<const GrTextureDomainEffect&>(sBase);
+bool GrTextureDomainEffect::onIsEqual(const GrEffectRef& sBase) const {
+    const GrTextureDomainEffect& s = CastEffect<GrTextureDomainEffect>(sBase);
     return this->hasSameTextureParamsAndMatrix(s) && this->fTextureDomain == s.fTextureDomain;
 }
 
diff --git a/src/gpu/effects/GrTextureDomainEffect.h b/src/gpu/effects/GrTextureDomainEffect.h
index b7f665c..81b3da4 100644
--- a/src/gpu/effects/GrTextureDomainEffect.h
+++ b/src/gpu/effects/GrTextureDomainEffect.h
@@ -77,7 +77,7 @@
                           WrapMode,
                           bool bilerp);
 
-    virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
+    virtual bool onIsEqual(const GrEffectRef&) const SK_OVERRIDE;
 
     GR_DECLARE_EFFECT_TEST;
 
diff --git a/src/gpu/gl/GrGLEffect.cpp b/src/gpu/gl/GrGLEffect.cpp
index 0bbf1f7..ccea269 100644
--- a/src/gpu/gl/GrGLEffect.cpp
+++ b/src/gpu/gl/GrGLEffect.cpp
@@ -20,11 +20,11 @@
 void GrGLEffect::setData(const GrGLUniformManager&, const GrEffectStage&) {
 }
 
-GrGLEffect::EffectKey GrGLEffect::GenTextureKey(const GrEffect& effect,
+GrGLEffect::EffectKey GrGLEffect::GenTextureKey(const GrEffectRef* effect,
                                                 const GrGLCaps& caps) {
     EffectKey key = 0;
-    for (int index = 0; index < effect.numTextures(); ++index) {
-        const GrTextureAccess& access = effect.textureAccess(index);
+    for (int index = 0; index < (*effect)->numTextures(); ++index) {
+        const GrTextureAccess& access = (*effect)->textureAccess(index);
         EffectKey value = GrGLShaderBuilder::KeyForTextureAccess(access, caps) << index;
         GrAssert(0 == (value & key)); // keys for each access ought not to overlap
         key |= value;
diff --git a/src/gpu/gl/GrGLEffect.h b/src/gpu/gl/GrGLEffect.h
index f2142c5..32fc960 100644
--- a/src/gpu/gl/GrGLEffect.h
+++ b/src/gpu/gl/GrGLEffect.h
@@ -86,7 +86,28 @@
 
     const char* name() const { return fFactory.name(); }
 
-    static EffectKey GenTextureKey(const GrEffect&, const GrGLCaps&);
+    static EffectKey GenTextureKey(const GrEffectRef*, const GrGLCaps&);
+
+   /**
+    * GrGLEffect subclasses get passed a GrEffectStage in their emitCode and setData functions.
+    * The GrGLEffect usually needs to cast the stage's effect to the GrEffect subclass that
+    * generated the GrGLEffect. This helper does just that.
+    */
+    template <typename T>
+    static const T& GetEffectFromStage(const GrEffectStage& effectStage) {
+        GrAssert(NULL != effectStage.getEffect());
+        return CastEffect<T>(*effectStage.getEffect());
+    }
+
+   /**
+    * Extracts the GrEffect from a GrEffectRef and down-casts to a GrEffect subclass. Usually used
+    * in a GrGLEffect subclass's constructor (which takes const GrEffectRef&).
+    */
+    template <typename T>
+    static const T& CastEffect(const GrEffectRef& effectRef) {
+        GrAssert(NULL != effectRef.get());
+        return *static_cast<const T*>(effectRef.get());
+    }
 
 protected:
     const GrBackendEffectFactory& fFactory;
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 26127e4..e6daa9c 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -914,7 +914,7 @@
             for (int u = 0; u < numSamplers; ++u) {
                 UniformHandle handle = fUniformHandles.fSamplerUnis[s][u];
                 if (GrGLUniformManager::kInvalidUniformHandle != handle) {
-                    const GrTextureAccess& access = stage.getEffect()->textureAccess(u);
+                    const GrTextureAccess& access = (*stage.getEffect())->textureAccess(u);
                     GrGLTexture* texture = static_cast<GrGLTexture*>(access.getTexture());
                     gpu->bindTexture(texUnitIdx, access.getParams(), texture);
                     ++texUnitIdx;
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp
index 0845fdd..a8514ad 100644
--- a/src/gpu/gl/GrGLShaderBuilder.cpp
+++ b/src/gpu/gl/GrGLShaderBuilder.cpp
@@ -422,16 +422,16 @@
                                 SkTArray<GrGLUniformManager::UniformHandle, true>* samplerHandles) {
     GrAssert(NULL != stage.getEffect());
 
-    const GrEffect& effect = *stage.getEffect();
-    int numTextures = effect.numTextures();
+    const GrEffectRef& effect = *stage.getEffect();
+    int numTextures = effect->numTextures();
     SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers;
     textureSamplers.push_back_n(numTextures);
     for (int i = 0; i < numTextures; ++i) {
-        textureSamplers[i].init(this, &effect.textureAccess(i), i);
+        textureSamplers[i].init(this, &effect->textureAccess(i), i);
         samplerHandles->push_back(textureSamplers[i].fSamplerUniform);
     }
 
-    GrGLEffect* glEffect = effect.getFactory().createGLInstance(effect);
+    GrGLEffect* glEffect = effect->getFactory().createGLInstance(effect);
 
     // Enclose custom code in a block to avoid namespace conflicts
     this->fVSCode.appendf("\t{ // %s\n", glEffect->name());
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index 3d9f0fe..7e0d0b0 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -563,7 +563,7 @@
         bool skip = s < drawState.getFirstCoverageStage() ? skipColor : skipCoverage;
         if (!skip && drawState.isStageEnabled(s)) {
             lastEnabledStage = s;
-            const GrEffect* effect = drawState.getStage(s).getEffect();
+            const GrEffectRef& effect = *drawState.getStage(s).getEffect();
             const GrBackendEffectFactory& factory = effect->getFactory();
             desc->fEffectKeys[s] = factory.glEffectKey(drawState.getStage(s), this->glCaps());
         } else {