From eed56f0fe5a2101361439023aa083724b7e72296 Mon Sep 17 00:00:00 2001 From: John Stiles Date: Thu, 4 Jun 2020 13:30:51 -0400 Subject: [PATCH] Update GrFragmentProcessor::SwizzleOutput 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. This CL also adds a GM test for SwizzleOutput, since this did not appear to be covered by existing unit tests. Change-Id: I3d8176395bb42eab7ff471c9137597402b5b3a69 Bug: skia:10217 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/293884 Commit-Queue: John Stiles Reviewed-by: Greg Daniel --- gm/swizzle.cpp | 43 +++++++++++++++++++++++++++++++++ gn/gm.gni | 1 + src/gpu/GrFragmentProcessor.cpp | 26 ++++++++++++-------- 3 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 gm/swizzle.cpp diff --git a/gm/swizzle.cpp b/gm/swizzle.cpp new file mode 100644 index 0000000000..2d298b2d72 --- /dev/null +++ b/gm/swizzle.cpp @@ -0,0 +1,43 @@ +/* + * Copyright 2019 Google LLC. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "gm/gm.h" +#include "include/core/SkCanvas.h" +#include "include/core/SkImageInfo.h" +#include "include/core/SkMatrix.h" +#include "include/core/SkRect.h" +#include "include/core/SkTypes.h" +#include "include/gpu/GrContext.h" +#include "src/gpu/GrBitmapTextureMaker.h" +#include "src/gpu/GrContextPriv.h" +#include "src/gpu/GrFragmentProcessor.h" +#include "src/gpu/GrRenderTargetContext.h" +#include "src/gpu/GrRenderTargetContextPriv.h" +#include "src/gpu/ops/GrFillRectOp.h" +#include "tools/Resources.h" +#include "tools/ToolUtils.h" + +DEF_SIMPLE_GPU_GM(swizzle, ctx, rtCtx, canvas, 512, 512) { + SkRect bounds = SkRect::MakeIWH(512, 512); + + SkBitmap bmp; + GetResourceAsBitmap("images/mandrill_512_q075.jpg", &bmp); + GrBitmapTextureMaker maker(ctx, bmp, GrImageTexGenPolicy::kDraw); + auto view = maker.view(GrMipMapped::kNo); + if (!view) { + return; + } + std::unique_ptr imgFP = + GrTextureEffect::Make(std::move(view), bmp.alphaType(), SkMatrix()); + auto fp = GrFragmentProcessor::SwizzleOutput(std::move(imgFP), GrSwizzle("grb1")); + + GrPaint grPaint; + grPaint.addColorFragmentProcessor(std::move(fp)); + + rtCtx->priv().testingOnly_addDrawOp( + GrFillRectOp::MakeNonAARect(ctx, std::move(grPaint), SkMatrix(), bounds)); +} diff --git a/gn/gm.gni b/gn/gm.gni index 77605da296..f2d6cd05dd 100644 --- a/gn/gm.gni +++ b/gn/gm.gni @@ -349,6 +349,7 @@ gm_sources = [ "$_gm/stroketext.cpp", "$_gm/subsetshader.cpp", "$_gm/surface.cpp", + "$_gm/swizzle.cpp", "$_gm/tablecolorfilter.cpp", "$_gm/tallstretchedbitmaps.cpp", "$_gm/tessellation.cpp", diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp index 1163f37a20..05b9a31426 100644 --- a/src/gpu/GrFragmentProcessor.cpp +++ b/src/gpu/GrFragmentProcessor.cpp @@ -188,30 +188,38 @@ std::unique_ptr GrFragmentProcessor::SwizzleOutput( std::unique_ptr fp, const GrSwizzle& swizzle) { class SwizzleFragmentProcessor : public GrFragmentProcessor { public: - static std::unique_ptr Make(const GrSwizzle& swizzle) { - return std::unique_ptr(new SwizzleFragmentProcessor(swizzle)); + static std::unique_ptr Make(std::unique_ptr fp, + const GrSwizzle& swizzle) { + return std::unique_ptr( + new SwizzleFragmentProcessor(std::move(fp), swizzle)); } const char* name() const override { return "Swizzle"; } const GrSwizzle& swizzle() const { return fSwizzle; } - std::unique_ptr clone() const override { return Make(fSwizzle); } + std::unique_ptr clone() const override { + return Make(this->childProcessor(0).clone(), fSwizzle); + } private: - SwizzleFragmentProcessor(const GrSwizzle& swizzle) - : INHERITED(kSwizzleFragmentProcessor_ClassID, kAll_OptimizationFlags) - , fSwizzle(swizzle) {} + SwizzleFragmentProcessor(std::unique_ptr fp, const GrSwizzle& swizzle) + : INHERITED(kSwizzleFragmentProcessor_ClassID, ProcessorOptimizationFlags(fp.get())) + , fSwizzle(swizzle) { + this->registerChildProcessor(std::move(fp)); + } GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { class GLFP : public GrGLSLFragmentProcessor { public: void emitCode(EmitArgs& args) override { + SkString childColor = this->invokeChild(0, args); + const SwizzleFragmentProcessor& sfp = args.fFp.cast(); const GrSwizzle& swizzle = sfp.swizzle(); GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; fragBuilder->codeAppendf("%s = %s.%s;", - args.fOutputColor, args.fInputColor, swizzle.asString().c_str()); + args.fOutputColor, childColor.c_str(), swizzle.asString().c_str()); } }; return new GLFP; @@ -241,9 +249,7 @@ std::unique_ptr GrFragmentProcessor::SwizzleOutput( if (GrSwizzle::RGBA() == swizzle) { return fp; } - std::unique_ptr fpPipeline[] = { std::move(fp), - SwizzleFragmentProcessor::Make(swizzle) }; - return GrFragmentProcessor::RunInSeries(fpPipeline, 2); + return SwizzleFragmentProcessor::Make(std::move(fp), swizzle); } std::unique_ptr GrFragmentProcessor::MakeInputPremulAndMulByOutput(