Introduces new SingleTextureEffect base class for GrCustomStage objects.
This class tracks the texture that the object uses. A future commit will get rid of the
GrTexture pointer currenty stored in the GrDrawState, allowing us to have CustomStages
*without* textures.

Requires gyp change on next roll.

http://codereview.appspot.com/6306097/



git-svn-id: http://skia.googlecode.com/svn/trunk@4576 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 149359f..95e0eca 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -244,7 +244,7 @@
     sampleM.setIDiv(texture->width(), texture->height());
     drawState->sampler(0)->reset(sampleM);
     SkAutoTUnref<GrCustomStage> morph(
-        SkNEW_ARGS(GrMorphologyEffect, (direction, radius, morphType)));
+        SkNEW_ARGS(GrMorphologyEffect, (texture, direction, radius, morphType)));
     drawState->sampler(0)->setCustomStage(morph);
     drawState->setTexture(0, texture);
     gpu->drawSimpleRect(rect, NULL, 1 << 0);
@@ -264,7 +264,7 @@
     sampleM.setIDiv(texture->width(), texture->height());
     drawState->sampler(0)->reset(sampleM);
     SkAutoTUnref<GrConvolutionEffect> conv(SkNEW_ARGS(GrConvolutionEffect,
-                                                      (direction, radius)));
+                                                      (texture, direction, radius)));
     conv->setGaussianKernel(sigma);
     drawState->sampler(0)->setCustomStage(conv);
     drawState->setTexture(0, texture);
diff --git a/src/gpu/GrCustomStage.cpp b/src/gpu/GrCustomStage.cpp
index c0ec330..66b78a6 100644
--- a/src/gpu/GrCustomStage.cpp
+++ b/src/gpu/GrCustomStage.cpp
@@ -14,6 +14,7 @@
                                     GrProgramStageFactory::kIllegalStageClassID;
 
 GrCustomStage::GrCustomStage() {
+
 }
 
 GrCustomStage::~GrCustomStage() {
@@ -24,3 +25,23 @@
     return false;
 }
 
+bool GrCustomStage::isEqual(const GrCustomStage& s) const {
+    if (this->numTextures() != s.numTextures()) {
+        return false;
+    }
+    for (unsigned int i = 0; i < this->numTextures(); ++i) {
+        if (this->texture(i) != s.texture(i)) {
+            return false;
+        }
+    }
+    return true;
+}
+
+unsigned int GrCustomStage::numTextures() const {
+    return 0;
+}
+
+GrTexture* GrCustomStage::texture(unsigned int index) const {
+    return NULL;
+}
+
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 2a2bbcd..1154313 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -536,26 +536,36 @@
         }
         return false;
     }
+
     GrSamplerState* sampler = grPaint->textureSampler(kShaderTextureIdx);
