From 5a2a7b3096d05f7993fc2d4a48432628d6779f4b Mon Sep 17 00:00:00 2001 From: John Stiles Date: Thu, 4 Jun 2020 10:57:21 -0400 Subject: [PATCH] Update GrClampFragmentProcessor to use a child FP. We are updating FPs to receive their input via a child FP where possible, instead of relying on the input color. Change-Id: Ic30224a45c6e4dba46c1cbaa27735013e8b3935f Bug: skia:10217 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/293937 Reviewed-by: Michael Ludwig Commit-Queue: John Stiles --- src/gpu/GrFragmentProcessor.cpp | 6 +--- src/gpu/SkGr.cpp | 3 +- src/gpu/effects/GrClampFragmentProcessor.fp | 15 ++++++---- .../generated/GrClampFragmentProcessor.cpp | 28 +++++++++++++++---- .../generated/GrClampFragmentProcessor.h | 22 +++++++++++---- src/gpu/ops/GrTextureOp.cpp | 13 ++++----- 6 files changed, 56 insertions(+), 31 deletions(-) diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp index 5b6633928a..1163f37a20 100644 --- a/src/gpu/GrFragmentProcessor.cpp +++ b/src/gpu/GrFragmentProcessor.cpp @@ -181,11 +181,7 @@ std::unique_ptr GrFragmentProcessor::ClampPremulOutput( if (!fp) { return nullptr; } - std::unique_ptr fpPipeline[] = { - std::move(fp), - GrClampFragmentProcessor::Make(true) - }; - return GrFragmentProcessor::RunInSeries(fpPipeline, 2); + return GrClampFragmentProcessor::Make(std::move(fp), /*clampToPremul=*/true); } std::unique_ptr GrFragmentProcessor::SwizzleOutput( diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp index 735c78dd44..daa78e4f1a 100644 --- a/src/gpu/SkGr.cpp +++ b/src/gpu/SkGr.cpp @@ -395,7 +395,8 @@ static inline bool skpaint_to_grpaint_impl(GrRecordingContext* context, #endif if (GrColorTypeClampType(dstColorInfo.colorType()) == GrClampType::kManual) { if (grPaint->numColorFragmentProcessors()) { - grPaint->addColorFragmentProcessor(GrClampFragmentProcessor::Make(false)); + grPaint->addColorFragmentProcessor( + GrClampFragmentProcessor::Make(/*inputFP=*/nullptr, /*clampToPremul=*/false)); } else { auto color = grPaint->getColor4f(); grPaint->setColor4f({SkTPin(color.fR, 0.f, 1.f), diff --git a/src/gpu/effects/GrClampFragmentProcessor.fp b/src/gpu/effects/GrClampFragmentProcessor.fp index f81fe08de7..eb3deb3f49 100644 --- a/src/gpu/effects/GrClampFragmentProcessor.fp +++ b/src/gpu/effects/GrClampFragmentProcessor.fp @@ -5,19 +5,22 @@ * found in the LICENSE file. */ +in fragmentProcessor? inputFP; layout(key) in bool clampToPremul; @optimizationFlags { - kConstantOutputForConstantInput_OptimizationFlag | - kPreservesOpaqueInput_OptimizationFlag + (inputFP ? ProcessorOptimizationFlags(inputFP.get()) : kAll_OptimizationFlags) & + (kConstantOutputForConstantInput_OptimizationFlag | + kPreservesOpaqueInput_OptimizationFlag) } void main() { + half4 inputColor = (inputFP != null) ? sample(inputFP) : sk_InColor; @if (clampToPremul) { - half alpha = saturate(sk_InColor.a); - sk_OutColor = half4(clamp(sk_InColor.rgb, 0, alpha), alpha); + half alpha = saturate(inputColor.a); + sk_OutColor = half4(clamp(inputColor.rgb, 0, alpha), alpha); } else { - sk_OutColor = saturate(sk_InColor); + sk_OutColor = saturate(inputColor); } } @@ -33,5 +36,5 @@ void main() { } @test(d) { - return GrClampFragmentProcessor::Make(d->fRandom->nextBool()); + return GrClampFragmentProcessor::Make(/*inputFP=*/nullptr, d->fRandom->nextBool()); } diff --git a/src/gpu/effects/generated/GrClampFragmentProcessor.cpp b/src/gpu/effects/generated/GrClampFragmentProcessor.cpp index 7d692b52de..9eb218b51f 100644 --- a/src/gpu/effects/generated/GrClampFragmentProcessor.cpp +++ b/src/gpu/effects/generated/GrClampFragmentProcessor.cpp @@ -25,11 +25,18 @@ public: (void)_outer; auto clampToPremul = _outer.clampToPremul; (void)clampToPremul; + SkString _sample484; + if (_outer.inputFP_index >= 0) { + _sample484 = this->invokeChild(_outer.inputFP_index, args); + } else { + _sample484 = "half4(1)"; + } fragBuilder->codeAppendf( - "@if (%s) {\n half alpha = clamp(%s.w, 0.0, 1.0);\n %s = half4(clamp(%s.xyz, " - "0.0, alpha), alpha);\n} else {\n %s = clamp(%s, 0.0, 1.0);\n}\n", - (_outer.clampToPremul ? "true" : "false"), args.fInputColor, args.fOutputColor, - args.fInputColor, args.fOutputColor, args.fInputColor); + "half4 inputColor = %s ? %s : %s;\n@if (%s) {\n half alpha = " + "clamp(inputColor.w, 0.0, 1.0);\n %s = half4(clamp(inputColor.xyz, 0.0, alpha), " + "alpha);\n} else {\n %s = clamp(inputColor, 0.0, 1.0);\n}\n", + _outer.inputFP_index >= 0 ? "true" : "false", _sample484.c_str(), args.fInputColor, + (_outer.clampToPremul ? "true" : "false"), args.fOutputColor, args.fOutputColor); } private: @@ -51,13 +58,22 @@ bool GrClampFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) const } GrClampFragmentProcessor::GrClampFragmentProcessor(const GrClampFragmentProcessor& src) : INHERITED(kGrClampFragmentProcessor_ClassID, src.optimizationFlags()) - , clampToPremul(src.clampToPremul) {} + , inputFP_index(src.inputFP_index) + , clampToPremul(src.clampToPremul) { + if (inputFP_index >= 0) { + auto clone = src.childProcessor(inputFP_index).clone(); + if (src.childProcessor(inputFP_index).isSampledWithExplicitCoords()) { + clone->setSampledWithExplicitCoords(); + } + this->registerChildProcessor(std::move(clone)); + } +} std::unique_ptr GrClampFragmentProcessor::clone() const { return std::unique_ptr(new GrClampFragmentProcessor(*this)); } GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrClampFragmentProcessor); #if GR_TEST_UTILS std::unique_ptr GrClampFragmentProcessor::TestCreate(GrProcessorTestData* d) { - return GrClampFragmentProcessor::Make(d->fRandom->nextBool()); + return GrClampFragmentProcessor::Make(/*inputFP=*/nullptr, d->fRandom->nextBool()); } #endif diff --git a/src/gpu/effects/generated/GrClampFragmentProcessor.h b/src/gpu/effects/generated/GrClampFragmentProcessor.h index 61dc3a03d6..df2a6d1ae5 100644 --- a/src/gpu/effects/generated/GrClampFragmentProcessor.h +++ b/src/gpu/effects/generated/GrClampFragmentProcessor.h @@ -23,20 +23,30 @@ public: return {SkTPin(input.fR, 0.f, clampVal), SkTPin(input.fG, 0.f, clampVal), SkTPin(input.fB, 0.f, clampVal), clampedAlpha}; } - static std::unique_ptr Make(bool clampToPremul) { - return std::unique_ptr(new GrClampFragmentProcessor(clampToPremul)); + static std::unique_ptr Make(std::unique_ptr inputFP, + bool clampToPremul) { + return std::unique_ptr( + new GrClampFragmentProcessor(std::move(inputFP), clampToPremul)); } GrClampFragmentProcessor(const GrClampFragmentProcessor& src); std::unique_ptr clone() const override; const char* name() const override { return "ClampFragmentProcessor"; } + int inputFP_index = -1; bool clampToPremul; private: - GrClampFragmentProcessor(bool clampToPremul) + GrClampFragmentProcessor(std::unique_ptr inputFP, bool clampToPremul) : INHERITED(kGrClampFragmentProcessor_ClassID, - (OptimizationFlags)kConstantOutputForConstantInput_OptimizationFlag | - kPreservesOpaqueInput_OptimizationFlag) - , clampToPremul(clampToPremul) {} + (OptimizationFlags)(inputFP ? ProcessorOptimizationFlags(inputFP.get()) + : kAll_OptimizationFlags) & + (kConstantOutputForConstantInput_OptimizationFlag | + kPreservesOpaqueInput_OptimizationFlag)) + , clampToPremul(clampToPremul) { + if (inputFP) { + inputFP_index = this->numChildProcessors(); + this->registerChildProcessor(std::move(inputFP)); + } + } GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; bool onIsEqual(const GrFragmentProcessor&) const override; diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp index f07148e8a9..830d8d6db0 100644 --- a/src/gpu/ops/GrTextureOp.cpp +++ b/src/gpu/ops/GrTextureOp.cpp @@ -1058,21 +1058,20 @@ std::unique_ptr GrTextureOp::Make(GrRecordingContext* context, const auto& caps = *context->priv().caps(); SkRect localRect; if (quad->fLocal.asRect(&localRect)) { - fp = GrTextureEffect::MakeSubset(std::move(proxyView), alphaType, SkMatrix::I(), filter, - *subset, localRect, caps); + fp = GrTextureEffect::MakeSubset(std::move(proxyView), alphaType, SkMatrix::I(), + filter, *subset, localRect, caps); } else { - fp = GrTextureEffect::MakeSubset(std::move(proxyView), alphaType, SkMatrix::I(), filter, - *subset, caps); + fp = GrTextureEffect::MakeSubset(std::move(proxyView), alphaType, SkMatrix::I(), + filter, *subset, caps); } } else { fp = GrTextureEffect::Make(std::move(proxyView), alphaType, SkMatrix::I(), filter); } fp = GrColorSpaceXformEffect::Make(std::move(fp), std::move(textureXform)); - paint.addColorFragmentProcessor(std::move(fp)); if (saturate == GrTextureOp::Saturate::kYes) { - paint.addColorFragmentProcessor(GrClampFragmentProcessor::Make(false)); + fp = GrClampFragmentProcessor::Make(std::move(fp), /*clampToPremul=*/false); } - + paint.addColorFragmentProcessor(std::move(fp)); return GrFillRectOp::Make(context, std::move(paint), aaType, quad); } }