• 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 #include "glsl/GrGLSLFragmentProcessor.h"
13 #include "glsl/GrGLSLFragmentShaderBuilder.h"
14 #include "glsl/GrGLSLProgramBuilder.h"
15 #include "GrTexture.h"
16 #include "SkSLCPP.h"
17 #include "SkSLUtil.h"
18 class GrGLSLTwoPointConicalGradientLayout : public GrGLSLFragmentProcessor {
19 public:
GrGLSLTwoPointConicalGradientLayout()20     GrGLSLTwoPointConicalGradientLayout() {}
emitCode(EmitArgs & args)21     void emitCode(EmitArgs& args) override {
22         GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
23         const GrTwoPointConicalGradientLayout& _outer =
24                 args.fFp.cast<GrTwoPointConicalGradientLayout>();
25         (void)_outer;
26         auto gradientMatrix = _outer.gradientMatrix();
27         (void)gradientMatrix;
28         auto type = _outer.type();
29         (void)type;
30         auto isRadiusIncreasing = _outer.isRadiusIncreasing();
31         (void)isRadiusIncreasing;
32         auto isFocalOnCircle = _outer.isFocalOnCircle();
33         (void)isFocalOnCircle;
34         auto isWellBehaved = _outer.isWellBehaved();
35         (void)isWellBehaved;
36         auto isSwapped = _outer.isSwapped();
37         (void)isSwapped;
38         auto isNativelyFocal = _outer.isNativelyFocal();
39         (void)isNativelyFocal;
40         auto focalParams = _outer.focalParams();
41         (void)focalParams;
42         fFocalParamsVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType,
43                                                            kDefault_GrSLPrecision, "focalParams");
44         SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
45         fragBuilder->codeAppendf(
46                 "float2 p = %s;\nfloat t = -1.0;\nhalf v = 1.0;\n@switch (%d) {\n    case 1:\n     "
47                 "   {\n            half r0_2 = %s.y;\n            t = float(float(r0_2) - p.y * "
48                 "p.y);\n            if (t >= 0.0) {\n                t = p.x + sqrt(t);\n          "
49                 "  } else {\n                v = -1.0;\n            }\n        }\n        break;\n "
50                 "   case 0:\n        {\n            half r0 = %s.x;\n            @if (%s) {\n      "
51                 "          t = length(p) - float(r0);\n            } else {\n                t = "
52                 "-length(p) - float(r0);\n",
53                 sk_TransformedCoords2D_0.c_str(), (int)_outer.type(),
54                 args.fUniformHandler->getUniformCStr(fFocalParamsVar),
55                 args.fUniformHandler->getUniformCStr(fFocalParamsVar),
56                 (_outer.isRadiusIncreasing() ? "true" : "false"));
57         fragBuilder->codeAppendf(
58                 "            }\n        }\n        break;\n    case 2:\n        {\n            "
59                 "half invR1 = %s.x;\n            half fx = %s.y;\n            float x_t = -1.0;\n  "
60                 "          @if (%s) {\n                x_t = dot(p, p) / p.x;\n            } else "
61                 "if (%s) {\n                x_t = length(p) - p.x * float(invR1);\n            } "
62                 "else {\n                float temp = p.x * p.x - p.y * p.y;\n                if "
63                 "(temp >= 0.0) {\n                    @if (%s || !%s) {\n                        "
64                 "x_t = -sqrt(temp) - p.x * float",
65                 args.fUniformHandler->getUniformCStr(fFocalParamsVar),
66                 args.fUniformHandler->getUniformCStr(fFocalParamsVar),
67                 (_outer.isFocalOnCircle() ? "true" : "false"),
68                 (_outer.isWellBehaved() ? "true" : "false"),
69                 (_outer.isSwapped() ? "true" : "false"),
70                 (_outer.isRadiusIncreasing() ? "true" : "false"));
71         fragBuilder->codeAppendf(
72                 "(invR1);\n                    } else {\n                        x_t = sqrt(temp) "
73                 "- p.x * float(invR1);\n                    }\n                }\n            }\n  "
74                 "          @if (!%s) {\n                if (x_t <= 0.0) {\n                    v = "
75                 "-1.0;\n                }\n            }\n            @if (%s) {\n                "
76                 "@if (%s) {\n                    t = x_t;\n                } else {\n              "
77                 "      t = x_t + float(fx);\n                }\n            } else {\n             "
78                 "   @if (%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 (fFocalParamsPrev != focalParamsValue) {
99                 fFocalParamsPrev = focalParamsValue;
100                 pdman.set2f(fFocalParamsVar, focalParamsValue.fX, focalParamsValue.fY);
101             }
102         }
103     }
104     SkPoint fFocalParamsPrev = SkPoint::Make(SK_FloatNaN, SK_FloatNaN);
105     UniformHandle fFocalParamsVar;
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)fType);
113     b->add32((int32_t)fIsRadiusIncreasing);
114     b->add32((int32_t)fIsFocalOnCircle);
115     b->add32((int32_t)fIsWellBehaved);
116     b->add32((int32_t)fIsSwapped);
117     b->add32((int32_t)fIsNativelyFocal);
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 (fGradientMatrix != that.fGradientMatrix) return false;
123     if (fType != that.fType) return false;
124     if (fIsRadiusIncreasing != that.fIsRadiusIncreasing) return false;
125     if (fIsFocalOnCircle != that.fIsFocalOnCircle) return false;
126     if (fIsWellBehaved != that.fIsWellBehaved) return false;
127     if (fIsSwapped != that.fIsSwapped) return false;
128     if (fIsNativelyFocal != that.fIsNativelyFocal) return false;
129     if (fFocalParams != that.fFocalParams) return false;
130     return true;
131 }
GrTwoPointConicalGradientLayout(const GrTwoPointConicalGradientLayout & src)132 GrTwoPointConicalGradientLayout::GrTwoPointConicalGradientLayout(
133         const GrTwoPointConicalGradientLayout& src)
134         : INHERITED(kGrTwoPointConicalGradientLayout_ClassID, src.optimizationFlags())
135         , fGradientMatrix(src.fGradientMatrix)
136         , fType(src.fType)
137         , fIsRadiusIncreasing(src.fIsRadiusIncreasing)
138         , fIsFocalOnCircle(src.fIsFocalOnCircle)
139         , fIsWellBehaved(src.fIsWellBehaved)
140         , fIsSwapped(src.fIsSwapped)
141         , fIsNativelyFocal(src.fIsNativelyFocal)
142         , fFocalParams(src.fFocalParams)
143         , fCoordTransform0(src.fCoordTransform0) {
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