blob: 7ea975ffde16652c104f6d7f703041050f4a2877 [file] [log] [blame]
Ethan Nicholas420f1562017-07-14 13:11:38 -04001/*
2 * Copyright 2017 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8/*
9 * This file was autogenerated from GrEllipseEffect.fp; do not modify.
10 */
11#include "GrEllipseEffect.h"
12#if SK_SUPPORT_GPU
Ethan Nicholas420f1562017-07-14 13:11:38 -040013#include "glsl/GrGLSLFragmentProcessor.h"
14#include "glsl/GrGLSLFragmentShaderBuilder.h"
15#include "glsl/GrGLSLProgramBuilder.h"
Ethan Nicholas2d5f9b32017-12-13 14:36:14 -050016#include "GrTexture.h"
Ethan Nicholas420f1562017-07-14 13:11:38 -040017#include "SkSLCPP.h"
18#include "SkSLUtil.h"
19class GrGLSLEllipseEffect : public GrGLSLFragmentProcessor {
20public:
21 GrGLSLEllipseEffect() {}
22 void emitCode(EmitArgs& args) override {
23 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
24 const GrEllipseEffect& _outer = args.fFp.cast<GrEllipseEffect>();
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040025 (void)_outer;
Ethan Nicholas82399462017-10-16 12:35:44 -040026 auto edgeType = _outer.edgeType();
27 (void)edgeType;
28 auto center = _outer.center();
29 (void)center;
30 auto radii = _outer.radii();
31 (void)radii;
Chris Dalton47c8ed32017-11-15 18:27:09 -070032 prevRadii = float2(-1.0);
33 useScale = !sk_Caps.floatIs32Bits;
Ethan Nicholas8aa45692017-09-20 11:24:15 -040034 fEllipseVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat4_GrSLType,
Ethan Nicholasf7b88202017-09-18 14:10:39 -040035 kDefault_GrSLPrecision, "ellipse");
Ethan Nicholas420f1562017-07-14 13:11:38 -040036 if (useScale) {
Chris Dalton47c8ed32017-11-15 18:27:09 -070037 fScaleVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat2_GrSLType,
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040038 kDefault_GrSLPrecision, "scale");
Ethan Nicholas420f1562017-07-14 13:11:38 -040039 }
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040040 fragBuilder->codeAppendf(
Chris Dalton47c8ed32017-11-15 18:27:09 -070041 "float2 prevCenter;\nfloat2 prevRadii = float2(%f, %f);\nbool useScale = "
42 "%s;\nfloat2 d = sk_FragCoord.xy - %s.xy;\n@if (useScale) {\n d *= "
43 "%s.y;\n}\nfloat2 Z = d * %s.zw;\nfloat implicit = dot(Z, d) - 1.0;\nfloat "
44 "grad_dot = 4.0 * dot(Z, Z);\ngrad_dot = max(grad_dot, 0.0001);\nfloat approx_dist "
45 "= implicit * inversesqrt(grad_dot);\n@if (useScale) {\n approx_dist *= "
46 "%s.x;\n}\nhalf alpha;\n@switch (%d) {\n case 0:\n alpha = "
47 "half(approx_dist > 0.0 ? 0.0 : 1.0);\n break;\n case 1:\n ",
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040048 prevRadii.fX, prevRadii.fY, (useScale ? "true" : "false"),
49 args.fUniformHandler->getUniformCStr(fEllipseVar),
Chris Dalton47c8ed32017-11-15 18:27:09 -070050 fScaleVar.isValid() ? args.fUniformHandler->getUniformCStr(fScaleVar) : "float2(0)",
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040051 args.fUniformHandler->getUniformCStr(fEllipseVar),
Chris Dalton47c8ed32017-11-15 18:27:09 -070052 fScaleVar.isValid() ? args.fUniformHandler->getUniformCStr(fScaleVar) : "float2(0)",
Ethan Nicholasaae47c82017-11-10 15:34:03 -050053 (int)_outer.edgeType());
Ethan Nicholasd982d052017-10-16 10:22:03 -040054 fragBuilder->codeAppendf(
Chris Dalton47c8ed32017-11-15 18:27:09 -070055 " alpha = half(clamp(0.5 - approx_dist, 0.0, 1.0));\n break;\n case "
56 "2:\n alpha = half(approx_dist > 0.0 ? 1.0 : 0.0);\n break;\n "
57 "case 3:\n alpha = half(clamp(0.5 + approx_dist, 0.0, 1.0));\n "
58 "break;\n default:\n discard;\n}\n%s = %s * alpha;\n",
Ethan Nicholasd982d052017-10-16 10:22:03 -040059 args.fOutputColor, args.fInputColor ? args.fInputColor : "half4(1)");
Ethan Nicholas420f1562017-07-14 13:11:38 -040060 }
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040061
Ethan Nicholas420f1562017-07-14 13:11:38 -040062private:
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040063 void onSetData(const GrGLSLProgramDataManager& pdman,
64 const GrFragmentProcessor& _proc) override {
Ethan Nicholas420f1562017-07-14 13:11:38 -040065 const GrEllipseEffect& _outer = _proc.cast<GrEllipseEffect>();
66 auto edgeType = _outer.edgeType();
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040067 (void)edgeType;
Ethan Nicholas420f1562017-07-14 13:11:38 -040068 auto center = _outer.center();
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040069 (void)center;
Ethan Nicholas420f1562017-07-14 13:11:38 -040070 auto radii = _outer.radii();
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040071 (void)radii;
Ethan Nicholas420f1562017-07-14 13:11:38 -040072 UniformHandle& ellipse = fEllipseVar;
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040073 (void)ellipse;
Ethan Nicholas420f1562017-07-14 13:11:38 -040074 UniformHandle& scale = fScaleVar;
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040075 (void)scale;
Ethan Nicholas420f1562017-07-14 13:11:38 -040076
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040077 if (radii != prevRadii || center != prevCenter) {
78 float invRXSqd;
79 float invRYSqd;
Ethan Nicholas5b5f0962017-09-11 13:50:14 -070080 // If we're using a scale factor to work around precision issues, choose the larger
81 // radius as the scale factor. The inv radii need to be pre-adjusted by the scale
82 // factor.
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040083 if (scale.isValid()) {
84 if (radii.fX > radii.fY) {
85 invRXSqd = 1.f;
86 invRYSqd = (radii.fX * radii.fX) / (radii.fY * radii.fY);
87 pdman.set2f(scale, radii.fX, 1.f / radii.fX);
88 } else {
89 invRXSqd = (radii.fY * radii.fY) / (radii.fX * radii.fX);
90 invRYSqd = 1.f;
91 pdman.set2f(scale, radii.fY, 1.f / radii.fY);
92 }
Ethan Nicholas420f1562017-07-14 13:11:38 -040093 } else {
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040094 invRXSqd = 1.f / (radii.fX * radii.fX);
95 invRYSqd = 1.f / (radii.fY * radii.fY);
Ethan Nicholas420f1562017-07-14 13:11:38 -040096 }
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040097 pdman.set4f(ellipse, center.fX, center.fY, invRXSqd, invRYSqd);
98 prevCenter = center;
99 prevRadii = radii;
Ethan Nicholas420f1562017-07-14 13:11:38 -0400100 }
Ethan Nicholas420f1562017-07-14 13:11:38 -0400101 }
Ethan Nicholase9d172a2017-11-20 12:12:24 -0500102 SkPoint prevCenter = float2(0);
103 SkPoint prevRadii = float2(0);
104 bool useScale = false;
Ethan Nicholas420f1562017-07-14 13:11:38 -0400105 UniformHandle fEllipseVar;
106 UniformHandle fScaleVar;
107};
108GrGLSLFragmentProcessor* GrEllipseEffect::onCreateGLSLInstance() const {
109 return new GrGLSLEllipseEffect();
110}
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -0400111void GrEllipseEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
112 GrProcessorKeyBuilder* b) const {
Ethan Nicholasaae47c82017-11-10 15:34:03 -0500113 b->add32((int32_t)fEdgeType);
Ethan Nicholas420f1562017-07-14 13:11:38 -0400114}
115bool GrEllipseEffect::onIsEqual(const GrFragmentProcessor& other) const {
116 const GrEllipseEffect& that = other.cast<GrEllipseEffect>();
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -0400117 (void)that;
Ethan Nicholas420f1562017-07-14 13:11:38 -0400118 if (fEdgeType != that.fEdgeType) return false;
119 if (fCenter != that.fCenter) return false;
120 if (fRadii != that.fRadii) return false;
121 return true;
122}
Ethan Nicholasf57c0d62017-07-31 11:18:22 -0400123GrEllipseEffect::GrEllipseEffect(const GrEllipseEffect& src)
Ethan Nicholasabff9562017-10-09 10:54:08 -0400124 : INHERITED(kGrEllipseEffect_ClassID, src.optimizationFlags())
Ethan Nicholasf57c0d62017-07-31 11:18:22 -0400125 , fEdgeType(src.fEdgeType)
126 , fCenter(src.fCenter)
Ethan Nicholasabff9562017-10-09 10:54:08 -0400127 , fRadii(src.fRadii) {}
Brian Salomonaff329b2017-08-11 09:40:37 -0400128std::unique_ptr<GrFragmentProcessor> GrEllipseEffect::clone() const {
129 return std::unique_ptr<GrFragmentProcessor>(new GrEllipseEffect(*this));
Ethan Nicholasf57c0d62017-07-31 11:18:22 -0400130}
Ethan Nicholas420f1562017-07-14 13:11:38 -0400131GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrEllipseEffect);
132#if GR_TEST_UTILS
Brian Salomonaff329b2017-08-11 09:40:37 -0400133std::unique_ptr<GrFragmentProcessor> GrEllipseEffect::TestCreate(GrProcessorTestData* testData) {
Ethan Nicholas420f1562017-07-14 13:11:38 -0400134 SkPoint center;
135 center.fX = testData->fRandom->nextRangeScalar(0.f, 1000.f);
136 center.fY = testData->fRandom->nextRangeScalar(0.f, 1000.f);
137 SkScalar rx = testData->fRandom->nextRangeF(0.f, 1000.f);
138 SkScalar ry = testData->fRandom->nextRangeF(0.f, 1000.f);
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500139 GrClipEdgeType et;
Ethan Nicholas420f1562017-07-14 13:11:38 -0400140 do {
Ethan Nicholas1706f842017-11-10 11:58:19 -0500141 et = (GrClipEdgeType)testData->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
142 } while (GrClipEdgeType::kHairlineAA == et);
Brian Salomon14471772017-12-05 10:35:15 -0500143 return GrEllipseEffect::Make(et, center, SkPoint::Make(rx, ry),
144 *testData->caps()->shaderCaps());
Ethan Nicholas420f1562017-07-14 13:11:38 -0400145}
146#endif
147#endif