Replace ModulateRGBA effect with Xfermode using modulate blend.

This reduces our code size by reusing existing components to perform
the same blend, and generates a shader that should be conceptually
equivalent (although it gives the inliner a bit more work to do).

Change-Id: Ie2203f7613503476fa9d045aba58d9ef39f3ea26
Bug: skia:10457
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/302264
Commit-Queue: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp
index 289d45f..dc36c09 100644
--- a/src/gpu/GrFragmentProcessor.cpp
+++ b/src/gpu/GrFragmentProcessor.cpp
@@ -203,6 +203,14 @@
             GrXfermodeFragmentProcessor::ComposeBehavior::kSkModeBehavior);
 }
 
+std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::ModulateRGBA(
+        std::unique_ptr<GrFragmentProcessor> inputFP, const SkPMColor4f& color) {
+    auto colorFP = GrConstColorProcessor::Make(color);
+    return GrXfermodeFragmentProcessor::Make(
+            std::move(colorFP), std::move(inputFP), SkBlendMode::kModulate,
+            GrXfermodeFragmentProcessor::ComposeBehavior::kSkModeBehavior);
+}
+
 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::ClampPremulOutput(
         std::unique_ptr<GrFragmentProcessor> fp) {
     if (!fp) {
diff --git a/src/gpu/GrFragmentProcessor.h b/src/gpu/GrFragmentProcessor.h
index c23be06..812f06f 100644
--- a/src/gpu/GrFragmentProcessor.h
+++ b/src/gpu/GrFragmentProcessor.h
@@ -55,6 +55,13 @@
             std::unique_ptr<GrFragmentProcessor> child, const SkPMColor4f& color);
 
     /**
+     *  Returns a fragment processor that generates the passed-in color, modulated by the child's
+     *  RGBA color. (Pass a null FP to use the color from sk_InColor instead of a child FP.)
+     */
+    static std::unique_ptr<GrFragmentProcessor> ModulateRGBA(
+            std::unique_ptr<GrFragmentProcessor> child, const SkPMColor4f& color);
+
+    /**
      *  This assumes that the input color to the returned processor will be unpremul and that the
      *  passed processor (which becomes the returned processor's child) produces a premul output.
      *  The result of the returned processor is a premul of its input color modulated by the child
diff --git a/src/gpu/GrProcessor.h b/src/gpu/GrProcessor.h
index 03a4d11..ec1e09d 100644
--- a/src/gpu/GrProcessor.h
+++ b/src/gpu/GrProcessor.h
@@ -121,7 +121,6 @@
         kGrMatrixConvolutionEffect_ClassID,
         kGrMatrixEffect_ClassID,
         kGrMeshTestProcessor_ClassID,
-        kGrModulateRGBAEffect_ClassID,
         kGrMorphologyEffect_ClassID,
         kGrMixerEffect_ClassID,
         kGrOverrideInputFragmentProcessor_ClassID,
diff --git a/src/gpu/GrProcessorUnitTest.cpp b/src/gpu/GrProcessorUnitTest.cpp
index 7b8cd20..d257e44 100644
--- a/src/gpu/GrProcessorUnitTest.cpp
+++ b/src/gpu/GrProcessorUnitTest.cpp
@@ -81,7 +81,7 @@
  * we verify the count is as expected.  If a new factory is added, then these numbers must be
  * manually adjusted.
  */
-static const int kFPFactoryCount = 38;
+static const int kFPFactoryCount = 37;
 static const int kGPFactoryCount = 14;
 static const int kXPFactoryCount = 4;
 
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 8df9db0..1dd5902 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -45,7 +45,6 @@
 #include "src/gpu/effects/generated/GrClampFragmentProcessor.h"
 #include "src/gpu/effects/generated/GrConstColorProcessor.h"
 #include "src/gpu/effects/generated/GrDitherEffect.h"
-#include "src/gpu/effects/generated/GrModulateRGBAEffect.h"
 #include "src/image/SkImage_Base.h"
 #include "src/shaders/SkShaderBase.h"
 
@@ -263,7 +262,7 @@
             if (1.0f != paintAlpha) {
                 // No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all
                 // color channels. It's value should be treated as the same in ANY color space.
-                paintFP = GrModulateRGBAEffect::Make(
+                paintFP = GrFragmentProcessor::ModulateRGBA(
                         std::move(paintFP), {paintAlpha, paintAlpha, paintAlpha, paintAlpha});
             }
         } else {
@@ -286,7 +285,7 @@
             if (1.0f != paintAlpha) {
                 // No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all
                 // color channels. It's value should be treated as the same in ANY color space.
-                paintFP = GrModulateRGBAEffect::Make(
+                paintFP = GrFragmentProcessor::ModulateRGBA(
                         std::move(paintFP), {paintAlpha, paintAlpha, paintAlpha, paintAlpha});
             }
         } else {
diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp
index ae1827e..3dfe6c2 100644
--- a/src/gpu/effects/GrConvexPolyEffect.cpp
+++ b/src/gpu/effects/GrConvexPolyEffect.cpp
@@ -8,7 +8,6 @@
 #include "src/core/SkPathPriv.h"
 #include "src/gpu/effects/GrConvexPolyEffect.h"
 #include "src/gpu/effects/generated/GrAARectEffect.h"
-#include "src/gpu/effects/generated/GrModulateRGBAEffect.h"
 #include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
 #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
 #include "src/gpu/glsl/GrGLSLProgramDataManager.h"
@@ -106,13 +105,15 @@
     // skip the draw or omit the clip element.
     if (!SkPathPriv::CheapComputeFirstDirection(path, &dir)) {
         if (GrProcessorEdgeTypeIsInverseFill(type)) {
-            return GrFPSuccess(GrModulateRGBAEffect::Make(std::move(inputFP), SK_PMColor4fWHITE));
+            return GrFPSuccess(
+                    GrFragmentProcessor::ModulateRGBA(std::move(inputFP), SK_PMColor4fWHITE));
         }
         // This could use ConstColor instead of ModulateRGBA but it would trigger a debug print
         // about a coverage processor not being compatible with the alpha-as-coverage optimization.
         // We don't really care about this unlikely case so we just use ModulateRGBA to suppress
         // the print.
-        return GrFPSuccess(GrModulateRGBAEffect::Make(std::move(inputFP), SK_PMColor4fTRANSPARENT));
+        return GrFPSuccess(
+                GrFragmentProcessor::ModulateRGBA(std::move(inputFP), SK_PMColor4fTRANSPARENT));
     }
 
     SkScalar        edges[3 * kMaxEdges];
diff --git a/src/gpu/effects/GrModulateRGBAEffect.fp b/src/gpu/effects/GrModulateRGBAEffect.fp
deleted file mode 100644
index bc59055..0000000
--- a/src/gpu/effects/GrModulateRGBAEffect.fp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2020 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-in fragmentProcessor? inputFP;
-layout(ctype=SkPMColor4f, tracked) in uniform half4 color;
-
-@optimizationFlags {
-    (inputFP ? ProcessorOptimizationFlags(inputFP.get()) : kAll_OptimizationFlags) &
-            (kConstantOutputForConstantInput_OptimizationFlag |
-             kCompatibleWithCoverageAsAlpha_OptimizationFlag |
-             (color.isOpaque() ? kPreservesOpaqueInput_OptimizationFlag : kNone_OptimizationFlags))
-}
-
-void main() {
-    sk_OutColor = color * sample(inputFP, sk_InColor);
-}
-
-@class {
-    SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& inColor) const override {
-        SkPMColor4f input = this->numChildProcessors()
-            ? ConstantOutputForConstantInput(this->childProcessor(inputFP_index), inColor)
-            : inColor;
-        return color * input;
-    }
-}
-
-@test(d) {
-    SkPMColor4f color;
-    int colorPicker = d->fRandom->nextULessThan(3);
-    switch (colorPicker) {
-        case 0: {
-            uint32_t a = d->fRandom->nextULessThan(0x100);
-            uint32_t r = d->fRandom->nextULessThan(a+1);
-            uint32_t g = d->fRandom->nextULessThan(a+1);
-            uint32_t b = d->fRandom->nextULessThan(a+1);
-            color = SkPMColor4f::FromBytes_RGBA(GrColorPackRGBA(r, g, b, a));
-            break;
-        }
-        case 1:
-            color = SK_PMColor4fTRANSPARENT;
-            break;
-        case 2:
-            uint32_t c = d->fRandom->nextULessThan(0x100);
-            color = SkPMColor4f::FromBytes_RGBA(c | (c << 8) | (c << 16) | (c << 24));
-            break;
-    }
-    return GrModulateRGBAEffect::Make(/*inputFP=*/nullptr, color);
-}
diff --git a/src/gpu/effects/generated/GrModulateRGBAEffect.cpp b/src/gpu/effects/generated/GrModulateRGBAEffect.cpp
deleted file mode 100644
index 2598b57..0000000
--- a/src/gpu/effects/generated/GrModulateRGBAEffect.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright 2020 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 GrModulateRGBAEffect.fp; do not modify.
- **************************************************************************************************/
-#include "GrModulateRGBAEffect.h"
-
-#include "src/gpu/GrTexture.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
-#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
-#include "src/sksl/SkSLCPP.h"
-#include "src/sksl/SkSLUtil.h"
-class GrGLSLModulateRGBAEffect : public GrGLSLFragmentProcessor {
-public:
-    GrGLSLModulateRGBAEffect() {}
-    void emitCode(EmitArgs& args) override {
-        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
-        const GrModulateRGBAEffect& _outer = args.fFp.cast<GrModulateRGBAEffect>();
-        (void)_outer;
-        auto color = _outer.color;
-        (void)color;
-        colorVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag,
-                                                    kHalf4_GrSLType, "color");
-        SkString _input618(args.fInputColor);
-        SkString _sample618;
-        if (_outer.inputFP_index >= 0) {
-            _sample618 = this->invokeChild(_outer.inputFP_index, _input618.c_str(), args);
-        } else {
-            _sample618.swap(_input618);
-        }
-        fragBuilder->codeAppendf(
-                R"SkSL(%s = %s * %s;
-)SkSL",
-                args.fOutputColor, args.fUniformHandler->getUniformCStr(colorVar),
-                _sample618.c_str());
-    }
-
-private:
-    void onSetData(const GrGLSLProgramDataManager& pdman,
-                   const GrFragmentProcessor& _proc) override {
-        const GrModulateRGBAEffect& _outer = _proc.cast<GrModulateRGBAEffect>();
-        {
-            const SkPMColor4f& colorValue = _outer.color;
-            if (colorPrev != colorValue) {
-                colorPrev = colorValue;
-                pdman.set4fv(colorVar, 1, colorValue.vec());
-            }
-        }
-    }
-    SkPMColor4f colorPrev = {SK_FloatNaN, SK_FloatNaN, SK_FloatNaN, SK_FloatNaN};
-    UniformHandle colorVar;
-};
-GrGLSLFragmentProcessor* GrModulateRGBAEffect::onCreateGLSLInstance() const {
-    return new GrGLSLModulateRGBAEffect();
-}
-void GrModulateRGBAEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
-                                                 GrProcessorKeyBuilder* b) const {}
-bool GrModulateRGBAEffect::onIsEqual(const GrFragmentProcessor& other) const {
-    const GrModulateRGBAEffect& that = other.cast<GrModulateRGBAEffect>();
-    (void)that;
-    if (color != that.color) return false;
-    return true;
-}
-GrModulateRGBAEffect::GrModulateRGBAEffect(const GrModulateRGBAEffect& src)
-        : INHERITED(kGrModulateRGBAEffect_ClassID, src.optimizationFlags()), color(src.color) {
-    if (src.inputFP_index >= 0) {
-        inputFP_index = this->cloneAndRegisterChildProcessor(src.childProcessor(src.inputFP_index));
-    }
-}
-std::unique_ptr<GrFragmentProcessor> GrModulateRGBAEffect::clone() const {
-    return std::unique_ptr<GrFragmentProcessor>(new GrModulateRGBAEffect(*this));
-}
-GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrModulateRGBAEffect);
-#if GR_TEST_UTILS
-std::unique_ptr<GrFragmentProcessor> GrModulateRGBAEffect::TestCreate(GrProcessorTestData* d) {
-    SkPMColor4f color;
-    int colorPicker = d->fRandom->nextULessThan(3);
-    switch (colorPicker) {
-        case 0: {
-            uint32_t a = d->fRandom->nextULessThan(0x100);
-            uint32_t r = d->fRandom->nextULessThan(a + 1);
-            uint32_t g = d->fRandom->nextULessThan(a + 1);
-            uint32_t b = d->fRandom->nextULessThan(a + 1);
-            color = SkPMColor4f::FromBytes_RGBA(GrColorPackRGBA(r, g, b, a));
-            break;
-        }
-        case 1:
-            color = SK_PMColor4fTRANSPARENT;
-            break;
-        case 2:
-            uint32_t c = d->fRandom->nextULessThan(0x100);
-            color = SkPMColor4f::FromBytes_RGBA(c | (c << 8) | (c << 16) | (c << 24));
-            break;
-    }
-    return GrModulateRGBAEffect::Make(/*inputFP=*/nullptr, color);
-}
-#endif
diff --git a/src/gpu/effects/generated/GrModulateRGBAEffect.h b/src/gpu/effects/generated/GrModulateRGBAEffect.h
deleted file mode 100644
index 0ef5330..0000000
--- a/src/gpu/effects/generated/GrModulateRGBAEffect.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2020 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 GrModulateRGBAEffect.fp; do not modify.
- **************************************************************************************************/
-#ifndef GrModulateRGBAEffect_DEFINED
-#define GrModulateRGBAEffect_DEFINED
-
-#include "include/core/SkM44.h"
-#include "include/core/SkTypes.h"
-
-#include "src/gpu/GrFragmentProcessor.h"
-
-class GrModulateRGBAEffect : public GrFragmentProcessor {
-public:
-    SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& inColor) const override {
-        SkPMColor4f input = this->numChildProcessors()
-                                    ? ConstantOutputForConstantInput(
-                                              this->childProcessor(inputFP_index), inColor)
-                                    : inColor;
-        return color * input;
-    }
-    static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP,
-                                                     SkPMColor4f color) {
-        return std::unique_ptr<GrFragmentProcessor>(
-                new GrModulateRGBAEffect(std::move(inputFP), color));
-    }
-    GrModulateRGBAEffect(const GrModulateRGBAEffect& src);
-    std::unique_ptr<GrFragmentProcessor> clone() const override;
-    const char* name() const override { return "ModulateRGBAEffect"; }
-    int inputFP_index = -1;
-    SkPMColor4f color;
-
-private:
-    GrModulateRGBAEffect(std::unique_ptr<GrFragmentProcessor> inputFP, SkPMColor4f color)
-            : INHERITED(kGrModulateRGBAEffect_ClassID,
-                        (OptimizationFlags)(inputFP ? ProcessorOptimizationFlags(inputFP.get())
-                                                    : kAll_OptimizationFlags) &
-                                (kConstantOutputForConstantInput_OptimizationFlag |
-                                 kCompatibleWithCoverageAsAlpha_OptimizationFlag |
-                                 (color.isOpaque() ? kPreservesOpaqueInput_OptimizationFlag
-                                                   : kNone_OptimizationFlags)))
-            , color(color) {
-        inputFP_index = this->registerChild(std::move(inputFP), SkSL::SampleUsage::PassThrough());
-    }
-    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
-    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
-    bool onIsEqual(const GrFragmentProcessor&) const override;
-    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
-    typedef GrFragmentProcessor INHERITED;
-};
-#endif
diff --git a/src/shaders/SkPerlinNoiseShader.cpp b/src/shaders/SkPerlinNoiseShader.cpp
index f3632ab..77bc4b8 100644
--- a/src/shaders/SkPerlinNoiseShader.cpp
+++ b/src/shaders/SkPerlinNoiseShader.cpp
@@ -23,7 +23,6 @@
 #include "src/gpu/effects/GrMatrixEffect.h"
 #include "src/gpu/effects/GrTextureEffect.h"
 #include "src/gpu/effects/generated/GrConstColorProcessor.h"
-#include "src/gpu/effects/generated/GrModulateRGBAEffect.h"
 #include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
 #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
 #include "src/gpu/glsl/GrGLSLProgramDataManager.h"
@@ -1387,8 +1386,8 @@
             // TODO: Either treat the output of this shader as sRGB or allow client to specify a
             // color space of the noise. Either way, this case (and the GLSL) need to convert to
             // the destination.
-            auto inner = GrModulateRGBAEffect::Make(
-                    /*inputFP=*/nullptr, SkPMColor4f::FromBytes_RGBA(0x80404040));
+            auto inner = GrFragmentProcessor::ModulateRGBA(
+                    /*child=*/nullptr, SkPMColor4f::FromBytes_RGBA(0x80404040));
             return GrFragmentProcessor::MulChildByInputAlpha(std::move(inner));
         }
         // Emit zero.