rewrote GrAlphaThresholdFragmentProcessor in sksl

Bug: skia:
Change-Id: I641b206fc3bc19ac190ad94ee755ab9e1caab9b3
Reviewed-on: https://skia-review.googlesource.com/21341
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/effects/GrAlphaThresholdFragmentProcessor.cpp b/src/effects/GrAlphaThresholdFragmentProcessor.cpp
index 2a45c5b..51869f3 100644
--- a/src/effects/GrAlphaThresholdFragmentProcessor.cpp
+++ b/src/effects/GrAlphaThresholdFragmentProcessor.cpp
@@ -1,179 +1,102 @@
 /*
- * Copyright 2016 Google Inc.
+ * Copyright 2017 Google Inc.
  *
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
 
+/*
+ * This file was autogenerated from GrAlphaThresholdFragmentProcessor.fp; do not modify.
+ */
 #include "GrAlphaThresholdFragmentProcessor.h"
 
-#if SK_SUPPORT_GPU
-
-#include "GrContext.h"
-#include "SkRefCnt.h"
+    #if SK_SUPPORT_GPU
+    inline GrFragmentProcessor::OptimizationFlags GrAlphaThresholdFragmentProcessor::optFlags(
+                                                                             float outerThreshold) {
+        if (outerThreshold >= 1.0) {
+            return kPreservesOpaqueInput_OptimizationFlag |
+                   kCompatibleWithCoverageAsAlpha_OptimizationFlag;
+        } else {
+            return kCompatibleWithCoverageAsAlpha_OptimizationFlag;
+        }
+    }
 #include "glsl/GrGLSLColorSpaceXformHelper.h"
 #include "glsl/GrGLSLFragmentProcessor.h"
 #include "glsl/GrGLSLFragmentShaderBuilder.h"
