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