When getGLInstance is called on a frag proc, the resulting GrGLFragmentProcessor will be the root of a tree of GrGLFragmentProcessors that mirrors the GrFragmentProcessor's tree. This allows setData() to be called recursively (removing the responsibility from compose shader) and allows gl instances direct access to their children gl instances so they can emit their code.

BUG=skia:4182

Review URL: https://codereview.chromium.org/1287023009
diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp
index fd7e5c3..e55376d 100644
--- a/src/effects/SkAlphaThresholdFilter.cpp
+++ b/src/effects/SkAlphaThresholdFilter.cpp
@@ -81,8 +81,6 @@
     float innerThreshold() const { return fInnerThreshold; }
     float outerThreshold() const { return fOuterThreshold; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
 private:
     AlphaThresholdEffect(GrProcessorDataManager*,
                          GrTexture* texture,
@@ -106,6 +104,8 @@
         this->addTextureAccess(&fMaskTextureAccess);
     }
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
     bool onIsEqual(const GrFragmentProcessor&) const override;
@@ -130,7 +130,8 @@
 
     virtual void emitCode(EmitArgs&) override;
 
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
+protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
 
 private:
 
@@ -186,7 +187,7 @@
                            (GrGLSLExpr4(args.fInputColor) * GrGLSLExpr4("color")).c_str());
 }
 
-void GrGLAlphaThresholdEffect::setData(const GrGLProgramDataManager& pdman,
+void GrGLAlphaThresholdEffect::onSetData(const GrGLProgramDataManager& pdman,
                                        const GrProcessor& proc) {
     const AlphaThresholdEffect& alpha_threshold = proc.cast<AlphaThresholdEffect>();
     pdman.set1f(fInnerThresholdVar, alpha_threshold.innerThreshold());
@@ -213,7 +214,7 @@
     GrGLAlphaThresholdEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* AlphaThresholdEffect::createGLInstance() const {
+GrGLFragmentProcessor* AlphaThresholdEffect::onCreateGLInstance() const {
     return SkNEW_ARGS(GrGLAlphaThresholdEffect, (*this));
 }
 
diff --git a/src/effects/SkArithmeticMode_gpu.cpp b/src/effects/SkArithmeticMode_gpu.cpp
index 08851cb..39814e2 100644
--- a/src/effects/SkArithmeticMode_gpu.cpp
+++ b/src/effects/SkArithmeticMode_gpu.cpp
@@ -77,18 +77,19 @@
                             fEnforcePMColor);
     }
 
-    void setData(const GrGLProgramDataManager& pdman, const GrProcessor& proc) override {
-        const GrArithmeticFP& arith = proc.cast<GrArithmeticFP>();
-        pdman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4());
-        fEnforcePMColor = arith.enforcePMColor();
-    }
-
     static void GenKey(const GrProcessor& proc, const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) {
         const GrArithmeticFP& arith = proc.cast<GrArithmeticFP>();
         uint32_t key = arith.enforcePMColor() ? 1 : 0;
         b->add32(key);
     }
 
+protected:
+    void onSetData(const GrGLProgramDataManager& pdman, const GrProcessor& proc) override {
+        const GrArithmeticFP& arith = proc.cast<GrArithmeticFP>();
+        pdman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4());
+        fEnforcePMColor = arith.enforcePMColor();
+    }
+
 private:
     GrGLProgramDataManager::UniformHandle fKUni;
     bool fEnforcePMColor;
