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