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 <johnstiles@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/gm/swizzle.cpp b/gm/swizzle.cpp
new file mode 100644
index 0000000..2d298b2
--- /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<GrFragmentProcessor> 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 77605da..f2d6cd0 100644
--- a/gn/gm.gni
+++ b/gn/gm.gni
@@ -349,6 +349,7 @@
"$_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 1163f37..05b9a31 100644
--- a/src/gpu/GrFragmentProcessor.cpp
+++ b/src/gpu/GrFragmentProcessor.cpp
@@ -188,30 +188,38 @@
std::unique_ptr<GrFragmentProcessor> fp, const GrSwizzle& swizzle) {
class SwizzleFragmentProcessor : public GrFragmentProcessor {
public:
- static std::unique_ptr<GrFragmentProcessor> Make(const GrSwizzle& swizzle) {
- return std::unique_ptr<GrFragmentProcessor>(new SwizzleFragmentProcessor(swizzle));
+ static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp,
+ const GrSwizzle& swizzle) {
+ return std::unique_ptr<GrFragmentProcessor>(
+ new SwizzleFragmentProcessor(std::move(fp), swizzle));
}
const char* name() const override { return "Swizzle"; }
const GrSwizzle& swizzle() const { return fSwizzle; }
- std::unique_ptr<GrFragmentProcessor> clone() const override { return Make(fSwizzle); }
+ std::unique_ptr<GrFragmentProcessor> 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<GrFragmentProcessor> 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<SwizzleFragmentProcessor>();
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 @@
if (GrSwizzle::RGBA() == swizzle) {
return fp;
}
- std::unique_ptr<GrFragmentProcessor> fpPipeline[] = { std::move(fp),
- SwizzleFragmentProcessor::Make(swizzle) };
- return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
+ return SwizzleFragmentProcessor::Make(std::move(fp), swizzle);
}
std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MakeInputPremulAndMulByOutput(