-#include "glsl/GrGLSLUniformHandler.h"
-#include "../private/GrGLSL.h"
-
-inline GrFragmentProcessor::OptimizationFlags GrAlphaThresholdFragmentProcessor::OptFlags(float outerThreshold) {
-    if (outerThreshold >= 1.f) {
-        return kPreservesOpaqueInput_OptimizationFlag |
-               kCompatibleWithCoverageAsAlpha_OptimizationFlag;
-    } else {
-        return kCompatibleWithCoverageAsAlpha_OptimizationFlag;
-    }
-}
-
-GrAlphaThresholdFragmentProcessor::GrAlphaThresholdFragmentProcessor(
-                                                           sk_sp<GrTextureProxy> proxy,
-                                                           sk_sp<GrColorSpaceXform> colorSpaceXform,
-                                                           sk_sp<GrTextureProxy> maskProxy,
-                                                           float innerThreshold,
-                                                           float outerThreshold,
-                                                           const SkIRect& bounds)
-        : INHERITED(OptFlags(outerThreshold))
-        , fInnerThreshold(innerThreshold)
-        , fOuterThreshold(outerThreshold)
-        , fImageCoordTransform(SkMatrix::I(), proxy.get())
-        , fImageTextureSampler(std::move(proxy))
-        , fColorSpaceXform(std::move(colorSpaceXform))
-        , fMaskCoordTransform(
-                  SkMatrix::MakeTrans(SkIntToScalar(-bounds.x()), SkIntToScalar(-bounds.y())),
-                  maskProxy.get())
-        , fMaskTextureSampler(std::move(maskProxy)) {
-    this->initClassID<GrAlphaThresholdFragmentProcessor>();
-    this->addCoordTransform(&fImageCoordTransform);
-    this->addTextureSampler(&fImageTextureSampler);
-    this->addCoordTransform(&fMaskCoordTransform);
-    this->addTextureSampler(&fMaskTextureSampler);
-}
-
-bool GrAlphaThresholdFragmentProcessor::onIsEqual(const GrFragmentProcessor& sBase) const {
-    const GrAlphaThresholdFragmentProcessor& s = sBase.cast<GrAlphaThresholdFragmentProcessor>();
-    return (this->fInnerThreshold == s.fInnerThreshold &&
-            this->fOuterThreshold == s.fOuterThreshold);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-class GrGLAlphaThresholdFragmentProcessor : public GrGLSLFragmentProcessor {
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLAlphaThresholdFragmentProcessor : public GrGLSLFragmentProcessor {
 public:
-    void emitCode(EmitArgs&) override;
-
-    static inline void GenKey(const GrProcessor& effect, const GrShaderCaps&,
-                              GrProcessorKeyBuilder* b) {
-        const GrAlphaThresholdFragmentProcessor& atfp =
-            effect.cast<GrAlphaThresholdFragmentProcessor>();
-        b->add32(GrColorSpaceXform::XformKey(atfp.colorSpaceXform()));
+    GrGLSLAlphaThresholdFragmentProcessor() {}
+    void emitCode(EmitArgs& args) override {
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        const GrAlphaThresholdFragmentProcessor& _outer = args.fFp.cast<GrAlphaThresholdFragmentProcessor>();
+        (void) _outer;
+        fColorSpaceHelper.emitCode(args.fUniformHandler, _outer.colorXform().get());
+        fInnerThresholdVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "innerThreshold");
+        fOuterThresholdVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "outerThreshold");
+        SkSL::String sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
+        SkSL::String sk_TransformedCoords2D_1 = fragBuilder->ensureCoords2D(args.fTransformedCoords[1]);
+        fragBuilder->codeAppendf("vec4 _tmp0;\nvec4 color = (_tmp0 = texture(%s, %s) , %s != mat4(1.0) ? vec4(clamp((%s * vec4(_tmp0.xyz, 1.0)).xyz, 0.0, _tmp0.w), _tmp0.w) : _tmp0);\nvec4 mask_color = texture(%s, %s);\nif (mask_color.w < 0.5) {\n    if (color.w > %s) {\n        float scale = %s / color.w;\n        color.xyz *= scale;\n        color.w = %s;\n    }\n} else if (color.w < %s) {\n    float scale = %s / max(0.001, color.w);\n    color.xyz *= scale;\n    color.w = %s;\n}\n%s = color;\n", fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(), sk_TransformedCoords2D_0.c_str(), fColorSpaceHelper.isValid() ? args.fUniformHandler->getUniformCStr(fColorSpaceHelper.gamutXformUniform()) : "mat4(1.0)", fColorSpaceHelper.isValid() ? args.fUniformHandler->getUniformCStr(fColorSpaceHelper.gamutXformUniform()) : "mat4(1.0)", fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[1]).c_str(), sk_TransformedCoords2D_1.c_str(), args.fUniformHandler->getUniformCStr(fOuterThresholdVar), args.fUniformHandler->getUniformCStr(fOuterThresholdVar), args.fUniformHandler->getUniformCStr(fOuterThresholdVar), args.fUniformHandler->getUniformCStr(fInnerThresholdVar), args.fUniformHandler->getUniformCStr(fInnerThresholdVar), args.fUniformHandler->getUniformCStr(fInnerThresholdVar), args.fOutputColor);
     }
-
-protected:
-    void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override;
-
 private:
-    GrGLSLProgramDataManager::UniformHandle fInnerThresholdVar;
-    GrGLSLProgramDataManager::UniformHandle fOuterThresholdVar;
-    GrGLSLColorSpaceXformHelper fColorSpaceHelper;
-    typedef GrGLSLFragmentProcessor INHERITED;
-};
-
-void GrGLAlphaThresholdFragmentProcessor::emitCode(EmitArgs& args) {
-    GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
-    fInnerThresholdVar = uniformHandler->addUniform(kFragment_GrShaderFlag,
-                                                    kFloat_GrSLType, kDefault_GrSLPrecision,
-                                                    "inner_threshold");
-    fOuterThresholdVar = uniformHandler->addUniform(kFragment_GrShaderFlag,
-                                                    kFloat_GrSLType, kDefault_GrSLPrecision,
-                                                    "outer_threshold");
-
-    const GrAlphaThresholdFragmentProcessor& atfp =
-        args.fFp.cast<GrAlphaThresholdFragmentProcessor>();
-    fColorSpaceHelper.emitCode(uniformHandler, atfp.colorSpaceXform());
-
-    GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
-    SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
-    SkString maskCoords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[1]);
-
-    fragBuilder->codeAppendf("vec2 coord = %s;", coords2D.c_str());
-    fragBuilder->codeAppendf("vec2 mask_coord = %s;", maskCoords2D.c_str());
-    fragBuilder->codeAppend("vec4 input_color = ");
-    fragBuilder->appendTextureLookup(args.fTexSamplers[0], "coord", kVec2f_GrSLType,
-                                     &fColorSpaceHelper);
-    fragBuilder->codeAppend(";");
-    fragBuilder->codeAppend("vec4 mask_color = ");
-    fragBuilder->appendTextureLookup(args.fTexSamplers[1], "mask_coord");
-    fragBuilder->codeAppend(";");
-
-    fragBuilder->codeAppendf("float inner_thresh = %s;",
-                             uniformHandler->getUniformCStr(fInnerThresholdVar));
-    fragBuilder->codeAppendf("float outer_thresh = %s;",
-                             uniformHandler->getUniformCStr(fOuterThresholdVar));
-    fragBuilder->codeAppend("float mask = mask_color.a;");
-
-    fragBuilder->codeAppend("vec4 color = input_color;");
-    fragBuilder->codeAppend("if (mask < 0.5) {"
-                            "if (color.a > outer_thresh) {"
-                            "float scale = outer_thresh / color.a;"
-                            "color.rgb *= scale;"
-                            "color.a = outer_thresh;"
-                            "}"
-                            "} else if (color.a < inner_thresh) {"
-                            "float scale = inner_thresh / max(0.001, color.a);"
-                            "color.rgb *= scale;"
-                            "color.a = inner_thresh;"
-                            "}");
-
-    fragBuilder->codeAppendf("%s = %s * color;", args.fOutputColor, args.fInputColor);
-}
-
-void GrGLAlphaThresholdFragmentProcessor::onSetData(const GrGLSLProgramDataManager& pdman,
-                                                    const GrFragmentProcessor& proc) {
-    const GrAlphaThresholdFragmentProcessor& atfp = proc.cast<GrAlphaThresholdFragmentProcessor>();
-    pdman.set1f(fInnerThresholdVar, atfp.innerThreshold());
-    pdman.set1f(fOuterThresholdVar, atfp.outerThreshold());
-    if (SkToBool(atfp.colorSpaceXform())) {
-        fColorSpaceHelper.setData(pdman, atfp.colorSpaceXform());
+    void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
+        const GrAlphaThresholdFragmentProcessor& _outer = _proc.cast<GrAlphaThresholdFragmentProcessor>();
+        {
+        if (fColorSpaceHelper.isValid()) {
+            fColorSpaceHelper.setData(pdman, _outer.colorXform().get());
+        }
+        pdman.set1f(fInnerThresholdVar, _outer.innerThreshold());
+        pdman.set1f(fOuterThresholdVar, _outer.outerThreshold());
+        }
     }
+    UniformHandle fImageVar;
+    UniformHandle fMaskVar;
+    UniformHandle fInnerThresholdVar;
+    UniformHandle fOuterThresholdVar;
+    GrGLSLColorSpaceXformHelper fColorSpaceHelper;
+};
+GrGLSLFragmentProcessor* GrAlphaThresholdFragmentProcessor::onCreateGLSLInstance() const {
+    return new GrGLSLAlphaThresholdFragmentProcessor();
 }
