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>
This commit is contained in:
parent
7bf2600475
commit
85894305bf
@ -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/GrModulateRGBAEffect.h"
|
||||
#include "src/gpu/ops/GrDrawOp.h"
|
||||
#include "src/gpu/ops/GrFillRectOp.h"
|
||||
#include "tools/ToolUtils.h"
|
||||
@ -47,7 +46,7 @@
|
||||
|
||||
namespace skiagm {
|
||||
/**
|
||||
* This GM directly exercises GrConstColorProcessor, GrModulateRGBAEffect and GrModulateAlphaEffect.
|
||||
* This GM directly exercises GrConstColorProcessor, ModulateRGBA and ModulateAlpha.
|
||||
*/
|
||||
class ColorProcessor : public GpuGM {
|
||||
public:
|
||||
@ -131,9 +130,8 @@ protected:
|
||||
break;
|
||||
|
||||
case TestMode::kModulateRGBA:
|
||||
colorFP = GrModulateRGBAEffect::Make(
|
||||
std::move(baseFP),
|
||||
SkPMColor4f::FromBytes_RGBA(kColors[procColor]));
|
||||
colorFP = GrFragmentProcessor::ModulateRGBA(
|
||||
std::move(baseFP), SkPMColor4f::FromBytes_RGBA(kColors[procColor]));
|
||||
break;
|
||||
|
||||
case TestMode::kModulateAlpha:
|
||||
|
@ -344,8 +344,6 @@ skia_gpu_sources = [
|
||||
"$_src/gpu/effects/generated/GrMagnifierEffect.h",
|
||||
"$_src/gpu/effects/generated/GrMixerEffect.cpp",
|
||||
"$_src/gpu/effects/generated/GrMixerEffect.h",
|
||||
"$_src/gpu/effects/generated/GrModulateRGBAEffect.cpp",
|
||||
"$_src/gpu/effects/generated/GrModulateRGBAEffect.h",
|
||||
"$_src/gpu/effects/generated/GrOverrideInputFragmentProcessor.cpp",
|
||||
"$_src/gpu/effects/generated/GrOverrideInputFragmentProcessor.h",
|
||||
"$_src/gpu/effects/generated/GrRGBToHSLFilterEffect.cpp",
|
||||
|
@ -96,7 +96,6 @@ skia_gpu_processor_sources = [
|
||||
"$_src/gpu/effects/GrLumaColorFilterEffect.fp",
|
||||
"$_src/gpu/effects/GrMagnifierEffect.fp",
|
||||
"$_src/gpu/effects/GrMixerEffect.fp",
|
||||
"$_src/gpu/effects/GrModulateRGBAEffect.fp",
|
||||
"$_src/gpu/effects/GrOverrideInputFragmentProcessor.fp",
|
||||
"$_src/gpu/effects/GrRGBToHSLFilterEffect.fp",
|
||||
"$_src/gpu/effects/GrRRectBlurEffect.fp",
|
||||
|
@ -203,6 +203,14 @@ std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::ModulateAlpha(
|
||||
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) {
|
||||
|
@ -54,6 +54,13 @@ public:
|
||||
static std::unique_ptr<GrFragmentProcessor> ModulateAlpha(
|
||||
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.
|
||||
|
@ -121,7 +121,6 @@ public:
|
||||
kGrMatrixConvolutionEffect_ClassID,
|
||||
kGrMatrixEffect_ClassID,
|
||||
kGrMeshTestProcessor_ClassID,
|
||||
kGrModulateRGBAEffect_ClassID,
|
||||
kGrMorphologyEffect_ClassID,
|
||||
kGrMixerEffect_ClassID,
|
||||
kGrOverrideInputFragmentProcessor_ClassID,
|
||||
|
@ -81,7 +81,7 @@ SkTArray<GrXPFactoryTestFactory*, true>* GrXPFactoryTestFactory::GetFactories()
|
||||
* 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;
|
||||
|
||||
|
@ -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 @@ static inline bool skpaint_to_grpaint_impl(GrRecordingContext* context,
|
||||
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 @@ static inline bool skpaint_to_grpaint_impl(GrRecordingContext* context,
|
||||
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 {
|
||||
|
@ -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 @@ GrFPResult GrConvexPolyEffect::Make(std::unique_ptr<GrFragmentProcessor> inputFP
|
||||
// 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];
|
||||
|
@ -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);
|
||||
}
|
@ -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
|
@ -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
|
@ -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 @@ std::unique_ptr<GrFragmentProcessor> SkPerlinNoiseShaderImpl::asFragmentProcesso
|
||||
// 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.
|
||||
|
Loading…
Reference in New Issue
Block a user