blob: 28390d636718e372f0fac5f1b8f21a44d69ee1f6 [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
Ethan Nicholas130fb3f2018-02-01 12:14:34 -05008/**************************************************************************************************
9 *** This file was autogenerated from GrEllipseEffect.fp; do not modify.
10 **************************************************************************************************/
Ethan Nicholas420f1562017-07-14 13:11:38 -040011#include "GrEllipseEffect.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012
Greg Daniel456f9b52020-03-05 19:14:18 +000013#include "src/gpu/GrTexture.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
15#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
16#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
17#include "src/sksl/SkSLCPP.h"
18#include "src/sksl/SkSLUtil.h"
Ethan Nicholas420f1562017-07-14 13:11:38 -040019class GrGLSLEllipseEffect : public GrGLSLFragmentProcessor {
20public:
21 GrGLSLEllipseEffect() {}
22 void emitCode(EmitArgs& args) override {
23 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
Mike Kleind6ab77a2019-03-21 08:18:24 -050024 const GrEllipseEffect& _outer = args.fFp.cast<GrEllipseEffect>();
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040025 (void)_outer;
Ethan Nicholasbcd51e82019-04-09 10:40:41 -040026 auto edgeType = _outer.edgeType;
Ethan Nicholas82399462017-10-16 12:35:44 -040027 (void)edgeType;
Ethan Nicholasbcd51e82019-04-09 10:40:41 -040028 auto center = _outer.center;
Ethan Nicholas82399462017-10-16 12:35:44 -040029 (void)center;
Ethan Nicholasbcd51e82019-04-09 10:40:41 -040030 auto radii = _outer.radii;
Ethan Nicholas82399462017-10-16 12:35:44 -040031 (void)radii;
Mike Kleind6ab77a2019-03-21 08:18:24 -050032 prevRadii = float2(-1.0);
Jim Van Verth20ae25c2019-03-29 08:50:41 -040033 medPrecision = !sk_Caps.floatIs32Bits;
Ethan Nicholas16464c32020-04-06 13:53:05 -040034 ellipseVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag,
35 kFloat4_GrSLType, "ellipse");
Jim Van Verth20ae25c2019-03-29 08:50:41 -040036 if (medPrecision) {
Ethan Nicholas16464c32020-04-06 13:53:05 -040037 scaleVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag,
38 kFloat2_GrSLType, "scale");
Ethan Nicholas420f1562017-07-14 13:11:38 -040039 }
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040040 fragBuilder->codeAppendf(
John Stiles50819422020-06-18 13:00:38 -040041 R"SkSL(float2 prevCenter;
42float2 prevRadii = float2(%f, %f);
43bool medPrecision = %s;
44float2 d = sk_FragCoord.xy - %s.xy;
45@if (medPrecision) {
46 d *= %s.y;
47}
48float2 Z = d * %s.zw;
49float implicit = dot(Z, d) - 1.0;
50float grad_dot = 4.0 * dot(Z, Z);
51@if (medPrecision) {
52 grad_dot = max(grad_dot, 6.1036000261083245e-05);
53} else {
54 grad_dot = max(grad_dot, 1.1754999560161448e-38);
55}
56float approx_dist = implicit * inversesqrt(grad_dot);
57@if (medPrecision) {
58 approx_dist *= %s.x;
59}
60half alpha;
61@switch (%d) {
62 case 0:
63 alpha = approx_dist > 0.0 ? 0.0 : 1.0;
64 break;
65 case 1:
66 alpha = clamp(0.5 - half(approx_dist), 0.0, 1.0);
67 break;
68 case 2:
69 alpha = approx_dist > 0.0 ? 1.0 : 0.0;
70 break;
71 case 3:
72 alpha = clamp(0.5 + half(approx_dist), 0.0, 1.0);
73 break;
74 default:
75 discard;
76})SkSL",
Jim Van Verth20ae25c2019-03-29 08:50:41 -040077 prevRadii.fX, prevRadii.fY, (medPrecision ? "true" : "false"),
Ethan Nicholasbcd51e82019-04-09 10:40:41 -040078 args.fUniformHandler->getUniformCStr(ellipseVar),
79 scaleVar.isValid() ? args.fUniformHandler->getUniformCStr(scaleVar) : "float2(0)",
80 args.fUniformHandler->getUniformCStr(ellipseVar),
John Stiles50819422020-06-18 13:00:38 -040081 scaleVar.isValid() ? args.fUniformHandler->getUniformCStr(scaleVar) : "float2(0)",
John Stiles2fbe6172020-06-08 13:28:43 -040082 (int)_outer.edgeType);
John Stiles50819422020-06-18 13:00:38 -040083 SkString _input4481(args.fInputColor);
Brian Osman12c5d292020-07-13 16:11:35 -040084 SkString _sample4481 = this->invokeChild(0, _input4481.c_str(), args);
John Stiles50819422020-06-18 13:00:38 -040085 fragBuilder->codeAppendf(
86 R"SkSL(
87half4 inputColor = %s;
88%s = inputColor * alpha;
89)SkSL",
90 _sample4481.c_str(), args.fOutputColor);
Ethan Nicholas420f1562017-07-14 13:11:38 -040091 }
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040092
Ethan Nicholas420f1562017-07-14 13:11:38 -040093private:
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040094 void onSetData(const GrGLSLProgramDataManager& pdman,
Mike Kleind6ab77a2019-03-21 08:18:24 -050095 const GrFragmentProcessor& _proc) override {
96 const GrEllipseEffect& _outer = _proc.cast<GrEllipseEffect>();
Ethan Nicholasbcd51e82019-04-09 10:40:41 -040097 auto edgeType = _outer.edgeType;
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040098 (void)edgeType;
Ethan Nicholasbcd51e82019-04-09 10:40:41 -040099 auto center = _outer.center;
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -0400100 (void)center;
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400101 auto radii = _outer.radii;
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -0400102 (void)radii;
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400103 UniformHandle& ellipse = ellipseVar;
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -0400104 (void)ellipse;
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400105 UniformHandle& scale = scaleVar;
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -0400106 (void)scale;
Ethan Nicholas420f1562017-07-14 13:11:38 -0400107
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -0400108 if (radii != prevRadii || center != prevCenter) {
109 float invRXSqd;
110 float invRYSqd;
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700111 // If we're using a scale factor to work around precision issues, choose the larger
112 // radius as the scale factor. The inv radii need to be pre-adjusted by the scale
113 // factor.
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -0400114 if (scale.isValid()) {
115 if (radii.fX > radii.fY) {
116 invRXSqd = 1.f;
117 invRYSqd = (radii.fX * radii.fX) / (radii.fY * radii.fY);
118 pdman.set2f(scale, radii.fX, 1.f / radii.fX);
119 } else {
120 invRXSqd = (radii.fY * radii.fY) / (radii.fX * radii.fX);
121 invRYSqd = 1.f;
122 pdman.set2f(scale, radii.fY, 1.f / radii.fY);
123 }
Ethan Nicholas420f1562017-07-14 13:11:38 -0400124 } else {
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -0400125 invRXSqd = 1.f / (radii.fX * radii.fX);
126 invRYSqd = 1.f / (radii.fY * radii.fY);
Ethan Nicholas420f1562017-07-14 13:11:38 -0400127 }
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -0400128 pdman.set4f(ellipse, center.fX, center.fY, invRXSqd, invRYSqd);
129 prevCenter = center;
Mike Kleind6ab77a2019-03-21 08:18:24 -0500130 prevRadii = radii;
Ethan Nicholas420f1562017-07-14 13:11:38 -0400131 }
Ethan Nicholas420f1562017-07-14 13:11:38 -0400132 }
Mike Kleind6ab77a2019-03-21 08:18:24 -0500133 SkPoint prevCenter = float2(0);
134 SkPoint prevRadii = float2(0);
Jim Van Verth20ae25c2019-03-29 08:50:41 -0400135 bool medPrecision = false;
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400136 UniformHandle ellipseVar;
137 UniformHandle scaleVar;
Ethan Nicholas420f1562017-07-14 13:11:38 -0400138};
139GrGLSLFragmentProcessor* GrEllipseEffect::onCreateGLSLInstance() const {
140 return new GrGLSLEllipseEffect();
141}
Mike Kleind6ab77a2019-03-21 08:18:24 -0500142void GrEllipseEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -0400143 GrProcessorKeyBuilder* b) const {
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400144 b->add32((int32_t)edgeType);
Ethan Nicholas420f1562017-07-14 13:11:38 -0400145}
146bool GrEllipseEffect::onIsEqual(const GrFragmentProcessor& other) const {
147 const GrEllipseEffect& that = other.cast<GrEllipseEffect>();
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -0400148 (void)that;
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400149 if (edgeType != that.edgeType) return false;
150 if (center != that.center) return false;
151 if (radii != that.radii) return false;
Ethan Nicholas420f1562017-07-14 13:11:38 -0400152 return true;
153}
Ethan Nicholasf57c0d62017-07-31 11:18:22 -0400154GrEllipseEffect::GrEllipseEffect(const GrEllipseEffect& src)
Ethan Nicholasabff9562017-10-09 10:54:08 -0400155 : INHERITED(kGrEllipseEffect_ClassID, src.optimizationFlags())
Ethan Nicholasbcd51e82019-04-09 10:40:41 -0400156 , edgeType(src.edgeType)
157 , center(src.center)
John Stiles2fbe6172020-06-08 13:28:43 -0400158 , radii(src.radii) {
Brian Osman12c5d292020-07-13 16:11:35 -0400159 this->cloneAndRegisterAllChildProcessors(src);
John Stiles2fbe6172020-06-08 13:28:43 -0400160}
Brian Salomonaff329b2017-08-11 09:40:37 -0400161std::unique_ptr<GrFragmentProcessor> GrEllipseEffect::clone() const {
162 return std::unique_ptr<GrFragmentProcessor>(new GrEllipseEffect(*this));
Ethan Nicholasf57c0d62017-07-31 11:18:22 -0400163}
Ethan Nicholas420f1562017-07-14 13:11:38 -0400164GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrEllipseEffect);
165#if GR_TEST_UTILS
Brian Salomonaff329b2017-08-11 09:40:37 -0400166std::unique_ptr<GrFragmentProcessor> GrEllipseEffect::TestCreate(GrProcessorTestData* testData) {
Ethan Nicholas420f1562017-07-14 13:11:38 -0400167 SkPoint center;
Mike Kleind6ab77a2019-03-21 08:18:24 -0500168 center.fX = testData->fRandom->nextRangeScalar(0.f, 1000.f);
169 center.fY = testData->fRandom->nextRangeScalar(0.f, 1000.f);
170 SkScalar rx = testData->fRandom->nextRangeF(0.f, 1000.f);
171 SkScalar ry = testData->fRandom->nextRangeF(0.f, 1000.f);
John Stilesde975e32020-06-17 13:49:33 -0400172 bool success;
173 std::unique_ptr<GrFragmentProcessor> fp;
174 do {
175 GrClipEdgeType et = (GrClipEdgeType)testData->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
176 std::tie(success, fp) =
177 GrEllipseEffect::Make(/*inputFP=*/nullptr, et, center, SkPoint::Make(rx, ry),
178 *testData->caps()->shaderCaps());
179 } while (!success);
180 return fp;
Ethan Nicholas420f1562017-07-14 13:11:38 -0400181}
182#endif