-
-/////////////////////////////////////////////////////////////////////
-
+void GrAlphaThresholdFragmentProcessor::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
+    b->add32(GrColorSpaceXform::XformKey(fColorXform.get()));
+}
+bool GrAlphaThresholdFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) const {
+    const GrAlphaThresholdFragmentProcessor& that = other.cast<GrAlphaThresholdFragmentProcessor>();
+    (void) that;
+    if (fImage != that.fImage) return false;
+    if (fColorXform != that.fColorXform) return false;
+    if (fMask != that.fMask) return false;
+    if (fInnerThreshold != that.fInnerThreshold) return false;
+    if (fOuterThreshold != that.fOuterThreshold) return false;
+    return true;
+}
 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrAlphaThresholdFragmentProcessor);
-
 #if GR_TEST_UTILS
-sk_sp<GrFragmentProcessor> GrAlphaThresholdFragmentProcessor::TestCreate(GrProcessorTestData* d) {
-    sk_sp<GrTextureProxy> bmpProxy = d->textureProxy(GrProcessorUnitTest::kSkiaPMTextureIdx);
-    sk_sp<GrTextureProxy> maskProxy = d->textureProxy(GrProcessorUnitTest::kAlphaTextureIdx);
-    // Make the inner and outer thresholds be in (0, 1) exclusive and be sorted correctly.
-    float innerThresh = d->fRandom->nextUScalar1() * .99f + 0.005f;
-    float outerThresh = d->fRandom->nextUScalar1() * .99f + 0.005f;
+sk_sp<GrFragmentProcessor> GrAlphaThresholdFragmentProcessor::TestCreate(GrProcessorTestData* testData) {
+
+    sk_sp<GrTextureProxy> bmpProxy = testData->textureProxy(GrProcessorUnitTest::kSkiaPMTextureIdx);
+    sk_sp<GrTextureProxy> maskProxy = testData->textureProxy(GrProcessorUnitTest::kAlphaTextureIdx);
+    
+    float innerThresh = testData->fRandom->nextUScalar1() * .99f + 0.005f;
+    float outerThresh = testData->fRandom->nextUScalar1() * .99f + 0.005f;
     const int kMaxWidth = 1000;
     const int kMaxHeight = 1000;
-    uint32_t width = d->fRandom->nextULessThan(kMaxWidth);
-    uint32_t height = d->fRandom->nextULessThan(kMaxHeight);
-    uint32_t x = d->fRandom->nextULessThan(kMaxWidth - width);
-    uint32_t y = d->fRandom->nextULessThan(kMaxHeight - height);
+    uint32_t width = testData->fRandom->nextULessThan(kMaxWidth);
+    uint32_t height = testData->fRandom->nextULessThan(kMaxHeight);
+    uint32_t x = testData->fRandom->nextULessThan(kMaxWidth - width);
+    uint32_t y = testData->fRandom->nextULessThan(kMaxHeight - height);
     SkIRect bounds = SkIRect::MakeXYWH(x, y, width, height);
-    sk_sp<GrColorSpaceXform> colorSpaceXform = GrTest::TestColorXform(d->fRandom);
-    return GrAlphaThresholdFragmentProcessor::Make(std::move(bmpProxy),
-                                                   std::move(colorSpaceXform),
-                                                   std::move(maskProxy),
-                                                   innerThresh, outerThresh,
-                                                   bounds);
+    sk_sp<GrColorSpaceXform> colorSpaceXform = GrTest::TestColorXform(testData->fRandom);
+    return GrAlphaThresholdFragmentProcessor::Make(
+                                std::move(bmpProxy),
+                                colorSpaceXform,
+                                std::move(maskProxy),
+                                innerThresh, outerThresh,
+                                bounds);
 }
 #endif
 
-///////////////////////////////////////////////////////////////////////////////
-
-void GrAlphaThresholdFragmentProcessor::onGetGLSLProcessorKey(const GrShaderCaps& caps,
-                                                              GrProcessorKeyBuilder* b) const {
-    GrGLAlphaThresholdFragmentProcessor::GenKey(*this, caps, b);
-}
-
-GrGLSLFragmentProcessor* GrAlphaThresholdFragmentProcessor::onCreateGLSLInstance() const {
-    return new GrGLAlphaThresholdFragmentProcessor;
-}
-
-#endif
+    #endif
diff --git a/src/effects/GrAlphaThresholdFragmentProcessor.fp b/src/effects/GrAlphaThresholdFragmentProcessor.fp
new file mode 100644
index 0000000..a7010a7
--- /dev/null
+++ b/src/effects/GrAlphaThresholdFragmentProcessor.fp
@@ -0,0 +1,110 @@
+in uniform sampler2D image;
+in uniform colorSpaceXform colorXform;
+in uniform sampler2D mask;
+in uniform float innerThreshold;
+in uniform float outerThreshold;
+
+@class {
+    inline OptimizationFlags optFlags(float outerThreshold);
+}
+
+@constructorParams {
+    const SkIRect& bounds
+}
+
+@make {
+    static sk_sp<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> image,
+                                           sk_sp<GrColorSpaceXform> colorXform,
+                                           sk_sp<GrTextureProxy> mask,
+                                           float innerThreshold,
+                                           float outerThreshold,
+                                           const SkIRect& bounds) {
+        return sk_sp<GrFragmentProcessor>(new GrAlphaThresholdFragmentProcessor(image,
+                                                                                colorXform,
+                                                                                mask,
+                                                                                innerThreshold,
+                                                                                outerThreshold,
+                                                                                bounds));
+    }
+}
+
+@fields {
+    GrCoordTransform fImageCoordTransform;
+    GrCoordTransform fMaskCoordTransform;
+}
+
+@initializers {
+    fImageCoordTransform(SkMatrix::I(), image.get()),
+    fMaskCoordTransform(SkMatrix::MakeTrans(SkIntToScalar(-bounds.x()), SkIntToScalar(-bounds.y())),
+                        mask.get())
+}
+
+@constructorCode {
+    this->addCoordTransform(&fImageCoordTransform);
+    this->addCoordTransform(&fMaskCoordTransform);
+}
+
+@header {
+    #include "SkTypes.h"
+    #if SK_SUPPORT_GPU
+}
+
+@headerEnd {
+    #endif
+}
+
+@cpp {
+    #if SK_SUPPORT_GPU
+    inline GrFragmentProcessor::OptimizationFlags GrAlphaThresholdFragmentProcessor::optFlags(
+                                                                             float outerThreshold) {
+        if (outerThreshold >= 1.0) {
+            return kPreservesOpaqueInput_OptimizationFlag |
+                   kCompatibleWithCoverageAsAlpha_OptimizationFlag;
+        } else {
+            return kCompatibleWithCoverageAsAlpha_OptimizationFlag;
+        }
+    }
+}
+
+@cppEnd {
+    #endif
+}
+
+void main() {
+    vec4 color = texture(image, sk_TransformedCoords2D[0], colorXform);
+    vec4 mask_color = texture(mask, sk_TransformedCoords2D[1]);
+    if (mask_color.a < 0.5) {
+        if (color.a > outerThreshold) {
+            float scale = outerThreshold / color.a;
+            color.rgb *= scale;
+            color.a = outerThreshold;
+        }
+    } else if (color.a < innerThreshold) {
+        float scale = innerThreshold / max(0.001, color.a);
+        color.rgb *= scale;
+        color.a = innerThreshold;
+    }
+    sk_OutColor = color;
+}
+
+@test(testData) {
+    sk_sp<GrTextureProxy> bmpProxy = testData->textureProxy(GrProcessorUnitTest::kSkiaPMTextureIdx);
+    sk_sp<GrTextureProxy> maskProxy = testData->textureProxy(GrProcessorUnitTest::kAlphaTextureIdx);
+    // Make the inner and outer thresholds be in (0, 1) exclusive and be sorted correctly.
+    float innerThresh = testData->fRandom->nextUScalar1() * .99f + 0.005f;
+    float outerThresh = testData->fRandom->nextUScalar1() * .99f + 0.005f;
+    const int kMaxWidth = 1000;
+    const int kMaxHeight = 1000;
+    uint32_t width = testData->fRandom->nextULessThan(kMaxWidth);
+    uint32_t height = testData->fRandom->nextULessThan(kMaxHeight);
+    uint32_t x = testData->fRandom->nextULessThan(kMaxWidth - width);
+    uint32_t y = testData->fRandom->nextULessThan(kMaxHeight - height);
+    SkIRect bounds = SkIRect::MakeXYWH(x, y, width, height);
+    sk_sp<GrColorSpaceXform> colorSpaceXform = GrTest::TestColorXform(testData->fRandom);
+    return GrAlphaThresholdFragmentProcessor::Make(
+                                std::move(bmpProxy),
+                                colorSpaceXform,
+                                std::move(maskProxy),
+                                innerThresh, outerThresh,
+                                bounds);
+}
\ No newline at end of file
diff --git a/src/effects/GrAlphaThresholdFragmentProcessor.h b/src/effects/GrAlphaThresholdFragmentProcessor.h
index de58bbf..4540857 100644
--- a/src/effects/GrAlphaThresholdFragmentProcessor.h
+++ b/src/effects/GrAlphaThresholdFragmentProcessor.h
@@ -1,75 +1,79 @@
 /*
- * Copyright 2016 Google Inc.
+ * Copyright 2017 Google Inc.
  *
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
 
+/*
+ * This file was autogenerated from GrAlphaThresholdFragmentProcessor.fp; do not modify.
+ */
 #ifndef GrAlphaThresholdFragmentProcessor_DEFINED
 #define GrAlphaThresholdFragmentProcessor_DEFINED
 
-#include "SkTypes.h"
-
-#if SK_SUPPORT_GPU
-
-#include "GrColorSpaceXform.h"
-#include "GrCoordTransform.h"
+    #include "SkTypes.h"
+    #if SK_SUPPORT_GPU
 #include "GrFragmentProcessor.h"
-#include "GrProcessorUnitTest.h"
-
+#include "GrCoordTransform.h"
+#include "effects/GrProxyMove.h"
 class GrAlphaThresholdFragmentProcessor : public GrFragmentProcessor {
-
 public:
-    static sk_sp<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
-                                           sk_sp<GrColorSpaceXform> colorSpaceXform,
-                                           sk_sp<GrTextureProxy> maskProxy,
-                                           float innerThreshold,
-                                           float outerThreshold,
-                                           const SkIRect& bounds) {
-        return sk_sp<GrFragmentProcessor>(new GrAlphaThresholdFragmentProcessor(
-                                                                    std::move(proxy),
-                                                                    std::move(colorSpaceXform),
-                                                                    std::move(maskProxy),
-                                                                    innerThreshold, outerThreshold,
-                                                                    bounds));
-    }
 
-    const char* name() const override { return "Alpha Threshold"; }
-
+    inline OptimizationFlags optFlags(float outerThreshold);
+    sk_sp<GrColorSpaceXform> colorXform() const { return fColorXform; }
     float innerThreshold() const { return fInnerThreshold; }
     float outerThreshold() const { return fOuterThreshold; }
 
