Reland "SkMixerColorFilter GPU impl"
This reverts commit c2949ec67b92e455edd58e470564023c37df6e7a.
Reason for revert: not related to crossfade
Original change's description:
> Revert "SkMixerColorFilter GPU impl"
>
> This reverts commit e80f7eb9d6a15d42827108700990291d3efb5995.
>
> Reason for revert: break crossfade in chrome roll?
>
> Original change's description:
> > SkMixerColorFilter GPU impl
> >
> > Bug: skia:
> > Change-Id: Ia1e25e0c99737d9720c17f92f0d76a1cb7897ea8
> > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/193163
> > Commit-Queue: Florin Malita <fmalita@chromium.org>
> > Reviewed-by: Brian Salomon <bsalomon@google.com>
>
> TBR=bsalomon@google.com,ethannicholas@google.com,fmalita@chromium.org,reed@google.com
>
> Change-Id: Ib9464fcabc649b95ba131146690d6208af728436
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: skia:
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/197760
> Reviewed-by: Mike Reed <reed@google.com>
> Commit-Queue: Mike Reed <reed@google.com>
TBR=bsalomon@google.com,ethannicholas@google.com,fmalita@chromium.org,reed@google.com
Change-Id: Ie96e80e153aeab16c4ea35d5f1350372060228aa
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/197763
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/gn/gpu.gni b/gn/gpu.gni
index b692e18..bf6be62 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -343,6 +343,8 @@
"$_src/gpu/effects/GrMagnifierEffect.h",
"$_src/gpu/effects/GrMatrixConvolutionEffect.cpp",
"$_src/gpu/effects/GrMatrixConvolutionEffect.h",
+ "$_src/gpu/effects/GrMixerEffect.cpp",
+ "$_src/gpu/effects/GrMixerEffect.h",
"$_src/gpu/effects/GrOvalEffect.cpp",
"$_src/gpu/effects/GrOvalEffect.h",
"$_src/gpu/effects/GrPorterDuffXferProcessor.cpp",
diff --git a/gn/sksl.gni b/gn/sksl.gni
index 5890597..755fa95 100644
--- a/gn/sksl.gni
+++ b/gn/sksl.gni
@@ -41,6 +41,7 @@
"$_src/gpu/effects/GrEllipseEffect.fp",
"$_src/gpu/effects/GrLumaColorFilterEffect.fp",
"$_src/gpu/effects/GrMagnifierEffect.fp",
+ "$_src/gpu/effects/GrMixerEffect.fp",
"$_src/gpu/effects/GrPremulInputFragmentProcessor.fp",
"$_src/gpu/effects/GrRectBlurEffect.fp",
"$_src/gpu/effects/GrRRectBlurEffect.fp",
diff --git a/src/core/SkColorFilter.cpp b/src/core/SkColorFilter.cpp
index 9d6ee47..333dddf 100644
--- a/src/core/SkColorFilter.cpp
+++ b/src/core/SkColorFilter.cpp
@@ -21,6 +21,7 @@
#if SK_SUPPORT_GPU
#include "GrFragmentProcessor.h"
+#include "effects/GrMixerEffect.h"
#endif
bool SkColorFilter::asColorMode(SkColor*, SkBlendMode*) const {
@@ -325,8 +326,11 @@
#if SK_SUPPORT_GPU
std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(
- GrRecordingContext* context, const GrColorSpaceInfo&) const override {
- return nullptr;
+ GrRecordingContext* context, const GrColorSpaceInfo& dstColorSpaceInfo) const override {
+ return GrMixerEffect::Make(
+ fCF0->asFragmentProcessor(context, dstColorSpaceInfo),
+ fCF1 ? fCF1->asFragmentProcessor(context, dstColorSpaceInfo) : nullptr,
+ fWeight);
}
#endif
diff --git a/src/gpu/GrProcessor.h b/src/gpu/GrProcessor.h
index 19ab4ab..ba01e44 100644
--- a/src/gpu/GrProcessor.h
+++ b/src/gpu/GrProcessor.h
@@ -120,6 +120,7 @@
kGrMatrixConvolutionEffect_ClassID,
kGrMeshTestProcessor_ClassID,
kGrMorphologyEffect_ClassID,
+ kGrMixerEffect_ClassID,
kGrOverdrawFragmentProcessor_ClassID,
kGrPathProcessor_ClassID,
kGrPerlinNoise2Effect_ClassID,
diff --git a/src/gpu/effects/GrMixerEffect.cpp b/src/gpu/effects/GrMixerEffect.cpp
new file mode 100644
index 0000000..6e79f51
--- /dev/null
+++ b/src/gpu/effects/GrMixerEffect.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2019 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 GrMixerEffect.fp; do not modify.
+ **************************************************************************************************/
+#include "GrMixerEffect.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLMixerEffect : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLMixerEffect() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrMixerEffect& _outer = args.fFp.cast<GrMixerEffect>();
+ (void)_outer;
+ auto weight = _outer.weight();
+ (void)weight;
+ fWeightVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType,
+ kDefault_GrSLPrecision, "weight");
+ SkString _input0 = SkStringPrintf("%s", args.fInputColor);
+ SkString _child0("_child0");
+ this->emitChild(_outer.fp0_index(), _input0.c_str(), &_child0, args);
+ fragBuilder->codeAppendf("half4 in0 = %s;", _child0.c_str());
+ SkString _input1 = SkStringPrintf("%s", args.fInputColor);
+ SkString _child1("_child1");
+ if (_outer.fp1_index() >= 0) {
+ this->emitChild(_outer.fp1_index(), _input1.c_str(), &_child1, args);
+ } else {
+ fragBuilder->codeAppendf("half4 %s;", _child1.c_str());
+ }
+ fragBuilder->codeAppendf("\nhalf4 in1 = %s ? %s : %s;\n%s = mix(in0, in1, %s);\n",
+ _outer.fp1_index() >= 0 ? "true" : "false", _child1.c_str(),
+ args.fInputColor, args.fOutputColor,
+ args.fUniformHandler->getUniformCStr(fWeightVar));
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {
+ const GrMixerEffect& _outer = _proc.cast<GrMixerEffect>();
+ { pdman.set1f(fWeightVar, (_outer.weight())); }
+ }
+ UniformHandle fWeightVar;
+};
+GrGLSLFragmentProcessor* GrMixerEffect::onCreateGLSLInstance() const {
+ return new GrGLSLMixerEffect();
+}
+void GrMixerEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {}
+bool GrMixerEffect::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrMixerEffect& that = other.cast<GrMixerEffect>();
+ (void)that;
+ if (fWeight != that.fWeight) return false;
+ return true;
+}
+GrMixerEffect::GrMixerEffect(const GrMixerEffect& src)
+ : INHERITED(kGrMixerEffect_ClassID, src.optimizationFlags())
+ , fFp0_index(src.fFp0_index)
+ , fFp1_index(src.fFp1_index)
+ , fWeight(src.fWeight) {
+ this->registerChildProcessor(src.childProcessor(fFp0_index).clone());
+ if (fFp1_index >= 0) {
+ this->registerChildProcessor(src.childProcessor(fFp1_index).clone());
+ }
+}
+std::unique_ptr<GrFragmentProcessor> GrMixerEffect::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrMixerEffect(*this));
+}
diff --git a/src/gpu/effects/GrMixerEffect.fp b/src/gpu/effects/GrMixerEffect.fp
new file mode 100644
index 0000000..40fd336
--- /dev/null
+++ b/src/gpu/effects/GrMixerEffect.fp
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2019 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+// Mixes the output of two FPs.
+
+in fragmentProcessor fp0;
+in fragmentProcessor? fp1;
+in uniform half weight;
+
+@class {
+
+ static OptimizationFlags OptFlags(const std::unique_ptr<GrFragmentProcessor>& fp0,
+ const std::unique_ptr<GrFragmentProcessor>& fp1) {
+ auto get_flags = [](const std::unique_ptr<GrFragmentProcessor>& fp) {
+ auto flags = kNone_OptimizationFlags;
+
+ if (fp->compatibleWithCoverageAsAlpha()) {
+ flags |= kCompatibleWithCoverageAsAlpha_OptimizationFlag;
+ }
+
+ if (fp->preservesOpaqueInput()) {
+ flags |= kPreservesOpaqueInput_OptimizationFlag;
+ }
+
+ if (fp->hasConstantOutputForConstantInput()) {
+ flags |= kConstantOutputForConstantInput_OptimizationFlag;
+ }
+
+ return flags;
+ };
+
+ const auto fp0_flags = get_flags(fp0);
+
+ return fp1 ? (fp0_flags & get_flags(fp1)) : fp0_flags;
+ }
+
+ SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
+ const auto c0 = ConstantOutputForConstantInput(this->childProcessor(0), input),
+ c1 = (this->numChildProcessors() > 1)
+ ? ConstantOutputForConstantInput(this->childProcessor(1), input)
+ : input;
+ return {
+ c0.fR + (c1.fR - c0.fR) * fWeight,
+ c0.fG + (c1.fG - c0.fG) * fWeight,
+ c0.fB + (c1.fB - c0.fB) * fWeight,
+ c0.fA + (c1.fA - c0.fA) * fWeight
+ };
+ }
+}
+
+@optimizationFlags { OptFlags(fp0, fp1) }
+
+void main() {
+ half4 in0 = process(fp0, sk_InColor);
+ half4 in1 = (fp1 != null) ? process(fp1, sk_InColor) : sk_InColor;
+
+ sk_OutColor = mix(in0, in1, weight);
+}
diff --git a/src/gpu/effects/GrMixerEffect.h b/src/gpu/effects/GrMixerEffect.h
new file mode 100644
index 0000000..16ce6fc
--- /dev/null
+++ b/src/gpu/effects/GrMixerEffect.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2019 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 GrMixerEffect.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrMixerEffect_DEFINED
+#define GrMixerEffect_DEFINED
+#include "SkTypes.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrMixerEffect : public GrFragmentProcessor {
+public:
+ static OptimizationFlags OptFlags(const std::unique_ptr<GrFragmentProcessor>& fp0,
+ const std::unique_ptr<GrFragmentProcessor>& fp1) {
+ auto get_flags = [](const std::unique_ptr<GrFragmentProcessor>& fp) {
+ auto flags = kNone_OptimizationFlags;
+
+ if (fp->compatibleWithCoverageAsAlpha()) {
+ flags |= kCompatibleWithCoverageAsAlpha_OptimizationFlag;
+ }
+
+ if (fp->preservesOpaqueInput()) {
+ flags |= kPreservesOpaqueInput_OptimizationFlag;
+ }
+
+ if (fp->hasConstantOutputForConstantInput()) {
+ flags |= kConstantOutputForConstantInput_OptimizationFlag;
+ }
+
+ return flags;
+ };
+
+ const auto fp0_flags = get_flags(fp0);
+
+ return fp1 ? (fp0_flags & get_flags(fp1)) : fp0_flags;
+ }
+
+ SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
+ const auto c0 = ConstantOutputForConstantInput(this->childProcessor(0), input),
+ c1 = (this->numChildProcessors() > 1)
+ ? ConstantOutputForConstantInput(this->childProcessor(1), input)
+ : input;
+ return {c0.fR + (c1.fR - c0.fR) * fWeight, c0.fG + (c1.fG - c0.fG) * fWeight,
+ c0.fB + (c1.fB - c0.fB) * fWeight, c0.fA + (c1.fA - c0.fA) * fWeight};
+ }
+ int fp0_index() const { return fFp0_index; }
+ int fp1_index() const { return fFp1_index; }
+ float weight() const { return fWeight; }
+ static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp0,
+ std::unique_ptr<GrFragmentProcessor>
+ fp1,
+ float weight) {
+ return std::unique_ptr<GrFragmentProcessor>(
+ new GrMixerEffect(std::move(fp0), std::move(fp1), weight));
+ }
+ GrMixerEffect(const GrMixerEffect& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "MixerEffect"; }
+
+private:
+ GrMixerEffect(std::unique_ptr<GrFragmentProcessor> fp0,
+ std::unique_ptr<GrFragmentProcessor>
+ fp1,
+ float weight)
+ : INHERITED(kGrMixerEffect_ClassID, (OptimizationFlags)OptFlags(fp0, fp1))
+ , fWeight(weight) {
+ SkASSERT(fp0);
+ fFp0_index = this->numChildProcessors();
+ this->registerChildProcessor(std::move(fp0));
+ if (fp1) {
+ fFp1_index = this->numChildProcessors();
+ this->registerChildProcessor(std::move(fp1));
+ }
+ }
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ int fFp0_index = -1;
+ int fFp1_index = -1;
+ float fWeight;
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif