blob: 0d57b107acdfb2b784f53385fd08bd6ec3da7d59 [file] [log] [blame]
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +00001/*
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 "gl/GrGLEffect.h"
11#include "gl/GrGLSL.h"
12#include "GrTBackendEffectFactory.h"
13
14class GrGLConicEffect : public GrGLEffect {
15public:
16 GrGLConicEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
17
18 virtual void emitCode(GrGLShaderBuilder* builder,
19 const GrDrawEffect& drawEffect,
20 EffectKey key,
21 const char* outputColor,
22 const char* inputColor,
23 const TextureSamplerArray&) SK_OVERRIDE;
24
25 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
26
27 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
28
29private:
30 GrBezierEdgeType fEdgeType;
31
32 typedef GrGLEffect INHERITED;
33};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +000034
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000035GrGLConicEffect::GrGLConicEffect(const GrBackendEffectFactory& factory,
36 const GrDrawEffect& drawEffect)
37 : INHERITED (factory) {
38 const GrConicEffect& ce = drawEffect.castEffect<GrConicEffect>();
39 fEdgeType = ce.getEdgeType();
40}
41
42void GrGLConicEffect::emitCode(GrGLShaderBuilder* builder,
43 const GrDrawEffect& drawEffect,
44 EffectKey key,
45 const char* outputColor,
46 const char* inputColor,
47 const TextureSamplerArray& samplers) {
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +000048 GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder();
49 SkASSERT(NULL != vertexBuilder);
50
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000051 const char *vsName, *fsName;
52
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +000053 vertexBuilder->addVarying(kVec4f_GrSLType, "ConicCoeffs",
54 &vsName, &fsName);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000055 const SkString* attr0Name =
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +000056 vertexBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
57 vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000058
59 builder->fsCodeAppend("\t\tfloat edgeAlpha;\n");
60
61 switch (fEdgeType) {
62 case kHairAA_GrBezierEdgeType: {
63 SkAssertResult(builder->enableFeature(
64 GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
65 builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
66 builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
67 builder->fsCodeAppendf("\t\tfloat dfdx =\n"
68 "\t\t\t2.0*%s.x*dklmdx.x - %s.y*dklmdx.z - %s.z*dklmdx.y;\n",
69 fsName, fsName, fsName);
70 builder->fsCodeAppendf("\t\tfloat dfdy =\n"
71 "\t\t\t2.0*%s.x*dklmdy.x - %s.y*dklmdy.z - %s.z*dklmdy.y;\n",
72 fsName, fsName, fsName);
73 builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
74 builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
75 builder->fsCodeAppendf("\t\tfloat func = %s.x*%s.x - %s.y*%s.z;\n", fsName, fsName,
76 fsName, fsName);
77 builder->fsCodeAppend("\t\tfunc = abs(func);\n");
78 builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n");
79 builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
80 // Add line below for smooth cubic ramp
81 // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
82 break;
83 }
84 case kFillAA_GrBezierEdgeType: {
85 SkAssertResult(builder->enableFeature(
86 GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
87 builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
88 builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
89 builder->fsCodeAppendf("\t\tfloat dfdx =\n"
90 "\t\t\t2.0*%s.x*dklmdx.x - %s.y*dklmdx.z - %s.z*dklmdx.y;\n",
91 fsName, fsName, fsName);
92 builder->fsCodeAppendf("\t\tfloat dfdy =\n"
93 "\t\t\t2.0*%s.x*dklmdy.x - %s.y*dklmdy.z - %s.z*dklmdy.y;\n",
94 fsName, fsName, fsName);
95 builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
96 builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
97 builder->fsCodeAppendf("\t\tfloat func = %s.x*%s.x - %s.y*%s.z;\n", fsName, fsName,
98 fsName, fsName);
99 builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n");
100 builder->fsCodeAppend("\t\tedgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);\n");
101 // Add line below for smooth cubic ramp
102 // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
103 break;
104 }
105 case kFillNoAA_GrBezierEdgeType: {
106 builder->fsCodeAppendf("\t\tedgeAlpha = %s.x*%s.x - %s.y*%s.z;\n", fsName, fsName,
107 fsName, fsName);
108 builder->fsCodeAppend("\t\tedgeAlpha = float(edgeAlpha < 0.0);\n");
109 break;
110 }
111 }
112
113 SkString modulate;
114 GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha");
115 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str());
116}
117
118GrGLEffect::EffectKey GrGLConicEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
119 const GrConicEffect& ce = drawEffect.castEffect<GrConicEffect>();
120 return ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
121}
122
123//////////////////////////////////////////////////////////////////////////////
124
125GrConicEffect::~GrConicEffect() {}
126
127const GrBackendEffectFactory& GrConicEffect::getFactory() const {
128 return GrTBackendEffectFactory<GrConicEffect>::getInstance();
129}
130
131GrConicEffect::GrConicEffect(GrBezierEdgeType edgeType) : GrEffect() {
132 this->addVertexAttrib(kVec4f_GrSLType);
133 fEdgeType = edgeType;
134}
135
136bool GrConicEffect::onIsEqual(const GrEffect& other) const {
137 const GrConicEffect& ce = CastEffect<GrConicEffect>(other);
138 return (ce.fEdgeType == fEdgeType);
139}
140
141//////////////////////////////////////////////////////////////////////////////
142
143GR_DEFINE_EFFECT_TEST(GrConicEffect);
144
145GrEffectRef* GrConicEffect::TestCreate(SkMWCRandom* random,
146 GrContext*,
147 const GrDrawTargetCaps& caps,
148 GrTexture*[]) {
149 const GrBezierEdgeType edgeType = static_cast<GrBezierEdgeType>(random->nextULessThan(3));
150 return GrConicEffect::Create(edgeType, caps);
151}
152
153//////////////////////////////////////////////////////////////////////////////
154// Quad
155//////////////////////////////////////////////////////////////////////////////
156
157class GrGLQuadEffect : public GrGLEffect {
158public:
159 GrGLQuadEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
160
161 virtual void emitCode(GrGLShaderBuilder* builder,
162 const GrDrawEffect& drawEffect,
163 EffectKey key,
164 const char* outputColor,
165 const char* inputColor,
166 const TextureSamplerArray&) SK_OVERRIDE;
167
168 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
169
170 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
171
172private:
173 GrBezierEdgeType fEdgeType;
174
175 typedef GrGLEffect INHERITED;
176};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +0000177
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000178GrGLQuadEffect::GrGLQuadEffect(const GrBackendEffectFactory& factory,
179 const GrDrawEffect& drawEffect)
180 : INHERITED (factory) {
181 const GrQuadEffect& ce = drawEffect.castEffect<GrQuadEffect>();
182 fEdgeType = ce.getEdgeType();
183}
184
185void GrGLQuadEffect::emitCode(GrGLShaderBuilder* builder,
186 const GrDrawEffect& drawEffect,
187 EffectKey key,
188 const char* outputColor,
189 const char* inputColor,
190 const TextureSamplerArray& samplers) {
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000191 GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder();
192 SkASSERT(NULL != vertexBuilder);
193
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000194 const char *vsName, *fsName;
195
196 const SkString* attrName =
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000197 vertexBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000198 builder->fsCodeAppendf("\t\tfloat edgeAlpha;\n");
199
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000200 vertexBuilder->addVarying(kVec4f_GrSLType, "HairQuadEdge", &vsName, &fsName);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000201
202 switch (fEdgeType) {
203 case kHairAA_GrBezierEdgeType: {
204 SkAssertResult(builder->enableFeature(
205 GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
206 builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
207 builder->fsCodeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
208 builder->fsCodeAppendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
209 "\t\t 2.0*%s.x*duvdy.x - duvdy.y);\n",
210 fsName, fsName);
211 builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
212 fsName);
213 builder->fsCodeAppend("\t\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / dot(gF, gF));\n");
214 builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
215 // Add line below for smooth cubic ramp
216 // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
217 break;
218 }
219 case kFillAA_GrBezierEdgeType: {
220 SkAssertResult(builder->enableFeature(
221 GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
222 builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
223 builder->fsCodeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
224 builder->fsCodeAppendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
225 "\t\t 2.0*%s.x*duvdy.x - duvdy.y);\n",
226 fsName, fsName);
227 builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
228 fsName);
229 builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha / sqrt(dot(gF, gF));\n");
230 builder->fsCodeAppend("\t\tedgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);\n");
231 // Add line below for smooth cubic ramp
232 // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
233 break;
234 }
235 case kFillNoAA_GrBezierEdgeType: {
236 builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
237 fsName);
238 builder->fsCodeAppend("\t\tedgeAlpha = float(edgeAlpha < 0.0);\n");
239 break;
240 }
241 }
242
243 SkString modulate;
244 GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha");
245 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str());
246
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000247 vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000248}
249
250GrGLEffect::EffectKey GrGLQuadEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
251 const GrQuadEffect& ce = drawEffect.castEffect<GrQuadEffect>();
252 return ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
253}
254
255//////////////////////////////////////////////////////////////////////////////
256
257GrQuadEffect::~GrQuadEffect() {}
258
259const GrBackendEffectFactory& GrQuadEffect::getFactory() const {
260 return GrTBackendEffectFactory<GrQuadEffect>::getInstance();
261}
262
263GrQuadEffect::GrQuadEffect(GrBezierEdgeType edgeType) : GrEffect() {
264 this->addVertexAttrib(kVec4f_GrSLType);
265 fEdgeType = edgeType;
266}
267
268bool GrQuadEffect::onIsEqual(const GrEffect& other) const {
269 const GrQuadEffect& ce = CastEffect<GrQuadEffect>(other);
270 return (ce.fEdgeType == fEdgeType);
271}
272
273//////////////////////////////////////////////////////////////////////////////
274
275GR_DEFINE_EFFECT_TEST(GrQuadEffect);
276
277GrEffectRef* GrQuadEffect::TestCreate(SkMWCRandom* random,
278 GrContext*,
279 const GrDrawTargetCaps& caps,
280 GrTexture*[]) {
281 const GrBezierEdgeType edgeType = static_cast<GrBezierEdgeType>(random->nextULessThan(3));
282 return GrQuadEffect::Create(edgeType, caps);
283}
284
285//////////////////////////////////////////////////////////////////////////////
286// Cubic
287//////////////////////////////////////////////////////////////////////////////
288
289class GrGLCubicEffect : public GrGLEffect {
290public:
291 GrGLCubicEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
292
293 virtual void emitCode(GrGLShaderBuilder* builder,
294 const GrDrawEffect& drawEffect,
295 EffectKey key,
296 const char* outputColor,
297 const char* inputColor,
298 const TextureSamplerArray&) SK_OVERRIDE;
299
300 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
301
302 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
303
304private:
305 GrBezierEdgeType fEdgeType;
306
307 typedef GrGLEffect INHERITED;
308};
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +0000309
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000310GrGLCubicEffect::GrGLCubicEffect(const GrBackendEffectFactory& factory,
311 const GrDrawEffect& drawEffect)
312 : INHERITED (factory) {
313 const GrCubicEffect& ce = drawEffect.castEffect<GrCubicEffect>();
314 fEdgeType = ce.getEdgeType();
315}
316
317void GrGLCubicEffect::emitCode(GrGLShaderBuilder* builder,
318 const GrDrawEffect& drawEffect,
319 EffectKey key,
320 const char* outputColor,
321 const char* inputColor,
322 const TextureSamplerArray& samplers) {
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000323 GrGLShaderBuilder::VertexBuilder* vertexBuilder = builder->getVertexBuilder();
324 SkASSERT(NULL != vertexBuilder);
325
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000326 const char *vsName, *fsName;
327
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000328 vertexBuilder->addVarying(kVec4f_GrSLType, "CubicCoeffs",
329 &vsName, &fsName);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000330 const SkString* attr0Name =
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000331 vertexBuilder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
332 vertexBuilder->vsCodeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str());
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000333
334 builder->fsCodeAppend("\t\tfloat edgeAlpha;\n");
335
336 switch (fEdgeType) {
337 case kHairAA_GrBezierEdgeType: {
338 SkAssertResult(builder->enableFeature(
339 GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
340 builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
341 builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
342 builder->fsCodeAppendf("\t\tfloat dfdx =\n"
343 "\t\t3.0*%s.x*%s.x*dklmdx.x - %s.y*dklmdx.z - %s.z*dklmdx.y;\n",
344 fsName, fsName, fsName, fsName);
345 builder->fsCodeAppendf("\t\tfloat dfdy =\n"
346 "\t\t3.0*%s.x*%s.x*dklmdy.x - %s.y*dklmdy.z - %s.z*dklmdy.y;\n",
347 fsName, fsName, fsName, fsName);
348 builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
349 builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
350 builder->fsCodeAppendf("\t\tfloat func = %s.x*%s.x*%s.x - %s.y*%s.z;\n",
351 fsName, fsName, fsName, fsName, fsName);
352 builder->fsCodeAppend("\t\tfunc = abs(func);\n");
353 builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n");
354 builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
355 // Add line below for smooth cubic ramp
356 // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
357 break;
358 }
359 case kFillAA_GrBezierEdgeType: {
360 SkAssertResult(builder->enableFeature(
361 GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
362 builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
363 builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
364 builder->fsCodeAppendf("\t\tfloat dfdx =\n"
365 "\t\t3.0*%s.x*%s.x*dklmdx.x - %s.y*dklmdx.z - %s.z*dklmdx.y;\n",
366 fsName, fsName, fsName, fsName);
367 builder->fsCodeAppendf("\t\tfloat dfdy =\n"
368 "\t\t3.0*%s.x*%s.x*dklmdy.x - %s.y*dklmdy.z - %s.z*dklmdy.y;\n",
369 fsName, fsName, fsName, fsName);
370 builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
371 builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
372 builder->fsCodeAppendf("\t\tfloat func = %s.x*%s.x*%s.x - %s.y*%s.z;\n",
373 fsName, fsName, fsName, fsName, fsName);
374 builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n");
375 builder->fsCodeAppend("\t\tedgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);\n");
376 // Add line below for smooth cubic ramp
377 // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
378 break;
379 }
380 case kFillNoAA_GrBezierEdgeType: {
381 builder->fsCodeAppendf("\t\tedgeAlpha = %s.x*%s.x*%s.x - %s.y*%s.z;\n",
382 fsName, fsName, fsName, fsName, fsName);
383 builder->fsCodeAppend("\t\tedgeAlpha = float(edgeAlpha < 0.0);\n");
384 break;
385 }
386 }
387
388 SkString modulate;
389 GrGLSLModulatef<4>(&modulate, inputColor, "edgeAlpha");
390 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str());
391}
392
393GrGLEffect::EffectKey GrGLCubicEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
394 const GrCubicEffect& ce = drawEffect.castEffect<GrCubicEffect>();
395 return ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
396}
397
398//////////////////////////////////////////////////////////////////////////////
399
400GrCubicEffect::~GrCubicEffect() {}
401
402const GrBackendEffectFactory& GrCubicEffect::getFactory() const {
403 return GrTBackendEffectFactory<GrCubicEffect>::getInstance();
404}
405
406GrCubicEffect::GrCubicEffect(GrBezierEdgeType edgeType) : GrEffect() {
407 this->addVertexAttrib(kVec4f_GrSLType);
408 fEdgeType = edgeType;
409}
410
411bool GrCubicEffect::onIsEqual(const GrEffect& other) const {
412 const GrCubicEffect& ce = CastEffect<GrCubicEffect>(other);
413 return (ce.fEdgeType == fEdgeType);
414}
415
416//////////////////////////////////////////////////////////////////////////////
417
418GR_DEFINE_EFFECT_TEST(GrCubicEffect);
419
420GrEffectRef* GrCubicEffect::TestCreate(SkMWCRandom* random,
421 GrContext*,
422 const GrDrawTargetCaps& caps,
423 GrTexture*[]) {
424 const GrBezierEdgeType edgeType = static_cast<GrBezierEdgeType>(random->nextULessThan(3));
425 return GrCubicEffect::Create(edgeType, caps);
426}