-    GrColorSpaceXform* colorSpaceXform() const { return fColorSpaceXform.get(); }
-
+    static sk_sp<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> image,
+                                           sk_sp<GrColorSpaceXform> colorXform,
+                                           sk_sp<GrTextureProxy> mask,
+                                           float innerThreshold,
+                                           float outerThreshold,
+                                           const SkIRect& bounds) {
+        return sk_sp<GrFragmentProcessor>(new GrAlphaThresholdFragmentProcessor(image,
+                                                                                colorXform,
+                                                                                mask,
+                                                                                innerThreshold,
+                                                                                outerThreshold,
+                                                                                bounds));
+    }
+    const char* name() const override { return "AlphaThresholdFragmentProcessor"; }
 private:
-    static OptimizationFlags OptFlags(float outerThreshold);
+    GrAlphaThresholdFragmentProcessor(sk_sp<GrTextureProxy> image, sk_sp<GrColorSpaceXform> colorXform, sk_sp<GrTextureProxy> mask, float innerThreshold, float outerThreshold, 
+    const SkIRect& bounds
+)
+    : INHERITED(kNone_OptimizationFlags)
+    , 
+    fImageCoordTransform(SkMatrix::I(), image.get()),
+    fMaskCoordTransform(SkMatrix::MakeTrans(SkIntToScalar(-bounds.x()), SkIntToScalar(-bounds.y())),
+                        mask.get())
 
