Wrap GrEffects in GrEffectPtr.

This is the first step towards automatic recycling of scratch resouces in the cache via ref-cnts.

R=robertphillips@google.com
Review URL: https://codereview.appspot.com/7092061

git-svn-id: http://skia.googlecode.com/svn/trunk@7222 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/effects/SkBlendImageFilter.cpp b/src/effects/SkBlendImageFilter.cpp
index 74ec7e3..d9fb320 100644
--- a/src/effects/SkBlendImageFilter.cpp
+++ b/src/effects/SkBlendImageFilter.cpp
@@ -143,7 +143,13 @@
 
 class GrBlendEffect : public GrEffect {
 public:
-    GrBlendEffect(SkBlendImageFilter::Mode mode, GrTexture* foreground, GrTexture* background);
+    static GrEffectRef* Create(SkBlendImageFilter::Mode mode,
+                               GrTexture* foreground,
+                               GrTexture* background) {
+        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrBlendEffect, (mode, foreground, background)));
+        return CreateEffectPtr(effect);
+    }
+
     virtual ~GrBlendEffect();
 
     virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
@@ -156,6 +162,7 @@
     void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
 private:
+    GrBlendEffect(SkBlendImageFilter::Mode mode, GrTexture* foreground, GrTexture* background);
     GrTextureAccess             fForegroundAccess;
     GrTextureAccess             fBackgroundAccess;
     SkBlendImageFilter::Mode    fMode;
@@ -218,7 +225,7 @@
 
     GrPaint paint;
     paint.colorStage(0)->setEffect(
-        SkNEW_ARGS(GrBlendEffect, (fMode, foreground.get(), background.get())))->unref();
+        GrBlendEffect::Create(fMode, foreground.get(), background.get()))->unref();
     context->drawRect(paint, rect);
     return dst;
 }
diff --git a/src/effects/SkColorMatrixFilter.cpp b/src/effects/SkColorMatrixFilter.cpp
index 2ff4fd6..85f6ccd 100644
--- a/src/effects/SkColorMatrixFilter.cpp
+++ b/src/effects/SkColorMatrixFilter.cpp
@@ -325,9 +325,12 @@
 
 class ColorMatrixEffect : public GrEffect {
 public:
-    static const char* Name() { return "Color Matrix"; }
+    static GrEffectRef* Create(const SkColorMatrix& matrix) {
+        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(ColorMatrixEffect, (matrix)));
+        return CreateEffectPtr(effect);
+    }
 
-    ColorMatrixEffect(const SkColorMatrix& matrix) : fMatrix(matrix) {}
+    static const char* Name() { return "Color Matrix"; }
 
     virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
         return GrTBackendEffectFactory<ColorMatrixEffect>::getInstance();
@@ -451,6 +454,8 @@
     };
 
 private:
+    ColorMatrixEffect(const SkColorMatrix& matrix) : fMatrix(matrix) {}
+
     SkColorMatrix fMatrix;
 
     typedef GrGLEffect INHERITED;
@@ -458,18 +463,18 @@
 
 GR_DEFINE_EFFECT_TEST(ColorMatrixEffect);
 
-GrEffect* ColorMatrixEffect::TestCreate(SkRandom* random,
-                                        GrContext*,
-                                        GrTexture* dummyTextures[2]) {
+GrEffectRef* ColorMatrixEffect::TestCreate(SkRandom* random,
+                                           GrContext*,
+                                           GrTexture* dummyTextures[2]) {
     SkColorMatrix colorMatrix;
     for (size_t i = 0; i < SK_ARRAY_COUNT(colorMatrix.fMat); ++i) {
         colorMatrix.fMat[i] = random->nextSScalar1();
     }
-    return SkNEW_ARGS(ColorMatrixEffect, (colorMatrix));
+    return ColorMatrixEffect::Create(colorMatrix);
 }
 
-GrEffect* SkColorMatrixFilter::asNewEffect(GrContext*) const {
-    return SkNEW_ARGS(ColorMatrixEffect, (fMatrix));
+GrEffectRef* SkColorMatrixFilter::asNewEffect(GrContext*) const {
+    return ColorMatrixEffect::Create(fMatrix);
 }
 
 #endif
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index b5f33ee..36ca6af 100644
--- a/src/effects/SkDisplacementMapEffect.cpp
+++ b/src/effects/SkDisplacementMapEffect.cpp
@@ -232,9 +232,17 @@
 
 class GrDisplacementMapEffect : public GrEffect {
 public:
-    GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
-                            SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,
-                            SkScalar scale, GrTexture* displacement, GrTexture* color);
+    static GrEffectRef* Create(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
+                               SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,
+                               SkScalar scale, GrTexture* displacement, GrTexture* color) {
+        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrDisplacementMapEffect, (xChannelSelector,
+                                                                           yChannelSelector,
+                                                                           scale,
+                                                                           displacement,
+                                                                           color)));
+        return CreateEffectPtr(effect);
+    }
+
     virtual ~GrDisplacementMapEffect();
 
     virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
@@ -251,6 +259,10 @@
     void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
 
 private:
+    GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
+                            SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,
+                            SkScalar scale, GrTexture* displacement, GrTexture* color);
+
     GR_DECLARE_EFFECT_TEST;
 
     GrTextureAccess             fDisplacementAccess;
@@ -319,8 +331,11 @@
 
     GrPaint paint;
     paint.colorStage(0)->setEffect(
-        SkNEW_ARGS(GrDisplacementMapEffect, (fXChannelSelector, fYChannelSelector, fScale,
-                                             displacement.get(), color.get())))->unref();
+        GrDisplacementMapEffect::Create(fXChannelSelector,
+                                        fYChannelSelector,
+                                        fScale,
+                                        displacement.get(),
+                                        color.get()))->unref();
     context->drawRect(paint, rect);
     return dst;
 }
