• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013 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 #include "GrBezierEffect.h"
9 
10 #include "glsl/GrGLSLFragmentShaderBuilder.h"
11 #include "glsl/GrGLSLGeometryProcessor.h"
12 #include "glsl/GrGLSLProgramDataManager.h"
13 #include "glsl/GrGLSLUniformHandler.h"
14 #include "glsl/GrGLSLUtil.h"
15 #include "glsl/GrGLSLVarying.h"
16 #include "glsl/GrGLSLVertexShaderBuilder.h"
17 
18 class GrGLConicEffect : public GrGLSLGeometryProcessor {
19 public:
20     GrGLConicEffect(const GrGeometryProcessor&);
21 
22     void onEmitCode(EmitArgs&, GrGPArgs*) override;
23 
24     static inline void GenKey(const GrGeometryProcessor&,
25                               const GrGLSLCaps&,
26                               GrProcessorKeyBuilder*);
27 
setData(const GrGLSLProgramDataManager & pdman,const GrPrimitiveProcessor & primProc)28     void setData(const GrGLSLProgramDataManager& pdman,
29                  const GrPrimitiveProcessor& primProc) override {
30         const GrConicEffect& ce = primProc.cast<GrConicEffect>();
31 
32         if (!ce.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(ce.viewMatrix())) {
33             fViewMatrix = ce.viewMatrix();
34             float viewMatrix[3 * 3];
35             GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
36             pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
37         }
38 
39         if (ce.color() != fColor) {
40             float c[4];
41             GrColorToRGBAFloat(ce.color(), c);
42             pdman.set4fv(fColorUniform, 1, c);
43             fColor = ce.color();
44         }
45 
46         if (ce.coverageScale() != 0xff && ce.coverageScale() != fCoverageScale) {
47             pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(ce.coverageScale()));
48             fCoverageScale = ce.coverageScale();
49         }
50     }
51 
setTransformData(const GrPrimitiveProcessor & primProc,const GrGLSLProgramDataManager & pdman,int index,const SkTArray<const GrCoordTransform *,true> & transforms)52     void setTransformData(const GrPrimitiveProcessor& primProc,
53                           const GrGLSLProgramDataManager& pdman,
54                           int index,
55                           const SkTArray<const GrCoordTransform*, true>& transforms) override {
56         this->setTransformDataHelper<GrConicEffect>(primProc, pdman, index, transforms);
57     }
58 
59 private:
60     SkMatrix fViewMatrix;
61     GrColor fColor;
62     uint8_t fCoverageScale;
63     GrPrimitiveEdgeType fEdgeType;
64     UniformHandle fColorUniform;
65     UniformHandle fCoverageScaleUniform;
66     UniformHandle fViewMatrixUniform;
67 
68     typedef GrGLSLGeometryProcessor INHERITED;
69 };
70 
GrGLConicEffect(const GrGeometryProcessor & processor)71 GrGLConicEffect::GrGLConicEffect(const GrGeometryProcessor& processor)
72     : fViewMatrix(SkMatrix::InvalidMatrix()), fColor(GrColor_ILLEGAL), fCoverageScale(0xff) {
73     const GrConicEffect& ce = processor.cast<GrConicEffect>();
74     fEdgeType = ce.getEdgeType();
75 }
76 
onEmitCode(EmitArgs & args,GrGPArgs * gpArgs)77 void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
78     GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
79     const GrConicEffect& gp = args.fGP.cast<GrConicEffect>();
80     GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
81     GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
82 
83     // emit attributes
84     varyingHandler->emitAttributes(gp);
85 
86     GrGLSLVertToFrag v(kVec4f_GrSLType);
87     varyingHandler->addVarying("ConicCoeffs", &v, kHigh_GrSLPrecision);
88     vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inConicCoeffs()->fName);
89 
90     GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
91     // Setup pass through color
92     if (!gp.colorIgnored()) {
93         this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform);
94     }
95 
96     // Setup position
97     this->setupPosition(vertBuilder,
98                         uniformHandler,
99                         gpArgs,
100                         gp.inPosition()->fName,
101                         gp.viewMatrix(),
102                         &fViewMatrixUniform);
103 
104     // emit transforms with position
105     this->emitTransforms(vertBuilder,
106                          varyingHandler,
107                          uniformHandler,
108                          gpArgs->fPositionVar,
109                          gp.inPosition()->fName,
110                          gp.localMatrix(),
111                          args.fTransformsIn,
112                          args.fTransformsOut);
113 
114     // TODO: this precision check should actually be a check on the number of bits
115     // high and medium provide and the selection of the lowest level that suffices.
116     // Additionally we should assert that the upstream code only lets us get here if
117     // either high or medium provides the required number of bits.
118     GrSLPrecision precision = kHigh_GrSLPrecision;
119     const GrShaderCaps::PrecisionInfo& highP = args.fGLSLCaps->getFloatShaderPrecisionInfo(
120                                                              kFragment_GrShaderType,
121                                                              kHigh_GrSLPrecision);
122     if (!highP.supported()) {
123         precision = kMedium_GrSLPrecision;
124     }
125 
126     GrGLSLShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, precision);
127     GrGLSLShaderVar dklmdx("dklmdx", kVec3f_GrSLType, 0, precision);
128     GrGLSLShaderVar dklmdy("dklmdy", kVec3f_GrSLType, 0, precision);
129     GrGLSLShaderVar dfdx("dfdx", kFloat_GrSLType, 0, precision);
130     GrGLSLShaderVar dfdy("dfdy", kFloat_GrSLType, 0, precision);
131     GrGLSLShaderVar gF("gF", kVec2f_GrSLType, 0, precision);
132     GrGLSLShaderVar gFM("gFM", kFloat_GrSLType, 0, precision);
133     GrGLSLShaderVar func("func", kFloat_GrSLType, 0, precision);
134 
135     fragBuilder->declAppend(edgeAlpha);
136     fragBuilder->declAppend(dklmdx);
137     fragBuilder->declAppend(dklmdy);
138     fragBuilder->declAppend(dfdx);
139     fragBuilder->declAppend(dfdy);
140     fragBuilder->declAppend(gF);
141     fragBuilder->declAppend(gFM);
142     fragBuilder->declAppend(func);
143 
144     switch (fEdgeType) {
145         case kHairlineAA_GrProcessorEdgeType: {
146             SkAssertResult(fragBuilder->enableFeature(
147                     GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
148             fragBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
149             fragBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
150             fragBuilder->codeAppendf("%s = 2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
151                                      dfdx.c_str(),
152                                      v.fsIn(), dklmdx.c_str(),
153                                      v.fsIn(), dklmdx.c_str(),
154                                      v.fsIn(), dklmdx.c_str());
155             fragBuilder->codeAppendf("%s = 2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
156                                      dfdy.c_str(),
157                                      v.fsIn(), dklmdy.c_str(),
158                                      v.fsIn(), dklmdy.c_str(),
159                                      v.fsIn(), dklmdy.c_str());
160             fragBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
161             fragBuilder->codeAppendf("%s = sqrt(dot(%s, %s));",
162                                      gFM.c_str(), gF.c_str(), gF.c_str());
163             fragBuilder->codeAppendf("%s = %s.x*%s.x - %s.y*%s.z;",
164                                      func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
165             fragBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
166             fragBuilder->codeAppendf("%s = %s / %s;",
167                                      edgeAlpha.c_str(), func.c_str(), gFM.c_str());
168             fragBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);",
169                                      edgeAlpha.c_str(), edgeAlpha.c_str());
170             // Add line below for smooth cubic ramp
171             // fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
172             break;
173         }
174         case kFillAA_GrProcessorEdgeType: {
175             SkAssertResult(fragBuilder->enableFeature(
176                     GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
177             fragBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
178             fragBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
179             fragBuilder->codeAppendf("%s ="
180                                      "2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
181                                      dfdx.c_str(),
182                                      v.fsIn(), dklmdx.c_str(),
183                                      v.fsIn(), dklmdx.c_str(),
184                                      v.fsIn(), dklmdx.c_str());
185             fragBuilder->codeAppendf("%s ="
186                                      "2.0 * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
187                                      dfdy.c_str(),
188                                      v.fsIn(), dklmdy.c_str(),
189                                      v.fsIn(), dklmdy.c_str(),
190                                      v.fsIn(), dklmdy.c_str());
191             fragBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
192             fragBuilder->codeAppendf("%s = sqrt(dot(%s, %s));",
193                                      gFM.c_str(), gF.c_str(), gF.c_str());
194             fragBuilder->codeAppendf("%s = %s.x * %s.x - %s.y * %s.z;",
195                                      func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
196             fragBuilder->codeAppendf("%s = %s / %s;",
197                                      edgeAlpha.c_str(), func.c_str(), gFM.c_str());
198             fragBuilder->codeAppendf("%s = clamp(1.0 - %s, 0.0, 1.0);",
199                                      edgeAlpha.c_str(), edgeAlpha.c_str());
200             // Add line below for smooth cubic ramp
201             // fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
202             break;
203         }
204         case kFillBW_GrProcessorEdgeType: {
205             fragBuilder->codeAppendf("%s = %s.x * %s.x - %s.y * %s.z;",
206                                      edgeAlpha.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
207             fragBuilder->codeAppendf("%s = float(%s < 0.0);",
208                                      edgeAlpha.c_str(), edgeAlpha.c_str());
209             break;
210         }
211         default:
212             SkFAIL("Shouldn't get here");
213     }
214 
215     // TODO should we really be doing this?
216     if (gp.coverageScale() != 0xff) {
217         const char* coverageScale;
218         fCoverageScaleUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
219                                                            kFloat_GrSLType,
220                                                            kHigh_GrSLPrecision,
221                                                            "Coverage",
222                                                            &coverageScale);
223         fragBuilder->codeAppendf("%s = vec4(%s * %s);",
224                                  args.fOutputCoverage, coverageScale, edgeAlpha.c_str());
225     } else {
226         fragBuilder->codeAppendf("%s = vec4(%s);", args.fOutputCoverage, edgeAlpha.c_str());
227     }
228 }
229 
GenKey(const GrGeometryProcessor & gp,const GrGLSLCaps &,GrProcessorKeyBuilder * b)230 void GrGLConicEffect::GenKey(const GrGeometryProcessor& gp,
231                              const GrGLSLCaps&,
232                              GrProcessorKeyBuilder* b) {
233     const GrConicEffect& ce = gp.cast<GrConicEffect>();
234     uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
235     key |= GrColor_ILLEGAL != ce.color() ? 0x4 : 0x0;
236     key |= 0xff != ce.coverageScale() ? 0x8 : 0x0;
237     key |= ce.usesLocalCoords() && ce.localMatrix().hasPerspective() ? 0x10 : 0x0;
238     key |= ComputePosKey(ce.viewMatrix()) << 5;
239     b->add32(key);
240 }
241 
242 //////////////////////////////////////////////////////////////////////////////
243 
~GrConicEffect()244 GrConicEffect::~GrConicEffect() {}
245 
getGLSLProcessorKey(const GrGLSLCaps & caps,GrProcessorKeyBuilder * b) const246 void GrConicEffect::getGLSLProcessorKey(const GrGLSLCaps& caps,
247                                         GrProcessorKeyBuilder* b) const {
248     GrGLConicEffect::GenKey(*this, caps, b);
249 }
250 
createGLSLInstance(const GrGLSLCaps &) const251 GrGLSLPrimitiveProcessor* GrConicEffect::createGLSLInstance(const GrGLSLCaps&) const {
252     return new GrGLConicEffect(*this);
253 }
254 
GrConicEffect(GrColor color,const SkMatrix & viewMatrix,uint8_t coverage,GrPrimitiveEdgeType edgeType,const SkMatrix & localMatrix,bool usesLocalCoords)255 GrConicEffect::GrConicEffect(GrColor color, const SkMatrix& viewMatrix, uint8_t coverage,
256                              GrPrimitiveEdgeType edgeType, const SkMatrix& localMatrix,
257                              bool usesLocalCoords)
258     : fColor(color)
259     , fViewMatrix(viewMatrix)
260     , fLocalMatrix(viewMatrix)
261     , fUsesLocalCoords(usesLocalCoords)
262     , fCoverageScale(coverage)
263     , fEdgeType(edgeType) {
264     this->initClassID<GrConicEffect>();
265     fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType,
266                                                    kHigh_GrSLPrecision));
267     fInConicCoeffs = &this->addVertexAttrib(Attribute("inConicCoeffs",
268                                                       kVec4f_GrVertexAttribType));
269 }
270 
271 //////////////////////////////////////////////////////////////////////////////
272 
273 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrConicEffect);
274 
TestCreate(GrProcessorTestData * d)275 const GrGeometryProcessor* GrConicEffect::TestCreate(GrProcessorTestData* d) {
276     GrGeometryProcessor* gp;
277     do {
278         GrPrimitiveEdgeType edgeType =
279                 static_cast<GrPrimitiveEdgeType>(
280                         d->fRandom->nextULessThan(kGrProcessorEdgeTypeCnt));
281         gp = GrConicEffect::Create(GrRandomColor(d->fRandom), GrTest::TestMatrix(d->fRandom),
282                                    edgeType, *d->fCaps,
283                                    GrTest::TestMatrix(d->fRandom), d->fRandom->nextBool());
284     } while (nullptr == gp);
285     return gp;
286 }
287 
288 //////////////////////////////////////////////////////////////////////////////
289 // Quad
290 //////////////////////////////////////////////////////////////////////////////
291 
292 class GrGLQuadEffect : public GrGLSLGeometryProcessor {
293 public:
294     GrGLQuadEffect(const GrGeometryProcessor&);
295 
296     void onEmitCode(EmitArgs&, GrGPArgs*) override;
297 
298     static inline void GenKey(const GrGeometryProcessor&,
299                               const GrGLSLCaps&,
300                               GrProcessorKeyBuilder*);
301 
setData(const GrGLSLProgramDataManager & pdman,const GrPrimitiveProcessor & primProc)302     void setData(const GrGLSLProgramDataManager& pdman,
303                  const GrPrimitiveProcessor& primProc) override {
304         const GrQuadEffect& qe = primProc.cast<GrQuadEffect>();
305 
306         if (!qe.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(qe.viewMatrix())) {
307             fViewMatrix = qe.viewMatrix();
308             float viewMatrix[3 * 3];
309             GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
310             pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
311         }
312 
313         if (qe.color() != fColor) {
314             float c[4];
315             GrColorToRGBAFloat(qe.color(), c);
316             pdman.set4fv(fColorUniform, 1, c);
317             fColor = qe.color();
318         }
319 
320         if (qe.coverageScale() != 0xff && qe.coverageScale() != fCoverageScale) {
321             pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(qe.coverageScale()));
322             fCoverageScale = qe.coverageScale();
323         }
324     }
325 
setTransformData(const GrPrimitiveProcessor & primProc,const GrGLSLProgramDataManager & pdman,int index,const SkTArray<const GrCoordTransform *,true> & transforms)326     void setTransformData(const GrPrimitiveProcessor& primProc,
327                           const GrGLSLProgramDataManager& pdman,
328                           int index,
329                           const SkTArray<const GrCoordTransform*, true>& transforms) override {
330         this->setTransformDataHelper<GrQuadEffect>(primProc, pdman, index, transforms);
331     }
332 
333 private:
334     SkMatrix fViewMatrix;
335     GrColor fColor;
336     uint8_t fCoverageScale;
337     GrPrimitiveEdgeType fEdgeType;
338     UniformHandle fColorUniform;
339     UniformHandle fCoverageScaleUniform;
340     UniformHandle fViewMatrixUniform;
341 
342     typedef GrGLSLGeometryProcessor INHERITED;
343 };
344 
GrGLQuadEffect(const GrGeometryProcessor & processor)345 GrGLQuadEffect::GrGLQuadEffect(const GrGeometryProcessor& processor)
346     : fViewMatrix(SkMatrix::InvalidMatrix()), fColor(GrColor_ILLEGAL), fCoverageScale(0xff) {
347     const GrQuadEffect& ce = processor.cast<GrQuadEffect>();
348     fEdgeType = ce.getEdgeType();
349 }
350 
onEmitCode(EmitArgs & args,GrGPArgs * gpArgs)351 void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
352     GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
353     const GrQuadEffect& gp = args.fGP.cast<GrQuadEffect>();
354     GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
355     GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
356 
357     // emit attributes
358     varyingHandler->emitAttributes(gp);
359 
360     GrGLSLVertToFrag v(kVec4f_GrSLType);
361     varyingHandler->addVarying("HairQuadEdge", &v);
362     vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inHairQuadEdge()->fName);
363 
364     GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
365     // Setup pass through color
366     if (!gp.colorIgnored()) {
367         this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform);
368     }
369 
370     // Setup position
371     this->setupPosition(vertBuilder,
372                         uniformHandler,
373                         gpArgs,
374                         gp.inPosition()->fName,
375                         gp.viewMatrix(),
376                         &fViewMatrixUniform);
377 
378     // emit transforms with position
379     this->emitTransforms(vertBuilder,
380                          varyingHandler,
381                          uniformHandler,
382                          gpArgs->fPositionVar,
383                          gp.inPosition()->fName,
384                          gp.localMatrix(),
385                          args.fTransformsIn,
386                          args.fTransformsOut);
387 
388     fragBuilder->codeAppendf("float edgeAlpha;");
389 
390     switch (fEdgeType) {
391         case kHairlineAA_GrProcessorEdgeType: {
392             SkAssertResult(fragBuilder->enableFeature(
393                     GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
394             fragBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
395             fragBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
396             fragBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
397                                      "               2.0 * %s.x * duvdy.x - duvdy.y);",
398                                      v.fsIn(), v.fsIn());
399             fragBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);",
400                                      v.fsIn(), v.fsIn(), v.fsIn());
401             fragBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));");
402             fragBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
403             // Add line below for smooth cubic ramp
404             // fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
405             break;
406         }
407         case kFillAA_GrProcessorEdgeType: {
408             SkAssertResult(fragBuilder->enableFeature(
409                     GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
410             fragBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
411             fragBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
412             fragBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
413                                      "               2.0 * %s.x * duvdy.x - duvdy.y);",
414                                      v.fsIn(), v.fsIn());
415             fragBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);",
416                                      v.fsIn(), v.fsIn(), v.fsIn());
417             fragBuilder->codeAppend("edgeAlpha = edgeAlpha / sqrt(dot(gF, gF));");
418             fragBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
419             // Add line below for smooth cubic ramp
420             // fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
421             break;
422         }
423         case kFillBW_GrProcessorEdgeType: {
424             fragBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);",
425                                      v.fsIn(), v.fsIn(), v.fsIn());
426             fragBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
427             break;
428         }
429         default:
430             SkFAIL("Shouldn't get here");
431     }
432 
433     if (0xff != gp.coverageScale()) {
434         const char* coverageScale;
435         fCoverageScaleUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
436                                                            kFloat_GrSLType,
437                                                            kDefault_GrSLPrecision,
438                                                            "Coverage",
439                                                            &coverageScale);
440         fragBuilder->codeAppendf("%s = vec4(%s * edgeAlpha);", args.fOutputCoverage, coverageScale);
441     } else {
442         fragBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage);
443     }
444 }
445 
GenKey(const GrGeometryProcessor & gp,const GrGLSLCaps &,GrProcessorKeyBuilder * b)446 void GrGLQuadEffect::GenKey(const GrGeometryProcessor& gp,
447                             const GrGLSLCaps&,
448                             GrProcessorKeyBuilder* b) {
449     const GrQuadEffect& ce = gp.cast<GrQuadEffect>();
450     uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
451     key |= ce.color() != GrColor_ILLEGAL ? 0x4 : 0x0;
452     key |= ce.coverageScale() != 0xff ? 0x8 : 0x0;
453     key |= ce.usesLocalCoords() && ce.localMatrix().hasPerspective() ? 0x10 : 0x0;
454     key |= ComputePosKey(ce.viewMatrix()) << 5;
455     b->add32(key);
456 }
457 
458 //////////////////////////////////////////////////////////////////////////////
459 
~GrQuadEffect()460 GrQuadEffect::~GrQuadEffect() {}
461 
getGLSLProcessorKey(const GrGLSLCaps & caps,GrProcessorKeyBuilder * b) const462 void GrQuadEffect::getGLSLProcessorKey(const GrGLSLCaps& caps,
463                                        GrProcessorKeyBuilder* b) const {
464     GrGLQuadEffect::GenKey(*this, caps, b);
465 }
466 
createGLSLInstance(const GrGLSLCaps &) const467 GrGLSLPrimitiveProcessor* GrQuadEffect::createGLSLInstance(const GrGLSLCaps&) const {
468     return new GrGLQuadEffect(*this);
469 }
470 
GrQuadEffect(GrColor color,const SkMatrix & viewMatrix,uint8_t coverage,GrPrimitiveEdgeType edgeType,const SkMatrix & localMatrix,bool usesLocalCoords)471 GrQuadEffect::GrQuadEffect(GrColor color, const SkMatrix& viewMatrix, uint8_t coverage,
472                            GrPrimitiveEdgeType edgeType, const SkMatrix& localMatrix,
473                            bool usesLocalCoords)
474     : fColor(color)
475     , fViewMatrix(viewMatrix)
476     , fLocalMatrix(localMatrix)
477     , fUsesLocalCoords(usesLocalCoords)
478     , fCoverageScale(coverage)
479     , fEdgeType(edgeType) {
480     this->initClassID<GrQuadEffect>();
481     fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType,
482                                                    kHigh_GrSLPrecision));
483     fInHairQuadEdge = &this->addVertexAttrib(Attribute("inHairQuadEdge",
484                                                         kVec4f_GrVertexAttribType));
485 }
486 
487 //////////////////////////////////////////////////////////////////////////////
488 
489 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrQuadEffect);
490 
TestCreate(GrProcessorTestData * d)491 const GrGeometryProcessor* GrQuadEffect::TestCreate(GrProcessorTestData* d) {
492     GrGeometryProcessor* gp;
493     do {
494         GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(
495                 d->fRandom->nextULessThan(kGrProcessorEdgeTypeCnt));
496         gp = GrQuadEffect::Create(GrRandomColor(d->fRandom),
497                                   GrTest::TestMatrix(d->fRandom),
498                                   edgeType, *d->fCaps,
499                                   GrTest::TestMatrix(d->fRandom),
500                                   d->fRandom->nextBool());
501     } while (nullptr == gp);
502     return gp;
503 }
504 
505 //////////////////////////////////////////////////////////////////////////////
506 // Cubic
507 //////////////////////////////////////////////////////////////////////////////
508 
509 class GrGLCubicEffect : public GrGLSLGeometryProcessor {
510 public:
511     GrGLCubicEffect(const GrGeometryProcessor&);
512 
513     void onEmitCode(EmitArgs&, GrGPArgs*) override;
514 
515     static inline void GenKey(const GrGeometryProcessor&,
516                               const GrGLSLCaps&,
517                               GrProcessorKeyBuilder*);
518 
setData(const GrGLSLProgramDataManager & pdman,const GrPrimitiveProcessor & primProc)519     void setData(const GrGLSLProgramDataManager& pdman,
520                  const GrPrimitiveProcessor& primProc) override {
521         const GrCubicEffect& ce = primProc.cast<GrCubicEffect>();
522 
523         if (!ce.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(ce.viewMatrix())) {
524             fViewMatrix = ce.viewMatrix();
525             float viewMatrix[3 * 3];
526             GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
527             pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
528         }
529 
530         if (ce.color() != fColor) {
531             float c[4];
532             GrColorToRGBAFloat(ce.color(), c);
533             pdman.set4fv(fColorUniform, 1, c);
534             fColor = ce.color();
535         }
536     }
537 
538 private:
539     SkMatrix fViewMatrix;
540     GrColor fColor;
541     GrPrimitiveEdgeType fEdgeType;
542     UniformHandle fColorUniform;
543     UniformHandle fViewMatrixUniform;
544 
545     typedef GrGLSLGeometryProcessor INHERITED;
546 };
547 
GrGLCubicEffect(const GrGeometryProcessor & processor)548 GrGLCubicEffect::GrGLCubicEffect(const GrGeometryProcessor& processor)
549     : fViewMatrix(SkMatrix::InvalidMatrix()), fColor(GrColor_ILLEGAL) {
550     const GrCubicEffect& ce = processor.cast<GrCubicEffect>();
551     fEdgeType = ce.getEdgeType();
552 }
553 
onEmitCode(EmitArgs & args,GrGPArgs * gpArgs)554 void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
555     GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
556     const GrCubicEffect& gp = args.fGP.cast<GrCubicEffect>();
557     GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
558     GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
559 
560     // emit attributes
561     varyingHandler->emitAttributes(gp);
562 
563     GrGLSLVertToFrag v(kVec4f_GrSLType);
564     varyingHandler->addVarying("CubicCoeffs", &v, kHigh_GrSLPrecision);
565     vertBuilder->codeAppendf("%s = %s;", v.vsOut(), gp.inCubicCoeffs()->fName);
566 
567     GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
568     // Setup pass through color
569     if (!gp.colorIgnored()) {
570         this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform);
571     }
572 
573     // Setup position
574     this->setupPosition(vertBuilder,
575                         uniformHandler,
576                         gpArgs,
577                         gp.inPosition()->fName,
578                         gp.viewMatrix(),
579                         &fViewMatrixUniform);
580 
581     // emit transforms with position
582     this->emitTransforms(vertBuilder,
583                          varyingHandler,
584                          uniformHandler,
585                          gpArgs->fPositionVar,
586                          gp.inPosition()->fName,
587                          args.fTransformsIn,
588                          args.fTransformsOut);
589 
590 
591     GrGLSLShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
592     GrGLSLShaderVar dklmdx("dklmdx", kVec3f_GrSLType, 0, kHigh_GrSLPrecision);
593     GrGLSLShaderVar dklmdy("dklmdy", kVec3f_GrSLType, 0, kHigh_GrSLPrecision);
594     GrGLSLShaderVar dfdx("dfdx", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
595     GrGLSLShaderVar dfdy("dfdy", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
596     GrGLSLShaderVar gF("gF", kVec2f_GrSLType, 0, kHigh_GrSLPrecision);
597     GrGLSLShaderVar gFM("gFM", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
598     GrGLSLShaderVar func("func", kFloat_GrSLType, 0, kHigh_GrSLPrecision);
599 
600     fragBuilder->declAppend(edgeAlpha);
601     fragBuilder->declAppend(dklmdx);
602     fragBuilder->declAppend(dklmdy);
603     fragBuilder->declAppend(dfdx);
604     fragBuilder->declAppend(dfdy);
605     fragBuilder->declAppend(gF);
606     fragBuilder->declAppend(gFM);
607     fragBuilder->declAppend(func);
608 
609     switch (fEdgeType) {
610         case kHairlineAA_GrProcessorEdgeType: {
611             SkAssertResult(fragBuilder->enableFeature(
612                     GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
613             fragBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
614             fragBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
615             fragBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
616                                      dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
617                                      dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
618             fragBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
619                                      dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
620                                      dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
621             fragBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
622             fragBuilder->codeAppendf("%s = sqrt(dot(%s, %s));",
623                                      gFM.c_str(), gF.c_str(), gF.c_str());
624             fragBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
625                                      func.c_str(), v.fsIn(), v.fsIn(),
626                                      v.fsIn(), v.fsIn(), v.fsIn());
627             fragBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
628             fragBuilder->codeAppendf("%s = %s / %s;",
629                                      edgeAlpha.c_str(), func.c_str(), gFM.c_str());
630             fragBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);",
631                                      edgeAlpha.c_str(), edgeAlpha.c_str());
632             // Add line below for smooth cubic ramp
633             // fragBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
634             //                        edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
635             //                        edgeAlpha.c_str());
636             break;
637         }
638         case kFillAA_GrProcessorEdgeType: {
639             SkAssertResult(fragBuilder->enableFeature(
640                     GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
641             fragBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
642             fragBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
643             fragBuilder->codeAppendf("%s ="
644                                      "3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
645                                      dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
646                                      dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
647             fragBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
648                                      dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
649                                      dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
650             fragBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
651             fragBuilder->codeAppendf("%s = sqrt(dot(%s, %s));",
652                                      gFM.c_str(), gF.c_str(), gF.c_str());
653             fragBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
654                                      func.c_str(),
655                                      v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
656             fragBuilder->codeAppendf("%s = %s / %s;",
657                                      edgeAlpha.c_str(), func.c_str(), gFM.c_str());
658             fragBuilder->codeAppendf("%s = clamp(1.0 - %s, 0.0, 1.0);",
659                                      edgeAlpha.c_str(), edgeAlpha.c_str());
660             // Add line below for smooth cubic ramp
661             // fragBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",
662             //                        edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(),
663             //                        edgeAlpha.c_str());
664             break;
665         }
666         case kFillBW_GrProcessorEdgeType: {
667             fragBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
668                                      edgeAlpha.c_str(), v.fsIn(), v.fsIn(),
669                                      v.fsIn(), v.fsIn(), v.fsIn());
670             fragBuilder->codeAppendf("%s = float(%s < 0.0);", edgeAlpha.c_str(), edgeAlpha.c_str());
671             break;
672         }
673         default:
674             SkFAIL("Shouldn't get here");
675     }
676 
677 
678     fragBuilder->codeAppendf("%s = vec4(%s);", args.fOutputCoverage, edgeAlpha.c_str());
679 }
680 
GenKey(const GrGeometryProcessor & gp,const GrGLSLCaps &,GrProcessorKeyBuilder * b)681 void GrGLCubicEffect::GenKey(const GrGeometryProcessor& gp,
682                              const GrGLSLCaps&,
683                              GrProcessorKeyBuilder* b) {
684     const GrCubicEffect& ce = gp.cast<GrCubicEffect>();
685     uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
686     key |= ce.color() != GrColor_ILLEGAL ? 0x4 : 0x8;
687     key |= ComputePosKey(ce.viewMatrix()) << 5;
688     b->add32(key);
689 }
690 
691 //////////////////////////////////////////////////////////////////////////////
692 
~GrCubicEffect()693 GrCubicEffect::~GrCubicEffect() {}
694 
getGLSLProcessorKey(const GrGLSLCaps & caps,GrProcessorKeyBuilder * b) const695 void GrCubicEffect::getGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const {
696     GrGLCubicEffect::GenKey(*this, caps, b);
697 }
698 
createGLSLInstance(const GrGLSLCaps &) const699 GrGLSLPrimitiveProcessor* GrCubicEffect::createGLSLInstance(const GrGLSLCaps&) const {
700     return new GrGLCubicEffect(*this);
701 }
702 
GrCubicEffect(GrColor color,const SkMatrix & viewMatrix,GrPrimitiveEdgeType edgeType)703 GrCubicEffect::GrCubicEffect(GrColor color, const SkMatrix& viewMatrix,
704                              GrPrimitiveEdgeType edgeType)
705     : fColor(color)
706     , fViewMatrix(viewMatrix)
707     , fEdgeType(edgeType) {
708     this->initClassID<GrCubicEffect>();
709     fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType,
710                                                    kHigh_GrSLPrecision));
711     fInCubicCoeffs = &this->addVertexAttrib(Attribute("inCubicCoeffs",
712                                                         kVec4f_GrVertexAttribType));
713 }
714 
715 //////////////////////////////////////////////////////////////////////////////
716 
717 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrCubicEffect);
718 
TestCreate(GrProcessorTestData * d)719 const GrGeometryProcessor* GrCubicEffect::TestCreate(GrProcessorTestData* d) {
720     GrGeometryProcessor* gp;
721     do {
722         GrPrimitiveEdgeType edgeType =
723                 static_cast<GrPrimitiveEdgeType>(
724                         d->fRandom->nextULessThan(kGrProcessorEdgeTypeCnt));
725         gp = GrCubicEffect::Create(GrRandomColor(d->fRandom),
726                                    GrTest::TestMatrix(d->fRandom), edgeType, *d->fCaps);
727     } while (nullptr == gp);
728     return gp;
729 }
730 
731