+    GrTexture* texture = act->set(dev, bitmap, sampler);
+    if (NULL == texture) {
+        SkDebugf("Couldn't convert bitmap to texture.\n");
+        return false;
+    }
+    grPaint->setTexture(kShaderTextureIdx, texture);
+
     switch (bmptype) {
         case SkShader::kRadial_BitmapType:
-            sampler->setCustomStage(SkNEW(GrRadialGradient))->unref();
+            sampler->setCustomStage(SkNEW_ARGS(GrRadialGradient, (texture)))->unref();
             sampler->setFilter(GrSamplerState::kBilinear_Filter);
             break;
         case SkShader::kSweep_BitmapType:
-            sampler->setCustomStage(SkNEW(GrSweepGradient))->unref();
+            sampler->setCustomStage(SkNEW_ARGS(GrSweepGradient, (texture)))->unref();
             sampler->setFilter(GrSamplerState::kBilinear_Filter);
             break;
         case SkShader::kTwoPointRadial_BitmapType:
             sampler->setCustomStage(SkNEW_ARGS(GrRadial2Gradient,
-                         (twoPointParams[0],
+                         (texture,
+                          twoPointParams[0],
                           twoPointParams[1],
                           twoPointParams[2] < 0)))->unref();
             sampler->setFilter(GrSamplerState::kBilinear_Filter);
             break;
         case SkShader::kTwoPointConical_BitmapType:
             sampler->setCustomStage(SkNEW_ARGS(GrConical2Gradient,
-                                               (twoPointParams[0],
+                                               (texture,
+                                                twoPointParams[0],
                                                 twoPointParams[1],
                                                 twoPointParams[2])))->unref();
             sampler->setFilter(GrSamplerState::kBilinear_Filter);
@@ -571,13 +581,6 @@
     sampler->setWrapX(sk_tile_mode_to_grwrap(tileModes[0]));
     sampler->setWrapY(sk_tile_mode_to_grwrap(tileModes[1]));
 
-    GrTexture* texture = act->set(dev, bitmap, sampler);
-    if (NULL == texture) {
-        SkDebugf("Couldn't convert bitmap to texture.\n");
-        return false;
-    }
-    grPaint->setTexture(kShaderTextureIdx, texture);
-
     // since our texture coords will be in local space, we wack the texture
     // matrix to map them back into 0...1 before we load it
     SkMatrix localM;
@@ -1474,7 +1477,7 @@
     desc.fConfig = kRGBA_8888_PM_GrPixelConfig;
     GrCustomStage* stage;
 
-    if (filter->asNewCustomStage(&stage)) {
+    if (filter->asNewCustomStage(&stage, texture)) {
         GrAutoScratchTexture dst(context, desc);
         apply_custom_stage(context, texture, dst.texture(), rect, stage);
         texture = dst.detach();
@@ -1607,7 +1610,7 @@
     SkSize size;
     SkISize radius;
 
-    if (!filter->asNewCustomStage(NULL) &&
+    if (!filter->asNewCustomStage(NULL, NULL) &&
         !filter->asABlur(&size) &&
         !filter->asADilate(&radius) &&
         !filter->asAnErode(&radius)) {
diff --git a/src/gpu/effects/Gr1DKernelEffect.h b/src/gpu/effects/Gr1DKernelEffect.h
index b6e116f..9ef7652 100644
--- a/src/gpu/effects/Gr1DKernelEffect.h
+++ b/src/gpu/effects/Gr1DKernelEffect.h
@@ -8,7 +8,7 @@
 #ifndef Gr1DKernelEffect_DEFINED
 #define Gr1DKernelEffect_DEFINED
 
-#include "GrCustomStage.h"
+#include "GrSingleTextureEffect.h"
 
 /**
  * Base class for 1D kernel effects. The kernel operates either in X or Y and
@@ -18,7 +18,7 @@
  * read. Since the center pixel is also read, the total width is one larger than
  * two times the radius.
  */
-class Gr1DKernelEffect : public GrCustomStage {
+class Gr1DKernelEffect : public GrSingleTextureEffect {
 
 public:
     enum Direction {
@@ -26,9 +26,11 @@
         kY_Direction,
     };
 
-    Gr1DKernelEffect(Direction direction,
+    Gr1DKernelEffect(GrTexture* texture,
+                     Direction direction,
                      int radius)
-        : fDirection(direction)
+        : GrSingleTextureEffect(texture)
+        , fDirection(direction)
         , fRadius(radius) {}
 
     virtual ~Gr1DKernelEffect() {};
@@ -44,7 +46,7 @@
     Direction       fDirection;
     int             fRadius;
 
-    typedef GrCustomStage INHERITED;
+    typedef GrSingleTextureEffect INHERITED;
 };
 
 #endif
diff --git a/src/gpu/effects/GrConvolutionEffect.cpp b/src/gpu/effects/GrConvolutionEffect.cpp
index 42dc2b4..4970d62 100644
--- a/src/gpu/effects/GrConvolutionEffect.cpp
+++ b/src/gpu/effects/GrConvolutionEffect.cpp
@@ -28,7 +28,6 @@
     virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE;
 
     virtual void setData(const GrGLInterface*,
-                         const GrGLTexture&,
                          const GrCustomStage&,
                          int stageNum) SK_OVERRIDE;
 
@@ -118,11 +117,11 @@
 }
 
 void GrGLConvolutionEffect::setData(const GrGLInterface* gl,
-                                    const GrGLTexture& texture,
                                     const GrCustomStage& data,
                                     int stageNum) {
     const GrConvolutionEffect& conv =
         static_cast<const GrConvolutionEffect&>(data);
+    GrTexture& texture = *data.texture(0);
     // the code we generated was for a specific kernel radius
     GrAssert(conv.radius() == fRadius);
     float imageIncrement[2] = { 0 };
@@ -148,10 +147,11 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrConvolutionEffect::GrConvolutionEffect(Direction direction,
+GrConvolutionEffect::GrConvolutionEffect(GrTexture* texture,
+                                         Direction direction,
                                          int radius,
                                          const float* kernel)
-    : Gr1DKernelEffect(direction, radius) {
+    : Gr1DKernelEffect(texture, direction, radius) {
     GrAssert(radius <= kMaxKernelRadius);
     int width = this->width();
     if (NULL != kernel) {
@@ -171,9 +171,10 @@
 bool GrConvolutionEffect::isEqual(const GrCustomStage& sBase) const {
      const GrConvolutionEffect& s =
         static_cast<const GrConvolutionEffect&>(sBase);
-    return (this->radius() == s.radius() &&
-             this->direction() == s.direction() &&
-             0 == memcmp(fKernel, s.fKernel, this->width() * sizeof(float)));
+    return (INHERITED::isEqual(sBase) &&
+            this->radius() == s.radius() &&
+            this->direction() == s.direction() &&
+            0 == memcmp(fKernel, s.fKernel, this->width() * sizeof(float)));
 }
 
 void GrConvolutionEffect::setGaussianKernel(float sigma) {
diff --git a/src/gpu/effects/GrConvolutionEffect.h b/src/gpu/effects/GrConvolutionEffect.h
index fd6883b..58cad83 100644
--- a/src/gpu/effects/GrConvolutionEffect.h
+++ b/src/gpu/effects/GrConvolutionEffect.h
@@ -21,7 +21,8 @@
 
 public:
 
-    GrConvolutionEffect(Direction, int halfWidth, const float* kernel = NULL);
+    GrConvolutionEffect(GrTexture*, Direction,
+                        int halfWidth, const float* kernel = NULL);
     virtual ~GrConvolutionEffect();
 
     void setKernel(const float* kernel) {
diff --git a/src/gpu/effects/GrGradientEffects.cpp b/src/gpu/effects/GrGradientEffects.cpp
index 6045956..d4719b3 100644
--- a/src/gpu/effects/GrGradientEffects.cpp
+++ b/src/gpu/effects/GrGradientEffects.cpp
@@ -49,7 +49,8 @@
 /////////////////////////////////////////////////////////////////////
 
 
-GrRadialGradient::GrRadialGradient() {
+GrRadialGradient::GrRadialGradient(GrTexture* texture)
+    : GrSingleTextureEffect(texture) {
 
 }
 
@@ -63,7 +64,7 @@
 }
 
 bool GrRadialGradient::isEqual(const GrCustomStage& sBase) const {
-    return true;
+    return INHERITED::isEqual(sBase);
 }
 
 /////////////////////////////////////////////////////////////////////
@@ -86,7 +87,6 @@
                         const char* samplerName) SK_OVERRIDE;
     virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE;
     virtual void setData(const GrGLInterface*,
-                         const GrGLTexture&,
                          const GrCustomStage&,
                          int stageNum) SK_OVERRIDE;
 
@@ -257,7 +257,6 @@
 }
 
 void GrGLRadial2Gradient::setData(const GrGLInterface* gl,
-                                  const GrGLTexture& texture,
                                   const GrCustomStage& baseData,
                                   int stageNum) {
     const GrRadial2Gradient& data =
@@ -296,10 +295,12 @@
 
 /////////////////////////////////////////////////////////////////////
 
-GrRadial2Gradient::GrRadial2Gradient(GrScalar center,
+GrRadial2Gradient::GrRadial2Gradient(GrTexture* texture,
+                                     GrScalar center,
                                      GrScalar radius,
                                      bool posRoot)
-    : fCenterX1 (center)
+    : GrSingleTextureEffect(texture)
+    , fCenterX1 (center)
     , fRadius0 (radius)
     , fPosRoot (posRoot) {
 
@@ -316,7 +317,8 @@
 
 bool GrRadial2Gradient::isEqual(const GrCustomStage& sBase) const {
     const GrRadial2Gradient& s = static_cast<const GrRadial2Gradient&>(sBase);
-    return (this->fCenterX1 == s.fCenterX1 &&
+    return (INHERITED::isEqual(sBase) &&
+            this->fCenterX1 == s.fCenterX1 &&
             this->fRadius0 == s.fRadius0 &&
             this->fPosRoot == s.fPosRoot);
 }
@@ -341,7 +343,6 @@
                         const char* samplerName) SK_OVERRIDE;
     virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE;
     virtual void setData(const GrGLInterface*,
-                         const GrGLTexture&,
                          const GrCustomStage&,
                          int stageNum) SK_OVERRIDE;
 
@@ -571,7 +572,6 @@
 }
 
 void GrGLConical2Gradient::setData(const GrGLInterface* gl,
-                                   const GrGLTexture& texture,
                                    const GrCustomStage& baseData,
                                    int stageNum) {
     const GrConical2Gradient& data =
@@ -612,10 +612,12 @@
 
 /////////////////////////////////////////////////////////////////////
 
-GrConical2Gradient::GrConical2Gradient(GrScalar center,
+GrConical2Gradient::GrConical2Gradient(GrTexture* texture,
+                                       GrScalar center,
                                        GrScalar radius,
                                        GrScalar diffRadius)
-    : fCenterX1 (center)
+    : GrSingleTextureEffect (texture)
+    , fCenterX1 (center)
     , fRadius0 (radius)
     , fDiffRadius (diffRadius) {
 
@@ -632,7 +634,8 @@
 
 bool GrConical2Gradient::isEqual(const GrCustomStage& sBase) const {
     const GrConical2Gradient& s = static_cast<const GrConical2Gradient&>(sBase);
-    return (this->fCenterX1 == s.fCenterX1 &&
+    return (INHERITED::isEqual(sBase) &&
+            this->fCenterX1 == s.fCenterX1 &&
             this->fRadius0 == s.fRadius0 &&
             this->fDiffRadius == s.fDiffRadius);
 }
@@ -677,7 +680,8 @@
 
 /////////////////////////////////////////////////////////////////////
 
-GrSweepGradient::GrSweepGradient() {
+GrSweepGradient::GrSweepGradient(GrTexture* texture)
+    : GrSingleTextureEffect(texture) {
 
 }
 
@@ -690,6 +694,6 @@
 }
 
 bool GrSweepGradient::isEqual(const GrCustomStage& sBase) const {
-    return true;
+    return INHERITED::isEqual(sBase);
 }
 
diff --git a/src/gpu/effects/GrGradientEffects.h b/src/gpu/effects/GrGradientEffects.h
index cf6827f..37e4642 100644
--- a/src/gpu/effects/GrGradientEffects.h
+++ b/src/gpu/effects/GrGradientEffects.h
@@ -8,7 +8,7 @@
 #ifndef GrGradientEffects_DEFINED
 #define GrGradientEffects_DEFINED
 
-#include "GrCustomStage.h"
+#include "GrSingleTextureEffect.h"
 #include "GrTypes.h"
 #include "GrScalar.h"
 
@@ -37,11 +37,11 @@
 
 class GrGLRadialGradient;
 
-class GrRadialGradient : public GrCustomStage {
+class GrRadialGradient : public GrSingleTextureEffect {
 
 public:
 
-    GrRadialGradient();
+    GrRadialGradient(GrTexture* texture);
     virtual ~GrRadialGradient();
 
     static const char* Name() { return "Radial Gradient"; }
@@ -52,24 +52,23 @@
 
 private:
 
-    typedef GrCustomStage INHERITED;
+    typedef GrSingleTextureEffect INHERITED;
 };
 
 class GrGLRadial2Gradient;
 
-class GrRadial2Gradient : public GrCustomStage {
+class GrRadial2Gradient : public GrSingleTextureEffect {
 
 public:
 
-    GrRadial2Gradient(GrScalar center, GrScalar radius, bool posRoot);
+    GrRadial2Gradient(GrTexture* texture, GrScalar center, GrScalar radius, bool posRoot);
     virtual ~GrRadial2Gradient();
 
     static const char* Name() { return "Two-Point Radial Gradient"; }
     virtual const GrProgramStageFactory& getFactory() const SK_OVERRIDE;
     virtual bool isEqual(const GrCustomStage&) const SK_OVERRIDE;
 
-    // The radial gradient parameters can collapse to a linear (instead
-    // of quadratic) equation.
+    // The radial gradient parameters can collapse to a linear (instead of quadratic) equation.
     bool isDegenerate() const { return GR_Scalar1 == fCenterX1; }
     GrScalar center() const { return fCenterX1; }
     GrScalar radius() const { return fRadius0; }
@@ -89,26 +88,24 @@
 
     // @}
 
-    typedef GrCustomStage INHERITED;
+    typedef GrSingleTextureEffect INHERITED;
 };
 
 class GrGLConical2Gradient;
 
-class GrConical2Gradient : public GrCustomStage {
+class GrConical2Gradient : public GrSingleTextureEffect {
 
 public:
 
-    GrConical2Gradient(GrScalar center, GrScalar radius, GrScalar diffRadius);
+    GrConical2Gradient(GrTexture* texture, GrScalar center, GrScalar radius, GrScalar diffRadius);
     virtual ~GrConical2Gradient();
 
     static const char* Name() { return "Two-Point Conical Gradient"; }
     virtual const GrProgramStageFactory& getFactory() const SK_OVERRIDE;
     virtual bool isEqual(const GrCustomStage&) const SK_OVERRIDE;
 
-    // The radial gradient parameters can collapse to a linear (instead
-    // of quadratic) equation.
-    bool isDegenerate() const { return SkScalarAbs(fDiffRadius) == 
-                                       SkScalarAbs(fCenterX1); }
+    // The radial gradient parameters can collapse to a linear (instead of quadratic) equation.
+    bool isDegenerate() const { return SkScalarAbs(fDiffRadius) == SkScalarAbs(fCenterX1); }
     GrScalar center() const { return fCenterX1; }
     GrScalar diffRadius() const { return fDiffRadius; }
     GrScalar radius() const { return fRadius0; }
@@ -127,16 +124,16 @@
 
     // @}
 
-    typedef GrCustomStage INHERITED;
+    typedef GrSingleTextureEffect INHERITED;
 };
 
 class GrGLSweepGradient;
 
-class GrSweepGradient : public GrCustomStage {
+class GrSweepGradient : public GrSingleTextureEffect {
 
 public:
 
-    GrSweepGradient();
+    GrSweepGradient(GrTexture* texture);
     virtual ~GrSweepGradient();
 
     static const char* Name() { return "Sweep Gradient"; }
@@ -147,7 +144,7 @@
 
 protected:
 
-    typedef GrCustomStage INHERITED;
+    typedef GrSingleTextureEffect INHERITED;
 };
 
 #endif
diff --git a/src/gpu/effects/GrMorphologyEffect.cpp b/src/gpu/effects/GrMorphologyEffect.cpp
index 43e8702..3ea2cbd 100644
--- a/src/gpu/effects/GrMorphologyEffect.cpp
+++ b/src/gpu/effects/GrMorphologyEffect.cpp
@@ -31,7 +31,6 @@
 
     virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE;
     virtual void setData(const GrGLInterface*, 
-                         const GrGLTexture&,
                          const GrCustomStage&,
                          int stageNum) SK_OVERRIDE;
 
@@ -124,11 +123,12 @@
 }
 
 void GrGLMorphologyEffect ::setData(const GrGLInterface* gl,
-                                    const GrGLTexture& texture,
                                     const GrCustomStage& data,
                                     int stageNum) {
     const Gr1DKernelEffect& kern =
         static_cast<const Gr1DKernelEffect&>(data);
+    GrGLTexture& texture =
+        *static_cast<GrGLTexture*>(data.texture(0));
     // the code we generated was for a specific kernel radius
     GrAssert(kern.radius() == fRadius);
     float imageIncrement[2] = { 0 };
@@ -147,10 +147,11 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrMorphologyEffect::GrMorphologyEffect(Direction direction,
+GrMorphologyEffect::GrMorphologyEffect(GrTexture* texture,
+                                       Direction direction,
                                        int radius,
                                        MorphologyType type)
-    : Gr1DKernelEffect(direction, radius)
+    : Gr1DKernelEffect(texture, direction, radius)
     , fType(type) {
 }
 
@@ -164,7 +165,8 @@
 bool GrMorphologyEffect::isEqual(const GrCustomStage& sBase) const {
     const GrMorphologyEffect& s =
         static_cast<const GrMorphologyEffect&>(sBase);
-    return (this->radius() == s.radius() &&
+    return (INHERITED::isEqual(sBase) &&
+            this->radius() == s.radius() &&
             this->direction() == s.direction() &&
             this->type() == s.type());
 }
diff --git a/src/gpu/effects/GrMorphologyEffect.h b/src/gpu/effects/GrMorphologyEffect.h
index c784460..c8bd2d5 100644
--- a/src/gpu/effects/GrMorphologyEffect.h
+++ b/src/gpu/effects/GrMorphologyEffect.h
@@ -25,7 +25,7 @@
 
     typedef GrContext::MorphologyType MorphologyType;
 
-    GrMorphologyEffect(Direction, int radius, MorphologyType);
+    GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType);
     virtual ~GrMorphologyEffect();
 
     MorphologyType type() const { return fType; }
diff --git a/src/gpu/effects/GrSingleTextureEffect.cpp b/src/gpu/effects/GrSingleTextureEffect.cpp
new file mode 100644
index 0000000..a373ebe
--- /dev/null
+++ b/src/gpu/effects/GrSingleTextureEffect.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "effects/GrSingleTextureEffect.h"
+#include "GrTexture.h"
+
+GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture)
+    : fTexture (texture) {
+    SkSafeRef(fTexture);
+}
+
+GrSingleTextureEffect::~GrSingleTextureEffect() {
+    SkSafeUnref(fTexture);
+}
+
+unsigned int GrSingleTextureEffect::numTextures() const {
+    return 1;
+}
+
+GrTexture* GrSingleTextureEffect::texture(unsigned int index) const {
+    GrAssert(0 == index);
+    return fTexture;
+}
+
+
diff --git a/src/gpu/effects/GrSingleTextureEffect.h b/src/gpu/effects/GrSingleTextureEffect.h
new file mode 100644
index 0000000..9a6bd1c
--- /dev/null
+++ b/src/gpu/effects/GrSingleTextureEffect.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrSingleTextureEffect_DEFINED
+#define GrSingleTextureEffect_DEFINED
+
+#include "GrCustomStage.h"
+
+class GrSingleTextureEffect : public GrCustomStage {
+
+public:
+    GrSingleTextureEffect(GrTexture* texture);
+    virtual ~GrSingleTextureEffect();
+
+    virtual unsigned int numTextures() const SK_OVERRIDE;
+    virtual GrTexture* texture(unsigned int index) const SK_OVERRIDE;
+
+private:
+    GrTexture* fTexture;
+
+    typedef GrCustomStage INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLProgramStage.cpp b/src/gpu/gl/GrGLProgramStage.cpp
index 487b468..b5e4f40 100644
--- a/src/gpu/gl/GrGLProgramStage.cpp
+++ b/src/gpu/gl/GrGLProgramStage.cpp
@@ -26,7 +26,6 @@
 }
 
 void GrGLProgramStage::setData(const GrGLInterface*,
-                               const GrGLTexture&,
                                const GrCustomStage&,
                                int stageNum) {
 }
diff --git a/src/gpu/gl/GrGLProgramStage.h b/src/gpu/gl/GrGLProgramStage.h
index fe3ed4b..9cf2c1a 100644
--- a/src/gpu/gl/GrGLProgramStage.h
+++ b/src/gpu/gl/GrGLProgramStage.h
@@ -82,7 +82,6 @@
         a stage and uploads any uniform variables required by the shaders
         created in emit*(). */
     virtual void setData(const GrGLInterface* gl,
-                         const GrGLTexture& texture,
                          const GrCustomStage& stage,
                          int stageNum);
 
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 7ebe9d7..edabb9c 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -2140,6 +2140,21 @@
     GrGLTexture* nextTexture = 
         static_cast<GrGLTexture*>(drawState->getTexture(stage));
 
+    // HACK - if we're using a new SingleTextureEffect, override
+    // the old texture pointer
+    const GrSamplerState& sampler = drawState->getSampler(stage);
+    GrCustomStage* customStage = sampler.getCustomStage();
+    if (customStage && customStage->numTextures()) {
+        nextTexture = 
+            static_cast<GrGLTexture*>(customStage->texture(0));
+    }
+
+    flushBoundTextureAndParams(stage, nextTexture);
+}
+
+void GrGpuGL::flushBoundTextureAndParams(int stage, GrGLTexture* nextTexture) {
+    GrDrawState* drawState = this->drawState();
+
     // true for now, but maybe not with GrEffect.
     GrAssert(NULL != nextTexture);
     // if we created a rt/tex and rendered to it without using a
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index 2d6aa68..0871a57 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -213,6 +213,7 @@
     // call to flushScissor must occur after all textures have been flushed via
     // this function.
     void flushBoundTextureAndParams(int stage);
+    void flushBoundTextureAndParams(int stage, GrGLTexture* nextTexture);
 
     // sets the texture matrix and domain for the currently bound program
     void flushTextureMatrixAndDomain(int stage);
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index 3a3d638..a7187d5 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -479,7 +479,7 @@
                         static_cast<const GrGLTexture*>(
                             this->getDrawState().getTexture(s));
                     fProgramData->fCustomStage[s]->setData(
-                        this->glInterface(), *texture,
+                        this->glInterface(),
                         *sampler.getCustomStage(), s);
                 }
             }
diff --git a/src/gpu/gl/GrGpuGL_unittest.cpp b/src/gpu/gl/GrGpuGL_unittest.cpp
index 044d477..004013a 100644
--- a/src/gpu/gl/GrGpuGL_unittest.cpp
+++ b/src/gpu/gl/GrGpuGL_unittest.cpp
@@ -77,7 +77,8 @@
             stageDesc->fOptFlags |= StageDesc::kNoPerspective_OptFlagBit;
             stageDesc->fInConfigFlags &= ~kMulByAlphaMask;
             return SkNEW_ARGS(GrConvolutionEffect,
-                              (gKernelDirections[direction],
+                              (NULL,
+                               gKernelDirections[direction],
                                kernelRadius,
                                kernel));
             }
@@ -88,7 +89,8 @@
             stageDesc->fOptFlags |= StageDesc::kNoPerspective_OptFlagBit;
             stageDesc->fInConfigFlags &= ~kMulByAlphaMask;
             return SkNEW_ARGS(GrMorphologyEffect,
-                              (gKernelDirections[direction],
+                              (NULL,
+                               gKernelDirections[direction],
                                kernelRadius,
                                GrContext::kErode_MorphologyType));
             }
@@ -99,12 +101,13 @@
             stageDesc->fOptFlags |= StageDesc::kNoPerspective_OptFlagBit;
             stageDesc->fInConfigFlags &= ~kMulByAlphaMask;
             return SkNEW_ARGS(GrMorphologyEffect,
-                              (gKernelDirections[direction],
+                              (NULL,
+                               gKernelDirections[direction],
                                kernelRadius,
                                GrContext::kDilate_MorphologyType));
             }
         case kRadialGradient_EffectType: {
-            return SkNEW(GrRadialGradient);
+            return SkNEW_ARGS(GrRadialGradient, (NULL));
             }
         case kRadial2Gradient_EffectType: {
             float center;
@@ -113,10 +116,10 @@
             } while (GR_Scalar1 == center);
             float radius = random->nextF();
             bool root = random_bool(random);
-            return SkNEW_ARGS(GrRadial2Gradient, (center, radius, root));
+            return SkNEW_ARGS(GrRadial2Gradient, (NULL, center, radius, root));
             }
         case kSweepGradient_EffectType: {
-            return SkNEW(GrSweepGradient);
+            return SkNEW_ARGS(GrSweepGradient, (NULL));
             }
         case kDiffuseDistant_EffectType: {
             SkPoint3 direction = random_point3(random);
@@ -127,7 +130,7 @@
             SkAutoTUnref<SkImageFilter> filter(SkLightingImageFilter::CreateDistantLitDiffuse(direction, lightColor, surfaceScale, kd));
             // does not work with perspective or mul-by-alpha-mask
             GrCustomStage* stage;
-            bool ok = filter->asNewCustomStage(&stage);
+            bool ok = filter->asNewCustomStage(&stage, NULL);
             SkASSERT(ok);
             return stage;
         }
@@ -139,7 +142,7 @@
             SkAutoTUnref<SkImageFilter> filter(SkLightingImageFilter::CreatePointLitDiffuse(location, lightColor, surfaceScale, kd));
             // does not work with perspective or mul-by-alpha-mask
             GrCustomStage* stage;
-            bool ok = filter->asNewCustomStage(&stage);
+            bool ok = filter->asNewCustomStage(&stage, NULL);
             SkASSERT(ok);
             return stage;
         }
@@ -156,7 +159,7 @@
                 location, target, specularExponent, cutoffAngle, lightColor, surfaceScale, ks, shininess));
             // does not work with perspective or mul-by-alpha-mask
             GrCustomStage* stage;
-            bool ok = filter->asNewCustomStage(&stage);
+            bool ok = filter->asNewCustomStage(&stage, NULL);
             SkASSERT(ok);
             return stage;
         }
@@ -170,7 +173,7 @@
             SkAutoTUnref<SkImageFilter> filter(SkLightingImageFilter::CreateDistantLitSpecular(direction, lightColor, surfaceScale, ks, shininess));
             // does not work with perspective or mul-by-alpha-mask
             GrCustomStage* stage;
-            bool ok = filter->asNewCustomStage(&stage);
+            bool ok = filter->asNewCustomStage(&stage, NULL);
             SkASSERT(ok);
             return stage;
         }
@@ -183,7 +186,7 @@
             SkAutoTUnref<SkImageFilter> filter(SkLightingImageFilter::CreatePointLitSpecular(location, lightColor, surfaceScale, ks, shininess));
             // does not work with perspective or mul-by-alpha-mask
             GrCustomStage* stage;
-            bool ok = filter->asNewCustomStage(&stage);
+            bool ok = filter->asNewCustomStage(&stage, NULL);
             SkASSERT(ok);
             return stage;
         }
@@ -200,7 +203,7 @@
                 location, target, specularExponent, cutoffAngle, lightColor, surfaceScale, ks, shininess));
             // does not work with perspective or mul-by-alpha-mask
             GrCustomStage* stage;
-            bool ok = filter->asNewCustomStage(&stage);
+            bool ok = filter->asNewCustomStage(&stage, NULL);
             SkASSERT(ok);
             return stage;
         }