@@ -369,9 +384,9 @@
 
 GR_DEFINE_EFFECT_TEST(GrDisplacementMapEffect);
 
-GrEffect* GrDisplacementMapEffect::TestCreate(SkRandom* random,
-                                              GrContext* context,
-                                              GrTexture* textures[]) {
+GrEffectRef* GrDisplacementMapEffect::TestCreate(SkRandom* random,
+                                                 GrContext* context,
+                                                 GrTexture* textures[]) {
     int texIdxDispl = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
                                            GrEffectUnitTest::kAlphaTextureIdx;
     int texIdxColor = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
@@ -385,8 +400,8 @@
         random->nextRangeU(1, kMaxComponent));
     SkScalar scale = random->nextUScalar1();
 
-    return SkNEW_ARGS(GrDisplacementMapEffect, (xChannelSelector, yChannelSelector, scale,
-                                                textures[texIdxDispl], textures[texIdxColor]));
+    return GrDisplacementMapEffect::Create(xChannelSelector, yChannelSelector, scale,
+                                           textures[texIdxDispl], textures[texIdxColor]);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index fc819de..337e8834 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -264,7 +264,7 @@
                                  SkScalar kd, SkImageFilter* input);
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDiffuseLightingImageFilter)
 
-    virtual bool asNewEffect(GrEffect** effect, GrTexture*) const SK_OVERRIDE;
+    virtual bool asNewEffect(GrEffectRef** effect, GrTexture*) const SK_OVERRIDE;
     SkScalar kd() const { return fKD; }
 
 protected:
@@ -284,7 +284,7 @@
     SkSpecularLightingImageFilter(SkLight* light, SkScalar surfaceScale, SkScalar ks, SkScalar shininess, SkImageFilter* input);
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSpecularLightingImageFilter)
 
-    virtual bool asNewEffect(GrEffect** effect, GrTexture*) const SK_OVERRIDE;
+    virtual bool asNewEffect(GrEffectRef** effect, GrTexture*) const SK_OVERRIDE;
     SkScalar ks() const { return fKS; }
     SkScalar shininess() const { return fShininess; }
 
@@ -326,10 +326,16 @@
 
 class GrDiffuseLightingEffect : public GrLightingEffect {
 public:
-    GrDiffuseLightingEffect(GrTexture* texture,
-                            const SkLight* light,
-                            SkScalar surfaceScale,
-                            SkScalar kd);
+    static GrEffectRef* Create(GrTexture* texture,
+                               const SkLight* light,
+                               SkScalar surfaceScale,
+                               SkScalar kd) {
+        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrDiffuseLightingEffect, (texture,
+                                                                           light,
+                                                                           surfaceScale,
+                                                                           kd)));
+        return CreateEffectPtr(effect);
+    }
 
     static const char* Name() { return "DiffuseLighting"; }
 
@@ -339,6 +345,11 @@
     virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
     SkScalar kd() const { return fKD; }
 private:
+    GrDiffuseLightingEffect(GrTexture* texture,
+                            const SkLight* light,
+                            SkScalar surfaceScale,
+                            SkScalar kd);
+
     GR_DECLARE_EFFECT_TEST;
     typedef GrLightingEffect INHERITED;
     SkScalar fKD;
@@ -346,12 +357,18 @@
 
 class GrSpecularLightingEffect : public GrLightingEffect {
 public:
-    GrSpecularLightingEffect(GrTexture* texture,
-                             const SkLight* light,
-                             SkScalar surfaceScale,
-                             SkScalar ks,
-                             SkScalar shininess);
-
+    static GrEffectRef* Create(GrTexture* texture,
+                               const SkLight* light,
+                               SkScalar surfaceScale,
+                               SkScalar ks,
+                               SkScalar shininess) {
+        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrSpecularLightingEffect, (texture,
+                                                                            light,
+                                                                            surfaceScale,
+                                                                            ks,
+                                                                            shininess)));
+        return CreateEffectPtr(effect);
+    }
     static const char* Name() { return "SpecularLighting"; }
 
     typedef GrGLSpecularLightingEffect GLEffect;
@@ -362,6 +379,12 @@
     SkScalar shininess() const { return fShininess; }
 
 private:
+    GrSpecularLightingEffect(GrTexture* texture,
+                             const SkLight* light,
+                             SkScalar surfaceScale,
+                             SkScalar ks,
+                             SkScalar shininess);
+
     GR_DECLARE_EFFECT_TEST;
     typedef GrLightingEffect INHERITED;
     SkScalar fKS;
@@ -832,12 +855,12 @@
     return true;
 }
 
