More threading of GrProcessorDataManager

TBR=bsalomon@google.com
BUG=skia:

Review URL: https://codereview.chromium.org/1230813003
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index 80c179c..678802b 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -365,7 +365,7 @@
 bool SkBitmapProcShader::asFragmentProcessor(GrContext* context, const SkPaint& paint,
                                              const SkMatrix& viewM,
                                              const SkMatrix* localMatrix, GrColor* paintColor,
-                                             GrProcessorDataManager*,
+                                             GrProcessorDataManager* procDataManager,
                                              GrFragmentProcessor** fp) const {
     SkMatrix matrix;
     matrix.setIDiv(fRawBitmap.width(), fRawBitmap.height());
@@ -441,9 +441,9 @@
                                                 SkColor2GrColorJustAlpha(paint.getColor());
 
     if (useBicubic) {
-        *fp = GrBicubicEffect::Create(texture, matrix, tm);
+        *fp = GrBicubicEffect::Create(procDataManager, texture, matrix, tm);
     } else {
-        *fp = GrSimpleTextureEffect::Create(texture, matrix, params);
+        *fp = GrSimpleTextureEffect::Create(procDataManager, texture, matrix, params);
     }
 
     return true;
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index 0436f08..2017170 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -1231,7 +1231,8 @@
         SkMatrix matrix;
         matrix.setIDiv(src->width(), src->height());
         // Blend pathTexture over blurTexture.
-        paint.addCoverageProcessor(GrSimpleTextureEffect::Create(src, matrix))->unref();
+        paint.addCoverageProcessor(GrSimpleTextureEffect::Create(paint.getProcessorDataManager(),
+                                                                 src, matrix))->unref();
         if (kInner_SkBlurStyle == fBlurStyle) {
             // inner:  dst = dst * src
             paint.setCoverageSetOpXPFactory(SkRegion::kIntersect_Op);
diff --git a/src/effects/SkGpuBlurUtils.cpp b/src/effects/SkGpuBlurUtils.cpp
index ad268d6..a6aa408 100644
--- a/src/effects/SkGpuBlurUtils.cpp
+++ b/src/effects/SkGpuBlurUtils.cpp
@@ -58,7 +58,7 @@
                                  float bounds[2]) {
     GrPaint paint;
     SkAutoTUnref<GrFragmentProcessor> conv(GrConvolutionEffect::CreateGaussian(
-        texture, direction, radius, sigma, useBounds, bounds));
+        paint.getProcessorDataManager(), texture, direction, radius, sigma, useBounds, bounds));
     paint.addColorProcessor(conv);
     drawContext->drawNonAARectToRect(rt, clip, paint, SkMatrix::I(), dstRect, srcRect);
 }
@@ -79,6 +79,7 @@
     SkIPoint kernelOffset = SkIPoint::Make(radiusX, radiusY);
     GrPaint paint;
     SkAutoTUnref<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::CreateGaussian(
+            paint.getProcessorDataManager(),
             texture, bounds, size, 1.0, 0.0, kernelOffset,
             useBounds ? GrTextureDomain::kClamp_Mode : GrTextureDomain::kIgnore_Mode,
             true, sigmaX, sigmaY));
