Implement sweep gradient layout
Add an FP that implements the sweep gradient effect and updates
SkSweepGradient to use the new system if possible.
Bug: skia:
Change-Id: I3f65da01afafae54c45848a6a78fd758f65eb4a6
Reviewed-on: https://skia-review.googlesource.com/148806
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/gradients/GrSweepGradientLayout.cpp b/src/gpu/gradients/GrSweepGradientLayout.cpp
new file mode 100644
index 0000000..227ff5f
--- /dev/null
+++ b/src/gpu/gradients/GrSweepGradientLayout.cpp
@@ -0,0 +1,104 @@
+/*
+ * 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 GrSweepGradientLayout.fp; do not modify.
+ **************************************************************************************************/
+#include "GrSweepGradientLayout.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLSweepGradientLayout : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLSweepGradientLayout() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrSweepGradientLayout& _outer = args.fFp.cast<GrSweepGradientLayout>();
+ (void)_outer;
+ auto gradientMatrix = _outer.gradientMatrix();
+ (void)gradientMatrix;
+ auto bias = _outer.bias();
+ (void)bias;
+ auto scale = _outer.scale();
+ (void)scale;
+ fBiasVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType,
+ kDefault_GrSLPrecision, "bias");
+ fScaleVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType,
+ kDefault_GrSLPrecision, "scale");
+ SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
+ fragBuilder->codeAppendf(
+ "half angle;\nif (sk_Caps.atan2ImplementedAsAtanYOverX) {\n angle = half(2.0 * "
+ "atan(-%s.y, length(%s) - %s.x));\n} else {\n angle = half(atan(-%s.y, "
+ "-%s.x));\n}\n%s = half4(((float(float(angle) * 0.15915494309180001) + 0.5) + %s) "
+ "* %s);\n",
+ sk_TransformedCoords2D_0.c_str(), sk_TransformedCoords2D_0.c_str(),
+ sk_TransformedCoords2D_0.c_str(), sk_TransformedCoords2D_0.c_str(),
+ sk_TransformedCoords2D_0.c_str(), args.fOutputColor,
+ args.fUniformHandler->getUniformCStr(fBiasVar),
+ args.fUniformHandler->getUniformCStr(fScaleVar));
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {
+ const GrSweepGradientLayout& _outer = _proc.cast<GrSweepGradientLayout>();
+ {
+ float biasValue = _outer.bias();
+ if (fBiasPrev != biasValue) {
+ fBiasPrev = biasValue;
+ pdman.set1f(fBiasVar, biasValue);
+ }
+ float scaleValue = _outer.scale();
+ if (fScalePrev != scaleValue) {
+ fScalePrev = scaleValue;
+ pdman.set1f(fScaleVar, scaleValue);
+ }
+ }
+ }
+ float fBiasPrev = SK_FloatNaN;
+ float fScalePrev = SK_FloatNaN;
+ UniformHandle fBiasVar;
+ UniformHandle fScaleVar;
+};
+GrGLSLFragmentProcessor* GrSweepGradientLayout::onCreateGLSLInstance() const {
+ return new GrGLSLSweepGradientLayout();
+}
+void GrSweepGradientLayout::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {}
+bool GrSweepGradientLayout::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrSweepGradientLayout& that = other.cast<GrSweepGradientLayout>();
+ (void)that;
+ if (fGradientMatrix != that.fGradientMatrix) return false;
+ if (fBias != that.fBias) return false;
+ if (fScale != that.fScale) return false;
+ return true;
+}
+GrSweepGradientLayout::GrSweepGradientLayout(const GrSweepGradientLayout& src)
+ : INHERITED(kGrSweepGradientLayout_ClassID, src.optimizationFlags())
+ , fGradientMatrix(src.fGradientMatrix)
+ , fBias(src.fBias)
+ , fScale(src.fScale)
+ , fCoordTransform0(src.fCoordTransform0) {
+ this->addCoordTransform(&fCoordTransform0);
+}
+std::unique_ptr<GrFragmentProcessor> GrSweepGradientLayout::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrSweepGradientLayout(*this));
+}
+
+std::unique_ptr<GrFragmentProcessor> GrSweepGradientLayout::Make(const SkSweepGradient& 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 GrSweepGradientLayout(matrix, grad.getTBias(), grad.getTScale()));
+}