Replace ModulateAlpha effect with Xfermode using src-in 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: Ie81e8b82d9b9c441533760d4e9f7e149bc0d969d
Bug: skia:10457
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/302262
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
diff --git a/gm/constcolorprocessor.cpp b/gm/constcolorprocessor.cpp
index 34e8c0c..2236c32 100644
--- a/gm/constcolorprocessor.cpp
+++ b/gm/constcolorprocessor.cpp
@@ -37,7 +37,6 @@
#include "src/gpu/GrRenderTargetContextPriv.h"
#include "src/gpu/SkGr.h"
#include "src/gpu/effects/generated/GrConstColorProcessor.h"
-#include "src/gpu/effects/generated/GrModulateAlphaEffect.h"
#include "src/gpu/effects/generated/GrModulateRGBAEffect.h"
#include "src/gpu/ops/GrDrawOp.h"
#include "src/gpu/ops/GrFillRectOp.h"
@@ -138,9 +137,8 @@
break;
case TestMode::kModulateAlpha:
- colorFP = GrModulateAlphaEffect::Make(
- std::move(baseFP),
- SkPMColor4f::FromBytes_RGBA(kColors[procColor]));
+ colorFP = GrFragmentProcessor::ModulateAlpha(
+ std::move(baseFP), SkPMColor4f::FromBytes_RGBA(kColors[procColor]));
break;
}
diff --git a/gn/gpu.gni b/gn/gpu.gni
index 5774e17..ac33d47 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -344,8 +344,6 @@
"$_src/gpu/effects/generated/GrMagnifierEffect.h",
"$_src/gpu/effects/generated/GrMixerEffect.cpp",
"$_src/gpu/effects/generated/GrMixerEffect.h",
- "$_src/gpu/effects/generated/GrModulateAlphaEffect.cpp",
- "$_src/gpu/effects/generated/GrModulateAlphaEffect.h",
"$_src/gpu/effects/generated/GrModulateRGBAEffect.cpp",
"$_src/gpu/effects/generated/GrModulateRGBAEffect.h",
"$_src/gpu/effects/generated/GrOverrideInputFragmentProcessor.cpp",
diff --git a/gn/sksl.gni b/gn/sksl.gni
index 043900a..1277da7 100644
--- a/gn/sksl.gni
+++ b/gn/sksl.gni
@@ -96,7 +96,6 @@
"$_src/gpu/effects/GrLumaColorFilterEffect.fp",
"$_src/gpu/effects/GrMagnifierEffect.fp",
"$_src/gpu/effects/GrMixerEffect.fp",
- "$_src/gpu/effects/GrModulateAlphaEffect.fp",
"$_src/gpu/effects/GrModulateRGBAEffect.fp",
"$_src/gpu/effects/GrOverrideInputFragmentProcessor.fp",
"$_src/gpu/effects/GrRGBToHSLFilterEffect.fp",
diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp
index 4925948..289d45f 100644
--- a/src/gpu/GrFragmentProcessor.cpp
+++ b/src/gpu/GrFragmentProcessor.cpp
@@ -195,6 +195,14 @@
return GrXfermodeFragmentProcessor::Make(/*src=*/nullptr, std::move(fp), SkBlendMode::kSrcIn);
}
+std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::ModulateAlpha(
+ std::unique_ptr<GrFragmentProcessor> inputFP, const SkPMColor4f& color) {
+ auto colorFP = GrConstColorProcessor::Make(color);
+ return GrXfermodeFragmentProcessor::Make(
+ std::move(colorFP), std::move(inputFP), SkBlendMode::kSrcIn,
+ 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 7a62cbf..c23be06 100644
--- a/src/gpu/GrFragmentProcessor.h
+++ b/src/gpu/GrFragmentProcessor.h
@@ -48,6 +48,13 @@
std::unique_ptr<GrFragmentProcessor> child);
/**
+ * Returns a fragment processor that generates the passed-in color, modulated by the child's
+ * alpha channel. (Pass a null FP to use the alpha from sk_InColor instead of a child FP.)
+ */
+ static std::unique_ptr<GrFragmentProcessor> ModulateAlpha(
+ 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 7bb2ccd..03a4d11 100644
--- a/src/gpu/GrProcessor.h
+++ b/src/gpu/GrProcessor.h
@@ -121,7 +121,6 @@
kGrMatrixConvolutionEffect_ClassID,
kGrMatrixEffect_ClassID,
kGrMeshTestProcessor_ClassID,
- kGrModulateAlphaEffect_ClassID,
kGrModulateRGBAEffect_ClassID,
kGrMorphologyEffect_ClassID,
kGrMixerEffect_ClassID,
diff --git a/src/gpu/GrProcessorUnitTest.cpp b/src/gpu/GrProcessorUnitTest.cpp
index b7b3ab2..7b8cd20 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 = 39;
+static const int kFPFactoryCount = 38;
static const int kGPFactoryCount = 14;
static const int kXPFactoryCount = 4;
diff --git a/src/gpu/effects/GrModulateAlphaEffect.fp b/src/gpu/effects/GrModulateAlphaEffect.fp
deleted file mode 100644
index 761cd2a..0000000
--- a/src/gpu/effects/GrModulateAlphaEffect.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).a;
-}
-
-@class {
- SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& inColor) const override {
- SkPMColor4f input = this->numChildProcessors()
- ? ConstantOutputForConstantInput(this->childProcessor(inputFP_index), inColor)
- : inColor;
- return color * input.fA;
- }
-}
-
-@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 GrModulateAlphaEffect::Make(/*inputFP=*/nullptr, color);
-}
diff --git a/src/gpu/effects/generated/GrModulateAlphaEffect.cpp b/src/gpu/effects/generated/GrModulateAlphaEffect.cpp
deleted file mode 100644
index 0b7d138..0000000
--- a/src/gpu/effects/generated/GrModulateAlphaEffect.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 GrModulateAlphaEffect.fp; do not modify.
- **************************************************************************************************/
-#include "GrModulateAlphaEffect.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 GrGLSLModulateAlphaEffect : public GrGLSLFragmentProcessor {
-public:
- GrGLSLModulateAlphaEffect() {}
- void emitCode(EmitArgs& args) override {
- GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
- const GrModulateAlphaEffect& _outer = args.fFp.cast<GrModulateAlphaEffect>();
- (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.w;
-)SkSL",
- args.fOutputColor, args.fUniformHandler->getUniformCStr(colorVar),
- _sample618.c_str());
- }
-
-private:
- void onSetData(const GrGLSLProgramDataManager& pdman,
- const GrFragmentProcessor& _proc) override {
- const GrModulateAlphaEffect& _outer = _proc.cast<GrModulateAlphaEffect>();
- {
- 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* GrModulateAlphaEffect::onCreateGLSLInstance() const {
- return new GrGLSLModulateAlphaEffect();
-}
-void GrModulateAlphaEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
- GrProcessorKeyBuilder* b) const {}
-bool GrModulateAlphaEffect::onIsEqual(const GrFragmentProcessor& other) const {
- const GrModulateAlphaEffect& that = other.cast<GrModulateAlphaEffect>();
- (void)that;
- if (color != that.color) return false;
- return true;
-}
-GrModulateAlphaEffect::GrModulateAlphaEffect(const GrModulateAlphaEffect& src)
- : INHERITED(kGrModulateAlphaEffect_ClassID, src.optimizationFlags()), color(src.color) {
- if (src.inputFP_index >= 0) {
- inputFP_index = this->cloneAndRegisterChildProcessor(src.childProcessor(src.inputFP_index));
- }
-}
-std::unique_ptr<GrFragmentProcessor> GrModulateAlphaEffect::clone() const {
- return std::unique_ptr<GrFragmentProcessor>(new GrModulateAlphaEffect(*this));
-}
-GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrModulateAlphaEffect);
-#if GR_TEST_UTILS
-std::unique_ptr<GrFragmentProcessor> GrModulateAlphaEffect::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 GrModulateAlphaEffect::Make(/*inputFP=*/nullptr, color);
-}
-#endif
diff --git a/src/gpu/effects/generated/GrModulateAlphaEffect.h b/src/gpu/effects/generated/GrModulateAlphaEffect.h
deleted file mode 100644
index bc971aa..0000000
--- a/src/gpu/effects/generated/GrModulateAlphaEffect.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 GrModulateAlphaEffect.fp; do not modify.
- **************************************************************************************************/
-#ifndef GrModulateAlphaEffect_DEFINED
-#define GrModulateAlphaEffect_DEFINED
-
-#include "include/core/SkM44.h"
-#include "include/core/SkTypes.h"
-
-#include "src/gpu/GrFragmentProcessor.h"
-
-class GrModulateAlphaEffect : public GrFragmentProcessor {
-public:
- SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& inColor) const override {
- SkPMColor4f input = this->numChildProcessors()
- ? ConstantOutputForConstantInput(
- this->childProcessor(inputFP_index), inColor)
- : inColor;
- return color * input.fA;
- }
- static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP,
- SkPMColor4f color) {
- return std::unique_ptr<GrFragmentProcessor>(
- new GrModulateAlphaEffect(std::move(inputFP), color));
- }
- GrModulateAlphaEffect(const GrModulateAlphaEffect& src);
- std::unique_ptr<GrFragmentProcessor> clone() const override;
- const char* name() const override { return "ModulateAlphaEffect"; }
- int inputFP_index = -1;
- SkPMColor4f color;
-
-private:
- GrModulateAlphaEffect(std::unique_ptr<GrFragmentProcessor> inputFP, SkPMColor4f color)
- : INHERITED(kGrModulateAlphaEffect_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/SkColorShader.cpp b/src/shaders/SkColorShader.cpp
index f20be14..169f9b8 100644
--- a/src/shaders/SkColorShader.cpp
+++ b/src/shaders/SkColorShader.cpp
@@ -114,13 +114,13 @@
#include "src/gpu/GrColorInfo.h"
#include "src/gpu/GrColorSpaceXform.h"
+#include "src/gpu/GrFragmentProcessor.h"
#include "src/gpu/SkGr.h"
-#include "src/gpu/effects/generated/GrModulateAlphaEffect.h"
std::unique_ptr<GrFragmentProcessor> SkColorShader::asFragmentProcessor(
const GrFPArgs& args) const {
- SkPMColor4f color = SkColorToPMColor4f(fColor, *args.fDstColorInfo);
- return GrModulateAlphaEffect::Make(/*inputFP=*/nullptr, color);
+ return GrFragmentProcessor::ModulateAlpha(/*child=*/nullptr,
+ SkColorToPMColor4f(fColor, *args.fDstColorInfo));
}
std::unique_ptr<GrFragmentProcessor> SkColor4Shader::asFragmentProcessor(
@@ -129,7 +129,7 @@
args.fDstColorInfo->colorSpace(), kUnpremul_SkAlphaType };
SkColor4f color = fColor;
steps.apply(color.vec());
- return GrModulateAlphaEffect::Make(/*inputFP=*/nullptr, color.premul());
+ return GrFragmentProcessor::ModulateAlpha(/*child=*/nullptr, color.premul());
}
#endif