• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 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 GrTwoPointConicalGradientLayout.fp; do not modify.
10  **************************************************************************************************/
11 #include "GrTwoPointConicalGradientLayout.h"
12 
13 #include "include/gpu/GrTexture.h"
14 #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"
19 class GrGLSLTwoPointConicalGradientLayout : public GrGLSLFragmentProcessor {
20 public:
GrGLSLTwoPointConicalGradientLayout()21     GrGLSLTwoPointConicalGradientLayout() {}
emitCode(EmitArgs & args)22     void emitCode(EmitArgs& args) override {
23         GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
24         const GrTwoPointConicalGradientLayout& _outer =
25                 args.fFp.cast<GrTwoPointConicalGradientLayout>();
26         (void)_outer;
27         auto gradientMatrix = _outer.gradientMatrix;
28         (void)gradientMatrix;
29         auto type = _outer.type;
30         (void)type;
31         auto isRadiusIncreasing = _outer.isRadiusIncreasing;
32         (void)isRadiusIncreasing;
33         auto isFocalOnCircle = _outer.isFocalOnCircle;
34         (void)isFocalOnCircle;
35         auto isWellBehaved = _outer.isWellBehaved;
36         (void)isWellBehaved;
37         auto isSwapped = _outer.isSwapped;
38         (void)isSwapped;
39         auto isNativelyFocal = _outer.isNativelyFocal;
40         (void)isNativelyFocal;
41         auto focalParams = _outer.focalParams;
42         (void)focalParams;
43         focalParamsVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType,
44                                                           "focalParams");
45         SkString sk_TransformedCoords2D_0 =
46                 fragBuilder->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint);
47         fragBuilder->codeAppendf(
48                 "float2 p = %s;\nfloat t = -1.0;\nhalf v = 1.0;\n@switch (%d) {\n    case 1:\n     "
49                 "   {\n            half r0_2 = %s.y;\n            t = float(r0_2) - p.y * p.y;\n   "
50                 "         if (t >= 0.0) {\n                t = p.x + sqrt(t);\n            } else "
51                 "{\n                v = -1.0;\n            }\n        }\n        break;\n    case "
52                 "0:\n        {\n            half r0 = %s.x;\n            @if (%s) {\n              "
53                 "  t = length(p) - float(r0);\n            } else {\n                t = "
54                 "-length(p) - float(r0);\n       ",
55                 sk_TransformedCoords2D_0.c_str(), (int)_outer.type,
56                 args.fUniformHandler->getUniformCStr(focalParamsVar),
57                 args.fUniformHandler->getUniformCStr(focalParamsVar),
58                 (_outer.isRadiusIncreasing ? "true" : "false"));
59         fragBuilder->codeAppendf(
60                 "     }\n        }\n        break;\n    case 2:\n        {\n            half invR1 "
61                 "= %s.x;\n            half fx = %s.y;\n            float x_t = -1.0;\n            "
62                 "@if (%s) {\n                x_t = dot(p, p) / p.x;\n            } else if (%s) "
63                 "{\n                x_t = length(p) - p.x * float(invR1);\n            } else {\n  "
64                 "              float temp = p.x * p.x - p.y * p.y;\n                if (temp >= "
65                 "0.0) {\n                    @if (%s || !%s) {\n                        x_t = "
66                 "-sqrt(temp) - p.x * float(invR1)",
67                 args.fUniformHandler->getUniformCStr(focalParamsVar),
68                 args.fUniformHandler->getUniformCStr(focalParamsVar),
69                 (_outer.isFocalOnCircle ? "true" : "false"),
70                 (_outer.isWellBehaved ? "true" : "false"), (_outer.isSwapped ? "true" : "false"),
71                 (_outer.isRadiusIncreasing ? "true" : "false"));
72         fragBuilder->codeAppendf(
73                 ";\n                    } else {\n                        x_t = sqrt(temp) - p.x * "
74                 "float(invR1);\n                    }\n                }\n            }\n          "
75                 "  @if (!%s) {\n                if (x_t <= 0.0) {\n                    v = -1.0;\n "
76                 "               }\n            }\n            @if (%s) {\n                @if (%s) "
77                 "{\n                    t = x_t;\n                } else {\n                    t "
78                 "= x_t + float(fx);\n                }\n            } else {\n                @if "
79                 "(%s) {\n              ",
80                 (_outer.isWellBehaved ? "true" : "false"),
81                 (_outer.isRadiusIncreasing ? "true" : "false"),
82                 (_outer.isNativelyFocal ? "true" : "false"),
83                 (_outer.isNativelyFocal ? "true" : "false"));
84         fragBuilder->codeAppendf(
85                 "      t = -x_t;\n                } else {\n                    t = -x_t + "
86                 "float(fx);\n                }\n            }\n            @if (%s) {\n            "
87                 "    t = 1.0 - t;\n            }\n        }\n        break;\n}\n%s = "
88                 "half4(half(t), v, 0.0, 0.0);\n",
89                 (_outer.isSwapped ? "true" : "false"), args.fOutputColor);
90     }
91 
92 private:
onSetData(const GrGLSLProgramDataManager & pdman,const GrFragmentProcessor & _proc)93     void onSetData(const GrGLSLProgramDataManager& pdman,
94                    const GrFragmentProcessor& _proc) override {
95         const GrTwoPointConicalGradientLayout& _outer =
96                 _proc.cast<GrTwoPointConicalGradientLayout>();
97         {
98             const SkPoint& focalParamsValue = _outer.focalParams;
99             if (focalParamsPrev != focalParamsValue) {
100                 focalParamsPrev = focalParamsValue;
101                 pdman.set2f(focalParamsVar, focalParamsValue.fX, focalParamsValue.fY);
102             }
103         }
104     }
105     SkPoint focalParamsPrev = SkPoint::Make(SK_FloatNaN, SK_FloatNaN);
106     UniformHandle focalParamsVar;
107 };
onCreateGLSLInstance() const108 GrGLSLFragmentProcessor* GrTwoPointConicalGradientLayout::onCreateGLSLInstance() const {
109     return new GrGLSLTwoPointConicalGradientLayout();
110 }
onGetGLSLProcessorKey(const GrShaderCaps & caps,GrProcessorKeyBuilder * b) const111 void GrTwoPointConicalGradientLayout::onGetGLSLProcessorKey(const GrShaderCaps& caps,
112                                                             GrProcessorKeyBuilder* b) const {
113     b->add32((int32_t)type);
114     b->add32((int32_t)isRadiusIncreasing);
115     b->add32((int32_t)isFocalOnCircle);
116     b->add32((int32_t)isWellBehaved);
117     b->add32((int32_t)isSwapped);
118     b->add32((int32_t)isNativelyFocal);
119 }
onIsEqual(const GrFragmentProcessor & other) const120 bool GrTwoPointConicalGradientLayout::onIsEqual(const GrFragmentProcessor& other) const {
121     const GrTwoPointConicalGradientLayout& that = other.cast<GrTwoPointConicalGradientLayout>();
122     (void)that;
123     if (gradientMatrix != that.gradientMatrix) return false;
124     if (type != that.type) return false;
125     if (isRadiusIncreasing != that.isRadiusIncreasing) return false;
126     if (isFocalOnCircle != that.isFocalOnCircle) return false;
127     if (isWellBehaved != that.isWellBehaved) return false;
128     if (isSwapped != that.isSwapped) return false;
129     if (isNativelyFocal != that.isNativelyFocal) return false;
130     if (focalParams != that.focalParams) return false;
131     return true;
132 }
GrTwoPointConicalGradientLayout(const GrTwoPointConicalGradientLayout & src)133 GrTwoPointConicalGradientLayout::GrTwoPointConicalGradientLayout(
134         const GrTwoPointConicalGradientLayout& src)
135         : INHERITED(kGrTwoPointConicalGradientLayout_ClassID, src.optimizationFlags())
136         , fCoordTransform0(src.fCoordTransform0)
137         , gradientMatrix(src.gradientMatrix)
138         , type(src.type)
139         , isRadiusIncreasing(src.isRadiusIncreasing)
140         , isFocalOnCircle(src.isFocalOnCircle)
141         , isWellBehaved(src.isWellBehaved)
142         , isSwapped(src.isSwapped)
143         , isNativelyFocal(src.isNativelyFocal)
144         , focalParams(src.focalParams) {
145     this->addCoordTransform(&fCoordTransform0);
146 }
clone() const147 std::unique_ptr<GrFragmentProcessor> GrTwoPointConicalGradientLayout::clone() const {
148     return std::unique_ptr<GrFragmentProcessor>(new GrTwoPointConicalGradientLayout(*this));
149 }
150 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrTwoPointConicalGradientLayout);
151 #if GR_TEST_UTILS
TestCreate(GrProcessorTestData * d)152 std::unique_ptr<GrFragmentProcessor> GrTwoPointConicalGradientLayout::TestCreate(
153         GrProcessorTestData* d) {
154     SkScalar scale = GrGradientShader::RandomParams::kGradientScale;
155     SkScalar offset = scale / 32.0f;
156 
157     SkPoint center1 = {d->fRandom->nextRangeScalar(0.0f, scale),
158                        d->fRandom->nextRangeScalar(0.0f, scale)};
159     SkPoint center2 = {d->fRandom->nextRangeScalar(0.0f, scale),
160                        d->fRandom->nextRangeScalar(0.0f, scale)};
161     SkScalar radius1 = d->fRandom->nextRangeScalar(0.0f, scale);
162     SkScalar radius2 = d->fRandom->nextRangeScalar(0.0f, scale);
163 
164     constexpr int kTestTypeMask = (1 << 2) - 1, kTestNativelyFocalBit = (1 << 2),
165                   kTestFocalOnCircleBit = (1 << 3), kTestSwappedBit = (1 << 4);
166     // We won't treat isWellDefined and isRadiusIncreasing specially because they
167     // should have high probability to be turned on and off as we're getting random
168     // radii and centers.
169 
170     int mask = d->fRandom->nextU();
171     int type = mask & kTestTypeMask;
172     if (type == static_cast<int>(Type::kRadial)) {
173         center2 = center1;
174         // Make sure that the radii are different
175         if (SkScalarNearlyZero(radius1 - radius2)) {
176             radius2 += offset;
177         }
178     } else if (type == static_cast<int>(Type::kStrip)) {
179         radius1 = std::max(radius1, .1f);  // Make sure that the radius is non-zero
180         radius2 = radius1;
181         // Make sure that the centers are different
182         if (SkScalarNearlyZero(SkPoint::Distance(center1, center2))) {
183             center2.fX += offset;
184         }
185     } else {  // kFocal_Type
186         // Make sure that the centers are different
187         if (SkScalarNearlyZero(SkPoint::Distance(center1, center2))) {
188             center2.fX += offset;
189         }
190 
191         if (kTestNativelyFocalBit & mask) {
192             radius1 = 0;
193         }
194         if (kTestFocalOnCircleBit & mask) {
195             radius2 = radius1 + SkPoint::Distance(center1, center2);
196         }
197         if (kTestSwappedBit & mask) {
198             std::swap(radius1, radius2);
199             radius2 = 0;
200         }
201 
202         // Make sure that the radii are different
203         if (SkScalarNearlyZero(radius1 - radius2)) {
204             radius2 += offset;
205         }
206     }
207 
208     if (SkScalarNearlyZero(radius1 - radius2) &&
209         SkScalarNearlyZero(SkPoint::Distance(center1, center2))) {
210         radius2 += offset;  // make sure that we're not degenerated
211     }
212 
213     GrGradientShader::RandomParams params(d->fRandom);
214     auto shader = params.fUseColors4f
215                           ? SkGradientShader::MakeTwoPointConical(
216                                     center1, radius1, center2, radius2, params.fColors4f,
217                                     params.fColorSpace, params.fStops, params.fColorCount,
218                                     params.fTileMode)
219                           : SkGradientShader::MakeTwoPointConical(
220                                     center1, radius1, center2, radius2, params.fColors,
221                                     params.fStops, params.fColorCount, params.fTileMode);
222     GrTest::TestAsFPArgs asFPArgs(d);
223     std::unique_ptr<GrFragmentProcessor> fp = as_SB(shader)->asFragmentProcessor(asFPArgs.args());
224 
225     SkASSERT_RELEASE(fp);
226     return fp;
227 }
228 #endif
229 
230 // .fp files do not let you reference outside enum definitions, so we have to explicitly map
231 // between the two compatible enum defs
convert_type(SkTwoPointConicalGradient::Type type)232 GrTwoPointConicalGradientLayout::Type convert_type(SkTwoPointConicalGradient::Type type) {
233     switch (type) {
234         case SkTwoPointConicalGradient::Type::kRadial:
235             return GrTwoPointConicalGradientLayout::Type::kRadial;
236         case SkTwoPointConicalGradient::Type::kStrip:
237             return GrTwoPointConicalGradientLayout::Type::kStrip;
238         case SkTwoPointConicalGradient::Type::kFocal:
239             return GrTwoPointConicalGradientLayout::Type::kFocal;
240     }
241     SkDEBUGFAIL("Should not be reachable");
242     return GrTwoPointConicalGradientLayout::Type::kRadial;
243 }
244 
Make(const SkTwoPointConicalGradient & grad,const GrFPArgs & args)245 std::unique_ptr<GrFragmentProcessor> GrTwoPointConicalGradientLayout::Make(
246         const SkTwoPointConicalGradient& grad, const GrFPArgs& args) {
247     GrTwoPointConicalGradientLayout::Type grType = convert_type(grad.getType());
248 
249     // The focalData struct is only valid if isFocal is true
250     const SkTwoPointConicalGradient::FocalData& focalData = grad.getFocalData();
251     bool isFocal = grType == Type::kFocal;
252 
253     // Calculate optimization switches from gradient specification
254     bool isFocalOnCircle = isFocal && focalData.isFocalOnCircle();
255     bool isWellBehaved = isFocal && focalData.isWellBehaved();
256     bool isSwapped = isFocal && focalData.isSwapped();
257     bool isNativelyFocal = isFocal && focalData.isNativelyFocal();
258 
259     // Type-specific calculations: isRadiusIncreasing, focalParams, and the gradient matrix.
260     // However, all types start with the total inverse local matrix calculated from the shader
261     // and args
262     bool isRadiusIncreasing;
263     SkPoint focalParams;  // really just a 2D tuple
264     SkMatrix matrix;
265 
266     // Initialize the base matrix
267     if (!grad.totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix)->invert(&matrix)) {
268         return nullptr;
269     }
270 
271     if (isFocal) {
272         isRadiusIncreasing = (1 - focalData.fFocalX) > 0;
273 
274         focalParams.set(1.0 / focalData.fR1, focalData.fFocalX);
275 
276         matrix.postConcat(grad.getGradientMatrix());
277     } else if (grType == Type::kRadial) {
278         SkScalar dr = grad.getDiffRadius();
279         isRadiusIncreasing = dr >= 0;
280 
281         SkScalar r0 = grad.getStartRadius() / dr;
282         focalParams.set(r0, r0 * r0);
283 
284         // GPU radial matrix is different from the original matrix, since we map the diff radius
285         // to have |dr| = 1, so manually compute the final gradient matrix here.
286 
287         // Map center to (0, 0)
288         matrix.postTranslate(-grad.getStartCenter().fX, -grad.getStartCenter().fY);
289 
290         // scale |diffRadius| to 1
291         matrix.postScale(1 / dr, 1 / dr);
292     } else {                         // kStrip
293         isRadiusIncreasing = false;  // kStrip doesn't use this flag
294 
295         SkScalar r0 = grad.getStartRadius() / grad.getCenterX1();
296         focalParams.set(r0, r0 * r0);
297 
298         matrix.postConcat(grad.getGradientMatrix());
299     }
300 
301     return std::unique_ptr<GrFragmentProcessor>(new GrTwoPointConicalGradientLayout(
302             matrix, grType, isRadiusIncreasing, isFocalOnCircle, isWellBehaved, isSwapped,
303             isNativelyFocal, focalParams));
304 }
305