-bool SkDiffuseLightingImageFilter::asNewEffect(GrEffect** effect,
+bool SkDiffuseLightingImageFilter::asNewEffect(GrEffectRef** effect,
                                                GrTexture* texture) const {
 #if SK_SUPPORT_GPU
     if (effect) {
         SkScalar scale = SkScalarMul(surfaceScale(), SkIntToScalar(255));
-        *effect = SkNEW_ARGS(GrDiffuseLightingEffect, (texture, light(), scale, kd()));
+        *effect = GrDiffuseLightingEffect::Create(texture, light(), scale, kd());
     }
     return true;
 #else
@@ -901,12 +924,12 @@
     return true;
 }
 
-bool SkSpecularLightingImageFilter::asNewEffect(GrEffect** effect,
+bool SkSpecularLightingImageFilter::asNewEffect(GrEffectRef** effect,
                                                 GrTexture* texture) const {
 #if SK_SUPPORT_GPU
     if (effect) {
         SkScalar scale = SkScalarMul(surfaceScale(), SkIntToScalar(255));
-        *effect = SkNEW_ARGS(GrSpecularLightingEffect, (texture, light(), scale, ks(), shininess()));
+        *effect = GrSpecularLightingEffect::Create(texture, light(), scale, ks(), shininess());
     }
     return true;
 #else
@@ -1054,14 +1077,14 @@
 
 GR_DEFINE_EFFECT_TEST(GrDiffuseLightingEffect);
 
-GrEffect* GrDiffuseLightingEffect::TestCreate(SkRandom* random,
-                                              GrContext* context,
-                                              GrTexture* textures[]) {
+GrEffectRef* GrDiffuseLightingEffect::TestCreate(SkRandom* random,
+                                                 GrContext* context,
+                                                 GrTexture* textures[]) {
     SkScalar surfaceScale = random->nextSScalar1();
     SkScalar kd = random->nextUScalar1();
     SkAutoTUnref<SkLight> light(create_random_light(random));
-    return SkNEW_ARGS(GrDiffuseLightingEffect, (textures[GrEffectUnitTest::kAlphaTextureIdx],
-                                                light, surfaceScale, kd));
+    return GrDiffuseLightingEffect::Create(textures[GrEffectUnitTest::kAlphaTextureIdx],
+                                           light, surfaceScale, kd);
 }
 
 
@@ -1267,15 +1290,15 @@
 
 GR_DEFINE_EFFECT_TEST(GrSpecularLightingEffect);
 
-GrEffect* GrSpecularLightingEffect::TestCreate(SkRandom* random,
-                                               GrContext* context,
-                                               GrTexture* textures[]) {
+GrEffectRef* GrSpecularLightingEffect::TestCreate(SkRandom* random,
+                                                  GrContext* context,
+                                                  GrTexture* textures[]) {
     SkScalar surfaceScale = random->nextSScalar1();
     SkScalar ks = random->nextUScalar1();
     SkScalar shininess = random->nextUScalar1();
     SkAutoTUnref<SkLight> light(create_random_light(random));
-    return SkNEW_ARGS(GrSpecularLightingEffect, (textures[GrEffectUnitTest::kAlphaTextureIdx],
-                                                 light, surfaceScale, ks, shininess));
+    return GrSpecularLightingEffect::Create(textures[GrEffectUnitTest::kAlphaTextureIdx],
+                                            light, surfaceScale, ks, shininess);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp
index 8cb1030..9b57bdc 100644
--- a/src/effects/SkMagnifierImageFilter.cpp
+++ b/src/effects/SkMagnifierImageFilter.cpp
@@ -26,20 +26,22 @@
 class GrMagnifierEffect : public GrSingleTextureEffect {
 
 public:
-    GrMagnifierEffect(GrTexture* texture,
-                      float xOffset,
-                      float yOffset,
-                      float xZoom,
-                      float yZoom,
-                      float xInset,
-                      float yInset)
-        : GrSingleTextureEffect(texture, MakeDivByTextureWHMatrix(texture))
-        , fXOffset(xOffset)
-        , fYOffset(yOffset)
-        , fXZoom(xZoom)
-        , fYZoom(yZoom)
-        , fXInset(xInset)
-        , fYInset(yInset) {}
+    static GrEffectRef* Create(GrTexture* texture,
+                               float xOffset,
+                               float yOffset,
+                               float xZoom,
+                               float yZoom,
+                               float xInset,
+                               float yInset) {
+        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrMagnifierEffect, (texture,
+                                                                     xOffset,
+                                                                     yOffset,
+                                                                     xZoom,
+                                                                     yZoom,
+                                                                     xInset,
+                                                                     yInset)));
+        return CreateEffectPtr(effect);
+    }
 
     virtual ~GrMagnifierEffect() {};
 
@@ -58,6 +60,21 @@
     typedef GrGLMagnifierEffect GLEffect;
 
 private:
+    GrMagnifierEffect(GrTexture* texture,
+                      float xOffset,
+                      float yOffset,
+                      float xZoom,
+                      float yZoom,
+                      float xInset,
+                      float yInset)
+        : GrSingleTextureEffect(texture, MakeDivByTextureWHMatrix(texture))
+        , fXOffset(xOffset)
+        , fYOffset(yOffset)
+        , fXZoom(xZoom)
+        , fYZoom(yZoom)
+        , fXInset(xInset)
+        , fYInset(yInset) {}
+
     GR_DECLARE_EFFECT_TEST;
 
     float fXOffset;
@@ -184,9 +201,9 @@
 
 GR_DEFINE_EFFECT_TEST(GrMagnifierEffect);
 
-GrEffect* GrMagnifierEffect::TestCreate(SkRandom* random,
-                                        GrContext* context,
-                                        GrTexture** textures) {
+GrEffectRef* GrMagnifierEffect::TestCreate(SkRandom* random,
+                                           GrContext* context,
+                                           GrTexture** textures) {
     const int kMaxWidth = 200;
     const int kMaxHeight = 200;
     const int kMaxInset = 20;
@@ -201,7 +218,7 @@
                 SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(y),
                                  SkIntToScalar(width), SkIntToScalar(height)),
                 inset));
-    GrEffect* effect;
+    GrEffectRef* effect;
     filter->asNewEffect(&effect, textures[0]);
     GrAssert(NULL != effect);
     return effect;
@@ -243,17 +260,16 @@
     SkASSERT(srcRect.x() >= 0 && srcRect.y() >= 0 && inset >= 0);
 }
 
-bool SkMagnifierImageFilter::asNewEffect(GrEffect** effect,
-                                         GrTexture* texture) const {
+bool SkMagnifierImageFilter::asNewEffect(GrEffectRef** effect, GrTexture* texture) const {
 #if SK_SUPPORT_GPU
     if (effect) {
-      *effect = SkNEW_ARGS(GrMagnifierEffect, (texture,
-                                               fSrcRect.x() / texture->width(),
-                                               fSrcRect.y() / texture->height(),
-                                               texture->width() / fSrcRect.width(),
-                                               texture->height() / fSrcRect.height(),
-                                               fInset / texture->width(),
-                                               fInset / texture->height()));
+      *effect = GrMagnifierEffect::Create(texture,
+                                          fSrcRect.x() / texture->width(),
+                                          fSrcRect.y() / texture->height(),
+                                          texture->width() / fSrcRect.width(),
+                                          texture->height() / fSrcRect.height(),
+                                          fInset / texture->width(),
+                                          fInset / texture->height());
     }
     return true;
 #else
diff --git a/src/effects/SkMatrixConvolutionImageFilter.cpp b/src/effects/SkMatrixConvolutionImageFilter.cpp
index 657c996..690cdd8 100644
--- a/src/effects/SkMatrixConvolutionImageFilter.cpp
+++ b/src/effects/SkMatrixConvolutionImageFilter.cpp
@@ -247,14 +247,24 @@
 class GrMatrixConvolutionEffect : public GrSingleTextureEffect {
 public:
     typedef SkMatrixConvolutionImageFilter::TileMode TileMode;
-    GrMatrixConvolutionEffect(GrTexture*,
-                              const SkISize& kernelSize,
-                              const SkScalar* kernel,
-                              SkScalar gain,
-                              SkScalar bias,
-                              const SkIPoint& target,
-                              TileMode tileMode,
-                              bool convolveAlpha);
+    static GrEffectRef* Create(GrTexture* texture,
+                               const SkISize& kernelSize,
+                               const SkScalar* kernel,
+                               SkScalar gain,
+                               SkScalar bias,
+                               const SkIPoint& target,
+                               TileMode tileMode,
+                               bool convolveAlpha) {
+        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrMatrixConvolutionEffect, (texture,
+                                                                             kernelSize,
+                                                                             kernel,
+                                                                             gain,
+                                                                             bias,
+                                                                             target,
+                                                                             tileMode,
+                                                                             convolveAlpha)));
+        return CreateEffectPtr(effect);
+    }
     virtual ~GrMatrixConvolutionEffect();
 
     virtual void getConstantColorComponents(GrColor* color,
@@ -280,6 +290,15 @@
     virtual bool isEqual(const GrEffect&) const SK_OVERRIDE;
 
 private:
+    GrMatrixConvolutionEffect(GrTexture*,
+                              const SkISize& kernelSize,
+                              const SkScalar* kernel,
+                              SkScalar gain,
+                              SkScalar bias,
+                              const SkIPoint& target,
+                              TileMode tileMode,
+                              bool convolveAlpha);
+
     SkISize  fKernelSize;
     float   *fKernel;
     float    fGain;
@@ -518,9 +537,9 @@
 // Allows for a 5x5 kernel (or 25x1, for that matter).
 #define MAX_KERNEL_SIZE 25
 
-GrEffect* GrMatrixConvolutionEffect::TestCreate(SkRandom* random,
-                                                GrContext* context,
-                                                GrTexture* textures[]) {
+GrEffectRef* GrMatrixConvolutionEffect::TestCreate(SkRandom* random,
+                                                   GrContext* context,
+                                                   GrTexture* textures[]) {
     int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
                                       GrEffectUnitTest::kAlphaTextureIdx;
     int width = random->nextRangeU(1, MAX_KERNEL_SIZE);
@@ -536,29 +555,29 @@
                                      random->nextRangeU(0, kernelSize.height()));
     TileMode tileMode = static_cast<TileMode>(random->nextRangeU(0, 2));
     bool convolveAlpha = random->nextBool();
-    return SkNEW_ARGS(GrMatrixConvolutionEffect, (textures[texIdx],
-                                                  kernelSize,
-                                                  kernel,
-                                                  gain,
-                                                  bias,
-                                                  target,
-                                                  tileMode,
-                                                  convolveAlpha));
+    return GrMatrixConvolutionEffect::Create(textures[texIdx],
+                                             kernelSize,
+                                             kernel,
+                                             gain,
+                                             bias,
+                                             target,
+                                             tileMode,
+                                             convolveAlpha);
 
 }
 
-bool SkMatrixConvolutionImageFilter::asNewEffect(GrEffect** effect,
+bool SkMatrixConvolutionImageFilter::asNewEffect(GrEffectRef** effect,
                                                  GrTexture* texture) const {
     bool ok = fKernelSize.width() * fKernelSize.height() <= MAX_KERNEL_SIZE;
     if (ok && effect) {
-        *effect = SkNEW_ARGS(GrMatrixConvolutionEffect, (texture,
-                                                         fKernelSize,
-                                                         fKernel,
-                                                         fGain,
-                                                         fBias,
-                                                         fTarget,
-                                                         fTileMode,
-                                                         fConvolveAlpha));
+        *effect = GrMatrixConvolutionEffect::Create(texture,
+                                                    fKernelSize,
+                                                    fKernel,
+                                                    fGain,
+                                                    fBias,
+                                                     fTarget,
+                                                     fTileMode,
+                                                     fConvolveAlpha);
     }
     return ok;
 }
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index 07b6449..7ce76c8 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -243,7 +243,11 @@
         kDilate_MorphologyType,
     };
 
-    GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType);
+    static GrEffectRef* Create(GrTexture* tex, Direction dir, int radius, MorphologyType type) {
+        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrMorphologyEffect, (tex, dir, radius, type)));
+        return CreateEffectPtr(effect);
+    }
+
     virtual ~GrMorphologyEffect();
 
     MorphologyType type() const { return fType; }
@@ -260,6 +264,8 @@
     MorphologyType fType;
 
 private:
+    GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType);
+
     GR_DECLARE_EFFECT_TEST;
 
     typedef Gr1DKernelEffect INHERITED;
@@ -406,9 +412,9 @@
 
 GR_DEFINE_EFFECT_TEST(GrMorphologyEffect);
 
-GrEffect* GrMorphologyEffect::TestCreate(SkRandom* random,
-                                         GrContext* context,
-                                         GrTexture* textures[]) {
+GrEffectRef* GrMorphologyEffect::TestCreate(SkRandom* random,
+                                            GrContext* context,
+                                            GrTexture* textures[]) {
     int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
                                       GrEffectUnitTest::kAlphaTextureIdx;
     Direction dir = random->nextBool() ? kX_Direction : kY_Direction;
@@ -417,7 +423,7 @@
     MorphologyType type = random->nextBool() ? GrMorphologyEffect::kErode_MorphologyType :
                                                GrMorphologyEffect::kDilate_MorphologyType;
 
-    return SkNEW_ARGS(GrMorphologyEffect, (textures[texIdx], dir, radius, type));
+    return GrMorphologyEffect::Create(textures[texIdx], dir, radius, type);
 }
 
 namespace {
@@ -429,10 +435,10 @@
                            GrMorphologyEffect::MorphologyType morphType,
                            Gr1DKernelEffect::Direction direction) {
     GrPaint paint;
-    paint.colorStage(0)->setEffect(SkNEW_ARGS(GrMorphologyEffect, (texture,
-                                                                   direction,
-                                                                   radius,
-                                                                   morphType)))->unref();
+    paint.colorStage(0)->setEffect(GrMorphologyEffect::Create(texture,
+                                                              direction,
+                                                              radius,
+                                                              morphType))->unref();
     context->drawRect(paint, rect);
 }
 
diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp
index 6713c20..7c2b4df 100644
--- a/src/effects/SkTableColorFilter.cpp
+++ b/src/effects/SkTableColorFilter.cpp
@@ -41,7 +41,7 @@
     virtual bool asComponentTable(SkBitmap* table) const SK_OVERRIDE;
 
 #if SK_SUPPORT_GPU
-    virtual GrEffect* asNewEffect(GrContext* context) const SK_OVERRIDE;
+    virtual GrEffectRef* asNewEffect(GrContext* context) const SK_OVERRIDE;
 #endif
 
     virtual void filterSpan(const SkPMColor src[], int count,
@@ -226,8 +226,11 @@
 
 class ColorTableEffect : public GrEffect {
 public:
+    static GrEffectRef* Create(GrTexture* texture, unsigned flags) {
+        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(ColorTableEffect, (texture, flags)));
+        return CreateEffectPtr(effect);
+    }
 
-    explicit ColorTableEffect(GrTexture* texture, unsigned flags);
     virtual ~ColorTableEffect();
 
     static const char* Name() { return "ColorTable"; }
@@ -239,6 +242,8 @@
     typedef GLColorTableEffect GLEffect;
 
 private:
+    explicit ColorTableEffect(GrTexture* texture, unsigned flags);
+
     GR_DECLARE_EFFECT_TEST;
 
     GrTextureAccess fTextureAccess;
@@ -365,20 +370,20 @@
 
 GR_DEFINE_EFFECT_TEST(ColorTableEffect);
 
-GrEffect* ColorTableEffect::TestCreate(SkRandom* random,
-                                       GrContext* context,
-                                       GrTexture* textures[]) {
+GrEffectRef* ColorTableEffect::TestCreate(SkRandom* random,
+                                          GrContext* context,
+                                          GrTexture* textures[]) {
     static unsigned kAllFlags = SkTable_ColorFilter::kR_Flag | SkTable_ColorFilter::kG_Flag |
                                 SkTable_ColorFilter::kB_Flag | SkTable_ColorFilter::kA_Flag;
-    return SkNEW_ARGS(ColorTableEffect, (textures[GrEffectUnitTest::kAlphaTextureIdx], kAllFlags));
+    return ColorTableEffect::Create(textures[GrEffectUnitTest::kAlphaTextureIdx], kAllFlags);
 }
 
-GrEffect* SkTable_ColorFilter::asNewEffect(GrContext* context) const {
+GrEffectRef* SkTable_ColorFilter::asNewEffect(GrContext* context) const {
     SkBitmap bitmap;
     this->asComponentTable(&bitmap);
     // passing NULL because this effect does no tiling or filtering.
     GrTexture* texture = GrLockCachedBitmapTexture(context, bitmap, NULL);
-    GrEffect* effect = SkNEW_ARGS(ColorTableEffect, (texture, fFlags));
+    GrEffectRef* effect = ColorTableEffect::Create(texture, fFlags);
 
     // Unlock immediately, this is not great, but we don't have a way of
     // knowing when else to unlock it currently. TODO: Remove this when
diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp
index 1788b7a..2785806 100644
--- a/src/effects/gradients/SkLinearGradient.cpp
+++ b/src/effects/gradients/SkLinearGradient.cpp
@@ -484,11 +484,14 @@
 class GrLinearGradient : public GrGradientEffect {
 public:
 
-    GrLinearGradient(GrContext* ctx,
-                     const SkLinearGradient& shader,
-                     const SkMatrix& matrix,
-                     SkShader::TileMode tm)
-        : INHERITED(ctx, shader, matrix, tm) { }
+    static GrEffectRef* Create(GrContext* ctx,
+                               const SkLinearGradient& shader,
+                               const SkMatrix& matrix,
+                               SkShader::TileMode tm) {
+        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrLinearGradient, (ctx, shader, matrix, tm)));
+        return CreateEffectPtr(effect);
+    }
+
     virtual ~GrLinearGradient() { }
 
     static const char* Name() { return "Linear Gradient"; }
@@ -499,6 +502,11 @@
     typedef GrGLLinearGradient GLEffect;
 
 private:
+    GrLinearGradient(GrContext* ctx,
+                     const SkLinearGradient& shader,
+                     const SkMatrix& matrix,
+                     SkShader::TileMode tm)
+        : INHERITED(ctx, shader, matrix, tm) { }
     GR_DECLARE_EFFECT_TEST;
 
     typedef GrGradientEffect INHERITED;
@@ -508,9 +516,9 @@
 
 GR_DEFINE_EFFECT_TEST(GrLinearGradient);
 
-GrEffect* GrLinearGradient::TestCreate(SkRandom* random,
-                                       GrContext* context,
-                                       GrTexture**) {
+GrEffectRef* GrLinearGradient::TestCreate(SkRandom* random,
+                                          GrContext* context,
+                                          GrTexture**) {
     SkPoint points[] = {{random->nextUScalar1(), random->nextUScalar1()},
                         {random->nextUScalar1(), random->nextUScalar1()}};
 
@@ -546,14 +554,14 @@
 
 /////////////////////////////////////////////////////////////////////
 
-GrEffect* SkLinearGradient::asNewEffect(GrContext* context, const SkPaint&) const {
+GrEffectRef* SkLinearGradient::asNewEffect(GrContext* context, const SkPaint&) const {
     SkASSERT(NULL != context);
     SkMatrix matrix;
     if (!this->getLocalMatrix().invert(&matrix)) {
         return NULL;
     }
     matrix.postConcat(fPtsToUnit);
-    return SkNEW_ARGS(GrLinearGradient, (context, *this, matrix, fTileMode));
+    return GrLinearGradient::Create(context, *this, matrix, fTileMode);
 }
 
 #else
diff --git a/src/effects/gradients/SkLinearGradient.h b/src/effects/gradients/SkLinearGradient.h
index e7935e4..046a1e1 100644
--- a/src/effects/gradients/SkLinearGradient.h
+++ b/src/effects/gradients/SkLinearGradient.h
@@ -22,7 +22,7 @@
     virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count) SK_OVERRIDE;
     virtual BitmapType asABitmap(SkBitmap*, SkMatrix*, TileMode*) const SK_OVERRIDE;
     virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
-    virtual GrEffect* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE;
+    virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE;
 
     SK_DEVELOPER_TO_STRING()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLinearGradient)
diff --git a/src/effects/gradients/SkRadialGradient.cpp b/src/effects/gradients/SkRadialGradient.cpp
index a33a9cd..4609db1 100644
--- a/src/effects/gradients/SkRadialGradient.cpp
+++ b/src/effects/gradients/SkRadialGradient.cpp
@@ -504,12 +504,12 @@
 
 class GrRadialGradient : public GrGradientEffect {
 public:
-
-    GrRadialGradient(GrContext* ctx,
-                     const SkRadialGradient& shader,
-                     const SkMatrix& matrix,
-                     SkShader::TileMode tm)
-        : INHERITED(ctx, shader, matrix, tm) {
+    static GrEffectRef* Create(GrContext* ctx,
+                               const SkRadialGradient& shader,
+                               const SkMatrix& matrix,
+                               SkShader::TileMode tm) {
+        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrRadialGradient, (ctx, shader, matrix, tm)));
+        return CreateEffectPtr(effect);
     }
 
     virtual ~GrRadialGradient() { }
@@ -522,6 +522,13 @@
     typedef GrGLRadialGradient GLEffect;
 
 private:
+    GrRadialGradient(GrContext* ctx,
+                     const SkRadialGradient& shader,
+                     const SkMatrix& matrix,
+                     SkShader::TileMode tm)
+        : INHERITED(ctx, shader, matrix, tm) {
+    }
+
     GR_DECLARE_EFFECT_TEST;
 
     typedef GrGradientEffect INHERITED;
@@ -531,9 +538,9 @@
 
 GR_DEFINE_EFFECT_TEST(GrRadialGradient);
 
-GrEffect* GrRadialGradient::TestCreate(SkRandom* random,
-                                       GrContext* context,
-                                       GrTexture**) {
+GrEffectRef* GrRadialGradient::TestCreate(SkRandom* random,
+                                          GrContext* context,
+                                          GrTexture**) {
     SkPoint center = {random->nextUScalar1(), random->nextUScalar1()};
     SkScalar radius = random->nextUScalar1();
 
@@ -569,7 +576,7 @@
 
 /////////////////////////////////////////////////////////////////////
 
-GrEffect* SkRadialGradient::asNewEffect(GrContext* context, const SkPaint&) const {
+GrEffectRef* SkRadialGradient::asNewEffect(GrContext* context, const SkPaint&) const {
     SkASSERT(NULL != context);
 
     SkMatrix matrix;
@@ -577,7 +584,7 @@
         return NULL;
     }
     matrix.postConcat(fPtsToUnit);
-    return SkNEW_ARGS(GrRadialGradient, (context, *this, matrix, fTileMode));
+    return GrRadialGradient::Create(context, *this, matrix, fTileMode);
 }
 
 #else
diff --git a/src/effects/gradients/SkRadialGradient.h b/src/effects/gradients/SkRadialGradient.h
index 0bb75c5..88530cd 100644
--- a/src/effects/gradients/SkRadialGradient.h
+++ b/src/effects/gradients/SkRadialGradient.h
@@ -24,7 +24,7 @@
                                  SkMatrix* matrix,
                                  TileMode* xy) const SK_OVERRIDE;
     virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
-    virtual GrEffect* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE;
+    virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE;
 
     SK_DEVELOPER_TO_STRING()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkRadialGradient)
diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp
index 493109e..91e239c 100644
--- a/src/effects/gradients/SkSweepGradient.cpp
+++ b/src/effects/gradients/SkSweepGradient.cpp
@@ -413,11 +413,12 @@
 
 class GrSweepGradient : public GrGradientEffect {
 public:
-
-    GrSweepGradient(GrContext* ctx,
-                    const SkSweepGradient& shader,
-                    const SkMatrix& matrix)
-    : INHERITED(ctx, shader, matrix, SkShader::kClamp_TileMode) { }
+    static GrEffectRef* Create(GrContext* ctx,
+                               const SkSweepGradient& shader,
+                               const SkMatrix& matrix) {
+        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrSweepGradient, (ctx, shader, matrix)));
+        return CreateEffectPtr(effect);
+    }
     virtual ~GrSweepGradient() { }
 
     static const char* Name() { return "Sweep Gradient"; }
@@ -428,6 +429,10 @@
     typedef GrGLSweepGradient GLEffect;
 
 private:
+    GrSweepGradient(GrContext* ctx,
+                    const SkSweepGradient& shader,
+                    const SkMatrix& matrix)
+    : INHERITED(ctx, shader, matrix, SkShader::kClamp_TileMode) { }
     GR_DECLARE_EFFECT_TEST;
 
     typedef GrGradientEffect INHERITED;
@@ -437,9 +442,9 @@
 
 GR_DEFINE_EFFECT_TEST(GrSweepGradient);
 
-GrEffect* GrSweepGradient::TestCreate(SkRandom* random,
-                                      GrContext* context,
-                                      GrTexture**) {
+GrEffectRef* GrSweepGradient::TestCreate(SkRandom* random,
+                                         GrContext* context,
+                                         GrTexture**) {
     SkPoint center = {random->nextUScalar1(), random->nextUScalar1()};
 
     SkColor colors[kMaxRandomGradientColors];
@@ -472,13 +477,13 @@
 
 /////////////////////////////////////////////////////////////////////
 
-GrEffect* SkSweepGradient::asNewEffect(GrContext* context, const SkPaint&) const {
+GrEffectRef* SkSweepGradient::asNewEffect(GrContext* context, const SkPaint&) const {
     SkMatrix matrix;
     if (!this->getLocalMatrix().invert(&matrix)) {
         return NULL;
     }
     matrix.postConcat(fPtsToUnit);
-    return SkNEW_ARGS(GrSweepGradient, (context, *this, matrix));
+    return GrSweepGradient::Create(context, *this, matrix);
 }
 
 #else
diff --git a/src/effects/gradients/SkSweepGradient.h b/src/effects/gradients/SkSweepGradient.h
index 4148966..95c1419 100644
--- a/src/effects/gradients/SkSweepGradient.h
+++ b/src/effects/gradients/SkSweepGradient.h
@@ -24,7 +24,7 @@
 
     virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
 
-    virtual GrEffect* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE;
+    virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE;
 
     SK_DEVELOPER_TO_STRING()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSweepGradient)
diff --git a/src/effects/gradients/SkTwoPointConicalGradient.cpp b/src/effects/gradients/SkTwoPointConicalGradient.cpp
index 23e4dcc..8d03c13 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient.cpp
+++ b/src/effects/gradients/SkTwoPointConicalGradient.cpp
@@ -369,14 +369,13 @@
 class GrConical2Gradient : public GrGradientEffect {
 public:
 
-    GrConical2Gradient(GrContext* ctx,
-                       const SkTwoPointConicalGradient& shader,
-                       const SkMatrix& matrix,
-                       SkShader::TileMode tm)
-        : INHERITED(ctx, shader, matrix, tm)
-        , fCenterX1(shader.getCenterX1())
-        , fRadius0(shader.getStartRadius())
-        , fDiffRadius(shader.getDiffRadius()) { }
+    static GrEffectRef* Create(GrContext* ctx,
+                               const SkTwoPointConicalGradient& shader,
+                               const SkMatrix& matrix,
+                               SkShader::TileMode tm) {
+        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrConical2Gradient, (ctx, shader, matrix, tm)));
+        return CreateEffectPtr(effect);
+    }
 
     virtual ~GrConical2Gradient() { }
 
@@ -401,6 +400,15 @@
     typedef GrGLConical2Gradient GLEffect;
 
 private:
+    GrConical2Gradient(GrContext* ctx,
+                       const SkTwoPointConicalGradient& shader,
+                       const SkMatrix& matrix,
+                       SkShader::TileMode tm)
+        : INHERITED(ctx, shader, matrix, tm)
+        , fCenterX1(shader.getCenterX1())
+        , fRadius0(shader.getStartRadius())
+        , fDiffRadius(shader.getDiffRadius()) { }
+
     GR_DECLARE_EFFECT_TEST;
 
     // @{
@@ -418,9 +426,9 @@
 
 GR_DEFINE_EFFECT_TEST(GrConical2Gradient);
 
-GrEffect* GrConical2Gradient::TestCreate(SkRandom* random,
-                                         GrContext* context,
-                                         GrTexture**) {
+GrEffectRef* GrConical2Gradient::TestCreate(SkRandom* random,
+                                            GrContext* context,
+                                            GrTexture**) {
     SkPoint center1 = {random->nextUScalar1(), random->nextUScalar1()};
     SkScalar radius1 = random->nextUScalar1();
     SkPoint center2;
@@ -684,7 +692,7 @@
 
 /////////////////////////////////////////////////////////////////////
 
-GrEffect* SkTwoPointConicalGradient::asNewEffect(GrContext* context, const SkPaint&) const {
+GrEffectRef* SkTwoPointConicalGradient::asNewEffect(GrContext* context, const SkPaint&) const {
     SkASSERT(NULL != context);
     SkASSERT(fPtsToUnit.isIdentity());
     // invert the localM, translate to center1, rotate so center2 is on x axis.
@@ -704,7 +712,7 @@
         matrix.postConcat(rot);
     }
 
-    return SkNEW_ARGS(GrConical2Gradient, (context, *this, matrix, fTileMode));
+    return GrConical2Gradient::Create(context, *this, matrix, fTileMode);
 }
 
 #else
diff --git a/src/effects/gradients/SkTwoPointConicalGradient.h b/src/effects/gradients/SkTwoPointConicalGradient.h
index 44432cc..32a7b80 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient.h
+++ b/src/effects/gradients/SkTwoPointConicalGradient.h
@@ -61,7 +61,7 @@
                                  SkMatrix* matrix,
                                  TileMode* xy) const;
     virtual SkShader::GradientType asAGradient(GradientInfo* info) const  SK_OVERRIDE;
-    virtual GrEffect* asNewEffect(GrContext* context, const SkPaint& paint) const SK_OVERRIDE;
+    virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint& paint) const SK_OVERRIDE;
 
     SkScalar getCenterX1() const { return SkPoint::Distance(fCenter1, fCenter2); }
     SkScalar getStartRadius() const { return fRadius1; }
diff --git a/src/effects/gradients/SkTwoPointRadialGradient.cpp b/src/effects/gradients/SkTwoPointRadialGradient.cpp
index 2e45809..8380a3f 100644
--- a/src/effects/gradients/SkTwoPointRadialGradient.cpp
+++ b/src/effects/gradients/SkTwoPointRadialGradient.cpp
@@ -428,15 +428,14 @@
 
 class GrRadial2Gradient : public GrGradientEffect {
 public:
+    static GrEffectRef* Create(GrContext* ctx,
+                               const SkTwoPointRadialGradient& shader,
+                               const SkMatrix& matrix,
+                               SkShader::TileMode tm) {
+        SkAutoTUnref<GrEffect> effect(SkNEW_ARGS(GrRadial2Gradient, (ctx, shader, matrix, tm)));
+        return CreateEffectPtr(effect);
+    }
 
-    GrRadial2Gradient(GrContext* ctx,
-                      const SkTwoPointRadialGradient& shader,
-                      const SkMatrix& matrix,
-                      SkShader::TileMode tm)
-        : INHERITED(ctx, shader, matrix, tm)
-        , fCenterX1(shader.getCenterX1())
-        , fRadius0(shader.getStartRadius())
-        , fPosRoot(shader.getDiffRadius() < 0) { }
     virtual ~GrRadial2Gradient() { }
 
     static const char* Name() { return "Two-Point Radial Gradient"; }
@@ -460,6 +459,15 @@
     typedef GrGLRadial2Gradient GLEffect;
 
 private:
+    GrRadial2Gradient(GrContext* ctx,
+                      const SkTwoPointRadialGradient& shader,
+                      const SkMatrix& matrix,
+                      SkShader::TileMode tm)
+        : INHERITED(ctx, shader, matrix, tm)
+        , fCenterX1(shader.getCenterX1())
+        , fRadius0(shader.getStartRadius())
+        , fPosRoot(shader.getDiffRadius() < 0) { }
+
     GR_DECLARE_EFFECT_TEST;
 
     // @{
@@ -479,9 +487,9 @@
 
 GR_DEFINE_EFFECT_TEST(GrRadial2Gradient);
 
-GrEffect* GrRadial2Gradient::TestCreate(SkRandom* random,
-                                        GrContext* context,
-                                        GrTexture**) {
+GrEffectRef* GrRadial2Gradient::TestCreate(SkRandom* random,
+                                           GrContext* context,
+                                           GrTexture**) {
     SkPoint center1 = {random->nextUScalar1(), random->nextUScalar1()};
     SkScalar radius1 = random->nextUScalar1();
     SkPoint center2;
@@ -683,7 +691,7 @@
 
 /////////////////////////////////////////////////////////////////////
 
-GrEffect* SkTwoPointRadialGradient::asNewEffect(GrContext* context, const SkPaint&) const {
+GrEffectRef* SkTwoPointRadialGradient::asNewEffect(GrContext* context, const SkPaint&) const {
     SkASSERT(NULL != context);
     // invert the localM, translate to center1 (fPtsToUni), rotate so center2 is on x axis.
     SkMatrix matrix;
@@ -701,7 +709,7 @@
         matrix.postConcat(rot);
     }
 
-    return SkNEW_ARGS(GrRadial2Gradient, (context, *this, matrix, fTileMode));
+    return GrRadial2Gradient::Create(context, *this, matrix, fTileMode);
 }
 
 #else
diff --git a/src/effects/gradients/SkTwoPointRadialGradient.h b/src/effects/gradients/SkTwoPointRadialGradient.h
index e0b0082..273d1c9 100644
--- a/src/effects/gradients/SkTwoPointRadialGradient.h
+++ b/src/effects/gradients/SkTwoPointRadialGradient.h
@@ -23,7 +23,7 @@
                                  SkMatrix* matrix,
                                  TileMode* xy) const SK_OVERRIDE;
     virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
-    virtual GrEffect* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE;
+    virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE;
 
     virtual void shadeSpan(int x, int y, SkPMColor* dstCParam,
                            int count) SK_OVERRIDE;