-    GrAlphaThresholdFragmentProcessor(sk_sp<GrTextureProxy> proxy,
-                                      sk_sp<GrColorSpaceXform> colorSpaceXform,
-                                      sk_sp<GrTextureProxy> maskProxy,
-                                      float innerThreshold,
-                                      float outerThreshold,
-                                      const SkIRect& bounds);
+    , fImage(std::move(image))
+    , fColorXform(colorXform)
+    , fMask(std::move(mask))
+    , fInnerThreshold(innerThreshold)
+    , fOuterThreshold(outerThreshold) {
 
+    this->addCoordTransform(&fImageCoordTransform);
+    this->addCoordTransform(&fMaskCoordTransform);
+        this->addTextureSampler(&fImage);
+        this->addTextureSampler(&fMask);
+        this->initClassID<GrAlphaThresholdFragmentProcessor>();
+    }
     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
-
-    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
-
+    void onGetGLSLProcessorKey(const GrShaderCaps&,GrProcessorKeyBuilder*) const override;
     bool onIsEqual(const GrFragmentProcessor&) const override;
-
     GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
 
+    GrCoordTransform fImageCoordTransform;
+    GrCoordTransform fMaskCoordTransform;
+    TextureSampler fImage;
+    sk_sp<GrColorSpaceXform> fColorXform;
+    TextureSampler fMask;
     float fInnerThreshold;
     float fOuterThreshold;
-    GrCoordTransform fImageCoordTransform;
-    TextureSampler   fImageTextureSampler;
-    // Color space transform is for the image (not the mask)
-    sk_sp<GrColorSpaceXform> fColorSpaceXform;
-    GrCoordTransform fMaskCoordTransform;
-    TextureSampler   fMaskTextureSampler;
-
     typedef GrFragmentProcessor INHERITED;
 };
 
-#endif
+    #endif
 #endif