blob: 566e50401949e75f5795058918bbc3ace2e7d7d3 [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"
Ethan Nicholas420f1562017-07-14 13:11:38 -040012#include "glsl/GrGLSLFragmentProcessor.h"
13#include "glsl/GrGLSLFragmentShaderBuilder.h"
14#include "glsl/GrGLSLProgramBuilder.h"
Ethan Nicholas2d5f9b32017-12-13 14:36:14 -050015#include "GrTexture.h"
Ethan Nicholas420f1562017-07-14 13:11:38 -040016#include "SkSLCPP.h"
17#include "SkSLUtil.h"
18class GrGLSLEllipseEffect : public GrGLSLFragmentProcessor {
19public:
20 GrGLSLEllipseEffect() {}
21 void emitCode(EmitArgs& args) override {
22 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
23 const GrEllipseEffect& _outer = args.fFp.cast<GrEllipseEffect>();
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040024 (void)_outer;
Ethan Nicholas82399462017-10-16 12:35:44 -040025 auto edgeType = _outer.edgeType();
26 (void)edgeType;
27 auto center = _outer.center();
28 (void)center;
29 auto radii = _outer.radii();
30 (void)radii;
Chris Dalton47c8ed32017-11-15 18:27:09 -070031 prevRadii = float2(-1.0);
32 useScale = !sk_Caps.floatIs32Bits;
Ethan Nicholas8aa45692017-09-20 11:24:15 -040033 fEllipseVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat4_GrSLType,
Ethan Nicholasf7b88202017-09-18 14:10:39 -040034 kDefault_GrSLPrecision, "ellipse");
Ethan Nicholas420f1562017-07-14 13:11:38 -040035 if (useScale) {
Chris Dalton47c8ed32017-11-15 18:27:09 -070036 fScaleVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat2_GrSLType,
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040037 kDefault_GrSLPrecision, "scale");
Ethan Nicholas420f1562017-07-14 13:11:38 -040038 }
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040039 fragBuilder->codeAppendf(
Chris Dalton47c8ed32017-11-15 18:27:09 -070040 "float2 prevCenter;\nfloat2 prevRadii = float2(%f, %f);\nbool useScale = "
41 "%s;\nfloat2 d = sk_FragCoord.xy - %s.xy;\n@if (useScale) {\n d *= "
42 "%s.y;\n}\nfloat2 Z = d * %s.zw;\nfloat implicit = dot(Z, d) - 1.0;\nfloat "
43 "grad_dot = 4.0 * dot(Z, Z);\ngrad_dot = max(grad_dot, 0.0001);\nfloat approx_dist "
44 "= implicit * inversesqrt(grad_dot);\n@if (useScale) {\n approx_dist *= "
45 "%s.x;\n}\nhalf alpha;\n@switch (%d) {\n case 0:\n alpha = "
46 "half(approx_dist > 0.0 ? 0.0 : 1.0);\n break;\n case 1:\n ",
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040047 prevRadii.fX, prevRadii.fY, (useScale ? "true" : "false"),
48 args.fUniformHandler->getUniformCStr(fEllipseVar),
Chris Dalton47c8ed32017-11-15 18:27:09 -070049 fScaleVar.isValid() ? args.fUniformHandler->getUniformCStr(fScaleVar) : "float2(0)",
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040050 args.fUniformHandler->getUniformCStr(fEllipseVar),
Chris Dalton47c8ed32017-11-15 18:27:09 -070051 fScaleVar.isValid() ? args.fUniformHandler->getUniformCStr(fScaleVar) : "float2(0)",
Ethan Nicholasaae47c82017-11-10 15:34:03 -050052 (int)_outer.edgeType());
Ethan Nicholasd982d052017-10-16 10:22:03 -040053 fragBuilder->codeAppendf(
Chris Dalton47c8ed32017-11-15 18:27:09 -070054 " alpha = half(clamp(0.5 - approx_dist, 0.0, 1.0));\n break;\n case "
55 "2:\n alpha = half(approx_dist > 0.0 ? 1.0 : 0.0);\n break;\n "
56 "case 3:\n alpha = half(clamp(0.5 + approx_dist, 0.0, 1.0));\n "
57 "break;\n default:\n discard;\n}\n%s = %s * alpha;\n",
Michael Ludwig231de032018-08-30 14:33:01 -040058 args.fOutputColor, args.fInputColor);
Ethan Nicholas420f1562017-07-14 13:11:38 -040059 }
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040060
Ethan Nicholas420f1562017-07-14 13:11:38 -040061private:
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040062 void onSetData(const GrGLSLProgramDataManager& pdman,
63 const GrFragmentProcessor& _proc) override {
Ethan Nicholas420f1562017-07-14 13:11:38 -040064 const GrEllipseEffect& _outer = _proc.cast<GrEllipseEffect>();
65 auto edgeType = _outer.edgeType();
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040066 (void)edgeType;
Ethan Nicholas420f1562017-07-14 13:11:38 -040067 auto center = _outer.center();
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040068 (void)center;
Ethan Nicholas420f1562017-07-14 13:11:38 -040069 auto radii = _outer.radii();
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040070 (void)radii;
Ethan Nicholas420f1562017-07-14 13:11:38 -040071 UniformHandle& ellipse = fEllipseVar;
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040072 (void)ellipse;
Ethan Nicholas420f1562017-07-14 13:11:38 -040073 UniformHandle& scale = fScaleVar;
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040074 (void)scale;
Ethan Nicholas420f1562017-07-14 13:11:38 -040075
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040076 if (radii != prevRadii || center != prevCenter) {
77 float invRXSqd;
78 float invRYSqd;
Ethan Nicholas5b5f0962017-09-11 13:50:14 -070079 // If we're using a scale factor to work around precision issues, choose the larger
80 // radius as the scale factor. The inv radii need to be pre-adjusted by the scale
81 // factor.
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040082 if (scale.isValid()) {
83 if (radii.fX > radii.fY) {
84 invRXSqd = 1.f;
85 invRYSqd = (radii.fX * radii.fX) / (radii.fY * radii.fY);
86 pdman.set2f(scale, radii.fX, 1.f / radii.fX);
87 } else {
88 invRXSqd = (radii.fY * radii.fY) / (radii.fX * radii.fX);
89 invRYSqd = 1.f;
90 pdman.set2f(scale, radii.fY, 1.f / radii.fY);
91 }
Ethan Nicholas420f1562017-07-14 13:11:38 -040092 } else {
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040093 invRXSqd = 1.f / (radii.fX * radii.fX);
94 invRYSqd = 1.f / (radii.fY * radii.fY);
Ethan Nicholas420f1562017-07-14 13:11:38 -040095 }
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -040096 pdman.set4f(ellipse, center.fX, center.fY, invRXSqd, invRYSqd);
97 prevCenter = center;
98 prevRadii = radii;
Ethan Nicholas420f1562017-07-14 13:11:38 -040099 }
Ethan Nicholas420f1562017-07-14 13:11:38 -0400100 }
Ethan Nicholase9d172a2017-11-20 12:12:24 -0500101 SkPoint prevCenter = float2(0);
102 SkPoint prevRadii = float2(0);
103 bool useScale = false;
Ethan Nicholas420f1562017-07-14 13:11:38 -0400104 UniformHandle fEllipseVar;
105 UniformHandle fScaleVar;
106};
107GrGLSLFragmentProcessor* GrEllipseEffect::onCreateGLSLInstance() const {
108 return new GrGLSLEllipseEffect();
109}
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -0400110void GrEllipseEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
111 GrProcessorKeyBuilder* b) const {
Ethan Nicholasaae47c82017-11-10 15:34:03 -0500112 b->add32((int32_t)fEdgeType);
Ethan Nicholas420f1562017-07-14 13:11:38 -0400113}
114bool GrEllipseEffect::onIsEqual(const GrFragmentProcessor& other) const {
115 const GrEllipseEffect& that = other.cast<GrEllipseEffect>();
Ethan Nicholasb7e8c3b2017-07-19 13:54:20 -0400116 (void)that;
Ethan Nicholas420f1562017-07-14 13:11:38 -0400117 if (fEdgeType != that.fEdgeType) return false;
118 if (fCenter != that.fCenter) return false;
119 if (fRadii != that.fRadii) return false;
120 return true;
121}
Ethan Nicholasf57c0d62017-07-31 11:18:22 -0400122GrEllipseEffect::GrEllipseEffect(const GrEllipseEffect& src)
Ethan Nicholasabff9562017-10-09 10:54:08 -0400123 : INHERITED(kGrEllipseEffect_ClassID, src.optimizationFlags())
Ethan Nicholasf57c0d62017-07-31 11:18:22 -0400124 , fEdgeType(src.fEdgeType)
125 , fCenter(src.fCenter)
Ethan Nicholasabff9562017-10-09 10:54:08 -0400126 , fRadii(src.fRadii) {}
Brian Salomonaff329b2017-08-11 09:40:37 -0400127std::unique_ptr<GrFragmentProcessor> GrEllipseEffect::clone() const {
128 return std::unique_ptr<GrFragmentProcessor>(new GrEllipseEffect(*this));
Ethan Nicholasf57c0d62017-07-31 11:18:22 -0400129}
Ethan Nicholas420f1562017-07-14 13:11:38 -0400130GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrEllipseEffect);
131#if GR_TEST_UTILS
Brian Salomonaff329b2017-08-11 09:40:37 -0400132std::unique_ptr<GrFragmentProcessor> GrEllipseEffect::TestCreate(GrProcessorTestData* testData) {
Ethan Nicholas420f1562017-07-14 13:11:38 -0400133 SkPoint center;
134 center.fX = testData->fRandom->nextRangeScalar(0.f, 1000.f);
135 center.fY = testData->fRandom->nextRangeScalar(0.f, 1000.f);
136 SkScalar rx = testData->fRandom->nextRangeF(0.f, 1000.f);
137 SkScalar ry = testData->fRandom->nextRangeF(0.f, 1000.f);
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500138 GrClipEdgeType et;
Ethan Nicholas420f1562017-07-14 13:11:38 -0400139 do {
Ethan Nicholas1706f842017-11-10 11:58:19 -0500140 et = (GrClipEdgeType)testData->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
141 } while (GrClipEdgeType::kHairlineAA == et);
Brian Salomon14471772017-12-05 10:35:15 -0500142 return GrEllipseEffect::Make(et, center, SkPoint::Make(rx, ry),
143 *testData->caps()->shaderCaps());
Ethan Nicholas420f1562017-07-14 13:11:38 -0400144}
145#endif