@@ -214,6 +215,7 @@
             domain.inset(i < scaleFactorX ? SK_ScalarHalf / srcTexture->width() : 0.0f,
                          i < scaleFactorY ? SK_ScalarHalf / srcTexture->height() : 0.0f);
             SkAutoTUnref<GrFragmentProcessor> fp(   GrTextureDomainEffect::Create(
+                paint.getProcessorDataManager(),
                 srcTexture,
                 matrix,
                 domain,
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index 3a96bc3..0df6f7a 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -306,7 +306,8 @@
     bool canFilterImageGPU() const override { return true; }
     bool filterImageGPU(Proxy*, const SkBitmap& src, const Context&,
                         SkBitmap* result, SkIPoint* offset) const override;
-    virtual GrFragmentProcessor* getFragmentProcessor(GrTexture*,
+    virtual GrFragmentProcessor* getFragmentProcessor(GrProcessorDataManager*,
+                                                      GrTexture*,
                                                       const SkMatrix&,
                                                       const SkIRect& bounds,
                                                       BoundaryMode boundaryMode) const = 0;
@@ -335,8 +336,9 @@
                                              BoundaryMode boundaryMode,
                                              const SkIRect& bounds) const {
     SkRect srcRect = dstRect.makeOffset(SkIntToScalar(bounds.x()), SkIntToScalar(bounds.y()));
-    GrFragmentProcessor* fp = this->getFragmentProcessor(src, matrix, bounds, boundaryMode);
     GrPaint paint;
+    GrFragmentProcessor* fp = this->getFragmentProcessor(paint.getProcessorDataManager(), src,
+                                                         matrix, bounds, boundaryMode);
     paint.addColorProcessor(fp)->unref();
     drawContext->drawNonAARectToRect(dst->asRenderTarget(), clip, paint, SkMatrix::I(),
                                      dstRect, srcRect);
@@ -432,7 +434,7 @@
     bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
                        SkBitmap* result, SkIPoint* offset) const override;
 #if SK_SUPPORT_GPU
-    GrFragmentProcessor* getFragmentProcessor(GrTexture*, const SkMatrix&,
+    GrFragmentProcessor* getFragmentProcessor(GrProcessorDataManager*, GrTexture*, const SkMatrix&,
                                               const SkIRect& bounds, BoundaryMode) const override;
 #endif
 
@@ -460,7 +462,7 @@
     bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
                        SkBitmap* result, SkIPoint* offset) const override;
 #if SK_SUPPORT_GPU
-    GrFragmentProcessor* getFragmentProcessor(GrTexture*, const SkMatrix&,
+    GrFragmentProcessor* getFragmentProcessor(GrProcessorDataManager*, GrTexture*, const SkMatrix&,
                                               const SkIRect& bounds, BoundaryMode) const override;
 #endif
 
@@ -475,8 +477,8 @@
 
 class GrLightingEffect : public GrSingleTextureEffect {
 public:
-    GrLightingEffect(GrTexture* texture, const SkLight* light, SkScalar surfaceScale,
-                     const SkMatrix& matrix, BoundaryMode boundaryMode);
+    GrLightingEffect(GrProcessorDataManager*, GrTexture* texture, const SkLight* light,
+                     SkScalar surfaceScale, const SkMatrix& matrix, BoundaryMode boundaryMode);
     virtual ~GrLightingEffect();
 
     const SkLight* light() const { return fLight; }
@@ -502,13 +504,15 @@
 
 class GrDiffuseLightingEffect : public GrLightingEffect {
 public:
-    static GrFragmentProcessor* Create(GrTexture* texture,
+    static GrFragmentProcessor* Create(GrProcessorDataManager* procDataManager,
+                                       GrTexture* texture,
                                        const SkLight* light,
                                        SkScalar surfaceScale,
                                        const SkMatrix& matrix,
                                        SkScalar kd,
                                        BoundaryMode boundaryMode) {
-        return SkNEW_ARGS(GrDiffuseLightingEffect, (texture,
+        return SkNEW_ARGS(GrDiffuseLightingEffect, (procDataManager,
+                                                    texture,
                                                     light,
                                                     surfaceScale,
                                                     matrix,
@@ -527,7 +531,8 @@
 private:
     bool onIsEqual(const GrFragmentProcessor&) const override;
 
-    GrDiffuseLightingEffect(GrTexture* texture,
+    GrDiffuseLightingEffect(GrProcessorDataManager*,
+                            GrTexture* texture,
                             const SkLight* light,
                             SkScalar surfaceScale,
                             const SkMatrix& matrix,
@@ -541,14 +546,16 @@
 
 class GrSpecularLightingEffect : public GrLightingEffect {
 public:
-    static GrFragmentProcessor* Create(GrTexture* texture,
+    static GrFragmentProcessor* Create(GrProcessorDataManager* procDataManager,
+                                       GrTexture* texture,
                                        const SkLight* light,
                                        SkScalar surfaceScale,
                                        const SkMatrix& matrix,
                                        SkScalar ks,
                                        SkScalar shininess,
                                        BoundaryMode boundaryMode) {
-        return SkNEW_ARGS(GrSpecularLightingEffect, (texture,
+        return SkNEW_ARGS(GrSpecularLightingEffect, (procDataManager,
+                                                     texture,
                                                      light,
                                                      surfaceScale,
                                                      matrix,
@@ -569,7 +576,8 @@
 private:
     bool onIsEqual(const GrFragmentProcessor&) const override;
 
-    GrSpecularLightingEffect(GrTexture* texture,
+    GrSpecularLightingEffect(GrProcessorDataManager*,
+                             GrTexture* texture,
                              const SkLight* light,
                              SkScalar surfaceScale,
                              const SkMatrix& matrix,
@@ -1225,13 +1233,15 @@
 
 #if SK_SUPPORT_GPU
 GrFragmentProcessor* SkDiffuseLightingImageFilter::getFragmentProcessor(
-                                                       GrTexture* texture,
-                                                       const SkMatrix& matrix,
-                                                       const SkIRect&,
-                                                       BoundaryMode boundaryMode
+                                                   GrProcessorDataManager* procDataManager,
+                                                   GrTexture* texture,
+                                                   const SkMatrix& matrix,
+                                                   const SkIRect&,
+                                                   BoundaryMode boundaryMode
 ) const {
-    SkScalar scale = SkScalarMul(surfaceScale(), SkIntToScalar(255));
-    return GrDiffuseLightingEffect::Create(texture, light(), scale, matrix, kd(), boundaryMode);
+    SkScalar scale = SkScalarMul(this->surfaceScale(), SkIntToScalar(255));
+    return GrDiffuseLightingEffect::Create(procDataManager, texture, this->light(), scale, matrix,
+                                           this->kd(), boundaryMode);
 }
 #endif
 
@@ -1359,13 +1369,14 @@
 
 #if SK_SUPPORT_GPU
 GrFragmentProcessor* SkSpecularLightingImageFilter::getFragmentProcessor(
-                                                         GrTexture* texture,
-                                                         const SkMatrix& matrix,
-                                                         const SkIRect&,
-                                                         BoundaryMode boundaryMode) const {
-    SkScalar scale = SkScalarMul(surfaceScale(), SkIntToScalar(255));
-    return GrSpecularLightingEffect::Create(texture, light(), scale, matrix, ks(), shininess(),
-                                            boundaryMode);
+                                                    GrProcessorDataManager* procDataManager,
+                                                    GrTexture* texture,
+                                                    const SkMatrix& matrix,
+                                                    const SkIRect&,
+                                                    BoundaryMode boundaryMode) const {
+    SkScalar scale = SkScalarMul(this->surfaceScale(), SkIntToScalar(255));
+    return GrSpecularLightingEffect::Create(procDataManager, texture, this->light(), scale, matrix,
+                                            this->ks(), this->shininess(), boundaryMode);
 }
 #endif
 
@@ -1541,12 +1552,13 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrLightingEffect::GrLightingEffect(GrTexture* texture,
+GrLightingEffect::GrLightingEffect(GrProcessorDataManager* procDataManager,
+                                   GrTexture* texture,
                                    const SkLight* light,
                                    SkScalar surfaceScale,
                                    const SkMatrix& matrix,
                                    BoundaryMode boundaryMode)
-    : INHERITED(texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture))
+    : INHERITED(procDataManager, texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture))
     , fLight(light)
     , fSurfaceScale(surfaceScale)
     , fFilterMatrix(matrix)
@@ -1570,13 +1582,14 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrDiffuseLightingEffect::GrDiffuseLightingEffect(GrTexture* texture,
+GrDiffuseLightingEffect::GrDiffuseLightingEffect(GrProcessorDataManager* procDataManager,
+                                                 GrTexture* texture,
                                                  const SkLight* light,
                                                  SkScalar surfaceScale,
                                                  const SkMatrix& matrix,
                                                  SkScalar kd,
                                                  BoundaryMode boundaryMode)
-    : INHERITED(texture, light, surfaceScale, matrix, boundaryMode), fKD(kd) {
+    : INHERITED(procDataManager, texture, light, surfaceScale, matrix, boundaryMode), fKD(kd) {
     this->initClassID<GrDiffuseLightingEffect>();
 }
 
@@ -1606,7 +1619,8 @@
         matrix[i] = d->fRandom->nextUScalar1();
     }
     BoundaryMode mode = static_cast<BoundaryMode>(d->fRandom->nextU() % kBoundaryModeCount);
-    return GrDiffuseLightingEffect::Create(d->fTextures[GrProcessorUnitTest::kAlphaTextureIdx],
+    return GrDiffuseLightingEffect::Create(d->fProcDataManager,
+                                           d->fTextures[GrProcessorUnitTest::kAlphaTextureIdx],
                                            light, surfaceScale, matrix, kd, mode);
 }
 
@@ -1771,14 +1785,15 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrSpecularLightingEffect::GrSpecularLightingEffect(GrTexture* texture,
+GrSpecularLightingEffect::GrSpecularLightingEffect(GrProcessorDataManager* procDataManager,
+                                                   GrTexture* texture,
                                                    const SkLight* light,
                                                    SkScalar surfaceScale,
                                                    const SkMatrix& matrix,
                                                    SkScalar ks,
                                                    SkScalar shininess,
                                                    BoundaryMode boundaryMode)
-    : INHERITED(texture, light, surfaceScale, matrix, boundaryMode),
+    : INHERITED(procDataManager, texture, light, surfaceScale, matrix, boundaryMode),
       fKS(ks),
       fShininess(shininess) {
     this->initClassID<GrSpecularLightingEffect>();
@@ -1812,7 +1827,8 @@
         matrix[i] = d->fRandom->nextUScalar1();
     }
     BoundaryMode mode = static_cast<BoundaryMode>(d->fRandom->nextU() % kBoundaryModeCount);
-    return GrSpecularLightingEffect::Create(d->fTextures[GrProcessorUnitTest::kAlphaTextureIdx],
+    return GrSpecularLightingEffect::Create(d->fProcDataManager,
+                                            d->fTextures[GrProcessorUnitTest::kAlphaTextureIdx],
                                             light, surfaceScale, matrix, ks, shininess, mode);
 }
 
diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp
index d6ed6ee..09a598e 100644
--- a/src/effects/SkMagnifierImageFilter.cpp
+++ b/src/effects/SkMagnifierImageFilter.cpp
@@ -23,7 +23,8 @@
 class GrMagnifierEffect : public GrSingleTextureEffect {
 
 public:
-    static GrFragmentProcessor* Create(GrTexture* texture,
+    static GrFragmentProcessor* Create(GrProcessorDataManager* procDataManager,
+                                       GrTexture* texture,
                                        const SkRect& bounds,
                                        float xOffset,
                                        float yOffset,
@@ -31,7 +32,8 @@
                                        float yInvZoom,
                                        float xInvInset,
                                        float yInvInset) {
-        return SkNEW_ARGS(GrMagnifierEffect, (texture,
+        return SkNEW_ARGS(GrMagnifierEffect, (procDataManager,
+                                              texture,
                                               bounds,
                                               xOffset,
                                               yOffset,
@@ -63,7 +65,8 @@
     float y_inv_inset() const { return fYInvInset; }
 
 private:
-    GrMagnifierEffect(GrTexture* texture,
+    GrMagnifierEffect(GrProcessorDataManager* procDataManager,
+                      GrTexture* texture,
                       const SkRect& bounds,
                       float xOffset,
                       float yOffset,
@@ -71,7 +74,7 @@
                       float yInvZoom,
                       float xInvInset,
                       float yInvInset)
-        : GrSingleTextureEffect(texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture))
+        : INHERITED(procDataManager, texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture))
         , fBounds(bounds)
         , fXOffset(xOffset)
         , fYOffset(yOffset)
@@ -219,6 +222,7 @@
     uint32_t inset = d->fRandom->nextULessThan(kMaxInset);
 
     GrFragmentProcessor* effect = GrMagnifierEffect::Create(
+        d->fProcDataManager,
         texture,
         SkRect::MakeWH(SkIntToScalar(kMaxWidth), SkIntToScalar(kMaxHeight)),
         (float) width / texture->width(),
@@ -273,7 +277,8 @@
 }
 
 #if SK_SUPPORT_GPU
-bool SkMagnifierImageFilter::asFragmentProcessor(GrFragmentProcessor** fp, GrProcessorDataManager*,
+bool SkMagnifierImageFilter::asFragmentProcessor(GrFragmentProcessor** fp,
+                                                 GrProcessorDataManager* procDataManager,
                                                  GrTexture* texture, const SkMatrix&,
                                                  const SkIRect&bounds) const {
     if (fp) {
@@ -288,7 +293,8 @@
             SkIntToScalar(texture->width()) / bounds.width(),
             SkIntToScalar(texture->height()) / bounds.height());
         SkScalar invInset = fInset > 0 ? SkScalarInvert(fInset) : SK_Scalar1;
-        *fp = GrMagnifierEffect::Create(texture,
+        *fp = GrMagnifierEffect::Create(procDataManager,
+                                        texture,
                                         effectBounds,
                                         fSrcRect.x() / texture->width(),
                                         yOffset / texture->height(),
diff --git a/src/effects/SkMatrixConvolutionImageFilter.cpp b/src/effects/SkMatrixConvolutionImageFilter.cpp
index 70e6740..92ac934 100644
--- a/src/effects/SkMatrixConvolutionImageFilter.cpp
+++ b/src/effects/SkMatrixConvolutionImageFilter.cpp
@@ -348,7 +348,7 @@
 }
 
 bool SkMatrixConvolutionImageFilter::asFragmentProcessor(GrFragmentProcessor** fp,
-                                                         GrProcessorDataManager*,
+                                                         GrProcessorDataManager* procDataManager,
                                                          GrTexture* texture,
                                                          const SkMatrix&,
                                                          const SkIRect& bounds) const {
@@ -356,7 +356,8 @@
         return fKernelSize.width() * fKernelSize.height() <= MAX_KERNEL_SIZE;
     }
     SkASSERT(fKernelSize.width() * fKernelSize.height() <= MAX_KERNEL_SIZE);
-    *fp = GrMatrixConvolutionEffect::Create(texture,
+    *fp = GrMatrixConvolutionEffect::Create(procDataManager,
+                                            texture,
                                             bounds,
                                             fKernelSize,
                                             fKernel,
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index f284360..62b90cb 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -298,14 +298,15 @@
         kDilate_MorphologyType,
     };
 
-    static GrFragmentProcessor* Create(GrTexture* tex, Direction dir, int radius,
-                                       MorphologyType type) {
-        return SkNEW_ARGS(GrMorphologyEffect, (tex, dir, radius, type));
+    static GrFragmentProcessor* Create(GrProcessorDataManager* procDataManager, GrTexture* tex,
+                                       Direction dir, int radius, MorphologyType type) {
+        return SkNEW_ARGS(GrMorphologyEffect, (procDataManager, tex, dir, radius, type));
     }
 
-    static GrFragmentProcessor* Create(GrTexture* tex, Direction dir, int radius,
-                                       MorphologyType type, float bounds[2]) {
-        return SkNEW_ARGS(GrMorphologyEffect, (tex, dir, radius, type, bounds));
+    static GrFragmentProcessor* Create(GrProcessorDataManager* procDataManager, GrTexture* tex,
+                                       Direction dir, int radius, MorphologyType type,
+                                       float bounds[2]) {
+        return SkNEW_ARGS(GrMorphologyEffect, (procDataManager, tex, dir, radius, type, bounds));
     }
 
     virtual ~GrMorphologyEffect();
@@ -331,8 +332,9 @@
 
     void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
 
-    GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType);
-    GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType, float bounds[2]);
+    GrMorphologyEffect(GrProcessorDataManager*, GrTexture*, Direction, int radius, MorphologyType);
+    GrMorphologyEffect(GrProcessorDataManager*, GrTexture*, Direction, int radius, MorphologyType,
+                       float bounds[2]);
 
     GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
@@ -494,21 +496,23 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrMorphologyEffect::GrMorphologyEffect(GrTexture* texture,
+GrMorphologyEffect::GrMorphologyEffect(GrProcessorDataManager* procDataManager,
+                                       GrTexture* texture,
                                        Direction direction,
                                        int radius,
                                        MorphologyType type)
-    : Gr1DKernelEffect(texture, direction, radius)
+    : INHERITED(procDataManager, texture, direction, radius)
     , fType(type), fUseRange(false) {
     this->initClassID<GrMorphologyEffect>();
 }
 
-GrMorphologyEffect::GrMorphologyEffect(GrTexture* texture,
+GrMorphologyEffect::GrMorphologyEffect(GrProcessorDataManager* procDataManager,
+                                       GrTexture* texture,
                                        Direction direction,
                                        int radius,
                                        MorphologyType type,
                                        float range[2])
-    : Gr1DKernelEffect(texture, direction, radius)
+    : INHERITED(procDataManager, texture, direction, radius)
     , fType(type), fUseRange(true) {
     this->initClassID<GrMorphologyEffect>();
     fRange[0] = range[0];
@@ -552,7 +556,7 @@
     MorphologyType type = d->fRandom->nextBool() ? GrMorphologyEffect::kErode_MorphologyType :
                                                GrMorphologyEffect::kDilate_MorphologyType;
 
-    return GrMorphologyEffect::Create(d->fTextures[texIdx], dir, radius, type);
+    return GrMorphologyEffect::Create(d->fProcDataManager, d->fTextures[texIdx], dir, radius, type);
 }
 
 namespace {
@@ -569,7 +573,8 @@
                            float bounds[2],
                            Gr1DKernelEffect::Direction direction) {
     GrPaint paint;
-    paint.addColorProcessor(GrMorphologyEffect::Create(texture,
+    paint.addColorProcessor(GrMorphologyEffect::Create(paint.getProcessorDataManager(),
+                                                       texture,
                                                        direction,
                                                        radius,
                                                        morphType,
@@ -588,7 +593,8 @@
                                      GrMorphologyEffect::MorphologyType morphType,
                                      Gr1DKernelEffect::Direction direction) {
     GrPaint paint;
-    paint.addColorProcessor(GrMorphologyEffect::Create(texture,
+    paint.addColorProcessor(GrMorphologyEffect::Create(paint.getProcessorDataManager(),
+                                                       texture,
                                                        direction,
                                                        radius,
                                                        morphType))->unref();
diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp
index 44908a9..f1334a2 100644
--- a/src/effects/SkXfermodeImageFilter.cpp
+++ b/src/effects/SkXfermodeImageFilter.cpp
@@ -183,6 +183,7 @@
     src.getBounds(&srcRect);
 
     SkAutoTUnref<GrFragmentProcessor> foregroundDomain(GrTextureDomainEffect::Create(
+        paint.getProcessorDataManager(),
         foregroundTex, foregroundMatrix,
         GrTextureDomain::MakeTexelDomain(foregroundTex, foreground.bounds()),
         GrTextureDomain::kDecal_Mode,
diff --git a/src/gpu/GrBlurUtils.cpp b/src/gpu/GrBlurUtils.cpp
index caea2b4..d273371 100644
--- a/src/gpu/GrBlurUtils.cpp
+++ b/src/gpu/GrBlurUtils.cpp
@@ -36,7 +36,8 @@
     matrix.setTranslate(-maskRect.fLeft, -maskRect.fTop);
     matrix.postIDiv(mask->width(), mask->height());
 
-    grp->addCoverageProcessor(GrSimpleTextureEffect::Create(mask, matrix,
+    grp->addCoverageProcessor(GrSimpleTextureEffect::Create(grp->getProcessorDataManager(),
+                                                            mask, matrix,
                                                             kDevice_GrCoordSet))->unref();
 
     SkMatrix inverse;
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index 17a15a3..76cfbf6 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -47,7 +47,8 @@
     SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height());
     // This could be a long-lived effect that is cached with the alpha-mask.
     pipelineBuilder->addCoverageProcessor(
-        GrTextureDomainEffect::Create(result,
+        GrTextureDomainEffect::Create(pipelineBuilder->getProcessorDataManager(),
+                                      result,
                                       mat,
                                       GrTextureDomain::MakeTexelDomain(result, domainTexels),
                                       GrTextureDomain::kDecal_Mode,
@@ -480,7 +481,8 @@
     sampleM.setIDiv(srcMask->width(), srcMask->height());
 
     pipelineBuilder->addCoverageProcessor(
-        GrTextureDomainEffect::Create(srcMask,
+        GrTextureDomainEffect::Create(pipelineBuilder->getProcessorDataManager(),
+                                      srcMask,
                                       sampleM,
                                       GrTextureDomain::MakeTexelDomain(srcMask, srcBound),
                                       GrTextureDomain::kDecal_Mode,
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 5cb8934..1c60074 100755
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -382,11 +382,13 @@
     // allocate a tmp buffer and sw convert the pixels to premul
     SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0);
 
+    GrPaint paint;
     if (kUnpremul_PixelOpsFlag & pixelOpsFlags) {
         if (!GrPixelConfigIs8888(srcConfig)) {
             return false;
         }
-        fp.reset(this->createUPMToPMEffect(texture, swapRAndB, textureMatrix));
+        fp.reset(this->createUPMToPMEffect(paint.getProcessorDataManager(), texture, swapRAndB,
+                                           textureMatrix));
         // handle the unpremul step on the CPU if we couldn't create an effect to do it.
         if (!fp) {
             size_t tmpRowBytes = 4 * width;
@@ -399,8 +401,10 @@
             buffer = tmpPixels.get();
         }
     }
+
     if (!fp) {
-        fp.reset(GrConfigConversionEffect::Create(texture,
+        fp.reset(GrConfigConversionEffect::Create(paint.getProcessorDataManager(),
+                                                  texture,
                                                   swapRAndB,
                                                   GrConfigConversionEffect::kNone_PMConversion,
                                                   textureMatrix));
@@ -425,7 +429,6 @@
         return false;
     }
 
-    GrPaint paint;
     paint.addColorProcessor(fp);
 
     SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
@@ -523,9 +526,11 @@
             textureMatrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top);
             textureMatrix.postIDiv(src->width(), src->height());
 
+            GrPaint paint;
             SkAutoTUnref<const GrFragmentProcessor> fp;
             if (unpremul) {
-                fp.reset(this->createPMToUPMEffect(src, swapRAndB, textureMatrix));
+                fp.reset(this->createPMToUPMEffect(paint.getProcessorDataManager(), src, swapRAndB,
+                                                   textureMatrix));
                 if (fp) {
                     unpremul = false; // we no longer need to do this on CPU after the read back.
                 }
@@ -534,7 +539,7 @@
             // there is no longer any point to using the scratch.
             if (fp || flipY || swapRAndB) {
                 if (!fp) {
-                    fp.reset(GrConfigConversionEffect::Create(
+                    fp.reset(GrConfigConversionEffect::Create(paint.getProcessorDataManager(),
                             src, swapRAndB, GrConfigConversionEffect::kNone_PMConversion,
                             textureMatrix));
                 }
@@ -549,7 +554,6 @@
                         return false;
                     }
 
-                    GrPaint paint;
                     paint.addColorProcessor(fp);
 
                     SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
@@ -705,7 +709,8 @@
 }
 }
 
-const GrFragmentProcessor* GrContext::createPMToUPMEffect(GrTexture* texture,
+const GrFragmentProcessor* GrContext::createPMToUPMEffect(GrProcessorDataManager* procDataManager,
+                                                          GrTexture* texture,
                                                           bool swapRAndB,
                                                           const SkMatrix& matrix) {
     if (!fDidTestPMConversions) {
@@ -715,13 +720,15 @@
     GrConfigConversionEffect::PMConversion pmToUPM =
         static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion);
     if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) {
-        return GrConfigConversionEffect::Create(texture, swapRAndB, pmToUPM, matrix);
+        return GrConfigConversionEffect::Create(procDataManager, texture, swapRAndB, pmToUPM,
+                                                matrix);
     } else {
         return NULL;
     }
 }
 
-const GrFragmentProcessor* GrContext::createUPMToPMEffect(GrTexture* texture,
+const GrFragmentProcessor* GrContext::createUPMToPMEffect(GrProcessorDataManager* procDataManager,
+                                                          GrTexture* texture,
                                                           bool swapRAndB,
                                                           const SkMatrix& matrix) {
     if (!fDidTestPMConversions) {
@@ -731,7 +738,8 @@
     GrConfigConversionEffect::PMConversion upmToPM =
         static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion);
     if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) {
-        return GrConfigConversionEffect::Create(texture, swapRAndB, upmToPM, matrix);
+        return GrConfigConversionEffect::Create(procDataManager, texture, swapRAndB, upmToPM,
+                                                matrix);
     } else {
         return NULL;
     }
diff --git a/src/gpu/GrPaint.cpp b/src/gpu/GrPaint.cpp
index 3c40c96..f1533dd 100644
--- a/src/gpu/GrPaint.cpp
+++ b/src/gpu/GrPaint.cpp
@@ -24,23 +24,27 @@
 }
 
 void GrPaint::addColorTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
-    this->addColorProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref();
+    this->addColorProcessor(GrSimpleTextureEffect::Create(&fProcDataManager, texture,
+                                                          matrix))->unref();
 }
 
 void GrPaint::addCoverageTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
-    this->addCoverageProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref();
+    this->addCoverageProcessor(GrSimpleTextureEffect::Create(&fProcDataManager, texture,
+                                                             matrix))->unref();
 }
 
 void GrPaint::addColorTextureProcessor(GrTexture* texture,
                                        const SkMatrix& matrix,
                                        const GrTextureParams& params) {
-    this->addColorProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
+    this->addColorProcessor(GrSimpleTextureEffect::Create(&fProcDataManager, texture, matrix,
+                                                          params))->unref();
 }
 
 void GrPaint::addCoverageTextureProcessor(GrTexture* texture,
                                           const SkMatrix& matrix,
                                           const GrTextureParams& params) {
-    this->addCoverageProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
+    this->addCoverageProcessor(GrSimpleTextureEffect::Create(&fProcDataManager, texture, matrix,
+                                                             params))->unref();
 }
 
 bool GrPaint::isConstantBlendedColor(GrColor* color) const {
diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h
index df384b3..4f9016b 100644
--- a/src/gpu/GrPipelineBuilder.h
+++ b/src/gpu/GrPipelineBuilder.h
@@ -84,23 +84,27 @@
      * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates.
      */
     void addColorTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
-        this->addColorProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref();
+        this->addColorProcessor(GrSimpleTextureEffect::Create(&fProcDataManager, texture,
+                                                              matrix))->unref();
     }
 
     void addCoverageTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
-        this->addCoverageProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref();
+        this->addCoverageProcessor(GrSimpleTextureEffect::Create(&fProcDataManager, texture,
+                                                                 matrix))->unref();
     }
 
     void addColorTextureProcessor(GrTexture* texture,
                                   const SkMatrix& matrix,
                                   const GrTextureParams& params) {
-        this->addColorProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
+        this->addColorProcessor(GrSimpleTextureEffect::Create(&fProcDataManager, texture, matrix,
+                                                              params))->unref();
     }
 
     void addCoverageTextureProcessor(GrTexture* texture,
                                      const SkMatrix& matrix,
                                      const GrTextureParams& params) {
-        this->addCoverageProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
+        this->addCoverageProcessor(GrSimpleTextureEffect::Create(&fProcDataManager, texture, matrix,
+                                                                 params))->unref();
     }
 
     /**
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp
index 9b9865e..28071d2 100644
--- a/src/gpu/GrSWMaskHelper.cpp
+++ b/src/gpu/GrSWMaskHelper.cpp
@@ -368,7 +368,8 @@
     maskMatrix.preTranslate(SkIntToScalar(-rect.fLeft), SkIntToScalar(-rect.fTop));
 
     pipelineBuilder->addCoverageProcessor(
-                         GrSimpleTextureEffect::Create(texture,
+                         GrSimpleTextureEffect::Create(pipelineBuilder->getProcessorDataManager(),
+                                                       texture,
                                                        maskMatrix,
                                                        GrTextureParams::kNone_FilterMode,
                                                        kDevice_GrCoordSet))->unref();
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 028ab56..e0658b3 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1206,7 +1206,12 @@
                       SkScalarMul(srcRect.fBottom, hInv));
 
     SkRect textureDomain = SkRect::MakeEmpty();
+
+    // Construct a GrPaint by setting the bitmap texture as the first effect and then configuring
+    // the rest from the SkPaint.
+    GrPaint grPaint;
     SkAutoTUnref<GrFragmentProcessor> fp;
+
     if (needsTextureDomain && !(flags & SkCanvas::kBleed_DrawBitmapRectFlag)) {
         // Use a constrained texture domain to avoid color bleeding
         SkScalar left, top, right, bottom;
@@ -1226,9 +1231,11 @@
         }
         textureDomain.setLTRB(left, top, right, bottom);
         if (bicubic) {
-            fp.reset(GrBicubicEffect::Create(texture, SkMatrix::I(), textureDomain));
+            fp.reset(GrBicubicEffect::Create(grPaint.getProcessorDataManager(), texture,
+                                             SkMatrix::I(), textureDomain));
         } else {
-            fp.reset(GrTextureDomainEffect::Create(texture,
+            fp.reset(GrTextureDomainEffect::Create(grPaint.getProcessorDataManager(),
+                                                   texture,
                                                    SkMatrix::I(),
                                                    textureDomain,
                                                    GrTextureDomain::kClamp_Mode,
@@ -1237,14 +1244,13 @@
     } else if (bicubic) {
         SkASSERT(GrTextureParams::kNone_FilterMode == params.filterMode());
         SkShader::TileMode tileModes[2] = { params.getTileModeX(), params.getTileModeY() };
-        fp.reset(GrBicubicEffect::Create(texture, SkMatrix::I(), tileModes));
+        fp.reset(GrBicubicEffect::Create(grPaint.getProcessorDataManager(), texture, SkMatrix::I(),
+                                         tileModes));
     } else {
-        fp.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), params));
+        fp.reset(GrSimpleTextureEffect::Create(grPaint.getProcessorDataManager(), texture,
+                                               SkMatrix::I(), params));
     }
 
-    // Construct a GrPaint by setting the bitmap texture as the first effect and then configuring
-    // the rest from the SkPaint.
-    GrPaint grPaint;
     grPaint.addColorProcessor(fp);
     bool alphaOnly = !(kAlpha_8_SkColorType == bitmap.colorType());
     GrColor paintColor = (alphaOnly) ? SkColor2GrColorJustAlpha(paint.getColor()) :
diff --git a/src/gpu/effects/Gr1DKernelEffect.h b/src/gpu/effects/Gr1DKernelEffect.h
index a195b76..0aec4b1 100644
--- a/src/gpu/effects/Gr1DKernelEffect.h
+++ b/src/gpu/effects/Gr1DKernelEffect.h
@@ -28,10 +28,11 @@
         kY_Direction,
     };
 
-    Gr1DKernelEffect(GrTexture* texture,
+    Gr1DKernelEffect(GrProcessorDataManager* procDataManager,
+                     GrTexture* texture,
                      Direction direction,
                      int radius)
-        : GrSingleTextureEffect(texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture))
+        : INHERITED(procDataManager, texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture))
         , fDirection(direction)
         , fRadius(radius) {}
 
diff --git a/src/gpu/effects/GrBicubicEffect.cpp b/src/gpu/effects/GrBicubicEffect.cpp
index c4ceeba..027a3c7 100644
--- a/src/gpu/effects/GrBicubicEffect.cpp
+++ b/src/gpu/effects/GrBicubicEffect.cpp
@@ -134,22 +134,25 @@
     }
 }
 
-GrBicubicEffect::GrBicubicEffect(GrTexture* texture,
+GrBicubicEffect::GrBicubicEffect(GrProcessorDataManager* procDataManager,
+                                 GrTexture* texture,
                                  const SkScalar coefficients[16],
                                  const SkMatrix &matrix,
                                  const SkShader::TileMode tileModes[2])
-  : INHERITED(texture, matrix, GrTextureParams(tileModes, GrTextureParams::kNone_FilterMode))
+  : INHERITED(procDataManager, texture, matrix,
+              GrTextureParams(tileModes, GrTextureParams::kNone_FilterMode))
   , fDomain(GrTextureDomain::IgnoredDomain()) {
     this->initClassID<GrBicubicEffect>();
     convert_row_major_scalar_coeffs_to_column_major_floats(fCoefficients, coefficients);
 }
 
-GrBicubicEffect::GrBicubicEffect(GrTexture* texture,
+GrBicubicEffect::GrBicubicEffect(GrProcessorDataManager* procDataManager,
+                                 GrTexture* texture,
                                  const SkScalar coefficients[16],
                                  const SkMatrix &matrix,
                                  const SkRect& domain)
-  : INHERITED(texture, matrix, GrTextureParams(SkShader::kClamp_TileMode,
-                                               GrTextureParams::kNone_FilterMode))
+  : INHERITED(procDataManager, texture, matrix,
+              GrTextureParams(SkShader::kClamp_TileMode, GrTextureParams::kNone_FilterMode))
   , fDomain(domain, GrTextureDomain::kClamp_Mode) {
     this->initClassID<GrBicubicEffect>();
     convert_row_major_scalar_coeffs_to_column_major_floats(fCoefficients, coefficients);
@@ -187,7 +190,7 @@
     for (int i = 0; i < 16; i++) {
         coefficients[i] = d->fRandom->nextSScalar1();
     }
-    return GrBicubicEffect::Create(d->fTextures[texIdx], coefficients);
+    return GrBicubicEffect::Create(d->fProcDataManager, d->fTextures[texIdx], coefficients);
 }
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/effects/GrBicubicEffect.h b/src/gpu/effects/GrBicubicEffect.h
index b81c93e..11075f2 100644
--- a/src/gpu/effects/GrBicubicEffect.h
+++ b/src/gpu/effects/GrBicubicEffect.h
@@ -36,15 +36,16 @@
     /**
      * Create a simple filter effect with custom bicubic coefficients and optional domain.
      */
-    static GrFragmentProcessor* Create(GrTexture* tex, const SkScalar coefficients[16],
-                            const SkRect* domain = NULL) {
+    static GrFragmentProcessor* Create(GrProcessorDataManager* procDataManager, GrTexture* tex,
+                                       const SkScalar coefficients[16],
+                                       const SkRect* domain = NULL) {
         if (NULL == domain) {
             static const SkShader::TileMode kTileModes[] = { SkShader::kClamp_TileMode,
                                                              SkShader::kClamp_TileMode };
-            return Create(tex, coefficients, GrCoordTransform::MakeDivByTextureWHMatrix(tex),
-                          kTileModes);
+            return Create(procDataManager, tex, coefficients,
+                          GrCoordTransform::MakeDivByTextureWHMatrix(tex), kTileModes);
         } else {
-            return SkNEW_ARGS(GrBicubicEffect, (tex, coefficients,
+            return SkNEW_ARGS(GrBicubicEffect, (procDataManager, tex, coefficients,
                                                 GrCoordTransform::MakeDivByTextureWHMatrix(tex),
                                                 *domain));
         }
@@ -53,27 +54,29 @@
     /**
      * Create a Mitchell filter effect with specified texture matrix and x/y tile modes.
      */
-    static GrFragmentProcessor* Create(GrTexture* tex, const SkMatrix& matrix,
-                            SkShader::TileMode tileModes[2]) {
-        return Create(tex, gMitchellCoefficients, matrix, tileModes);
+    static GrFragmentProcessor* Create(GrProcessorDataManager* procDataManager, GrTexture* tex,
+                                       const SkMatrix& matrix,
+                                       SkShader::TileMode tileModes[2]) {
+        return Create(procDataManager, tex, gMitchellCoefficients, matrix, tileModes);
     }
 
     /**
      * Create a filter effect with custom bicubic coefficients, the texture matrix, and the x/y
      * tilemodes.
      */
-    static GrFragmentProcessor* Create(GrTexture* tex, const SkScalar coefficients[16],
-                                       const SkMatrix& matrix,
+    static GrFragmentProcessor* Create(GrProcessorDataManager* procDataManager, GrTexture* tex,
+                                       const SkScalar coefficients[16], const SkMatrix& matrix,
                                        const SkShader::TileMode tileModes[2]) {
-        return SkNEW_ARGS(GrBicubicEffect, (tex, coefficients, matrix, tileModes));
+        return SkNEW_ARGS(GrBicubicEffect, (procDataManager, tex, coefficients, matrix, tileModes));
     }
 
     /**
      * Create a Mitchell filter effect with a texture matrix and a domain.
      */
-    static GrFragmentProcessor* Create(GrTexture* tex, const SkMatrix& matrix,
-                                       const SkRect& domain) {
-        return SkNEW_ARGS(GrBicubicEffect, (tex, gMitchellCoefficients, matrix, domain));
+    static GrFragmentProcessor* Create(GrProcessorDataManager* procDataManager, GrTexture* tex,
+                                       const SkMatrix& matrix, const SkRect& domain) {
+        return SkNEW_ARGS(GrBicubicEffect, (procDataManager, tex, gMitchellCoefficients, matrix,
+                                            domain));
     }
 
     /**
@@ -87,9 +90,9 @@
                                  GrTextureParams::FilterMode* filterMode);
 
 private:
-    GrBicubicEffect(GrTexture*, const SkScalar coefficients[16],
+    GrBicubicEffect(GrProcessorDataManager*, GrTexture*, const SkScalar coefficients[16],
                     const SkMatrix &matrix, const SkShader::TileMode tileModes[2]);
-    GrBicubicEffect(GrTexture*, const SkScalar coefficients[16],
+    GrBicubicEffect(GrProcessorDataManager*, GrTexture*, const SkScalar coefficients[16],
                     const SkMatrix &matrix, const SkRect& domain);
     bool onIsEqual(const GrFragmentProcessor&) const override;
 
diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp
index 8b072f6..4927e29 100644
--- a/src/gpu/effects/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/GrConfigConversionEffect.cpp
@@ -100,11 +100,12 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrConfigConversionEffect::GrConfigConversionEffect(GrTexture* texture,
+GrConfigConversionEffect::GrConfigConversionEffect(GrProcessorDataManager* procDataManager,
+                                                   GrTexture* texture,
                                                    bool swapRedAndBlue,
                                                    PMConversion pmConversion,
                                                    const SkMatrix& matrix)
-    : GrSingleTextureEffect(texture, matrix)
+    : INHERITED(procDataManager, texture, matrix)
     , fSwapRedAndBlue(swapRedAndBlue)
     , fPMConversion(pmConversion) {
     this->initClassID<GrConfigConversionEffect>();
@@ -137,7 +138,8 @@
         swapRB = d->fRandom->nextBool();
     }
     return SkNEW_ARGS(GrConfigConversionEffect,
-                                      (d->fTextures[GrProcessorUnitTest::kSkiaPMTextureIdx],
+                                      (d->fProcDataManager,
+                                       d->fTextures[GrProcessorUnitTest::kSkiaPMTextureIdx],
                                        swapRB,
                                        pmConv,
                                        GrTest::TestMatrix(d->fRandom)));
@@ -220,17 +222,22 @@
         // from readTex to tempTex followed by a PM->UPM draw to readTex and finally read the data.
         // We then verify that two reads produced the same values.
 
+        GrPaint paint1;
+        GrPaint paint2;
+        GrPaint paint3;
         SkAutoTUnref<GrFragmentProcessor> pmToUPM1(
                 SkNEW_ARGS(GrConfigConversionEffect,
-                           (dataTex, false, *pmToUPMRule, SkMatrix::I())));
+                           (paint1.getProcessorDataManager(), dataTex, false, *pmToUPMRule,
+                            SkMatrix::I())));
         SkAutoTUnref<GrFragmentProcessor> upmToPM(
                 SkNEW_ARGS(GrConfigConversionEffect,
-                           (readTex, false, *upmToPMRule, SkMatrix::I())));
+                           (paint2.getProcessorDataManager(), readTex, false, *upmToPMRule,
+                            SkMatrix::I())));
         SkAutoTUnref<GrFragmentProcessor> pmToUPM2(
                 SkNEW_ARGS(GrConfigConversionEffect,
-                           (tempTex, false, *pmToUPMRule, SkMatrix::I())));
+                           (paint3.getProcessorDataManager(), tempTex, false, *pmToUPMRule,
+                            SkMatrix::I())));
 
-        GrPaint paint1;
         paint1.addColorProcessor(pmToUPM1);
         drawContext->drawNonAARectToRect(readTex->asRenderTarget(),
                                          GrClip::WideOpen(),
@@ -241,7 +248,6 @@
 
         readTex->readPixels(0, 0, 256, 256, kRGBA_8888_GrPixelConfig, firstRead);
 
-        GrPaint paint2;
         paint2.addColorProcessor(upmToPM);
         drawContext->drawNonAARectToRect(tempTex->asRenderTarget(),
                                          GrClip::WideOpen(),
@@ -250,7 +256,6 @@
                                          kDstRect,
                                          kSrcRect);
 
-        GrPaint paint3;
         paint3.addColorProcessor(pmToUPM2);
         drawContext->drawNonAARectToRect(readTex->asRenderTarget(),
                                          GrClip::WideOpen(),
@@ -277,15 +282,16 @@
     }
 }
 
-const GrFragmentProcessor* GrConfigConversionEffect::Create(GrTexture* texture,
-                                                 bool swapRedAndBlue,
-                                                 PMConversion pmConversion,
-                                                 const SkMatrix& matrix) {
+const GrFragmentProcessor* GrConfigConversionEffect::Create(GrProcessorDataManager* procDataManager,
+                                                            GrTexture* texture,
+                                                            bool swapRedAndBlue,
+                                                            PMConversion pmConversion,
+                                                            const SkMatrix& matrix) {
     if (!swapRedAndBlue && kNone_PMConversion == pmConversion) {
         // If we returned a GrConfigConversionEffect that was equivalent to a GrSimpleTextureEffect
         // then we may pollute our texture cache with redundant shaders. So in the case that no
         // conversions were requested we instead return a GrSimpleTextureEffect.
-        return GrSimpleTextureEffect::Create(texture, matrix);
+        return GrSimpleTextureEffect::Create(procDataManager, texture, matrix);
     } else {
         if (kRGBA_8888_GrPixelConfig != texture->config() &&
             kBGRA_8888_GrPixelConfig != texture->config() &&
@@ -293,7 +299,8 @@
             // The PM conversions assume colors are 0..255
             return NULL;
         }
-        return SkNEW_ARGS(GrConfigConversionEffect, (texture,
+        return SkNEW_ARGS(GrConfigConversionEffect, (procDataManager,
+                                                     texture,
                                                      swapRedAndBlue,
                                                      pmConversion,
                                                      matrix));
diff --git a/src/gpu/effects/GrConfigConversionEffect.h b/src/gpu/effects/GrConfigConversionEffect.h
index 3b47166..f00a284 100644
--- a/src/gpu/effects/GrConfigConversionEffect.h
+++ b/src/gpu/effects/GrConfigConversionEffect.h
@@ -34,8 +34,8 @@
         kPMConversionCnt
     };
 
-    static const GrFragmentProcessor* Create(GrTexture*, bool swapRedAndBlue, PMConversion,
-                                             const SkMatrix&);
+    static const GrFragmentProcessor* Create(GrProcessorDataManager*, GrTexture*,
+                                             bool swapRedAndBlue, PMConversion, const SkMatrix&);
 
     const char* name() const override { return "Config Conversion"; }
 
@@ -56,10 +56,11 @@
                                                PMConversion* UPMToPMRule);
 
 private:
-    GrConfigConversionEffect(GrTexture*,
-                            bool swapRedAndBlue,
-                            PMConversion pmConversion,
-                            const SkMatrix& matrix);
+    GrConfigConversionEffect(GrProcessorDataManager*,
+                             GrTexture*,
+                             bool swapRedAndBlue,
+                             PMConversion pmConversion,
+                             const SkMatrix& matrix);
 
     bool onIsEqual(const GrFragmentProcessor&) const override;
 
diff --git a/src/gpu/effects/GrConvolutionEffect.cpp b/src/gpu/effects/GrConvolutionEffect.cpp
index 9f3c6c1..f5b5e22 100644
--- a/src/gpu/effects/GrConvolutionEffect.cpp
+++ b/src/gpu/effects/GrConvolutionEffect.cpp
@@ -154,13 +154,14 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrConvolutionEffect::GrConvolutionEffect(GrTexture* texture,
+GrConvolutionEffect::GrConvolutionEffect(GrProcessorDataManager* procDataManager,
+                                         GrTexture* texture,
                                          Direction direction,
                                          int radius,
                                          const float* kernel,
                                          bool useBounds,
                                          float bounds[2])
-    : Gr1DKernelEffect(texture, direction, radius), fUseBounds(useBounds) {
+    : INHERITED(procDataManager, texture, direction, radius), fUseBounds(useBounds) {
     this->initClassID<GrConvolutionEffect>();
     SkASSERT(radius <= kMaxKernelRadius);
     SkASSERT(kernel);
@@ -171,13 +172,14 @@
     memcpy(fBounds, bounds, sizeof(fBounds));
 }
 
-GrConvolutionEffect::GrConvolutionEffect(GrTexture* texture,
+GrConvolutionEffect::GrConvolutionEffect(GrProcessorDataManager* procDataManager,
+                                         GrTexture* texture,
                                          Direction direction,
                                          int radius,
                                          float gaussianSigma,
                                          bool useBounds,
                                          float bounds[2])
-    : Gr1DKernelEffect(texture, direction, radius), fUseBounds(useBounds) {
+    : INHERITED(procDataManager, texture, direction, radius), fUseBounds(useBounds) {
     this->initClassID<GrConvolutionEffect>();
     SkASSERT(radius <= kMaxKernelRadius);
     int width = this->width();
@@ -239,7 +241,8 @@
     }
 
     bool useBounds = d->fRandom->nextBool();
-    return GrConvolutionEffect::Create(d->fTextures[texIdx],
+    return GrConvolutionEffect::Create(d->fProcDataManager,
+                                       d->fTextures[texIdx],
                                        dir,
                                        radius,
                                        kernel,
diff --git a/src/gpu/effects/GrConvolutionEffect.h b/src/gpu/effects/GrConvolutionEffect.h
index b885f19..066da19 100644
--- a/src/gpu/effects/GrConvolutionEffect.h
+++ b/src/gpu/effects/GrConvolutionEffect.h
@@ -21,13 +21,15 @@
 public:
 
     /// Convolve with an arbitrary user-specified kernel
-    static GrFragmentProcessor* Create(GrTexture* tex,
+    static GrFragmentProcessor* Create(GrProcessorDataManager* procDataManager,
+                                       GrTexture* tex,
                                        Direction dir,
                                        int halfWidth,
                                        const float* kernel,
                                        bool useBounds,
                                        float bounds[2]) {
-        return SkNEW_ARGS(GrConvolutionEffect, (tex,
+        return SkNEW_ARGS(GrConvolutionEffect, (procDataManager,
+                                                tex,
                                                 dir,
                                                 halfWidth,
                                                 kernel,
@@ -36,13 +38,15 @@
     }
 
     /// Convolve with a Gaussian kernel
-    static GrFragmentProcessor* CreateGaussian(GrTexture* tex,
+    static GrFragmentProcessor* CreateGaussian(GrProcessorDataManager* procDataManager,
+                                               GrTexture* tex,
                                                Direction dir,
                                                int halfWidth,
                                                float gaussianSigma,
                                                bool useBounds,
                                                float bounds[2]) {
-        return SkNEW_ARGS(GrConvolutionEffect, (tex,
+        return SkNEW_ARGS(GrConvolutionEffect, (procDataManager,
+                                                tex,
                                                 dir,
                                                 halfWidth,
                                                 gaussianSigma,
@@ -81,14 +85,16 @@
     float fBounds[2];
 
 private:
-    GrConvolutionEffect(GrTexture*, Direction,
+    GrConvolutionEffect(GrProcessorDataManager*,
+                        GrTexture*, Direction,
                         int halfWidth,
                         const float* kernel,
                         bool useBounds,
                         float bounds[2]);
 
     /// Convolve with a Gaussian kernel
-    GrConvolutionEffect(GrTexture*, Direction,
+    GrConvolutionEffect(GrProcessorDataManager*,
+                        GrTexture*, Direction,
                         int halfWidth,
                         float gaussianSigma,
                         bool useBounds,
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.cpp b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
index 0dd83b4..24e7820 100644
--- a/src/gpu/effects/GrMatrixConvolutionEffect.cpp
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
@@ -138,7 +138,8 @@
     fDomain.setData(pdman, conv.domain(), texture.origin());
 }
 
-GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture,
+GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrProcessorDataManager* procDataManager,
+                                                     GrTexture* texture,
                                                      const SkIRect& bounds,
                                                      const SkISize& kernelSize,
                                                      const SkScalar* kernel,
@@ -147,7 +148,7 @@
                                                      const SkIPoint& kernelOffset,
                                                      GrTextureDomain::Mode tileMode,
                                                      bool convolveAlpha)
-  : INHERITED(texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture)),
+  : INHERITED(procDataManager, texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture)),
     fKernelSize(kernelSize),
     fGain(SkScalarToFloat(gain)),
     fBias(SkScalarToFloat(bias) / 255.0f),
@@ -187,7 +188,8 @@
 
 // Static function to create a 2D convolution
 GrFragmentProcessor*
-GrMatrixConvolutionEffect::CreateGaussian(GrTexture* texture,
+GrMatrixConvolutionEffect::CreateGaussian(GrProcessorDataManager* procDataManager,
+                                          GrTexture* texture,
                                           const SkIRect& bounds,
                                           const SkISize& kernelSize,
                                           SkScalar gain,
@@ -223,7 +225,8 @@
     for (int i = 0; i < width * height; ++i) {
         kernel[i] *= scale;
     }
-    return SkNEW_ARGS(GrMatrixConvolutionEffect, (texture,
+    return SkNEW_ARGS(GrMatrixConvolutionEffect, (procDataManager,
+                                                  texture,
                                                   bounds,
                                                   kernelSize,
                                                   kernel,
@@ -257,7 +260,8 @@
     GrTextureDomain::Mode tileMode =
             static_cast<GrTextureDomain::Mode>(d->fRandom->nextRangeU(0, 2));
     bool convolveAlpha = d->fRandom->nextBool();
-    return GrMatrixConvolutionEffect::Create(d->fTextures[texIdx],
+    return GrMatrixConvolutionEffect::Create(d->fProcDataManager,
+                                             d->fTextures[texIdx],
                                              bounds,
                                              kernelSize,
                                              kernel.get(),
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.h b/src/gpu/effects/GrMatrixConvolutionEffect.h
index 6a340fb..7a95df3 100644
--- a/src/gpu/effects/GrMatrixConvolutionEffect.h
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.h
@@ -18,7 +18,8 @@
 
 class GrMatrixConvolutionEffect : public GrSingleTextureEffect {
 public:
-    static GrFragmentProcessor* Create(GrTexture* texture,
+    static GrFragmentProcessor* Create(GrProcessorDataManager* procDataManager,
+                                       GrTexture* texture,
                                        const SkIRect& bounds,
                                        const SkISize& kernelSize,
                                        const SkScalar* kernel,
@@ -27,7 +28,8 @@
                                        const SkIPoint& kernelOffset,
                                        GrTextureDomain::Mode tileMode,
                                        bool convolveAlpha) {
-        return SkNEW_ARGS(GrMatrixConvolutionEffect, (texture,
+        return SkNEW_ARGS(GrMatrixConvolutionEffect, (procDataManager,
+                                                      texture,
                                                       bounds,
                                                       kernelSize,
                                                       kernel,
@@ -38,7 +40,8 @@
                                                       convolveAlpha));
     }
 
-    static GrFragmentProcessor* CreateGaussian(GrTexture* texture,
+    static GrFragmentProcessor* CreateGaussian(GrProcessorDataManager*,
+                                               GrTexture* texture,
                                                const SkIRect& bounds,
                                                const SkISize& kernelSize,
                                                SkScalar gain,
@@ -67,7 +70,8 @@
     GrGLFragmentProcessor* createGLInstance() const override;
 
 private:
-    GrMatrixConvolutionEffect(GrTexture*,
+    GrMatrixConvolutionEffect(GrProcessorDataManager*,
+                              GrTexture*,
                               const SkIRect& bounds,
                               const SkISize& kernelSize,
                               const SkScalar* kernel,
diff --git a/src/gpu/effects/GrSimpleTextureEffect.cpp b/src/gpu/effects/GrSimpleTextureEffect.cpp
index 0f6f403..c1b2811 100644
--- a/src/gpu/effects/GrSimpleTextureEffect.cpp
+++ b/src/gpu/effects/GrSimpleTextureEffect.cpp
@@ -77,5 +77,6 @@
     GrCoordSet coordSet = kCoordSets[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kCoordSets))];
 
     const SkMatrix& matrix = GrTest::TestMatrix(d->fRandom);
-    return GrSimpleTextureEffect::Create(d->fTextures[texIdx], matrix, coordSet);
+    return GrSimpleTextureEffect::Create(d->fProcDataManager, d->fTextures[texIdx], matrix,
+                                         coordSet);
 }
diff --git a/src/gpu/effects/GrSimpleTextureEffect.h b/src/gpu/effects/GrSimpleTextureEffect.h
index 79e660f..70d3622 100644
--- a/src/gpu/effects/GrSimpleTextureEffect.h
+++ b/src/gpu/effects/GrSimpleTextureEffect.h
@@ -23,26 +23,30 @@
 class GrSimpleTextureEffect : public GrSingleTextureEffect {
 public:
     /* unfiltered, clamp mode */
-    static GrFragmentProcessor* Create(GrTexture* tex,
+    static GrFragmentProcessor* Create(GrProcessorDataManager* procDataManager,
+                                       GrTexture* tex,
                                        const SkMatrix& matrix,
                                        GrCoordSet coordSet = kLocal_GrCoordSet) {
-        return SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, GrTextureParams::kNone_FilterMode,
-                                                  coordSet));
+        return SkNEW_ARGS(GrSimpleTextureEffect, (procDataManager, tex, matrix,
+                                                  GrTextureParams::kNone_FilterMode, coordSet));
     }
 
     /* clamp mode */
-    static GrFragmentProcessor* Create(GrTexture* tex,
+    static GrFragmentProcessor* Create(GrProcessorDataManager* procDataManager,
+                                       GrTexture* tex,
                                        const SkMatrix& matrix,
                                        GrTextureParams::FilterMode filterMode,
                                        GrCoordSet coordSet = kLocal_GrCoordSet) {
-        return SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, filterMode, coordSet));
+        return SkNEW_ARGS(GrSimpleTextureEffect, (procDataManager, tex, matrix, filterMode,
+                                                  coordSet));
     }
 
-    static GrFragmentProcessor* Create(GrTexture* tex,
+    static GrFragmentProcessor* Create(GrProcessorDataManager* procDataManager,
+                                       GrTexture* tex,
                                        const SkMatrix& matrix,
                                        const GrTextureParams& p,
                                        GrCoordSet coordSet = kLocal_GrCoordSet) {
-        return SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, p, coordSet));
+        return SkNEW_ARGS(GrSimpleTextureEffect, (procDataManager, tex, matrix, p, coordSet));
     }
 
     virtual ~GrSimpleTextureEffect() {}
@@ -54,19 +58,21 @@
     GrGLFragmentProcessor* createGLInstance() const override;
 
 private:
-    GrSimpleTextureEffect(GrTexture* texture,
+    GrSimpleTextureEffect(GrProcessorDataManager* procDataManager,
+                          GrTexture* texture,
                           const SkMatrix& matrix,
                           GrTextureParams::FilterMode filterMode,
                           GrCoordSet coordSet)
-        : GrSingleTextureEffect(texture, matrix, filterMode, coordSet) {
+        : GrSingleTextureEffect(procDataManager, texture, matrix, filterMode, coordSet) {
         this->initClassID<GrSimpleTextureEffect>();
     }
 
-    GrSimpleTextureEffect(GrTexture* texture,
+    GrSimpleTextureEffect(GrProcessorDataManager* procDataManager,
+                          GrTexture* texture,
                           const SkMatrix& matrix,
                           const GrTextureParams& params,
                           GrCoordSet coordSet)
-        : GrSingleTextureEffect(texture, matrix, params, coordSet) {
+        : GrSingleTextureEffect(procDataManager, texture, matrix, params, coordSet) {
         this->initClassID<GrSimpleTextureEffect>();
     }
 
diff --git a/src/gpu/effects/GrSingleTextureEffect.cpp b/src/gpu/effects/GrSingleTextureEffect.cpp
index c291735..e4e20a9 100644
--- a/src/gpu/effects/GrSingleTextureEffect.cpp
+++ b/src/gpu/effects/GrSingleTextureEffect.cpp
@@ -7,7 +7,8 @@
 
 #include "effects/GrSingleTextureEffect.h"
 
-GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
+GrSingleTextureEffect::GrSingleTextureEffect(GrProcessorDataManager* procDataManager,
+                                             GrTexture* texture,
                                              const SkMatrix& m,
                                              GrCoordSet coordSet)
     : fCoordTransform(coordSet, m, texture, GrTextureParams::kNone_FilterMode)
@@ -16,7 +17,8 @@
     this->addTextureAccess(&fTextureAccess);
 }
 
-GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
+GrSingleTextureEffect::GrSingleTextureEffect(GrProcessorDataManager* procDataManager,
+                                             GrTexture* texture,
                                              const SkMatrix& m,
                                              GrTextureParams::FilterMode filterMode,
                                              GrCoordSet coordSet)
@@ -26,7 +28,8 @@
     this->addTextureAccess(&fTextureAccess);
 }
 
-GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture,
+GrSingleTextureEffect::GrSingleTextureEffect(GrProcessorDataManager* procDataManager,
+                                             GrTexture* texture,
                                              const SkMatrix& m,
                                              const GrTextureParams& params,
                                              GrCoordSet coordSet)
diff --git a/src/gpu/effects/GrSingleTextureEffect.h b/src/gpu/effects/GrSingleTextureEffect.h
index 9df0cff..cd952c4 100644
--- a/src/gpu/effects/GrSingleTextureEffect.h
+++ b/src/gpu/effects/GrSingleTextureEffect.h
@@ -25,11 +25,14 @@
 
 protected:
     /** unfiltered, clamp mode */
-    GrSingleTextureEffect(GrTexture*, const SkMatrix&, GrCoordSet = kLocal_GrCoordSet);
-    /** clamp mode */
-    GrSingleTextureEffect(GrTexture*, const SkMatrix&, GrTextureParams::FilterMode filterMode,
+    GrSingleTextureEffect(GrProcessorDataManager*, GrTexture*, const SkMatrix&,
                           GrCoordSet = kLocal_GrCoordSet);
-    GrSingleTextureEffect(GrTexture*,
+    /** clamp mode */
+    GrSingleTextureEffect(GrProcessorDataManager*, GrTexture*, const SkMatrix&,
+                          GrTextureParams::FilterMode filterMode,
+                          GrCoordSet = kLocal_GrCoordSet);
+    GrSingleTextureEffect(GrProcessorDataManager*,
+                          GrTexture*,
                           const SkMatrix&,
                           const GrTextureParams&,
                           GrCoordSet = kLocal_GrCoordSet);
diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp
index 31f51aa..73eb8ff 100644
--- a/src/gpu/effects/GrTextureDomain.cpp
+++ b/src/gpu/effects/GrTextureDomain.cpp
@@ -218,7 +218,8 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrFragmentProcessor* GrTextureDomainEffect::Create(GrTexture* texture,
+GrFragmentProcessor* GrTextureDomainEffect::Create(GrProcessorDataManager* procDataManager,
+                                                   GrTexture* texture,
                                                    const SkMatrix& matrix,
                                                    const SkRect& domain,
                                                    GrTextureDomain::Mode mode,
@@ -227,10 +228,11 @@
     static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1};
     if (GrTextureDomain::kIgnore_Mode == mode ||
         (GrTextureDomain::kClamp_Mode == mode && domain.contains(kFullRect))) {
-        return GrSimpleTextureEffect::Create(texture, matrix, filterMode);
+        return GrSimpleTextureEffect::Create(procDataManager, texture, matrix, filterMode);
     } else {
 
-        return SkNEW_ARGS(GrTextureDomainEffect, (texture,
+        return SkNEW_ARGS(GrTextureDomainEffect, (procDataManager,
+                                                  texture,
                                                   matrix,
                                                   domain,
                                                   mode,
@@ -239,13 +241,14 @@
     }
 }
 
-GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture,
+GrTextureDomainEffect::GrTextureDomainEffect(GrProcessorDataManager* procDataManager,
+                                             GrTexture* texture,
                                              const SkMatrix& matrix,
                                              const SkRect& domain,
                                              GrTextureDomain::Mode mode,
                                              GrTextureParams::FilterMode filterMode,
                                              GrCoordSet coordSet)
-    : GrSingleTextureEffect(texture, matrix, filterMode, coordSet)
+    : GrSingleTextureEffect(procDataManager, texture, matrix, filterMode, coordSet)
     , fTextureDomain(domain, mode) {
     SkASSERT(mode != GrTextureDomain::kRepeat_Mode ||
             filterMode == GrTextureParams::kNone_FilterMode);
@@ -299,7 +302,8 @@
     const SkMatrix& matrix = GrTest::TestMatrix(d->fRandom);
     bool bilerp = mode != GrTextureDomain::kRepeat_Mode ? d->fRandom->nextBool() : false;
     GrCoordSet coords = d->fRandom->nextBool() ? kLocal_GrCoordSet : kDevice_GrCoordSet;
-    return GrTextureDomainEffect::Create(d->fTextures[texIdx],
+    return GrTextureDomainEffect::Create(d->fProcDataManager,
+                                         d->fTextures[texIdx],
                                          matrix,
                                          domain,
                                          mode,
diff --git a/src/gpu/effects/GrTextureDomain.h b/src/gpu/effects/GrTextureDomain.h
index 1610580..f9de4fa 100644
--- a/src/gpu/effects/GrTextureDomain.h
+++ b/src/gpu/effects/GrTextureDomain.h
@@ -157,7 +157,8 @@
 class GrTextureDomainEffect : public GrSingleTextureEffect {
 
 public:
-    static GrFragmentProcessor* Create(GrTexture*,
+    static GrFragmentProcessor* Create(GrProcessorDataManager*,
+                                       GrTexture*,
                                        const SkMatrix&,
                                        const SkRect& domain,
                                        GrTextureDomain::Mode,
@@ -178,7 +179,8 @@
     GrTextureDomain fTextureDomain;
 
 private:
-    GrTextureDomainEffect(GrTexture*,
+    GrTextureDomainEffect(GrProcessorDataManager*,
+                          GrTexture*,
                           const SkMatrix&,
                           const SkRect& domain,
                           GrTextureDomain::Mode,