Implement radial gradient layout
Adds a radial gradient FP in the same vein as the prior linear gradient
FP. It updates SkRadialGradient to try and use the new system before
falling back to the original GPU gradient code.
Bug: skia:
Change-Id: I0739832beeae18d0a7178ada44014d7885478031
Reviewed-on: https://skia-review.googlesource.com/148803
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/gn/gpu.gni b/gn/gpu.gni
index 5c1335a..463b5ed 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -405,6 +405,8 @@
"$_src/gpu/gradients/GrSingleIntervalGradientColorizer.h",
"$_src/gpu/gradients/GrLinearGradientLayout.cpp",
"$_src/gpu/gradients/GrLinearGradientLayout.h",
+ "$_src/gpu/gradients/GrRadialGradientLayout.cpp",
+ "$_src/gpu/gradients/GrRadialGradientLayout.h",
"$_src/gpu/gradients/GrClampedGradientEffect.cpp",
"$_src/gpu/gradients/GrClampedGradientEffect.h",
"$_src/gpu/gradients/GrTiledGradientEffect.cpp",
diff --git a/gn/sksl.gni b/gn/sksl.gni
index ad34e22..4ec691e 100644
--- a/gn/sksl.gni
+++ b/gn/sksl.gni
@@ -48,6 +48,7 @@
"$_src/gpu/effects/GrYUVtoRGBEffect.fp",
"$_src/gpu/gradients/GrSingleIntervalGradientColorizer.fp",
"$_src/gpu/gradients/GrLinearGradientLayout.fp",
+ "$_src/gpu/gradients/GrRadialGradientLayout.fp",
"$_src/gpu/gradients/GrClampedGradientEffect.fp",
"$_src/gpu/gradients/GrTiledGradientEffect.fp",
]
diff --git a/src/gpu/GrProcessor.h b/src/gpu/GrProcessor.h
index 9eba390..0f5b11d 100644
--- a/src/gpu/GrProcessor.h
+++ b/src/gpu/GrProcessor.h
@@ -127,6 +127,7 @@
kGrPremulInputFragmentProcessor_ClassID,
kGrQuadEffect_ClassID,
kGrRadialGradient_ClassID,
+ kGrRadialGradientLayout_ClassID,
kGrRectBlurEffect_ClassID,
kGrRRectBlurEffect_ClassID,
kGrRRectShadowGeoProc_ClassID,
diff --git a/src/gpu/gradients/GrGradientShader.cpp b/src/gpu/gradients/GrGradientShader.cpp
index 83397a0..c277997 100644
--- a/src/gpu/gradients/GrGradientShader.cpp
+++ b/src/gpu/gradients/GrGradientShader.cpp
@@ -11,6 +11,8 @@
#include "GrTiledGradientEffect.h"
#include "GrLinearGradientLayout.h"
+#include "GrRadialGradientLayout.h"
+
#include "GrSingleIntervalGradientColorizer.h"
#include "SkGradientShaderPriv.h"
@@ -130,4 +132,9 @@
return make_gradient(shader, args, GrLinearGradientLayout::Make(shader, args));
}
+std::unique_ptr<GrFragmentProcessor> MakeRadial(const SkRadialGradient& shader,
+ const GrFPArgs& args) {
+ return make_gradient(shader,args, GrRadialGradientLayout::Make(shader, args));
+}
+
}
diff --git a/src/gpu/gradients/GrGradientShader.h b/src/gpu/gradients/GrGradientShader.h
index a781b02..22233fb 100644
--- a/src/gpu/gradients/GrGradientShader.h
+++ b/src/gpu/gradients/GrGradientShader.h
@@ -11,10 +11,14 @@
#include "GrFPArgs.h"
#include "SkGradientShaderPriv.h"
#include "SkLinearGradient.h"
+#include "SkRadialGradient.h"
namespace GrGradientShader {
std::unique_ptr<GrFragmentProcessor> MakeLinear(const SkLinearGradient& shader,
const GrFPArgs& args);
+
+ std::unique_ptr<GrFragmentProcessor> MakeRadial(const SkRadialGradient& shader,
+ const GrFPArgs& args);
}
#endif // GrGradientShader_DEFINE
diff --git a/src/gpu/gradients/GrRadialGradientLayout.cpp b/src/gpu/gradients/GrRadialGradientLayout.cpp
new file mode 100644
index 0000000..02f45a6
--- /dev/null
+++ b/src/gpu/gradients/GrRadialGradientLayout.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2018 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 GrRadialGradientLayout.fp; do not modify.
+ **************************************************************************************************/
+#include "GrRadialGradientLayout.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLRadialGradientLayout : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLRadialGradientLayout() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrRadialGradientLayout& _outer = args.fFp.cast<GrRadialGradientLayout>();
+ (void)_outer;
+ auto gradientMatrix = _outer.gradientMatrix();
+ (void)gradientMatrix;
+ SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
+ fragBuilder->codeAppendf("%s = half4(half(length(%s.xy)));\n", args.fOutputColor,
+ sk_TransformedCoords2D_0.c_str());
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {}
+};
+GrGLSLFragmentProcessor* GrRadialGradientLayout::onCreateGLSLInstance() const {
+ return new GrGLSLRadialGradientLayout();
+}
+void GrRadialGradientLayout::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {}
+bool GrRadialGradientLayout::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrRadialGradientLayout& that = other.cast<GrRadialGradientLayout>();
+ (void)that;
+ if (fGradientMatrix != that.fGradientMatrix) return false;
+ return true;
+}
+GrRadialGradientLayout::GrRadialGradientLayout(const GrRadialGradientLayout& src)
+ : INHERITED(kGrRadialGradientLayout_ClassID, src.optimizationFlags())
+ , fGradientMatrix(src.fGradientMatrix)
+ , fCoordTransform0(src.fCoordTransform0) {
+ this->addCoordTransform(&fCoordTransform0);
+}
+std::unique_ptr<GrFragmentProcessor> GrRadialGradientLayout::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrRadialGradientLayout(*this));
+}
+
+std::unique_ptr<GrFragmentProcessor> GrRadialGradientLayout::Make(const SkRadialGradient& grad,
+ const GrFPArgs& args) {
+ SkMatrix matrix;
+ if (!grad.totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix)->invert(&matrix)) {
+ return nullptr;
+ }
+ matrix.postConcat(grad.getGradientMatrix());
+ return std::unique_ptr<GrFragmentProcessor>(new GrRadialGradientLayout(matrix));
+}
diff --git a/src/gpu/gradients/GrRadialGradientLayout.fp b/src/gpu/gradients/GrRadialGradientLayout.fp
new file mode 100644
index 0000000..dd62153
--- /dev/null
+++ b/src/gpu/gradients/GrRadialGradientLayout.fp
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+in half4x4 gradientMatrix;
+
+@coordTransform {
+ gradientMatrix
+}
+
+void main() {
+ sk_OutColor = half4(length(sk_TransformedCoords2D[0].xy));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+@header {
+ #include "SkRadialGradient.h"
+}
+
+@make {
+ static std::unique_ptr<GrFragmentProcessor> Make(const SkRadialGradient& gradient,
+ const GrFPArgs& args);
+}
+
+@cppEnd {
+ std::unique_ptr<GrFragmentProcessor> GrRadialGradientLayout::Make(
+ const SkRadialGradient& grad, const GrFPArgs& args) {
+ SkMatrix matrix;
+ if (!grad.totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix)->invert(&matrix)) {
+ return nullptr;
+ }
+ matrix.postConcat(grad.getGradientMatrix());
+ return std::unique_ptr<GrFragmentProcessor>(new GrRadialGradientLayout(matrix));
+ }
+}
diff --git a/src/gpu/gradients/GrRadialGradientLayout.h b/src/gpu/gradients/GrRadialGradientLayout.h
new file mode 100644
index 0000000..3fa034c
--- /dev/null
+++ b/src/gpu/gradients/GrRadialGradientLayout.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2018 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 GrRadialGradientLayout.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrRadialGradientLayout_DEFINED
+#define GrRadialGradientLayout_DEFINED
+#include "SkTypes.h"
+
+#include "SkRadialGradient.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrRadialGradientLayout : public GrFragmentProcessor {
+public:
+ const SkMatrix44& gradientMatrix() const { return fGradientMatrix; }
+
+ static std::unique_ptr<GrFragmentProcessor> Make(const SkRadialGradient& gradient,
+ const GrFPArgs& args);
+ GrRadialGradientLayout(const GrRadialGradientLayout& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "RadialGradientLayout"; }
+
+private:
+ GrRadialGradientLayout(SkMatrix44 gradientMatrix)
+ : INHERITED(kGrRadialGradientLayout_ClassID, kNone_OptimizationFlags)
+ , fGradientMatrix(gradientMatrix)
+ , fCoordTransform0(gradientMatrix) {
+ this->addCoordTransform(&fCoordTransform0);
+ }
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ SkMatrix44 fGradientMatrix;
+ GrCoordTransform fCoordTransform0;
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif
diff --git a/src/shaders/gradients/SkRadialGradient.cpp b/src/shaders/gradients/SkRadialGradient.cpp
index 70edb65..9d86162 100644
--- a/src/shaders/gradients/SkRadialGradient.cpp
+++ b/src/shaders/gradients/SkRadialGradient.cpp
@@ -67,6 +67,8 @@
#include "GrShaderCaps.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "gradients/GrGradientShader.h"
+
class GrRadialGradient : public GrGradientEffect {
public:
class GLSLRadialProcessor;
@@ -162,6 +164,12 @@
std::unique_ptr<GrFragmentProcessor> SkRadialGradient::asFragmentProcessor(
const GrFPArgs& args) const {
+ // Try to use new gradient system first
+ std::unique_ptr<GrFragmentProcessor> gradient = GrGradientShader::MakeRadial(*this, args);
+ if (gradient) {
+ return gradient;
+ }
+
SkMatrix matrix;
if (!this->totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix)->invert(&matrix)) {
return nullptr;