blob: aebf6fbbba478e0673cd5e59e74f76aa267bc846 [file] [log] [blame]
commit-bot@chromium.org78a10782013-08-21 19:27:48 +00001
2/*
3 * Copyright 2013 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9// This test only works with the GPU backend.
10
11#include "gm.h"
12
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000013#if SK_SUPPORT_GPU
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000014
15#include "GrContext.h"
16#include "GrPathUtils.h"
17#include "GrTest.h"
18#include "SkColorPriv.h"
19#include "SkDevice.h"
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000020#include "SkGeometry.h"
21
22#include "effects/GrBezierEffect.h"
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000023
24// Position & KLM line eq values. These are the vertex attributes for Bezier curves. The last value
25// of the Vec4f is ignored.
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000026namespace {
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000027extern const GrVertexAttrib kAttribs[] = {
28 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
29 {kVec4f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding}
30};
commit-bot@chromium.orgc3fe5492014-01-30 18:15:51 +000031}
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000032
33static inline SkScalar eval_line(const SkPoint& p, const SkScalar lineEq[3], SkScalar sign) {
34 return sign * (lineEq[0] * p.fX + lineEq[1] * p.fY + lineEq[2]);
35}
36
37namespace skiagm {
38/**
39 * This GM directly exercises effects that draw Bezier curves in the GPU backend.
40 */
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000041class BezierCubicEffects : public GM {
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000042public:
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000043 BezierCubicEffects() {
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000044 this->setBGColor(0xFFFFFFFF);
45 }
46
47protected:
48 virtual SkString onShortName() SK_OVERRIDE {
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000049 return SkString("bezier_cubic_effects");
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000050 }
51
52 virtual SkISize onISize() SK_OVERRIDE {
53 return make_isize(800, 800);
54 }
55
56 virtual uint32_t onGetFlags() const SK_OVERRIDE {
57 // This is a GPU-specific GM.
58 return kGPUOnly_Flag;
59 }
60
61
62 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000063 SkBaseDevice* device = canvas->getTopDevice();
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000064 GrRenderTarget* rt = device->accessRenderTarget();
65 if (NULL == rt) {
66 return;
67 }
68 GrContext* context = rt->getContext();
69 if (NULL == context) {
70 return;
71 }
72
73 struct Vertex {
74 SkPoint fPosition;
75 float fKLM[4]; // The last value is ignored. The effect expects a vec4f.
76 };
77
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000078 static const int kNumCubics = 15;
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +000079 SkRandom rand;
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000080
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000081 // Mult by 3 for each edge effect type
82 int numCols = SkScalarCeilToInt(SkScalarSqrt(SkIntToScalar(kNumCubics*3)));
83 int numRows = SkScalarCeilToInt(SkIntToScalar(kNumCubics*3) / numCols);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000084 SkScalar w = SkIntToScalar(rt->width()) / numCols;
85 SkScalar h = SkIntToScalar(rt->height()) / numRows;
86 int row = 0;
87 int col = 0;
88
89 for (int i = 0; i < kNumCubics; ++i) {
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000090 SkPoint baseControlPts[] = {
91 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
92 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
93 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
94 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000095 };
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +000096 for(int edgeType = 0; edgeType < kGrEffectEdgeTypeCnt; ++edgeType) {
97 SkAutoTUnref<GrEffectRef> effect;
98 { // scope to contain GrTestTarget
99 GrTestTarget tt;
100 context->getTestTarget(&tt);
101 if (NULL == tt.target()) {
102 continue;
103 }
104 GrEffectEdgeType et = (GrEffectEdgeType)edgeType;
105 effect.reset(GrCubicEffect::Create(et, *tt.target()->caps()));
106 if (!effect) {
107 continue;
108 }
109 }
110
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000111 SkScalar x = SkScalarMul(col, w);
112 SkScalar y = SkScalarMul(row, h);
113 SkPoint controlPts[] = {
114 {x + baseControlPts[0].fX, y + baseControlPts[0].fY},
115 {x + baseControlPts[1].fX, y + baseControlPts[1].fY},
116 {x + baseControlPts[2].fX, y + baseControlPts[2].fY},
117 {x + baseControlPts[3].fX, y + baseControlPts[3].fY}
118 };
119 SkPoint chopped[10];
120 SkScalar klmEqs[9];
121 SkScalar klmSigns[3];
122 int cnt = GrPathUtils::chopCubicAtLoopIntersection(controlPts,
123 chopped,
124 klmEqs,
125 klmSigns);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000126
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000127 SkPaint ctrlPtPaint;
128 ctrlPtPaint.setColor(rand.nextU() | 0xFF000000);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000129 for (int i = 0; i < 4; ++i) {
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000130 canvas->drawCircle(controlPts[i].fX, controlPts[i].fY, 6.f, ctrlPtPaint);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000131 }
132
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000133 SkPaint polyPaint;
134 polyPaint.setColor(0xffA0A0A0);
135 polyPaint.setStrokeWidth(0);
136 polyPaint.setStyle(SkPaint::kStroke_Style);
137 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, controlPts, polyPaint);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000138
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000139 SkPaint choppedPtPaint;
140 choppedPtPaint.setColor(~ctrlPtPaint.getColor() | 0xFF000000);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000141
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000142 for (int c = 0; c < cnt; ++c) {
143 SkPoint* pts = chopped + 3 * c;
144
145 for (int i = 0; i < 4; ++i) {
146 canvas->drawCircle(pts[i].fX, pts[i].fY, 3.f, choppedPtPaint);
147 }
148
149 SkRect bounds;
150 bounds.set(pts, 4);
151
152 SkPaint boundsPaint;
153 boundsPaint.setColor(0xff808080);
154 boundsPaint.setStrokeWidth(0);
155 boundsPaint.setStyle(SkPaint::kStroke_Style);
156 canvas->drawRect(bounds, boundsPaint);
157
158 Vertex verts[4];
159 verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
160 bounds.fRight, bounds.fBottom,
161 sizeof(Vertex));
162 for (int v = 0; v < 4; ++v) {
163 verts[v].fKLM[0] = eval_line(verts[v].fPosition, klmEqs + 0, klmSigns[c]);
164 verts[v].fKLM[1] = eval_line(verts[v].fPosition, klmEqs + 3, klmSigns[c]);
165 verts[v].fKLM[2] = eval_line(verts[v].fPosition, klmEqs + 6, 1.f);
166 }
167
168 GrTestTarget tt;
169 context->getTestTarget(&tt);
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000170 SkASSERT(NULL != tt.target());
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000171 GrDrawState* drawState = tt.target()->drawState();
172 drawState->setVertexAttribs<kAttribs>(2);
173
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000174 drawState->addCoverageEffect(effect, 1);
175 drawState->setRenderTarget(rt);
176 drawState->setColor(0xff000000);
177
178 tt.target()->setVertexSourceToArray(verts, 4);
179 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
180 tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000181 }
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000182 ++col;
183 if (numCols == col) {
184 col = 0;
185 ++row;
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000186 }
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000187 }
188 }
189 }
190
191private:
192 typedef GM INHERITED;
193};
194
195//////////////////////////////////////////////////////////////////////////////
196
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000197/**
198 * This GM directly exercises effects that draw Bezier curves in the GPU backend.
199 */
200class BezierConicEffects : public GM {
201public:
202 BezierConicEffects() {
203 this->setBGColor(0xFFFFFFFF);
204 }
205
206protected:
207 virtual SkString onShortName() SK_OVERRIDE {
208 return SkString("bezier_conic_effects");
209 }
210
211 virtual SkISize onISize() SK_OVERRIDE {
212 return make_isize(800, 800);
213 }
214
215 virtual uint32_t onGetFlags() const SK_OVERRIDE {
216 // This is a GPU-specific GM.
217 return kGPUOnly_Flag;
218 }
219
220
221 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
robertphillips@google.com1f2f3382013-08-29 11:54:56 +0000222 SkBaseDevice* device = canvas->getTopDevice();
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000223 GrRenderTarget* rt = device->accessRenderTarget();
224 if (NULL == rt) {
225 return;
226 }
227 GrContext* context = rt->getContext();
228 if (NULL == context) {
229 return;
230 }
231
232 struct Vertex {
233 SkPoint fPosition;
234 float fKLM[4]; // The last value is ignored. The effect expects a vec4f.
235 };
236
237 static const int kNumConics = 10;
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000238 SkRandom rand;
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000239
240 // Mult by 3 for each edge effect type
241 int numCols = SkScalarCeilToInt(SkScalarSqrt(SkIntToScalar(kNumConics*3)));
242 int numRows = SkScalarCeilToInt(SkIntToScalar(kNumConics*3) / numCols);
243 SkScalar w = SkIntToScalar(rt->width()) / numCols;
244 SkScalar h = SkIntToScalar(rt->height()) / numRows;
245 int row = 0;
246 int col = 0;
247
248 for (int i = 0; i < kNumConics; ++i) {
249 SkPoint baseControlPts[] = {
250 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
251 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
252 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}
253 };
254 SkScalar weight = rand.nextRangeF(0.f, 2.f);
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000255 for(int edgeType = 0; edgeType < kGrEffectEdgeTypeCnt; ++edgeType) {
256 SkAutoTUnref<GrEffectRef> effect;
257 { // scope to contain GrTestTarget
258 GrTestTarget tt;
259 context->getTestTarget(&tt);
260 if (NULL == tt.target()) {
261 continue;
262 }
263 GrEffectEdgeType et = (GrEffectEdgeType)edgeType;
264 effect.reset(GrConicEffect::Create(et, *tt.target()->caps()));
265 if (!effect) {
266 continue;
267 }
268 }
269
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000270 SkScalar x = SkScalarMul(col, w);
271 SkScalar y = SkScalarMul(row, h);
272 SkPoint controlPts[] = {
273 {x + baseControlPts[0].fX, y + baseControlPts[0].fY},
274 {x + baseControlPts[1].fX, y + baseControlPts[1].fY},
275 {x + baseControlPts[2].fX, y + baseControlPts[2].fY}
276 };
277 SkConic dst[4];
278 SkScalar klmEqs[9];
279 int cnt = chop_conic(controlPts, dst, weight);
280 GrPathUtils::getConicKLM(controlPts, weight, klmEqs);
281
282 SkPaint ctrlPtPaint;
283 ctrlPtPaint.setColor(rand.nextU() | 0xFF000000);
284 for (int i = 0; i < 3; ++i) {
285 canvas->drawCircle(controlPts[i].fX, controlPts[i].fY, 6.f, ctrlPtPaint);
286 }
287
288 SkPaint polyPaint;
289 polyPaint.setColor(0xffA0A0A0);
290 polyPaint.setStrokeWidth(0);
291 polyPaint.setStyle(SkPaint::kStroke_Style);
292 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, controlPts, polyPaint);
293
294 SkPaint choppedPtPaint;
295 choppedPtPaint.setColor(~ctrlPtPaint.getColor() | 0xFF000000);
296
297 for (int c = 0; c < cnt; ++c) {
298 SkPoint* pts = dst[c].fPts;
299 for (int i = 0; i < 3; ++i) {
300 canvas->drawCircle(pts[i].fX, pts[i].fY, 3.f, choppedPtPaint);
301 }
302
303 SkRect bounds;
304 //SkPoint bPts[] = {{0.f, 0.f}, {800.f, 800.f}};
305 //bounds.set(bPts, 2);
306 bounds.set(pts, 3);
307
308 SkPaint boundsPaint;
309 boundsPaint.setColor(0xff808080);
310 boundsPaint.setStrokeWidth(0);
311 boundsPaint.setStyle(SkPaint::kStroke_Style);
312 canvas->drawRect(bounds, boundsPaint);
313
314 Vertex verts[4];
315 verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
316 bounds.fRight, bounds.fBottom,
317 sizeof(Vertex));
318 for (int v = 0; v < 4; ++v) {
319 verts[v].fKLM[0] = eval_line(verts[v].fPosition, klmEqs + 0, 1.f);
320 verts[v].fKLM[1] = eval_line(verts[v].fPosition, klmEqs + 3, 1.f);
321 verts[v].fKLM[2] = eval_line(verts[v].fPosition, klmEqs + 6, 1.f);
322 }
323
324 GrTestTarget tt;
325 context->getTestTarget(&tt);
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000326 SkASSERT(NULL != tt.target());
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000327 GrDrawState* drawState = tt.target()->drawState();
328 drawState->setVertexAttribs<kAttribs>(2);
329
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000330 drawState->addCoverageEffect(effect, 1);
331 drawState->setRenderTarget(rt);
332 drawState->setColor(0xff000000);
333
334 tt.target()->setVertexSourceToArray(verts, 4);
335 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
336 tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
337 }
338 ++col;
339 if (numCols == col) {
340 col = 0;
341 ++row;
342 }
343 }
344 }
345 }
346
347private:
348 // Uses the max curvature function for quads to estimate
349 // where to chop the conic. If the max curvature is not
350 // found along the curve segment it will return 1 and
351 // dst[0] is the original conic. If it returns 2 the dst[0]
352 // and dst[1] are the two new conics.
353 int split_conic(const SkPoint src[3], SkConic dst[2], const SkScalar weight) {
354 SkScalar t = SkFindQuadMaxCurvature(src);
355 if (t == 0) {
356 if (dst) {
357 dst[0].set(src, weight);
358 }
359 return 1;
360 } else {
361 if (dst) {
362 SkConic conic;
363 conic.set(src, weight);
364 conic.chopAt(t, dst);
365 }
366 return 2;
367 }
368 }
369
370 // Calls split_conic on the entire conic and then once more on each subsection.
371 // Most cases will result in either 1 conic (chop point is not within t range)
372 // or 3 points (split once and then one subsection is split again).
373 int chop_conic(const SkPoint src[3], SkConic dst[4], const SkScalar weight) {
374 SkConic dstTemp[2];
375 int conicCnt = split_conic(src, dstTemp, weight);
376 if (2 == conicCnt) {
377 int conicCnt2 = split_conic(dstTemp[0].fPts, dst, dstTemp[0].fW);
378 conicCnt = conicCnt2 + split_conic(dstTemp[1].fPts, &dst[conicCnt2], dstTemp[1].fW);
379 } else {
380 dst[0] = dstTemp[0];
381 }
382 return conicCnt;
383 }
384
385 typedef GM INHERITED;
386};
387
388//////////////////////////////////////////////////////////////////////////////
389/**
390 * This GM directly exercises effects that draw Bezier quad curves in the GPU backend.
391 */
392class BezierQuadEffects : public GM {
393public:
394 BezierQuadEffects() {
395 this->setBGColor(0xFFFFFFFF);
396 }
397
398protected:
399 virtual SkString onShortName() SK_OVERRIDE {
400 return SkString("bezier_quad_effects");
401 }
402
403 virtual SkISize onISize() SK_OVERRIDE {
404 return make_isize(800, 800);
405 }
406
407 virtual uint32_t onGetFlags() const SK_OVERRIDE {
408 // This is a GPU-specific GM.
409 return kGPUOnly_Flag;
410 }
411
412
413 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
robertphillips@google.com1f2f3382013-08-29 11:54:56 +0000414 SkBaseDevice* device = canvas->getTopDevice();
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000415 GrRenderTarget* rt = device->accessRenderTarget();
416 if (NULL == rt) {
417 return;
418 }
419 GrContext* context = rt->getContext();
420 if (NULL == context) {
421 return;
422 }
423
424 struct Vertex {
425 SkPoint fPosition;
426 float fUV[4]; // The last two values are ignored. The effect expects a vec4f.
427 };
428
429 static const int kNumQuads = 5;
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000430 SkRandom rand;
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000431
432 int numCols = SkScalarCeilToInt(SkScalarSqrt(SkIntToScalar(kNumQuads*3)));
433 int numRows = SkScalarCeilToInt(SkIntToScalar(kNumQuads*3) / numCols);
434 SkScalar w = SkIntToScalar(rt->width()) / numCols;
435 SkScalar h = SkIntToScalar(rt->height()) / numRows;
436 int row = 0;
437 int col = 0;
438
439 for (int i = 0; i < kNumQuads; ++i) {
440 SkPoint baseControlPts[] = {
441 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
442 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
443 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}
444 };
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000445 for(int edgeType = 0; edgeType < kGrEffectEdgeTypeCnt; ++edgeType) {
446 SkAutoTUnref<GrEffectRef> effect;
447 { // scope to contain GrTestTarget
448 GrTestTarget tt;
449 context->getTestTarget(&tt);
450 if (NULL == tt.target()) {
451 continue;
452 }
453 GrEffectEdgeType et = (GrEffectEdgeType)edgeType;
454 effect.reset(GrQuadEffect::Create(et, *tt.target()->caps()));
455 if (!effect) {
456 continue;
457 }
458 }
459
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000460 SkScalar x = SkScalarMul(col, w);
461 SkScalar y = SkScalarMul(row, h);
462 SkPoint controlPts[] = {
463 {x + baseControlPts[0].fX, y + baseControlPts[0].fY},
464 {x + baseControlPts[1].fX, y + baseControlPts[1].fY},
465 {x + baseControlPts[2].fX, y + baseControlPts[2].fY}
466 };
467 SkPoint chopped[5];
468 int cnt = SkChopQuadAtMaxCurvature(controlPts, chopped);
469
470 SkPaint ctrlPtPaint;
471 ctrlPtPaint.setColor(rand.nextU() | 0xFF000000);
472 for (int i = 0; i < 3; ++i) {
473 canvas->drawCircle(controlPts[i].fX, controlPts[i].fY, 6.f, ctrlPtPaint);
474 }
475
476 SkPaint polyPaint;
477 polyPaint.setColor(0xffA0A0A0);
478 polyPaint.setStrokeWidth(0);
479 polyPaint.setStyle(SkPaint::kStroke_Style);
480 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, controlPts, polyPaint);
481
482 SkPaint choppedPtPaint;
483 choppedPtPaint.setColor(~ctrlPtPaint.getColor() | 0xFF000000);
484
485 for (int c = 0; c < cnt; ++c) {
486 SkPoint* pts = chopped + 2 * c;
487
488 for (int i = 0; i < 3; ++i) {
489 canvas->drawCircle(pts[i].fX, pts[i].fY, 3.f, choppedPtPaint);
490 }
491
492 SkRect bounds;
493 bounds.set(pts, 3);
494
495 SkPaint boundsPaint;
496 boundsPaint.setColor(0xff808080);
497 boundsPaint.setStrokeWidth(0);
498 boundsPaint.setStyle(SkPaint::kStroke_Style);
499 canvas->drawRect(bounds, boundsPaint);
500
501 Vertex verts[4];
502 verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
503 bounds.fRight, bounds.fBottom,
504 sizeof(Vertex));
505
506 GrPathUtils::QuadUVMatrix DevToUV(pts);
507 DevToUV.apply<4, sizeof(Vertex), sizeof(GrPoint)>(verts);
508
509 GrTestTarget tt;
510 context->getTestTarget(&tt);
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000511 SkASSERT(NULL != tt.target());
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000512 GrDrawState* drawState = tt.target()->drawState();
513 drawState->setVertexAttribs<kAttribs>(2);
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000514
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000515 drawState->addCoverageEffect(effect, 1);
516 drawState->setRenderTarget(rt);
517 drawState->setColor(0xff000000);
518
519 tt.target()->setVertexSourceToArray(verts, 4);
520 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
521 tt.target()->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 4, 6);
522 }
523 ++col;
524 if (numCols == col) {
525 col = 0;
526 ++row;
527 }
528 }
529 }
530 }
531
532private:
533 typedef GM INHERITED;
534};
535
536DEF_GM( return SkNEW(BezierCubicEffects); )
537DEF_GM( return SkNEW(BezierConicEffects); )
538DEF_GM( return SkNEW(BezierQuadEffects); )
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000539
540}
541
542#endif