Remove GrSingleTextureEffect

Change-Id: I510cc0657f9433b206dc2ab643fa557667263294
Reviewed-on: https://skia-review.googlesource.com/27180
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index 58064ce..2122406 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -25,7 +25,6 @@
 #include "GrTextureProxy.h"
 
 #include "SkGr.h"
-#include "effects/GrSingleTextureEffect.h"
 #include "effects/GrTextureDomain.h"
 #include "glsl/GrGLSLFragmentProcessor.h"
 #include "glsl/GrGLSLFragmentShaderBuilder.h"
@@ -593,7 +592,7 @@
 
 #if SK_SUPPORT_GPU
 
-class GrLightingEffect : public GrSingleTextureEffect {
+class GrLightingEffect : public GrFragmentProcessor {
 public:
     ~GrLightingEffect() override;
 
@@ -611,13 +610,15 @@
     bool onIsEqual(const GrFragmentProcessor&) const override;
 
 private:
+    GrCoordTransform fCoordTransform;
+    GrTextureDomain fDomain;
+    TextureSampler fTextureSampler;
     const SkImageFilterLight* fLight;
     SkScalar fSurfaceScale;
     SkMatrix fFilterMatrix;
     BoundaryMode fBoundaryMode;
-    GrTextureDomain fDomain;
 
-    typedef GrSingleTextureEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
 class GrDiffuseLightingEffect : public GrLightingEffect {
@@ -1685,12 +1686,17 @@
                                    BoundaryMode boundaryMode,
                                    const SkIRect* srcBounds)
         // Perhaps this could advertise the opaque or coverage-as-alpha optimizations?
-        : INHERITED(kNone_OptimizationFlags, proxy, nullptr, SkMatrix::I())
+        : INHERITED(kNone_OptimizationFlags)
+        , fCoordTransform(proxy.get())
+        , fDomain(create_domain(proxy.get(), srcBounds, GrTextureDomain::kDecal_Mode))
+        , fTextureSampler(std::move(proxy))
         , fLight(light)
         , fSurfaceScale(surfaceScale)
         , fFilterMatrix(matrix)
-        , fBoundaryMode(boundaryMode)
-        , fDomain(create_domain(proxy.get(), srcBounds, GrTextureDomain::kDecal_Mode)) {
+        , fBoundaryMode(boundaryMode) {
+    this->initClassID<GrLightingEffect>();
+    this->addCoordTransform(&fCoordTransform);
+    this->addTextureSampler(&fTextureSampler);
     fLight->ref();
 }
 
diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp
index b2c6714..558e490 100644
--- a/src/effects/SkMagnifierImageFilter.cpp
+++ b/src/effects/SkMagnifierImageFilter.cpp
@@ -17,16 +17,16 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 #if SK_SUPPORT_GPU
+#include "../private/GrGLSL.h"
 #include "GrContext.h"
+#include "GrCoordTransform.h"
 #include "GrTexture.h"
 #include "effects/GrProxyMove.h"
-#include "effects/GrSingleTextureEffect.h"
 #include "glsl/GrGLSLColorSpaceXformHelper.h"
 #include "glsl/GrGLSLFragmentProcessor.h"
 #include "glsl/GrGLSLFragmentShaderBuilder.h"
 #include "glsl/GrGLSLProgramDataManager.h"
 #include "glsl/GrGLSLUniformHandler.h"
-#include "../private/GrGLSL.h"
 #endif
 
 sk_sp<SkImageFilter> SkMagnifierImageFilter::Make(const SkRect& srcRect, SkScalar inset,
@@ -48,7 +48,7 @@
 }
 
 #if SK_SUPPORT_GPU
-class GrMagnifierEffect : public GrSingleTextureEffect {
+class GrMagnifierEffect : public GrFragmentProcessor {
 public:
     static sk_sp<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
                                            sk_sp<GrColorSpaceXform> colorSpaceXform,
@@ -69,6 +69,14 @@
 
     const char* name() const override { return "Magnifier"; }
 
+    SkString dumpInfo() const override {
+        SkString str;
+        str.appendf("Texture: %d", fTextureSampler.proxy()->uniqueID().asUInt());
+        return str;
+    }
+
+    const GrColorSpaceXform* colorSpaceXform() const { return fColorSpaceXform.get(); }
+
     const SkIRect& bounds() const { return fBounds; }    // Bounds of source image.
     const SkRect& srcRect() const { return fSrcRect; }
 
@@ -89,10 +97,11 @@
                       float yInvZoom,
                       float xInvInset,
                       float yInvInset)
-            : INHERITED{ModulationFlags(proxy->config()),
-                        GR_PROXY_MOVE(proxy),
-                        std::move(colorSpaceXform),
-                        SkMatrix::I()} // TODO: no GrSamplerParams::kBilerp_FilterMode?
+            : INHERITED{ModulateByConfigOptimizationFlags(proxy->config())}
+            // TODO: no GrSamplerParams::kBilerp_FilterMode?
+            , fCoordTransform(proxy.get())
+            , fTextureSampler(std::move(proxy))
+            , fColorSpaceXform(std::move(colorSpaceXform))
             , fBounds(bounds)
             , fSrcRect(srcRect)
             , fXInvZoom(xInvZoom)
@@ -100,6 +109,8 @@
             , fXInvInset(xInvInset)
             , fYInvInset(yInvInset) {
         this->initClassID<GrMagnifierEffect>();
+        this->addCoordTransform(&fCoordTransform);
+        this->addTextureSampler(&fTextureSampler);
     }
 
     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
@@ -110,6 +121,9 @@
 
     GR_DECLARE_FRAGMENT_PROCESSOR_TEST
 
+    GrCoordTransform fCoordTransform;
+    TextureSampler fTextureSampler;
+    sk_sp<GrColorSpaceXform> fColorSpaceXform;
     SkIRect fBounds;
     SkRect  fSrcRect;
     float fXInvZoom;
@@ -117,7 +131,7 @@
     float fXInvInset;
     float fYInvInset;
 
-    typedef GrSingleTextureEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
 // For brevity
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index 2cc224d..e2e8dba 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -326,7 +326,8 @@
                                        Direction direction,
                                        int radius,
                                        MorphologyType type)
-        : INHERITED{ModulationFlags(proxy->config()), GR_PROXY_MOVE(proxy), direction, radius}
+        : INHERITED{ModulateByConfigOptimizationFlags(proxy->config()), GR_PROXY_MOVE(proxy),
+                    direction, radius}
         , fType(type)
         , fUseRange(false) {
     this->initClassID<GrMorphologyEffect>();
@@ -337,7 +338,8 @@
                                        int radius,
                                        MorphologyType type,
                                        const float range[2])
-        : INHERITED{ModulationFlags(proxy->config()), GR_PROXY_MOVE(proxy), direction, radius}
+        : INHERITED{ModulateByConfigOptimizationFlags(proxy->config()), GR_PROXY_MOVE(proxy),
+                    direction, radius}
         , fType(type)
         , fUseRange(true) {
     this->initClassID<GrMorphologyEffect>();
diff --git a/src/gpu/GrFragmentProcessor.h b/src/gpu/GrFragmentProcessor.h
index 02ed0c7..78319c7 100644
--- a/src/gpu/GrFragmentProcessor.h
+++ b/src/gpu/GrFragmentProcessor.h
@@ -249,6 +249,21 @@
     };
     GR_DECL_BITFIELD_OPS_FRIENDS(OptimizationFlags)
 
+    /**
+     * Can be used as a helper to decide which fragment processor OptimizationFlags should be set.
+     * This assumes that the subclass output color will be a modulation of the input color with a
+     * value read from a texture of the passed config and that the texture contains premultiplied
+     * color or alpha values that are in range.
+     */
+    static OptimizationFlags ModulateByConfigOptimizationFlags(GrPixelConfig config) {
+        if (GrPixelConfigIsOpaque(config)) {
+            return kCompatibleWithCoverageAsAlpha_OptimizationFlag |
+                   kPreservesOpaqueInput_OptimizationFlag;
+        } else {
+            return kCompatibleWithCoverageAsAlpha_OptimizationFlag;
+        }
+    }
+
     GrFragmentProcessor(OptimizationFlags optimizationFlags) : fFlags(optimizationFlags) {
         SkASSERT((fFlags & ~kAll_OptimizationFlags) == 0);
     }
diff --git a/src/gpu/effects/Gr1DKernelEffect.h b/src/gpu/effects/Gr1DKernelEffect.h
index fbdfed6..8eac5cd 100644
--- a/src/gpu/effects/Gr1DKernelEffect.h
+++ b/src/gpu/effects/Gr1DKernelEffect.h
@@ -8,7 +8,8 @@
 #ifndef Gr1DKernelEffect_DEFINED
 #define Gr1DKernelEffect_DEFINED
 
-#include "GrSingleTextureEffect.h"
+#include "GrCoordTransform.h"
+#include "GrFragmentProcessor.h"
 #include "SkMatrix.h"
 
 /**
@@ -20,8 +21,7 @@
  * two times the radius.
  */
 
-class Gr1DKernelEffect : public GrSingleTextureEffect {
-
+class Gr1DKernelEffect : public GrFragmentProcessor {
 public:
     enum Direction {
         kX_Direction,
@@ -44,18 +44,24 @@
     }
 
 protected:
-    Gr1DKernelEffect(OptimizationFlags optFlags,
-                     sk_sp<GrTextureProxy> proxy, Direction direction, int radius)
-        : INHERITED(optFlags, std::move(proxy), nullptr, SkMatrix::I())
-        , fDirection(direction)
-        , fRadius(radius) {
+    Gr1DKernelEffect(OptimizationFlags optFlags, sk_sp<GrTextureProxy> proxy, Direction direction,
+                     int radius)
+            : INHERITED(optFlags)
+            , fCoordTransform(proxy.get())
+            , fTextureSampler(std::move(proxy))
+            , fDirection(direction)
+            , fRadius(radius) {
+        this->addCoordTransform(&fCoordTransform);
+        this->addTextureSampler(&fTextureSampler);
     }
 
 private:
-    Direction       fDirection;
-    int             fRadius;
+    GrCoordTransform fCoordTransform;
+    TextureSampler   fTextureSampler;
+    Direction        fDirection;
+    int              fRadius;
 
-    typedef GrSingleTextureEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
 #endif
diff --git a/src/gpu/effects/GrBicubicEffect.cpp b/src/gpu/effects/GrBicubicEffect.cpp
index f7441bc..9472f51 100644
--- a/src/gpu/effects/GrBicubicEffect.cpp
+++ b/src/gpu/effects/GrBicubicEffect.cpp
@@ -135,26 +135,31 @@
 
 GrBicubicEffect::GrBicubicEffect(sk_sp<GrTextureProxy> proxy,
                                  sk_sp<GrColorSpaceXform> colorSpaceXform,
-                                 const SkMatrix &matrix,
+                                 const SkMatrix& matrix,
                                  const SkShader::TileMode tileModes[2])
-        : INHERITED{ModulationFlags(proxy->config()),
-                    GR_PROXY_MOVE(proxy),
-                    std::move(colorSpaceXform),
-                    matrix,
-                    GrSamplerParams(tileModes, GrSamplerParams::kNone_FilterMode)}
-        , fDomain(GrTextureDomain::IgnoredDomain()) {
+        : INHERITED{ModulateByConfigOptimizationFlags(proxy->config())}
+        , fCoordTransform(matrix, proxy.get())
+        , fDomain(GrTextureDomain::IgnoredDomain())
+        , fTextureSampler(std::move(proxy),
+                          GrSamplerParams(tileModes, GrSamplerParams::kNone_FilterMode))
+        , fColorSpaceXform(std::move(colorSpaceXform)) {
     this->initClassID<GrBicubicEffect>();
+    this->addCoordTransform(&fCoordTransform);
+    this->addTextureSampler(&fTextureSampler);
 }
 
 GrBicubicEffect::GrBicubicEffect(sk_sp<GrTextureProxy> proxy,
                                  sk_sp<GrColorSpaceXform> colorSpaceXform,
-                                 const SkMatrix &matrix,
+                                 const SkMatrix& matrix,
                                  const SkRect& domain)
-        : INHERITED(ModulationFlags(proxy->config()), proxy,
-                    std::move(colorSpaceXform), matrix,
-                    GrSamplerParams(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode))
-        , fDomain(proxy.get(), domain, GrTextureDomain::kClamp_Mode) {
+        : INHERITED(ModulateByConfigOptimizationFlags(proxy->config()))
+        , fCoordTransform(matrix, proxy.get())
+        , fDomain(proxy.get(), domain, GrTextureDomain::kClamp_Mode)
+        , fTextureSampler(std::move(proxy))
+        , fColorSpaceXform(std::move(colorSpaceXform)) {
     this->initClassID<GrBicubicEffect>();
+    this->addCoordTransform(&fCoordTransform);
+    this->addTextureSampler(&fTextureSampler);
 }
 
 GrBicubicEffect::~GrBicubicEffect() {
diff --git a/src/gpu/effects/GrBicubicEffect.h b/src/gpu/effects/GrBicubicEffect.h
index e96d290..0d4c7c5 100644
--- a/src/gpu/effects/GrBicubicEffect.h
+++ b/src/gpu/effects/GrBicubicEffect.h
@@ -8,13 +8,12 @@
 #ifndef GrBicubicTextureEffect_DEFINED
 #define GrBicubicTextureEffect_DEFINED
 
-#include "GrSingleTextureEffect.h"
 #include "GrTextureDomain.h"
 #include "glsl/GrGLSLFragmentProcessor.h"
 
 class GrInvariantOutput;
 
-class GrBicubicEffect : public GrSingleTextureEffect {
+class GrBicubicEffect : public GrFragmentProcessor {
 public:
     enum {
         kFilterTexelPad = 2, // Given a src rect in texels to be filtered, this number of
@@ -26,6 +25,8 @@
 
     const GrTextureDomain& domain() const { return fDomain; }
 
+    const GrColorSpaceXform* colorSpaceXform() const { return fColorSpaceXform.get(); }
+
     /**
      * Create a Mitchell filter effect with specified texture matrix and x/y tile modes.
      */
@@ -72,11 +73,14 @@
 
     bool onIsEqual(const GrFragmentProcessor&) const override;
 
+    GrCoordTransform fCoordTransform;
     GrTextureDomain fDomain;
+    TextureSampler fTextureSampler;
+    sk_sp<GrColorSpaceXform> fColorSpaceXform;
 
     GR_DECLARE_FRAGMENT_PROCESSOR_TEST
 
-    typedef GrSingleTextureEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
 #endif
diff --git a/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp b/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp
index 1ab9b78..8e8c300 100644
--- a/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp
+++ b/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp
@@ -201,10 +201,8 @@
                                                             float gaussianSigma,
                                                             GrTextureDomain::Mode mode,
                                                             int bounds[2])
-        : INHERITED{ModulationFlags(proxy->config()),
-                    GR_PROXY_MOVE(proxy),
-                    direction,
-                    radius}
+        : INHERITED{ModulateByConfigOptimizationFlags(proxy->config()), GR_PROXY_MOVE(proxy),
+                    direction, radius}
         , fMode(mode) {
     this->initClassID<GrGaussianConvolutionFragmentProcessor>();
     SkASSERT(radius <= kMaxKernelRadius);
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.cpp b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
index abfe5b3..cb453fc 100644
--- a/src/gpu/effects/GrMatrixConvolutionEffect.cpp
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
@@ -158,15 +158,19 @@
                                                      const SkIPoint& kernelOffset,
                                                      GrTextureDomain::Mode tileMode,
                                                      bool convolveAlpha)
-    // To advertise either the modulation or opaqueness optimizations we'd have to examine the
-    // parameters.
-    : INHERITED(kNone_OptimizationFlags, proxy, nullptr, SkMatrix::I())
-    , fKernelSize(kernelSize)
-    , fGain(SkScalarToFloat(gain))
-    , fBias(SkScalarToFloat(bias) / 255.0f)
-    , fConvolveAlpha(convolveAlpha)
-    , fDomain(proxy.get(), GrTextureDomain::MakeTexelDomainForMode(bounds, tileMode), tileMode) {
+        // To advertise either the modulation or opaqueness optimizations we'd have to examine the
+        // parameters.
+        : INHERITED(kNone_OptimizationFlags)
+        , fCoordTransform(proxy.get())
+        , fDomain(proxy.get(), GrTextureDomain::MakeTexelDomainForMode(bounds, tileMode), tileMode)
+        , fTextureSampler(std::move(proxy))
+        , fKernelSize(kernelSize)
+        , fGain(SkScalarToFloat(gain))
+        , fBias(SkScalarToFloat(bias) / 255.0f)
+        , fConvolveAlpha(convolveAlpha) {
     this->initClassID<GrMatrixConvolutionEffect>();
+    this->addCoordTransform(&fCoordTransform);
+    this->addTextureSampler(&fTextureSampler);
     for (int i = 0; i < kernelSize.width() * kernelSize.height(); i++) {
         fKernel[i] = SkScalarToFloat(kernel[i]);
     }
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.h b/src/gpu/effects/GrMatrixConvolutionEffect.h
index 57e0fd9..a89d640 100644
--- a/src/gpu/effects/GrMatrixConvolutionEffect.h
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.h
@@ -8,14 +8,13 @@
 #ifndef GrMatrixConvolutionEffect_DEFINED
 #define GrMatrixConvolutionEffect_DEFINED
 
-#include "GrSingleTextureEffect.h"
 #include "GrTextureDomain.h"
 
 // A little bit less than the minimum # uniforms required by DX9SM2 (32).
 // Allows for a 5x5 kernel (or 25x1, for that matter).
 #define MAX_KERNEL_SIZE 25
 
-class GrMatrixConvolutionEffect : public GrSingleTextureEffect {
+class GrMatrixConvolutionEffect : public GrFragmentProcessor {
 public:
     static sk_sp<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
                                            const SkIRect& bounds,
@@ -70,18 +69,20 @@
 
     bool onIsEqual(const GrFragmentProcessor&) const override;
 
-    SkIRect         fBounds;
-    SkISize         fKernelSize;
-    float           fKernel[MAX_KERNEL_SIZE];
-    float           fGain;
-    float           fBias;
-    float           fKernelOffset[2];
-    bool            fConvolveAlpha;
-    GrTextureDomain fDomain;
+    GrCoordTransform fCoordTransform;
+    GrTextureDomain  fDomain;
+    TextureSampler   fTextureSampler;
+    SkIRect          fBounds;
+    SkISize          fKernelSize;
+    float            fKernel[MAX_KERNEL_SIZE];
+    float            fGain;
+    float            fBias;
+    float            fKernelOffset[2];
+    bool             fConvolveAlpha;
 
     GR_DECLARE_FRAGMENT_PROCESSOR_TEST
 
-    typedef GrSingleTextureEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
 #endif
diff --git a/src/gpu/effects/GrSingleTextureEffect.cpp b/src/gpu/effects/GrSingleTextureEffect.cpp
deleted file mode 100644
index 9dbf32d..0000000
--- a/src/gpu/effects/GrSingleTextureEffect.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "effects/GrSingleTextureEffect.h"
-
-#include "GrTextureProxy.h"
-
-GrSingleTextureEffect::GrSingleTextureEffect(OptimizationFlags optFlags,
-                                             sk_sp<GrTextureProxy> proxy,
-                                             sk_sp<GrColorSpaceXform> colorSpaceXform,
-                                             const SkMatrix& m)
-        : INHERITED(optFlags)
-        , fCoordTransform(m, proxy.get())
-        , fTextureSampler(std::move(proxy))
-        , fColorSpaceXform(std::move(colorSpaceXform)) {
-    this->addCoordTransform(&fCoordTransform);
-    this->addTextureSampler(&fTextureSampler);
-}
-
-GrSingleTextureEffect::GrSingleTextureEffect(OptimizationFlags optFlags,
-                                             sk_sp<GrTextureProxy> proxy,
-                                             sk_sp<GrColorSpaceXform> colorSpaceXform,
-                                             const SkMatrix& m,
-                                             GrSamplerParams::FilterMode filterMode)
-        : INHERITED(optFlags)
-        , fCoordTransform(m, proxy.get())
-        , fTextureSampler(std::move(proxy), filterMode)
-        , fColorSpaceXform(std::move(colorSpaceXform)) {
-    this->addCoordTransform(&fCoordTransform);
-    this->addTextureSampler(&fTextureSampler);
-}
-
-GrSingleTextureEffect::GrSingleTextureEffect(OptimizationFlags optFlags,
-                                             sk_sp<GrTextureProxy> proxy,
-                                             sk_sp<GrColorSpaceXform> colorSpaceXform,
-                                             const SkMatrix& m, const GrSamplerParams& params)
-        : INHERITED(optFlags)
-        , fCoordTransform(m, proxy.get())
-        , fTextureSampler(std::move(proxy), params)
-        , fColorSpaceXform(std::move(colorSpaceXform)) {
-    this->addCoordTransform(&fCoordTransform);
-    this->addTextureSampler(&fTextureSampler);
-}
diff --git a/src/gpu/effects/GrSingleTextureEffect.h b/src/gpu/effects/GrSingleTextureEffect.h
deleted file mode 100644
index eab29c6..0000000
--- a/src/gpu/effects/GrSingleTextureEffect.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrSingleTextureEffect_DEFINED
-#define GrSingleTextureEffect_DEFINED
-
-#include "GrFragmentProcessor.h"
-#include "GrColorSpaceXform.h"
-#include "GrCoordTransform.h"
-
-class GrTextureProxy;
-class SkMatrix;
-
-/**
- * A base class for effects that draw a single texture with a texture matrix. This effect has no
- * backend implementations. One must be provided by the subclass.
- */
-class GrSingleTextureEffect : public GrFragmentProcessor {
-public:
-    SkString dumpInfo() const override {
-        SkString str;
-        str.appendf("Texture: %d", fTextureSampler.proxy()->uniqueID().asUInt());
-        return str;
-    }
-
-    GrColorSpaceXform* colorSpaceXform() const { return fColorSpaceXform.get(); }
-
-protected:
-    /** unfiltered, clamp mode */
-    GrSingleTextureEffect(OptimizationFlags, sk_sp<GrTextureProxy>,
-                          sk_sp<GrColorSpaceXform>, const SkMatrix&);
-    /** clamp mode */
-    GrSingleTextureEffect(OptimizationFlags, sk_sp<GrTextureProxy>,
-                          sk_sp<GrColorSpaceXform>, const SkMatrix&,
-                          GrSamplerParams::FilterMode filterMode);
-    GrSingleTextureEffect(OptimizationFlags, sk_sp<GrTextureProxy>,
-                          sk_sp<GrColorSpaceXform>, const SkMatrix&, const GrSamplerParams&);
-
-    /**
-     * Can be used as a helper to decide which fragment processor OptimizationFlags should be set.
-     * This assumes that the subclass output color will be a modulation of the input color with a
-     * value read from the texture and that the texture contains premultiplied color or alpha values
-     * that are in range.
-     */
-    static OptimizationFlags ModulationFlags(GrPixelConfig config) {
-        if (GrPixelConfigIsOpaque(config)) {
-            return kCompatibleWithCoverageAsAlpha_OptimizationFlag |
-                   kPreservesOpaqueInput_OptimizationFlag;
-        } else {
-            return kCompatibleWithCoverageAsAlpha_OptimizationFlag;
-        }
-    }
-
-private:
-    GrCoordTransform         fCoordTransform;
-    TextureSampler           fTextureSampler;
-    sk_sp<GrColorSpaceXform> fColorSpaceXform;
-
-    typedef GrFragmentProcessor INHERITED;
-};
-
-#endif
diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp
index 17ad223..e26ea67 100644
--- a/src/gpu/effects/GrTextureDomain.cpp
+++ b/src/gpu/effects/GrTextureDomain.cpp
@@ -230,12 +230,16 @@
                                              const SkRect& domain,
                                              GrTextureDomain::Mode mode,
                                              GrSamplerParams::FilterMode filterMode)
-    : GrSingleTextureEffect(OptFlags(proxy->config(), mode), proxy,
-                            std::move(colorSpaceXform), matrix, filterMode)
-    , fTextureDomain(proxy.get(), domain, mode) {
+        : INHERITED(OptFlags(proxy->config(), mode))
+        , fCoordTransform(matrix, proxy.get())
+        , fTextureDomain(proxy.get(), domain, mode)
+        , fTextureSampler(std::move(proxy), filterMode)
+        , fColorSpaceXform(std::move(colorSpaceXform)) {
     SkASSERT(mode != GrTextureDomain::kRepeat_Mode ||
              filterMode == GrSamplerParams::kNone_FilterMode);
     this->initClassID<GrTextureDomainEffect>();
+    this->addCoordTransform(&fCoordTransform);
+    this->addTextureSampler(&fTextureSampler);
 }
 
 void GrTextureDomainEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
diff --git a/src/gpu/effects/GrTextureDomain.h b/src/gpu/effects/GrTextureDomain.h
index c74a991..f134d8d 100644
--- a/src/gpu/effects/GrTextureDomain.h
+++ b/src/gpu/effects/GrTextureDomain.h
@@ -8,7 +8,9 @@
 #ifndef GrTextureDomainEffect_DEFINED
 #define GrTextureDomainEffect_DEFINED
 
-#include "GrSingleTextureEffect.h"
+#include "GrCoordTransform.h"
+#include "GrFragmentProcessor.h"
+#include "GrColorSpaceXform.h"
 #include "glsl/GrGLSLFragmentProcessor.h"
 #include "glsl/GrGLSLProgramDataManager.h"
 
@@ -149,8 +151,7 @@
 /**
  * A basic texture effect that uses GrTextureDomain.
  */
-class GrTextureDomainEffect : public GrSingleTextureEffect {
-
+class GrTextureDomainEffect : public GrFragmentProcessor {
 public:
     static sk_sp<GrFragmentProcessor> Make(sk_sp<GrTextureProxy>,
                                            sk_sp<GrColorSpaceXform>,
@@ -171,7 +172,10 @@
     }
 
 private:
+    GrCoordTransform fCoordTransform;
     GrTextureDomain fTextureDomain;
+    TextureSampler fTextureSampler;
+    sk_sp<GrColorSpaceXform> fColorSpaceXform;
 
     GrTextureDomainEffect(sk_sp<GrTextureProxy>,
                           sk_sp<GrColorSpaceXform>,
@@ -188,9 +192,11 @@
 
     bool onIsEqual(const GrFragmentProcessor&) const override;
 
+    const GrColorSpaceXform* colorSpaceXform() const { return fColorSpaceXform.get(); }
+
     GR_DECLARE_FRAGMENT_PROCESSOR_TEST
 
-    typedef GrSingleTextureEffect INHERITED;
+    typedef GrFragmentProcessor INHERITED;
 };
 
 class GrDeviceSpaceTextureDecalFragmentProcessor : public GrFragmentProcessor {
diff --git a/src/gpu/glsl/GrGLSLColorSpaceXformHelper.h b/src/gpu/glsl/GrGLSLColorSpaceXformHelper.h
index 9653efb..b4605ba 100644
--- a/src/gpu/glsl/GrGLSLColorSpaceXformHelper.h
+++ b/src/gpu/glsl/GrGLSLColorSpaceXformHelper.h
@@ -20,7 +20,7 @@
 public:
     GrGLSLColorSpaceXformHelper() : fValid(false) {}
 
-    void emitCode(GrGLSLUniformHandler* uniformHandler, GrColorSpaceXform* colorSpaceXform,
+    void emitCode(GrGLSLUniformHandler* uniformHandler, const GrColorSpaceXform* colorSpaceXform,
                   uint32_t visibility = kFragment_GrShaderFlag) {
         SkASSERT(uniformHandler);
         if (colorSpaceXform) {
@@ -30,7 +30,7 @@
         }
     }
 
-    void setData(const GrGLSLProgramDataManager& pdman, GrColorSpaceXform* colorSpaceXform) {
+    void setData(const GrGLSLProgramDataManager& pdman, const GrColorSpaceXform* colorSpaceXform) {
         pdman.setSkMatrix44(fGamutXformVar, colorSpaceXform->srcToDst());
     }