@@ -116,7 +117,7 @@
     GLArithmeticFP::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* GrArithmeticFP::createGLInstance() const {
+GrGLFragmentProcessor* GrArithmeticFP::onCreateGLInstance() const {
     return SkNEW_ARGS(GLArithmeticFP, (*this));
 }
 
diff --git a/src/effects/SkArithmeticMode_gpu.h b/src/effects/SkArithmeticMode_gpu.h
index 36f0f40..4f780cf 100644
--- a/src/effects/SkArithmeticMode_gpu.h
+++ b/src/effects/SkArithmeticMode_gpu.h
@@ -42,8 +42,6 @@
 
     const char* name() const override { return "Arithmetic"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
     float k1() const { return fK1; }
     float k2() const { return fK2; }
     float k3() const { return fK3; }
@@ -51,6 +49,8 @@
     bool enforcePMColor() const { return fEnforcePMColor; }
 
 private:
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
 
     bool onIsEqual(const GrFragmentProcessor&) const override;
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index 18ac484..96789c2 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -611,8 +611,6 @@
 
     const char* name() const override { return "RectBlur"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
     /**
      * Create a simple filter effect with custom bicubic coefficients.
      */
@@ -641,6 +639,8 @@
     float getSigma() const { return fSigma; }
 
 private:
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *blur_profile);
 
     virtual void onGetGLProcessorKey(const GrGLSLCaps& caps,
@@ -667,7 +667,8 @@
     GrGLRectBlurEffect(const GrProcessor&) {}
     virtual void emitCode(EmitArgs&) override;
 
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
+protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
 
 private:
     typedef GrGLProgramDataManager::UniformHandle UniformHandle;
@@ -736,7 +737,7 @@
     fsBuilder->codeAppendf("\t%s = src * final;\n", args.fOutputColor );
 }
 
-void GrGLRectBlurEffect::setData(const GrGLProgramDataManager& pdman,
+void GrGLRectBlurEffect::onSetData(const GrGLProgramDataManager& pdman,
                                  const GrProcessor& proc) {
     const GrRectBlurEffect& rbe = proc.cast<GrRectBlurEffect>();
     SkRect rect = rbe.getRect();
@@ -800,7 +801,7 @@
     GrGLRectBlurEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* GrRectBlurEffect::createGLInstance() const {
+GrGLFragmentProcessor* GrRectBlurEffect::onCreateGLInstance() const {
     return SkNEW_ARGS(GrGLRectBlurEffect, (*this));
 }
 
@@ -880,9 +881,9 @@
     const SkRRect& getRRect() const { return fRRect; }
     float getSigma() const { return fSigma; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
 private:
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     GrRRectBlurEffect(float sigma, const SkRRect&, GrTexture* profileTexture);
 
     virtual void onGetGLProcessorKey(const GrGLSLCaps& caps,
@@ -1014,7 +1015,8 @@
 
     virtual void emitCode(EmitArgs&) override;
 
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
+protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
 
 private:
     GrGLProgramDataManager::UniformHandle fProxyRectUniform;
@@ -1077,7 +1079,7 @@
     fsBuilder->codeAppend(";\n");
 }
 
-void GrGLRRectBlurEffect::setData(const GrGLProgramDataManager& pdman,
+void GrGLRRectBlurEffect::onSetData(const GrGLProgramDataManager& pdman,
                                   const GrProcessor& proc) {
     const GrRRectBlurEffect& brre = proc.cast<GrRRectBlurEffect>();
     SkRRect rrect = brre.getRRect();
@@ -1099,7 +1101,7 @@
     GrGLRRectBlurEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* GrRRectBlurEffect::createGLInstance() const {
+GrGLFragmentProcessor* GrRRectBlurEffect::onCreateGLInstance() const {
     return SkNEW_ARGS(GrGLRRectBlurEffect, (*this));
 }
 
diff --git a/src/effects/SkColorCubeFilter.cpp b/src/effects/SkColorCubeFilter.cpp
index f37b695..fac01bc 100644
--- a/src/effects/SkColorCubeFilter.cpp
+++ b/src/effects/SkColorCubeFilter.cpp
@@ -168,7 +168,6 @@
 
     const char* name() const override { return "ColorCube"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
     int colorCubeSize() const { return fColorCubeAccess.getTexture()->width(); }
 
 
@@ -183,7 +182,8 @@
 
         static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*);
 
-        void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
+    protected:
+        void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
 
     private:
         GrGLProgramDataManager::UniformHandle fColorCubeSizeUni;
@@ -196,6 +196,8 @@
     virtual void onGetGLProcessorKey(const GrGLSLCaps& caps,
                                      GrProcessorKeyBuilder* b) const override;
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
 
     GrColorCubeEffect(GrTexture* colorCube);
@@ -220,7 +222,7 @@
     GLProcessor::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* GrColorCubeEffect::createGLInstance() const {
+GrGLFragmentProcessor* GrColorCubeEffect::onCreateGLInstance() const {
     return SkNEW_ARGS(GLProcessor, (*this));
 }
 
@@ -289,7 +291,7 @@
                            cubeIdx, nonZeroAlpha, args.fInputColor);
 }
 
-void GrColorCubeEffect::GLProcessor::setData(const GrGLProgramDataManager& pdman,
+void GrColorCubeEffect::GLProcessor::onSetData(const GrGLProgramDataManager& pdman,
                                              const GrProcessor& proc) {
     const GrColorCubeEffect& colorCube = proc.cast<GrColorCubeEffect>();
     SkScalar size = SkIntToScalar(colorCube.colorCubeSize());
diff --git a/src/effects/SkColorFilters.cpp b/src/effects/SkColorFilters.cpp
index bda3d9a..af3e38b 100644
--- a/src/effects/SkColorFilters.cpp
+++ b/src/effects/SkColorFilters.cpp
@@ -147,10 +147,6 @@
         return true;
     }
 
-    GrGLFragmentProcessor* createGLInstance() const override {
-        return SkNEW_ARGS(GLProcessor, (*this));
-    }
-
     const char* name() const override { return "ModeColorFilterEffect"; }
 
     SkXfermode::Mode mode() const { return fMode; }
@@ -190,7 +186,8 @@
             b->add32(colorModeFilter.mode());
         }
 
-        virtual void setData(const GrGLProgramDataManager& pdman,
+    protected:
+        virtual void onSetData(const GrGLProgramDataManager& pdman,
                              const GrProcessor& fp) override {
             if (fFilterColorUni.isValid()) {
                 const ModeColorFilterEffect& colorModeFilter = fp.cast<ModeColorFilterEffect>();
@@ -215,6 +212,10 @@
         this->initClassID<ModeColorFilterEffect>();
     }
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override {
+        return SkNEW_ARGS(GLProcessor, (*this));
+    }
+
     virtual void onGetGLProcessorKey(const GrGLSLCaps& caps,
                                      GrProcessorKeyBuilder* b) const override {
         GLProcessor::GenKey(*this, caps, b);
diff --git a/src/effects/SkColorMatrixFilter.cpp b/src/effects/SkColorMatrixFilter.cpp
index 0f90349..5845bc9 100644
--- a/src/effects/SkColorMatrixFilter.cpp
+++ b/src/effects/SkColorMatrixFilter.cpp
@@ -394,11 +394,6 @@
 
     const char* name() const override { return "Color Matrix"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override {
-        return SkNEW_ARGS(GLProcessor, (*this));
-    }
-
-
     GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
     class GLProcessor : public GrGLFragmentProcessor {
@@ -435,7 +430,8 @@
             fsBuilder->codeAppendf("\t%s.rgb *= %s.a;\n", args.fOutputColor, args.fOutputColor);
         }
 
-        virtual void setData(const GrGLProgramDataManager& uniManager,
+    protected:
+        virtual void onSetData(const GrGLProgramDataManager& uniManager,
                              const GrProcessor& proc) override {
             const ColorMatrixEffect& cme = proc.cast<ColorMatrixEffect>();
             const float* m = cme.fMatrix.fMat;
@@ -466,6 +462,10 @@
         this->initClassID<ColorMatrixEffect>();
     }
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override {
+        return SkNEW_ARGS(GLProcessor, (*this));
+    }
+
     virtual void onGetGLProcessorKey(const GrGLSLCaps& caps,
                                      GrProcessorKeyBuilder* b) const override {
         GLProcessor::GenKey(*this, caps, b);
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index c303301..f360fe1 100644
--- a/src/effects/SkDisplacementMapEffect.cpp
+++ b/src/effects/SkDisplacementMapEffect.cpp
@@ -310,9 +310,11 @@
 
     static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*);
 
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
     const GrTextureDomain::GLDomain& glDomain() const { return fGLDomain; }
 
+protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
+
 private:
     SkDisplacementMapEffect::ChannelSelectorType fXChannelSelector;
     SkDisplacementMapEffect::ChannelSelectorType fYChannelSelector;
@@ -344,10 +346,6 @@
 
     virtual ~GrDisplacementMapEffect();
 
-    GrGLFragmentProcessor* createGLInstance() const override {
-        return SkNEW_ARGS(GrGLDisplacementMapEffect, (*this));
-    }
-
     SkDisplacementMapEffect::ChannelSelectorType xChannelSelector() const
         { return fXChannelSelector; }
     SkDisplacementMapEffect::ChannelSelectorType yChannelSelector() const
@@ -358,6 +356,10 @@
     const GrTextureDomain& domain() const { return fDomain; }
 
 private:
+    GrGLFragmentProcessor* onCreateGLInstance() const override {
+        return SkNEW_ARGS(GrGLDisplacementMapEffect, (*this));
+    }
+
     virtual void onGetGLProcessorKey(const GrGLSLCaps& caps,
                                      GrProcessorKeyBuilder* b) const override {
         GrGLDisplacementMapEffect::GenKey(*this, caps, b);
@@ -621,7 +623,7 @@
     fsBuilder->codeAppend(";\n");
 }
 
-void GrGLDisplacementMapEffect::setData(const GrGLProgramDataManager& pdman,
+void GrGLDisplacementMapEffect::onSetData(const GrGLProgramDataManager& pdman,
                                         const GrProcessor& proc) {
     const GrDisplacementMapEffect& displacementMap = proc.cast<GrDisplacementMapEffect>();
     GrTexture* colorTex = displacementMap.texture(1);
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index 0b5e3e8..60904c7 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -533,11 +533,11 @@
 
     const char* name() const override { return "DiffuseLighting"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
     SkScalar kd() const { return fKD; }
 
 private:
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
     bool onIsEqual(const GrFragmentProcessor&) const override;
@@ -577,7 +577,7 @@
 
     const char* name() const override { return "SpecularLighting"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
 
     SkScalar ks() const { return fKS; }
     SkScalar shininess() const { return fShininess; }
@@ -1517,12 +1517,12 @@
 
     static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder* b);
 
-    /**
-     * Subclasses of GrGLLightingEffect must call INHERITED::setData();
-     */
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
-
 protected:
+    /**
+     * Subclasses of GrGLLightingEffect must call INHERITED::onSetData();
+     */
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
+
     virtual void emitLightFunc(GrGLFPBuilder*, SkString* funcName) = 0;
 
 private:
@@ -1540,7 +1540,9 @@
 public:
     GrGLDiffuseLightingEffect(const GrProcessor&);
     void emitLightFunc(GrGLFPBuilder*, SkString* funcName) override;
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
+
+protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
 
 private:
     typedef GrGLLightingEffect INHERITED;
@@ -1554,7 +1556,9 @@
 public:
     GrGLSpecularLightingEffect(const GrProcessor&);
     void emitLightFunc(GrGLFPBuilder*, SkString* funcName) override;
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
+
+protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
 
 private:
     typedef GrGLLightingEffect INHERITED;
@@ -1617,7 +1621,7 @@
     GrGLDiffuseLightingEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* GrDiffuseLightingEffect::createGLInstance() const {
+GrGLFragmentProcessor* GrDiffuseLightingEffect::onCreateGLInstance() const {
     return SkNEW_ARGS(GrGLDiffuseLightingEffect, (*this));
 }
 
@@ -1743,7 +1747,7 @@
     b->add32(lighting.boundaryMode() << 2 | lighting.light()->type());
 }
 
-void GrGLLightingEffect::setData(const GrGLProgramDataManager& pdman,
+void GrGLLightingEffect::onSetData(const GrGLProgramDataManager& pdman,
                                  const GrProcessor& proc) {
     const GrLightingEffect& lighting = proc.cast<GrLightingEffect>();
     GrTexture* texture = lighting.texture(0);
@@ -1784,9 +1788,9 @@
                                                       funcName);
 }
 
-void GrGLDiffuseLightingEffect::setData(const GrGLProgramDataManager& pdman,
+void GrGLDiffuseLightingEffect::onSetData(const GrGLProgramDataManager& pdman,
                                         const GrProcessor& proc) {
-    INHERITED::setData(pdman, proc);
+    INHERITED::onSetData(pdman, proc);
     const GrDiffuseLightingEffect& diffuse = proc.cast<GrDiffuseLightingEffect>();
     pdman.set1f(fKDUni, diffuse.kd());
 }
@@ -1819,7 +1823,7 @@
     GrGLSpecularLightingEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* GrSpecularLightingEffect::createGLInstance() const {
+GrGLFragmentProcessor* GrSpecularLightingEffect::onCreateGLInstance() const {
     return SkNEW_ARGS(GrGLSpecularLightingEffect, (*this));
 }
 
@@ -1876,9 +1880,9 @@
                                                       funcName);
 }
 
-void GrGLSpecularLightingEffect::setData(const GrGLProgramDataManager& pdman,
+void GrGLSpecularLightingEffect::onSetData(const GrGLProgramDataManager& pdman,
                                          const GrProcessor& effect) {
-    INHERITED::setData(pdman, effect);
+    INHERITED::onSetData(pdman, effect);
     const GrSpecularLightingEffect& spec = effect.cast<GrSpecularLightingEffect>();
     pdman.set1f(fKSUni, spec.ks());
     pdman.set1f(fShininessUni, spec.shininess());
diff --git a/src/effects/SkLightingShader.cpp b/src/effects/SkLightingShader.cpp
index 6ed9874..d441d9b 100644
--- a/src/effects/SkLightingShader.cpp
+++ b/src/effects/SkLightingShader.cpp
@@ -185,7 +185,15 @@
             fpb->codeAppendf("%s = vec4(result.rgb, diffuseColor.a);", args.fOutputColor);
         }
 
-        void setData(const GrGLProgramDataManager& pdman, const GrProcessor& proc) override {
+        static void GenKey(const GrProcessor& proc, const GrGLSLCaps&,
+                           GrProcessorKeyBuilder* b) {
+//            const LightingFP& lightingFP = proc.cast<LightingFP>();
+            // only one shader generated currently
+            b->add32(0x0);
+        }
+
+    protected:
+        void onSetData(const GrGLProgramDataManager& pdman, const GrProcessor& proc) override {
             const LightingFP& lightingFP = proc.cast<LightingFP>();
 
             const SkVector3& lightDir = lightingFP.lightDir();
@@ -207,13 +215,6 @@
             }
         }
 
-        static void GenKey(const GrProcessor& proc, const GrGLSLCaps&,
-                           GrProcessorKeyBuilder* b) {
-//            const LightingFP& lightingFP = proc.cast<LightingFP>();
-            // only one shader generated currently
-            b->add32(0x0);
-        }
-
     private:
         SkVector3 fLightDir;
         GrGLProgramDataManager::UniformHandle fLightDirUni;
@@ -225,8 +226,6 @@
         GrGLProgramDataManager::UniformHandle fAmbientColorUni;
     };
 
-    GrGLFragmentProcessor* createGLInstance() const override { return SkNEW(LightingGLFP); }
-
     void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override {
         LightingGLFP::GenKey(*this, caps, b);
     }
@@ -242,6 +241,8 @@
     const SkColor3f& ambientColor() const { return fAmbientColor; }
 
 private:
+    GrGLFragmentProcessor* onCreateGLInstance() const override { return SkNEW(LightingGLFP); }
+
     bool onIsEqual(const GrFragmentProcessor& proc) const override { 
         const LightingFP& lightingFP = proc.cast<LightingFP>();
         return fDeviceTransform == lightingFP.fDeviceTransform &&
diff --git a/src/effects/SkLumaColorFilter.cpp b/src/effects/SkLumaColorFilter.cpp
index 939accf..8d5181a 100644
--- a/src/effects/SkLumaColorFilter.cpp
+++ b/src/effects/SkLumaColorFilter.cpp
@@ -65,10 +65,6 @@
 
     const char* name() const override { return "Luminance-to-Alpha"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override {
-        return SkNEW_ARGS(GLProcessor, (*this));
-    }
-
     class GLProcessor : public GrGLFragmentProcessor {
     public:
         GLProcessor(const GrProcessor&) {}
@@ -100,6 +96,10 @@
         this->initClassID<LumaColorFilterEffect>();
     }
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override {
+        return SkNEW_ARGS(GLProcessor, (*this));
+    }
+
     virtual void onGetGLProcessorKey(const GrGLSLCaps& caps,
                                      GrProcessorKeyBuilder* b) const override {
         GLProcessor::GenKey(*this, caps, b);
diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp
index e0edb4a..baa1926 100644
--- a/src/effects/SkMagnifierImageFilter.cpp
+++ b/src/effects/SkMagnifierImageFilter.cpp
@@ -47,8 +47,6 @@
 
     const char* name() const override { return "Magnifier"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
     const SkRect& bounds() const { return fBounds; }    // Bounds of source image.
     // Offset to apply to zoomed pixels, (srcRect position / texture size).
     float x_offset() const { return fXOffset; }
@@ -83,6 +81,8 @@
         this->initClassID<GrMagnifierEffect>();
     }
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
     bool onIsEqual(const GrFragmentProcessor&) const override;
@@ -111,7 +111,8 @@
 
     virtual void emitCode(EmitArgs&) override;
 
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
+protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
 
 private:
     UniformHandle       fOffsetVar;
@@ -178,7 +179,7 @@
     fsBuilder->codeAppend(modulate.c_str());
 }
 
-void GrGLMagnifierEffect::setData(const GrGLProgramDataManager& pdman,
+void GrGLMagnifierEffect::onSetData(const GrGLProgramDataManager& pdman,
                                   const GrProcessor& effect) {
     const GrMagnifierEffect& zoom = effect.cast<GrMagnifierEffect>();
     pdman.set2f(fOffsetVar, zoom.x_offset(), zoom.y_offset());
@@ -195,7 +196,7 @@
     GrGLMagnifierEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* GrMagnifierEffect::createGLInstance() const {
+GrGLFragmentProcessor* GrMagnifierEffect::onCreateGLInstance() const {
     return SkNEW_ARGS(GrGLMagnifierEffect, (*this));
 }
 
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index 163f9d9..01e978e 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -224,8 +224,6 @@
 
     const char* name() const override { return "Morphology"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
 protected:
 
     MorphologyType fType;
@@ -233,6 +231,8 @@
     float fRange[2];
 
 private:
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
     bool onIsEqual(const GrFragmentProcessor&) const override;
@@ -258,7 +258,8 @@
 
     static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder* b);
 
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
+protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
 
 private:
     int width() const { return GrMorphologyEffect::WidthFromRadius(fRadius); }
@@ -359,7 +360,7 @@
     b->add32(key);
 }
 
-void GrGLMorphologyEffect::setData(const GrGLProgramDataManager& pdman,
+void GrGLMorphologyEffect::onSetData(const GrGLProgramDataManager& pdman,
                                    const GrProcessor& proc) {
     const GrMorphologyEffect& m = proc.cast<GrMorphologyEffect>();
     GrTexture& texture = *m.texture(0);
@@ -423,7 +424,7 @@
     GrGLMorphologyEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* GrMorphologyEffect::createGLInstance() const {
+GrGLFragmentProcessor* GrMorphologyEffect::onCreateGLInstance() const {
     return SkNEW_ARGS(GrGLMorphologyEffect, (*this));
 }
 bool GrMorphologyEffect::onIsEqual(const GrFragmentProcessor& sBase) const {
diff --git a/src/effects/SkPerlinNoiseShader.cpp b/src/effects/SkPerlinNoiseShader.cpp
index 989bdd1..501e636 100644
--- a/src/effects/SkPerlinNoiseShader.cpp
+++ b/src/effects/SkPerlinNoiseShader.cpp
@@ -489,10 +489,11 @@
 
     virtual void emitCode(EmitArgs&) override;
 
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
-
     static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder* b);
 
+protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
+
 private:
 
     GrGLProgramDataManager::UniformHandle fStitchDataUni;
@@ -527,10 +528,6 @@
 
     const char* name() const override { return "PerlinNoise"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override {
-        return SkNEW_ARGS(GrGLPerlinNoise, (*this));
-    }
-
     const SkPerlinNoiseShader::StitchData& stitchData() const { return fPaintingData->fStitchDataInit; }
 
     SkPerlinNoiseShader::Type type() const { return fType; }
@@ -541,6 +538,10 @@
     uint8_t alpha() const { return fAlpha; }
 
 private:
+    GrGLFragmentProcessor* onCreateGLInstance() const override {
+        return SkNEW_ARGS(GrGLPerlinNoise, (*this));
+    }
+
     virtual void onGetGLProcessorKey(const GrGLSLCaps& caps,
                                      GrProcessorKeyBuilder* b) const override {
         GrGLPerlinNoise::GenKey(*this, caps, b);
@@ -916,8 +917,8 @@
     b->add32(key);
 }
 
-void GrGLPerlinNoise::setData(const GrGLProgramDataManager& pdman, const GrProcessor& processor) {
-    INHERITED::setData(pdman, processor);
+void GrGLPerlinNoise::onSetData(const GrGLProgramDataManager& pdman, const GrProcessor& processor) {
+    INHERITED::onSetData(pdman, processor);
 
     const GrPerlinNoiseEffect& turbulence = processor.cast<GrPerlinNoiseEffect>();
 
diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp
index d743372..f39e88a 100644
--- a/src/effects/SkTableColorFilter.cpp
+++ b/src/effects/SkTableColorFilter.cpp
@@ -348,12 +348,12 @@
 
     const char* name() const override { return "ColorTable"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
     const GrTextureStripAtlas* atlas() const { return fAtlas; }
     int atlasRow() const { return fRow; }
 
 private:
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
     bool onIsEqual(const GrFragmentProcessor&) const override;
@@ -381,10 +381,11 @@
 
     virtual void emitCode(EmitArgs&) override;
 
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
-
     static void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder* b) {}
 
+protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
+
 private:
     UniformHandle fRGBAYValuesUni;
     typedef GrGLFragmentProcessor INHERITED;
@@ -393,7 +394,7 @@
 GLColorTableEffect::GLColorTableEffect(const GrProcessor&) {
 }
 
-void GLColorTableEffect::setData(const GrGLProgramDataManager& pdm, const GrProcessor& proc) {
+void GLColorTableEffect::onSetData(const GrGLProgramDataManager& pdm, const GrProcessor& proc) {
     // The textures are organized in a strip where the rows are ordered a, r, g, b.
     float rgbaYValues[4];
     const ColorTableEffect& cte = proc.cast<ColorTableEffect>();
@@ -505,7 +506,7 @@
     GLColorTableEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* ColorTableEffect::createGLInstance() const {
+GrGLFragmentProcessor* ColorTableEffect::onCreateGLInstance() const {
     return SkNEW_ARGS(GLColorTableEffect, (*this));
 }
 
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index 763cef5..ebfa75f 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -940,7 +940,7 @@
                    a);
 }
 
-void GrGLGradientEffect::setData(const GrGLProgramDataManager& pdman,
+void GrGLGradientEffect::onSetData(const GrGLProgramDataManager& pdman,
                                  const GrProcessor& processor) {
 
     const GrGradientEffect& e = processor.cast<GrGradientEffect>();
diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h
index 9bd66da..642c95f 100644
--- a/src/effects/gradients/SkGradientShaderPriv.h
+++ b/src/effects/gradients/SkGradientShaderPriv.h
@@ -399,7 +399,8 @@
     GrGLGradientEffect();
     virtual ~GrGLGradientEffect();
 
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
+protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
 
 protected:
     /**
diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp
index 7ca1b60..fb0aa98 100644
--- a/src/effects/gradients/SkLinearGradient.cpp
+++ b/src/effects/gradients/SkLinearGradient.cpp
@@ -495,10 +495,6 @@
 
     const char* name() const override { return "Linear Gradient"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override {
-        return SkNEW_ARGS(GrGLLinearGradient, (*this));
-    }
-
 private:
     GrLinearGradient(GrContext* ctx,
                      GrProcessorDataManager* procDataManager,
@@ -509,6 +505,10 @@
         this->initClassID<GrLinearGradient>();
     }
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override {
+        return SkNEW_ARGS(GrGLLinearGradient, (*this));
+    }
+
     virtual void onGetGLProcessorKey(const GrGLSLCaps& caps,
                                      GrProcessorKeyBuilder* b) const override {
         GrGLLinearGradient::GenKey(*this, caps, b);
diff --git a/src/effects/gradients/SkRadialGradient.cpp b/src/effects/gradients/SkRadialGradient.cpp
index 4f97e26..4ff635a 100644
--- a/src/effects/gradients/SkRadialGradient.cpp
+++ b/src/effects/gradients/SkRadialGradient.cpp
@@ -468,10 +468,6 @@
 
     const char* name() const override { return "Radial Gradient"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override {
-        return SkNEW_ARGS(GrGLRadialGradient, (*this));
-    }
-
 private:
     GrRadialGradient(GrContext* ctx,
                      GrProcessorDataManager* procDataManager,
@@ -482,6 +478,10 @@
         this->initClassID<GrRadialGradient>();
     }
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override {
+        return SkNEW_ARGS(GrGLRadialGradient, (*this));
+    }
+
     virtual void onGetGLProcessorKey(const GrGLSLCaps& caps,
                                      GrProcessorKeyBuilder* b) const override {
         GrGLRadialGradient::GenKey(*this, caps, b);
diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp
index 4936d31..1881690 100644
--- a/src/effects/gradients/SkSweepGradient.cpp
+++ b/src/effects/gradients/SkSweepGradient.cpp
@@ -214,10 +214,6 @@
 
     const char* name() const override { return "Sweep Gradient"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override {
-        return SkNEW_ARGS(GrGLSweepGradient, (*this));
-    }
-
 private:
     GrSweepGradient(GrContext* ctx,
                     GrProcessorDataManager* procDataManager,
@@ -227,6 +223,10 @@
         this->initClassID<GrSweepGradient>();
     }
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override {
+        return SkNEW_ARGS(GrGLSweepGradient, (*this));
+    }
+
     virtual void onGetGLProcessorKey(const GrGLSLCaps& caps,
                                      GrProcessorKeyBuilder* b) const override {
         GrGLSweepGradient::GenKey(*this, caps, b);
diff --git a/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp b/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp
index ffa60c8..6f60482 100644
--- a/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp
+++ b/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp
@@ -72,14 +72,14 @@
         return "Two-Point Conical Gradient Edge Touching";
     }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
     // The radial gradient parameters can collapse to a linear (instead of quadratic) equation.
     SkScalar center() const { return fCenterX1; }
     SkScalar diffRadius() const { return fDiffRadius; }
     SkScalar radius() const { return fRadius0; }
 
 private:
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
     bool onIsEqual(const GrFragmentProcessor& sBase) const override {
@@ -145,11 +145,12 @@
     virtual ~GLEdge2PtConicalEffect() { }
 
     virtual void emitCode(EmitArgs&) override;
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
 
     static void GenKey(const GrProcessor&, const GrGLSLCaps& caps, GrProcessorKeyBuilder* b);
 
 protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
+
     UniformHandle fParamUni;
 
     const char* fVSVaryingName;
@@ -173,7 +174,7 @@
     GLEdge2PtConicalEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* Edge2PtConicalEffect::createGLInstance() const {
+GrGLFragmentProcessor* Edge2PtConicalEffect::onCreateGLInstance() const {
     return SkNEW_ARGS(GLEdge2PtConicalEffect, (*this));
 }
 
@@ -277,9 +278,9 @@
     fsBuilder->codeAppend("\t}\n");
 }
 
-void GLEdge2PtConicalEffect::setData(const GrGLProgramDataManager& pdman,
+void GLEdge2PtConicalEffect::onSetData(const GrGLProgramDataManager& pdman,
                                      const GrProcessor& processor) {
-    INHERITED::setData(pdman, processor);
+    INHERITED::onSetData(pdman, processor);
     const Edge2PtConicalEffect& data = processor.cast<Edge2PtConicalEffect>();
     SkScalar radius0 = data.radius();
     SkScalar diffRadius = data.diffRadius();
@@ -385,12 +386,12 @@
         return "Two-Point Conical Gradient Focal Outside";
     }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
     bool isFlipped() const { return fIsFlipped; }
     SkScalar focal() const { return fFocalX; }
 
 private:
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
     bool onIsEqual(const GrFragmentProcessor& sBase) const override {
@@ -426,11 +427,12 @@
     virtual ~GLFocalOutside2PtConicalEffect() { }
 
     virtual void emitCode(EmitArgs&) override;
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
 
     static void GenKey(const GrProcessor&, const GrGLSLCaps& caps, GrProcessorKeyBuilder* b);
 
 protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
+
     UniformHandle fParamUni;
 
     const char* fVSVaryingName;
@@ -455,7 +457,7 @@
     GLFocalOutside2PtConicalEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* FocalOutside2PtConicalEffect::createGLInstance() const {
+GrGLFragmentProcessor* FocalOutside2PtConicalEffect::onCreateGLInstance() const {
     return SkNEW_ARGS(GLFocalOutside2PtConicalEffect, (*this));
 }
 
@@ -551,9 +553,9 @@
     fsBuilder->codeAppend("\t}\n");
 }
 
-void GLFocalOutside2PtConicalEffect::setData(const GrGLProgramDataManager& pdman,
+void GLFocalOutside2PtConicalEffect::onSetData(const GrGLProgramDataManager& pdman,
                                              const GrProcessor& processor) {
-    INHERITED::setData(pdman, processor);
+    INHERITED::onSetData(pdman, processor);
     const FocalOutside2PtConicalEffect& data = processor.cast<FocalOutside2PtConicalEffect>();
     SkASSERT(data.isFlipped() == fIsFlipped);
     SkScalar focal = data.focal();
@@ -601,13 +603,13 @@
         return "Two-Point Conical Gradient Focal Inside";
     }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
     SkScalar focal() const { return fFocalX; }
 
     typedef GLFocalInside2PtConicalEffect GLProcessor;
 
 private:
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
     bool onIsEqual(const GrFragmentProcessor& sBase) const override {
@@ -639,11 +641,12 @@
     virtual ~GLFocalInside2PtConicalEffect() {}
 
     virtual void emitCode(EmitArgs&) override;
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
 
     static void GenKey(const GrProcessor&, const GrGLSLCaps& caps, GrProcessorKeyBuilder* b);
 
 protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
+
     UniformHandle fFocalUni;
 
     const char* fVSVaryingName;
@@ -666,7 +669,7 @@
     GLFocalInside2PtConicalEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* FocalInside2PtConicalEffect::createGLInstance() const {
+GrGLFragmentProcessor* FocalInside2PtConicalEffect::onCreateGLInstance() const {
     return SkNEW_ARGS(GLFocalInside2PtConicalEffect, (*this));
 }
 
@@ -739,9 +742,9 @@
                     args.fSamplers);
 }
 
-void GLFocalInside2PtConicalEffect::setData(const GrGLProgramDataManager& pdman,
+void GLFocalInside2PtConicalEffect::onSetData(const GrGLProgramDataManager& pdman,
                                             const GrProcessor& processor) {
-    INHERITED::setData(pdman, processor);
+    INHERITED::onSetData(pdman, processor);
     const FocalInside2PtConicalEffect& data = processor.cast<FocalInside2PtConicalEffect>();
     SkScalar focal = data.focal();
 
@@ -837,8 +840,6 @@
 
     const char* name() const override { return "Two-Point Conical Gradient Inside"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
     SkScalar centerX() const { return fInfo.fCenterEnd.fX; }
     SkScalar centerY() const { return fInfo.fCenterEnd.fY; }
     SkScalar A() const { return fInfo.fA; }
@@ -846,6 +847,8 @@
     SkScalar C() const { return fInfo.fC; }
 
 private:
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     virtual void onGetGLProcessorKey(const GrGLSLCaps& caps,
                                      GrProcessorKeyBuilder* b) const override;
 
@@ -881,11 +884,12 @@
     virtual ~GLCircleInside2PtConicalEffect() {}
 
     virtual void emitCode(EmitArgs&) override;
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
 
     static void GenKey(const GrProcessor&, const GrGLSLCaps& caps, GrProcessorKeyBuilder* b);
 
 protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
+
     UniformHandle fCenterUni;
     UniformHandle fParamUni;
 
@@ -913,7 +917,7 @@
     GLCircleInside2PtConicalEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* CircleInside2PtConicalEffect::createGLInstance() const {
+GrGLFragmentProcessor* CircleInside2PtConicalEffect::onCreateGLInstance() const {
     return SkNEW_ARGS(GLCircleInside2PtConicalEffect, (*this));
 }
 
@@ -1005,9 +1009,9 @@
                     args.fSamplers);
 }
 
-void GLCircleInside2PtConicalEffect::setData(const GrGLProgramDataManager& pdman,
+void GLCircleInside2PtConicalEffect::onSetData(const GrGLProgramDataManager& pdman,
                                              const GrProcessor& processor) {
-    INHERITED::setData(pdman, processor);
+    INHERITED::onSetData(pdman, processor);
     const CircleInside2PtConicalEffect& data = processor.cast<CircleInside2PtConicalEffect>();
     SkScalar centerX = data.centerX();
     SkScalar centerY = data.centerY();
@@ -1053,8 +1057,6 @@
 
     const char* name() const override { return "Two-Point Conical Gradient Outside"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
     SkScalar centerX() const { return fInfo.fCenterEnd.fX; }
     SkScalar centerY() const { return fInfo.fCenterEnd.fY; }
     SkScalar A() const { return fInfo.fA; }
@@ -1064,6 +1066,8 @@
     bool isFlipped() const { return fIsFlipped; }
 
 private:
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
     bool onIsEqual(const GrFragmentProcessor& sBase) const override {
@@ -1109,11 +1113,12 @@
     virtual ~GLCircleOutside2PtConicalEffect() {}
 
     virtual void emitCode(EmitArgs&) override;
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
 
     static void GenKey(const GrProcessor&, const GrGLSLCaps& caps, GrProcessorKeyBuilder* b);
 
 protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
+
     UniformHandle fCenterUni;
     UniformHandle fParamUni;
 
@@ -1144,7 +1149,7 @@
     GLCircleOutside2PtConicalEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* CircleOutside2PtConicalEffect::createGLInstance() const {
+GrGLFragmentProcessor* CircleOutside2PtConicalEffect::onCreateGLInstance() const {
     return SkNEW_ARGS(GLCircleOutside2PtConicalEffect, (*this));
 }
 
@@ -1256,9 +1261,9 @@
     fsBuilder->codeAppend("\t}\n");
 }
 
-void GLCircleOutside2PtConicalEffect::setData(const GrGLProgramDataManager& pdman,
+void GLCircleOutside2PtConicalEffect::onSetData(const GrGLProgramDataManager& pdman,
                                               const GrProcessor& processor) {
-    INHERITED::setData(pdman, processor);
+    INHERITED::onSetData(pdman, processor);
     const CircleOutside2PtConicalEffect& data = processor.cast<CircleOutside2PtConicalEffect>();
     SkASSERT(data.isFlipped() == fIsFlipped);
     SkScalar centerX = data.centerX();
diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp
index 3090d0f..0eaab75 100644
--- a/src/gpu/GrProcessor.cpp
+++ b/src/gpu/GrProcessor.cpp
@@ -13,6 +13,7 @@
 #include "GrMemoryPool.h"
 #include "GrXferProcessor.h"
 #include "SkSpinlock.h"
+#include "gl/GrGLFragmentProcessor.h"
 
 #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
 
@@ -156,6 +157,15 @@
     return true;
 }
 
+GrGLFragmentProcessor* GrFragmentProcessor::createGLInstance() const {
+    GrGLFragmentProcessor* glFragProc = this->onCreateGLInstance();
+    glFragProc->fChildProcessors.push_back_n(fChildProcessors.count());
+    for (int i = 0; i < fChildProcessors.count(); ++i) {
+        glFragProc->fChildProcessors[i] = fChildProcessors[i].processor()->createGLInstance();
+    }
+    return glFragProc;
+}
+
 void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
     fCoordTransforms.push_back(transform);
     fUsesLocalCoords = fUsesLocalCoords || transform->sourceCoords() == kLocal_GrCoordSet;
diff --git a/src/gpu/effects/GrBicubicEffect.cpp b/src/gpu/effects/GrBicubicEffect.cpp
index d5cf039..e3b959d 100644
--- a/src/gpu/effects/GrBicubicEffect.cpp
+++ b/src/gpu/effects/GrBicubicEffect.cpp
@@ -25,14 +25,15 @@
 
     virtual void emitCode(EmitArgs&) override;
 
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
-
     static inline void GenKey(const GrProcessor& effect, const GrGLSLCaps&,
                               GrProcessorKeyBuilder* b) {
         const GrTextureDomain& domain = effect.cast<GrBicubicEffect>().domain();
         b->add32(GrTextureDomain::GLDomain::DomainKey(domain));
     }
 
+protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
+
 private:
     typedef GrGLProgramDataManager::UniformHandle UniformHandle;
 
@@ -104,7 +105,7 @@
                            GrGLSLExpr4(args.fInputColor)).c_str());
 }
 
-void GrGLBicubicEffect::setData(const GrGLProgramDataManager& pdman,
+void GrGLBicubicEffect::onSetData(const GrGLProgramDataManager& pdman,
                                 const GrProcessor& processor) {
     const GrBicubicEffect& bicubicEffect = processor.cast<GrBicubicEffect>();
     const GrTexture& texture = *processor.texture(0);
@@ -157,7 +158,7 @@
     GrGLBicubicEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* GrBicubicEffect::createGLInstance() const  {
+GrGLFragmentProcessor* GrBicubicEffect::onCreateGLInstance() const  {
     return SkNEW_ARGS(GrGLBicubicEffect, (*this));
 }
 
diff --git a/src/gpu/effects/GrBicubicEffect.h b/src/gpu/effects/GrBicubicEffect.h
index 810e443..f95b3f9 100644
--- a/src/gpu/effects/GrBicubicEffect.h
+++ b/src/gpu/effects/GrBicubicEffect.h
@@ -27,8 +27,6 @@
 
     const char* name() const override { return "Bicubic"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
     const GrTextureDomain& domain() const { return fDomain; }
 
     /**
@@ -93,6 +91,8 @@
     GrBicubicEffect(GrProcessorDataManager*, GrTexture*, const SkScalar coefficients[16],
                     const SkMatrix &matrix, const SkRect& domain);
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
     bool onIsEqual(const GrFragmentProcessor&) const override;
diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp
index c99351d..4c8813d 100644
--- a/src/gpu/effects/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/GrConfigConversionEffect.cpp
@@ -151,7 +151,7 @@
     GrGLConfigConversionEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* GrConfigConversionEffect::createGLInstance() const {
+GrGLFragmentProcessor* GrConfigConversionEffect::onCreateGLInstance() const {
     return SkNEW_ARGS(GrGLConfigConversionEffect, (*this));
 }
 
diff --git a/src/gpu/effects/GrConfigConversionEffect.h b/src/gpu/effects/GrConfigConversionEffect.h
index ba21c16..fc92a04 100644
--- a/src/gpu/effects/GrConfigConversionEffect.h
+++ b/src/gpu/effects/GrConfigConversionEffect.h
@@ -38,8 +38,6 @@
 
     const char* name() const override { return "Config Conversion"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
     bool swapsRedAndBlue() const { return fSwapRedAndBlue; }
     PMConversion  pmConversion() const { return fPMConversion; }
 
@@ -59,6 +57,8 @@
                              PMConversion pmConversion,
                              const SkMatrix& matrix);
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
     bool onIsEqual(const GrFragmentProcessor&) const override;
diff --git a/src/gpu/effects/GrConstColorProcessor.cpp b/src/gpu/effects/GrConstColorProcessor.cpp
index a909104..88bd82b 100644
--- a/src/gpu/effects/GrConstColorProcessor.cpp
+++ b/src/gpu/effects/GrConstColorProcessor.cpp
@@ -34,7 +34,8 @@
         }
     }
 
-    void setData(const GrGLProgramDataManager& pdm, const GrProcessor& processor) override {
+protected:
+    void onSetData(const GrGLProgramDataManager& pdm, const GrProcessor& processor) override {
         GrColor color = processor.cast<GrConstColorProcessor>().color();
         // We use the "illegal" color value as an uninit sentinel. However, ut isn't inherently
         // illegal to use this processor with unpremul colors. So we correctly handle the case
@@ -89,7 +90,7 @@
     b->add32(fMode);
 }
 
-GrGLFragmentProcessor* GrConstColorProcessor::createGLInstance() const  {
+GrGLFragmentProcessor* GrConstColorProcessor::onCreateGLInstance() const  {
     return SkNEW(GLConstColorProcessor);
 }
 
diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp
index 9c73e47..6c47768 100644
--- a/src/gpu/effects/GrConvexPolyEffect.cpp
+++ b/src/gpu/effects/GrConvexPolyEffect.cpp
@@ -26,8 +26,6 @@
 
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
 private:
     AARectEffect(GrPrimitiveEdgeType edgeType, const SkRect& rect)
         : fRect(rect), fEdgeType(edgeType) {
@@ -35,6 +33,8 @@
         this->setWillReadFragmentPosition();
     }
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     bool onIsEqual(const GrFragmentProcessor& other) const override {
         const AARectEffect& aare = other.cast<AARectEffect>();
         return fRect == aare.fRect;
@@ -85,7 +85,8 @@
 
     static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*);
 
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
+protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
 
 private:
     GrGLProgramDataManager::UniformHandle fRectUniform;
@@ -136,7 +137,7 @@
                            (GrGLSLExpr4(args.fInputColor) * GrGLSLExpr1("alpha")).c_str());
 }
 
-void GLAARectEffect::setData(const GrGLProgramDataManager& pdman, const GrProcessor& processor) {
+void GLAARectEffect::onSetData(const GrGLProgramDataManager& pdman, const GrProcessor& processor) {
     const AARectEffect& aare = processor.cast<AARectEffect>();
     const SkRect& rect = aare.getRect();
     if (rect != fPrevRect) {
@@ -156,7 +157,7 @@
     GLAARectEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* AARectEffect::createGLInstance() const  {
+GrGLFragmentProcessor* AARectEffect::onCreateGLInstance() const  {
     return SkNEW_ARGS(GLAARectEffect, (*this));
 }
 
@@ -170,7 +171,8 @@
 
     static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*);
 
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
+protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
 
 private:
     GrGLProgramDataManager::UniformHandle fEdgeUniform;
@@ -219,7 +221,7 @@
                            (GrGLSLExpr4(args.fInputColor) * GrGLSLExpr1("alpha")).c_str());
 }
 
-void GrGLConvexPolyEffect::setData(const GrGLProgramDataManager& pdman, const GrProcessor& effect) {
+void GrGLConvexPolyEffect::onSetData(const GrGLProgramDataManager& pdman, const GrProcessor& effect) {
     const GrConvexPolyEffect& cpe = effect.cast<GrConvexPolyEffect>();
     size_t byteSize = 3 * cpe.getEdgeCount() * sizeof(SkScalar);
     if (0 != memcmp(fPrevEdges, cpe.getEdges(), byteSize)) {
@@ -307,7 +309,7 @@
     GrGLConvexPolyEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* GrConvexPolyEffect::createGLInstance() const  {
+GrGLFragmentProcessor* GrConvexPolyEffect::onCreateGLInstance() const  {
     return SkNEW_ARGS(GrGLConvexPolyEffect, (*this));
 }
 
diff --git a/src/gpu/effects/GrConvexPolyEffect.h b/src/gpu/effects/GrConvexPolyEffect.h
index d18ed51..ead7fe4 100644
--- a/src/gpu/effects/GrConvexPolyEffect.h
+++ b/src/gpu/effects/GrConvexPolyEffect.h
@@ -69,11 +69,11 @@
 
     const SkScalar* getEdges() const { return fEdges; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
 private:
     GrConvexPolyEffect(GrPrimitiveEdgeType edgeType, int n, const SkScalar edges[]);
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
     bool onIsEqual(const GrFragmentProcessor& other) const override;
diff --git a/src/gpu/effects/GrConvolutionEffect.cpp b/src/gpu/effects/GrConvolutionEffect.cpp
index f99afc8..3ab9efb 100644
--- a/src/gpu/effects/GrConvolutionEffect.cpp
+++ b/src/gpu/effects/GrConvolutionEffect.cpp
@@ -19,10 +19,11 @@
 
     virtual void emitCode(EmitArgs&) override;
 
-    void setData(const GrGLProgramDataManager& pdman, const GrProcessor&) override;
-
     static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*);
 
+protected:
+    void onSetData(const GrGLProgramDataManager& pdman, const GrProcessor&) override;
+
 private:
     int width() const { return Gr1DKernelEffect::WidthFromRadius(fRadius); }
     bool useBounds() const { return fUseBounds; }
@@ -99,7 +100,7 @@
     fsBuilder->codeAppend(modulate.c_str());
 }
 
-void GrGLConvolutionEffect::setData(const GrGLProgramDataManager& pdman,
+void GrGLConvolutionEffect::onSetData(const GrGLProgramDataManager& pdman,
                                     const GrProcessor& processor) {
     const GrConvolutionEffect& conv = processor.cast<GrConvolutionEffect>();
     GrTexture& texture = *conv.texture(0);
@@ -199,7 +200,7 @@
     GrGLConvolutionEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* GrConvolutionEffect::createGLInstance() const  {
+GrGLFragmentProcessor* GrConvolutionEffect::onCreateGLInstance() const  {
     return SkNEW_ARGS(GrGLConvolutionEffect, (*this));
 }
 
diff --git a/src/gpu/effects/GrConvolutionEffect.h b/src/gpu/effects/GrConvolutionEffect.h
index e65c4c4..37faa08 100644
--- a/src/gpu/effects/GrConvolutionEffect.h
+++ b/src/gpu/effects/GrConvolutionEffect.h
@@ -63,8 +63,6 @@
 
     const char* name() const override { return "Convolution"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
     enum {
         // This was decided based on the min allowed value for the max texture
         // samples per fragment program run in DX9SM2 (32). A sigma param of 4.0
@@ -98,6 +96,8 @@
                         bool useBounds,
                         float bounds[2]);
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
     bool onIsEqual(const GrFragmentProcessor&) const override;
diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp
index e7023ca..761e177 100644
--- a/src/gpu/effects/GrCustomXfermode.cpp
+++ b/src/gpu/effects/GrCustomXfermode.cpp
@@ -459,8 +459,6 @@
         emit_custom_xfermode_code(mode, fsBuilder, args.fOutputColor, args.fInputColor, dstColor);
     }
 
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override {}
-
     static void GenKey(const GrFragmentProcessor& proc, const GrGLSLCaps&, GrProcessorKeyBuilder* b) {
         // The background may come from the dst or from a texture.
         uint32_t key = proc.numTextures();
@@ -469,6 +467,9 @@
         b->add32(key);
     }
 
+protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override {}
+
 private:
     typedef GrGLFragmentProcessor INHERITED;
 };
@@ -491,7 +492,7 @@
     GLCustomXferFP::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* GrCustomXferFP::createGLInstance() const {
+GrGLFragmentProcessor* GrCustomXferFP::onCreateGLInstance() const {
     return SkNEW_ARGS(GLCustomXferFP, (*this));
 }
 
@@ -625,7 +626,7 @@
 
     void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) override {}
 
-    typedef GrGLFragmentProcessor INHERITED;
+    typedef GrGLXferProcessor INHERITED;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/effects/GrCustomXfermodePriv.h b/src/gpu/effects/GrCustomXfermodePriv.h
index 2a4006b..05e07b6 100644
--- a/src/gpu/effects/GrCustomXfermodePriv.h
+++ b/src/gpu/effects/GrCustomXfermodePriv.h
@@ -29,14 +29,14 @@
 public:
     GrCustomXferFP(GrProcessorDataManager*, SkXfermode::Mode mode, GrTexture* background);
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
     const char* name() const override { return "Custom Xfermode"; }
 
     SkXfermode::Mode mode() const { return fMode; }
     const GrTextureAccess&  backgroundAccess() const { return fBackgroundAccess; }
 
 private:
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
 
     bool onIsEqual(const GrFragmentProcessor& other) const override; 
diff --git a/src/gpu/effects/GrDitherEffect.cpp b/src/gpu/effects/GrDitherEffect.cpp
index 6d39450..2b10ac0 100644
--- a/src/gpu/effects/GrDitherEffect.cpp
+++ b/src/gpu/effects/GrDitherEffect.cpp
@@ -25,14 +25,14 @@
 
     const char* name() const override { return "Dither"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
 private:
     DitherEffect() {
         this->initClassID<DitherEffect>();
         this->setWillReadFragmentPosition();
     }
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
     // All dither effects are equal
@@ -97,7 +97,7 @@
     GLDitherEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* DitherEffect::createGLInstance() const  {
+GrGLFragmentProcessor* DitherEffect::onCreateGLInstance() const  {
     return SkNEW_ARGS(GLDitherEffect, (*this));
 }
 
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.cpp b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
index 625a3e9..3da4c54 100644
--- a/src/gpu/effects/GrMatrixConvolutionEffect.cpp
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
@@ -16,7 +16,8 @@
 
     static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*);
 
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
+protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
 
 private:
     typedef GrGLProgramDataManager::UniformHandle UniformHandle;
@@ -110,7 +111,7 @@
     b->add32(GrTextureDomain::GLDomain::DomainKey(m.domain()));
 }
 
-void GrGLMatrixConvolutionEffect::setData(const GrGLProgramDataManager& pdman,
+void GrGLMatrixConvolutionEffect::onSetData(const GrGLProgramDataManager& pdman,
                                           const GrProcessor& processor) {
     const GrMatrixConvolutionEffect& conv = processor.cast<GrMatrixConvolutionEffect>();
     GrTexture& texture = *conv.texture(0);
@@ -160,7 +161,7 @@
     GrGLMatrixConvolutionEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* GrMatrixConvolutionEffect::createGLInstance() const  {
+GrGLFragmentProcessor* GrMatrixConvolutionEffect::onCreateGLInstance() const  {
     return SkNEW_ARGS(GrGLMatrixConvolutionEffect, (*this));
 }
 
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.h b/src/gpu/effects/GrMatrixConvolutionEffect.h
index ff0a51e..f3d6b24 100644
--- a/src/gpu/effects/GrMatrixConvolutionEffect.h
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.h
@@ -65,8 +65,6 @@
 
     const char* name() const override { return "MatrixConvolution"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
 private:
     GrMatrixConvolutionEffect(GrProcessorDataManager*,
                               GrTexture*,
@@ -79,6 +77,8 @@
                               GrTextureDomain::Mode tileMode,
                               bool convolveAlpha);
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
     bool onIsEqual(const GrFragmentProcessor&) const override;
diff --git a/src/gpu/effects/GrOvalEffect.cpp b/src/gpu/effects/GrOvalEffect.cpp
index 1fb54ae..3fb7b90 100644
--- a/src/gpu/effects/GrOvalEffect.cpp
+++ b/src/gpu/effects/GrOvalEffect.cpp
@@ -23,8 +23,6 @@
 
     const char* name() const override { return "Circle"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
     const SkPoint& getCenter() const { return fCenter; }
     SkScalar getRadius() const { return fRadius; }
 
@@ -33,6 +31,8 @@
 private:
     CircleEffect(GrPrimitiveEdgeType, const SkPoint& center, SkScalar radius);
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
     bool onIsEqual(const GrFragmentProcessor&) const override;
@@ -97,7 +97,8 @@
 
     static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*);
 
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
+protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
 
 private:
     GrGLProgramDataManager::UniformHandle fCircleUniform;
@@ -152,7 +153,7 @@
     b->add32(ce.getEdgeType());
 }
 
-void GLCircleEffect::setData(const GrGLProgramDataManager& pdman, const GrProcessor& processor) {
+void GLCircleEffect::onSetData(const GrGLProgramDataManager& pdman, const GrProcessor& processor) {
     const CircleEffect& ce = processor.cast<CircleEffect>();
     if (ce.getRadius() != fPrevRadius || ce.getCenter() != fPrevCenter) {
         SkScalar radius = ce.getRadius();
@@ -175,7 +176,7 @@
     GLCircleEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* CircleEffect::createGLInstance() const  {
+GrGLFragmentProcessor* CircleEffect::onCreateGLInstance() const  {
     return SkNEW_ARGS(GLCircleEffect, (*this));
 }
 
@@ -190,8 +191,6 @@
 
     const char* name() const override { return "Ellipse"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
     const SkPoint& getCenter() const { return fCenter; }
     SkVector getRadii() const { return fRadii; }
 
@@ -200,6 +199,8 @@
 private:
     EllipseEffect(GrPrimitiveEdgeType, const SkPoint& center, SkScalar rx, SkScalar ry);
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
     bool onIsEqual(const GrFragmentProcessor&) const override;
@@ -267,7 +268,8 @@
 
     static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*);
 
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
+protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
 
 private:
     GrGLProgramDataManager::UniformHandle fEllipseUniform;
@@ -332,7 +334,7 @@
     b->add32(ee.getEdgeType());
 }
 
-void GLEllipseEffect::setData(const GrGLProgramDataManager& pdman, const GrProcessor& effect) {
+void GLEllipseEffect::onSetData(const GrGLProgramDataManager& pdman, const GrProcessor& effect) {
     const EllipseEffect& ee = effect.cast<EllipseEffect>();
     if (ee.getRadii() != fPrevRadii || ee.getCenter() != fPrevCenter) {
         SkScalar invRXSqd = 1.f / (ee.getRadii().fX * ee.getRadii().fX);
@@ -350,7 +352,7 @@
     GLEllipseEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* EllipseEffect::createGLInstance() const  {
+GrGLFragmentProcessor* EllipseEffect::onCreateGLInstance() const  {
     return SkNEW_ARGS(GLEllipseEffect, (*this));
 }
 
diff --git a/src/gpu/effects/GrRRectEffect.cpp b/src/gpu/effects/GrRRectEffect.cpp
index 271a997..519d72c 100644
--- a/src/gpu/effects/GrRRectEffect.cpp
+++ b/src/gpu/effects/GrRRectEffect.cpp
@@ -49,8 +49,6 @@
 
     const char* name() const override { return "CircularRRect"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
     const SkRRect& getRRect() const { return fRRect; }
 
     uint32_t getCircularCornerFlags() const { return fCircularCornerFlags; }
@@ -60,6 +58,8 @@
 private:
     CircularRRectEffect(GrPrimitiveEdgeType, uint32_t circularCornerFlags, const SkRRect&);
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
     bool onIsEqual(const GrFragmentProcessor& other) const override;
@@ -132,7 +132,8 @@
 
     static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*);
 
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
+protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
 
 private:
     GrGLProgramDataManager::UniformHandle fInnerRectUniform;
@@ -280,7 +281,7 @@
     b->add32((crre.getCircularCornerFlags() << 3) | crre.getEdgeType());
 }
 
-void GLCircularRRectEffect::setData(const GrGLProgramDataManager& pdman,
+void GLCircularRRectEffect::onSetData(const GrGLProgramDataManager& pdman,
                                     const GrProcessor& processor) {
     const CircularRRectEffect& crre = processor.cast<CircularRRectEffect>();
     const SkRRect& rrect = crre.getRRect();
@@ -366,7 +367,7 @@
     GLCircularRRectEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* CircularRRectEffect::createGLInstance() const  {
+GrGLFragmentProcessor* CircularRRectEffect::onCreateGLInstance() const  {
     return SkNEW_ARGS(GLCircularRRectEffect, (*this));
 }
 
@@ -380,8 +381,6 @@
 
     const char* name() const override { return "EllipticalRRect"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
     const SkRRect& getRRect() const { return fRRect; }
 
     GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
@@ -389,6 +388,8 @@
 private:
     EllipticalRRectEffect(GrPrimitiveEdgeType, const SkRRect&);
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
     bool onIsEqual(const GrFragmentProcessor& other) const override;
@@ -477,7 +478,8 @@
 
     static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*);
 
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
+protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
 
 private:
     GrGLProgramDataManager::UniformHandle fInnerRectUniform;
@@ -570,7 +572,7 @@
     b->add32(erre.getRRect().getType() | erre.getEdgeType() << 3);
 }
 
-void GLEllipticalRRectEffect::setData(const GrGLProgramDataManager& pdman,
+void GLEllipticalRRectEffect::onSetData(const GrGLProgramDataManager& pdman,
                                       const GrProcessor& effect) {
     const EllipticalRRectEffect& erre = effect.cast<EllipticalRRectEffect>();
     const SkRRect& rrect = erre.getRRect();
@@ -614,7 +616,7 @@
     GLEllipticalRRectEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* EllipticalRRectEffect::createGLInstance() const  {
+GrGLFragmentProcessor* EllipticalRRectEffect::onCreateGLInstance() const  {
     return SkNEW_ARGS(GLEllipticalRRectEffect, (*this));
 }
 
diff --git a/src/gpu/effects/GrSimpleTextureEffect.cpp b/src/gpu/effects/GrSimpleTextureEffect.cpp
index e3389bb..0bd1fcd 100644
--- a/src/gpu/effects/GrSimpleTextureEffect.cpp
+++ b/src/gpu/effects/GrSimpleTextureEffect.cpp
@@ -42,7 +42,7 @@
     GrGLSimpleTextureEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* GrSimpleTextureEffect::createGLInstance() const  {
+GrGLFragmentProcessor* GrSimpleTextureEffect::onCreateGLInstance() const  {
     return SkNEW_ARGS(GrGLSimpleTextureEffect, (*this));
 }
 
diff --git a/src/gpu/effects/GrSimpleTextureEffect.h b/src/gpu/effects/GrSimpleTextureEffect.h
index c86b136..ab10ecf 100644
--- a/src/gpu/effects/GrSimpleTextureEffect.h
+++ b/src/gpu/effects/GrSimpleTextureEffect.h
@@ -53,8 +53,6 @@
 
     const char* name() const override { return "SimpleTexture"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
 private:
     GrSimpleTextureEffect(GrProcessorDataManager* procDataManager,
                           GrTexture* texture,
@@ -74,6 +72,8 @@
         this->initClassID<GrSimpleTextureEffect>();
     }
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
     bool onIsEqual(const GrFragmentProcessor& other) const override { return true; }
diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp
index 7cc454e..3810c34 100644
--- a/src/gpu/effects/GrTextureDomain.cpp
+++ b/src/gpu/effects/GrTextureDomain.cpp
@@ -176,10 +176,11 @@
 
     virtual void emitCode(EmitArgs&) override;
 
-    void setData(const GrGLProgramDataManager&, const GrProcessor&) override;
-
     static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*);
 
+protected:
+    void onSetData(const GrGLProgramDataManager&, const GrProcessor&) override;
+
 private:
     GrTextureDomain::GLDomain         fGLDomain;
     typedef GrGLFragmentProcessor INHERITED;
@@ -198,7 +199,7 @@
                             args.fInputColor);
 }
 
-void GrGLTextureDomainEffect::setData(const GrGLProgramDataManager& pdman,
+void GrGLTextureDomainEffect::onSetData(const GrGLProgramDataManager& pdman,
                                       const GrProcessor& processor) {
     const GrTextureDomainEffect& textureDomainEffect = processor.cast<GrTextureDomainEffect>();
     const GrTextureDomain& domain = textureDomainEffect.textureDomain();
@@ -260,7 +261,7 @@
     GrGLTextureDomainEffect::GenKey(*this, caps, b);
 }
 
-GrGLFragmentProcessor* GrTextureDomainEffect::createGLInstance() const  {
+GrGLFragmentProcessor* GrTextureDomainEffect::onCreateGLInstance() const  {
     return SkNEW_ARGS(GrGLTextureDomainEffect, (*this));
 }
 
diff --git a/src/gpu/effects/GrTextureDomain.h b/src/gpu/effects/GrTextureDomain.h
index 7cf75d6..a2e6652 100644
--- a/src/gpu/effects/GrTextureDomain.h
+++ b/src/gpu/effects/GrTextureDomain.h
@@ -169,8 +169,6 @@
 
     const char* name() const override { return "TextureDomain"; }
 
-    GrGLFragmentProcessor* createGLInstance() const override;
-
     const GrTextureDomain& textureDomain() const { return fTextureDomain; }
 
 protected:
@@ -185,6 +183,8 @@
                           GrTextureParams::FilterMode,
                           GrCoordSet);
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override;
+
     void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
 
     bool onIsEqual(const GrFragmentProcessor&) const override;
diff --git a/src/gpu/effects/GrYUVtoRGBEffect.cpp b/src/gpu/effects/GrYUVtoRGBEffect.cpp
index 7d77c1f..913c37e 100644
--- a/src/gpu/effects/GrYUVtoRGBEffect.cpp
+++ b/src/gpu/effects/GrYUVtoRGBEffect.cpp
@@ -80,7 +80,8 @@
             fsBuilder->codeAppendf(".r,\n\t\t1.0) * %s;\n", yuvMatrix);
         }
 
-        virtual void setData(const GrGLProgramDataManager& pdman,
+    protected:
+        virtual void onSetData(const GrGLProgramDataManager& pdman,
                              const GrProcessor& processor) override {
             const YUVtoRGBEffect& yuvEffect = processor.cast<YUVtoRGBEffect>();
             switch (yuvEffect.getColorSpace()) {
@@ -102,10 +103,6 @@
         typedef GrGLFragmentProcessor INHERITED;
     };
 
-    GrGLFragmentProcessor* createGLInstance() const override {
-        return SkNEW_ARGS(GLProcessor, (*this));
-    }
-
 private:
     YUVtoRGBEffect(GrProcessorDataManager*, GrTexture* yTexture, GrTexture* uTexture,
                    GrTexture* vTexture, const SkMatrix yuvMatrix[3],
@@ -126,6 +123,10 @@
         this->addTextureAccess(&fVAccess);
     }
 
+    GrGLFragmentProcessor* onCreateGLInstance() const override {
+        return SkNEW_ARGS(GLProcessor, (*this));
+    }
+
     virtual void onGetGLProcessorKey(const GrGLSLCaps& caps,
                                      GrProcessorKeyBuilder* b) const override {
         GLProcessor::GenKey(*this, caps, b);
diff --git a/src/gpu/gl/GrGLFragmentProcessor.cpp b/src/gpu/gl/GrGLFragmentProcessor.cpp
new file mode 100644
index 0000000..d300da1
--- /dev/null
+++ b/src/gpu/gl/GrGLFragmentProcessor.cpp
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrGLFragmentProcessor.h"
+#include "GrFragmentProcessor.h"
+
+void GrGLFragmentProcessor::setData(const GrGLProgramDataManager& pdman,
+                                    const GrFragmentProcessor& processor) {
+    this->onSetData(pdman, processor);
+    SkASSERT(fChildProcessors.count() == processor.numChildProcessors());
+    for (int i = 0; i < fChildProcessors.count(); ++i) {
+        fChildProcessors[i]->setData(pdman, processor.childProcessor(i));
+    }
+}
diff --git a/src/gpu/gl/GrGLFragmentProcessor.h b/src/gpu/gl/GrGLFragmentProcessor.h
index e130dba..c7964dc 100644
--- a/src/gpu/gl/GrGLFragmentProcessor.h
+++ b/src/gpu/gl/GrGLFragmentProcessor.h
@@ -18,7 +18,11 @@
 public:
     GrGLFragmentProcessor() {}
 
-    virtual ~GrGLFragmentProcessor() {}
+    virtual ~GrGLFragmentProcessor() {
+        for (int i = 0; i < fChildProcessors.count(); ++i) {
+            SkDELETE(fChildProcessors[i]);
+        }
+    }
 
     typedef GrGLProgramDataManager::UniformHandle UniformHandle;
     typedef GrGLProcessor::TransformedCoordsArray TransformedCoordsArray;
@@ -66,17 +70,29 @@
 
     virtual void emitCode(EmitArgs&) = 0;
 
-    /** A GrGLFragmentProcessor instance can be reused with any GrFragmentProcessor that produces
-        the same stage key; this function reads data from a GrFragmentProcessor and uploads any
-        uniform variables required by the shaders created in emitCode(). The GrFragmentProcessor
-        parameter is guaranteed to be of the same type that created this GrGLFragmentProcessor and
-        to have an identical processor key as the one that created this GrGLFragmentProcessor.  */
-    // TODO update this to pass in GrFragmentProcessor
-    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) {}
+    void setData(const GrGLProgramDataManager& pdman, const GrFragmentProcessor& processor);
 
     static void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*) {}
 
+    int numChildProcessors() const { return fChildProcessors.count(); }
+
+    GrGLFragmentProcessor* childProcessor(int index) const {
+        return fChildProcessors[index];
+    }
+
+protected:
+    /** A GrGLFragmentProcessor instance can be reused with any GrFragmentProcessor that produces
+    the same stage key; this function reads data from a GrFragmentProcessor and uploads any
+    uniform variables required by the shaders created in emitCode(). The GrFragmentProcessor
+    parameter is guaranteed to be of the same type that created this GrGLFragmentProcessor and
+    to have an identical processor key as the one that created this GrGLFragmentProcessor.  */
+    // TODO update this to pass in GrFragmentProcessor
+    virtual void onSetData(const GrGLProgramDataManager&, const GrProcessor&) {}
+
 private:
+    SkTArray<GrGLFragmentProcessor*, true> fChildProcessors;
+
+    friend class GrFragmentProcessor;
     typedef GrGLProcessor INHERITED;
 };
 
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 589b963..5af84e0 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -107,7 +107,7 @@
     int numProcessors = fFragmentProcessors->fProcs.count();
     for (int e = 0; e < numProcessors; ++e) {
         const GrPendingFragmentStage& stage = pipeline.getFragmentStage(e);
-        const GrProcessor& processor = *stage.processor();
+        const GrFragmentProcessor& processor = *stage.processor();
         fFragmentProcessors->fProcs[e]->fGLProc->setData(fProgramDataManager, processor);
         this->setTransformData(primProc,
                                stage,