blob: 2045e38ec4c57c56a562bc869eddf30dafaf270c [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},
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +000029 {kVec4f_GrVertexAttribType, sizeof(SkPoint), kEffect_GrVertexAttribBinding}
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000030};
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 {
tfarinaf5393182014-06-09 23:59:03 -070053 return SkISize::Make(800, 800);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000054 }
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 {
reed@google.com9c135db2014-03-12 18:28:35 +000063 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000064 if (NULL == rt) {
65 return;
66 }
67 GrContext* context = rt->getContext();
68 if (NULL == context) {
69 return;
70 }
71
72 struct Vertex {
73 SkPoint fPosition;
74 float fKLM[4]; // The last value is ignored. The effect expects a vec4f.
75 };
76
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000077 static const int kNumCubics = 15;
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +000078 SkRandom rand;
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000079
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000080 // Mult by 3 for each edge effect type
81 int numCols = SkScalarCeilToInt(SkScalarSqrt(SkIntToScalar(kNumCubics*3)));
82 int numRows = SkScalarCeilToInt(SkIntToScalar(kNumCubics*3) / numCols);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000083 SkScalar w = SkIntToScalar(rt->width()) / numCols;
84 SkScalar h = SkIntToScalar(rt->height()) / numRows;
85 int row = 0;
86 int col = 0;
87
88 for (int i = 0; i < kNumCubics; ++i) {
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000089 SkPoint baseControlPts[] = {
90 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
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)}
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000094 };
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +000095 for(int edgeType = 0; edgeType < kGrEffectEdgeTypeCnt; ++edgeType) {
bsalomon83d081a2014-07-08 09:56:10 -070096 SkAutoTUnref<GrEffect> effect;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +000097 { // scope to contain GrTestTarget
98 GrTestTarget tt;
99 context->getTestTarget(&tt);
100 if (NULL == tt.target()) {
101 continue;
102 }
103 GrEffectEdgeType et = (GrEffectEdgeType)edgeType;
104 effect.reset(GrCubicEffect::Create(et, *tt.target()->caps()));
105 if (!effect) {
106 continue;
107 }
108 }
109
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000110 SkScalar x = SkScalarMul(col, w);
111 SkScalar y = SkScalarMul(row, h);
112 SkPoint controlPts[] = {
113 {x + baseControlPts[0].fX, y + baseControlPts[0].fY},
114 {x + baseControlPts[1].fX, y + baseControlPts[1].fY},
115 {x + baseControlPts[2].fX, y + baseControlPts[2].fY},
116 {x + baseControlPts[3].fX, y + baseControlPts[3].fY}
117 };
118 SkPoint chopped[10];
119 SkScalar klmEqs[9];
120 SkScalar klmSigns[3];
121 int cnt = GrPathUtils::chopCubicAtLoopIntersection(controlPts,
122 chopped,
123 klmEqs,
124 klmSigns);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000125
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000126 SkPaint ctrlPtPaint;
127 ctrlPtPaint.setColor(rand.nextU() | 0xFF000000);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000128 for (int i = 0; i < 4; ++i) {
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000129 canvas->drawCircle(controlPts[i].fX, controlPts[i].fY, 6.f, ctrlPtPaint);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000130 }
131
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000132 SkPaint polyPaint;
133 polyPaint.setColor(0xffA0A0A0);
134 polyPaint.setStrokeWidth(0);
135 polyPaint.setStyle(SkPaint::kStroke_Style);
136 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, controlPts, polyPaint);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000137
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000138 SkPaint choppedPtPaint;
139 choppedPtPaint.setColor(~ctrlPtPaint.getColor() | 0xFF000000);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000140
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000141 for (int c = 0; c < cnt; ++c) {
142 SkPoint* pts = chopped + 3 * c;
143
144 for (int i = 0; i < 4; ++i) {
145 canvas->drawCircle(pts[i].fX, pts[i].fY, 3.f, choppedPtPaint);
146 }
147
148 SkRect bounds;
149 bounds.set(pts, 4);
150
151 SkPaint boundsPaint;
152 boundsPaint.setColor(0xff808080);
153 boundsPaint.setStrokeWidth(0);
154 boundsPaint.setStyle(SkPaint::kStroke_Style);
155 canvas->drawRect(bounds, boundsPaint);
156
157 Vertex verts[4];
158 verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
159 bounds.fRight, bounds.fBottom,
160 sizeof(Vertex));
161 for (int v = 0; v < 4; ++v) {
162 verts[v].fKLM[0] = eval_line(verts[v].fPosition, klmEqs + 0, klmSigns[c]);
163 verts[v].fKLM[1] = eval_line(verts[v].fPosition, klmEqs + 3, klmSigns[c]);
164 verts[v].fKLM[2] = eval_line(verts[v].fPosition, klmEqs + 6, 1.f);
165 }
166
167 GrTestTarget tt;
168 context->getTestTarget(&tt);
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000169 SkASSERT(NULL != tt.target());
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000170 GrDrawState* drawState = tt.target()->drawState();
171 drawState->setVertexAttribs<kAttribs>(2);
172
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000173 drawState->addCoverageEffect(effect, 1);
174 drawState->setRenderTarget(rt);
175 drawState->setColor(0xff000000);
176
177 tt.target()->setVertexSourceToArray(verts, 4);
178 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
179 tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000180 }
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000181 ++col;
182 if (numCols == col) {
183 col = 0;
184 ++row;
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000185 }
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000186 }
187 }
188 }
189
190private:
191 typedef GM INHERITED;
192};
193
194//////////////////////////////////////////////////////////////////////////////
195
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000196/**
197 * This GM directly exercises effects that draw Bezier curves in the GPU backend.
198 */
199class BezierConicEffects : public GM {
200public:
201 BezierConicEffects() {
202 this->setBGColor(0xFFFFFFFF);
203 }
204
205protected:
206 virtual SkString onShortName() SK_OVERRIDE {
207 return SkString("bezier_conic_effects");
208 }
209
210 virtual SkISize onISize() SK_OVERRIDE {
tfarinaf5393182014-06-09 23:59:03 -0700211 return SkISize::Make(800, 800);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000212 }
213
214 virtual uint32_t onGetFlags() const SK_OVERRIDE {
215 // This is a GPU-specific GM.
216 return kGPUOnly_Flag;
217 }
218
219
220 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
reed@google.com9c135db2014-03-12 18:28:35 +0000221 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000222 if (NULL == rt) {
223 return;
224 }
225 GrContext* context = rt->getContext();
226 if (NULL == context) {
227 return;
228 }
229
230 struct Vertex {
231 SkPoint fPosition;
232 float fKLM[4]; // The last value is ignored. The effect expects a vec4f.
233 };
234
235 static const int kNumConics = 10;
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000236 SkRandom rand;
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000237
238 // Mult by 3 for each edge effect type
239 int numCols = SkScalarCeilToInt(SkScalarSqrt(SkIntToScalar(kNumConics*3)));
240 int numRows = SkScalarCeilToInt(SkIntToScalar(kNumConics*3) / numCols);
241 SkScalar w = SkIntToScalar(rt->width()) / numCols;
242 SkScalar h = SkIntToScalar(rt->height()) / numRows;
243 int row = 0;
244 int col = 0;
245
246 for (int i = 0; i < kNumConics; ++i) {
247 SkPoint baseControlPts[] = {
248 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
249 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
250 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}
251 };
252 SkScalar weight = rand.nextRangeF(0.f, 2.f);
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000253 for(int edgeType = 0; edgeType < kGrEffectEdgeTypeCnt; ++edgeType) {
bsalomon83d081a2014-07-08 09:56:10 -0700254 SkAutoTUnref<GrEffect> effect;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000255 { // scope to contain GrTestTarget
256 GrTestTarget tt;
257 context->getTestTarget(&tt);
258 if (NULL == tt.target()) {
259 continue;
260 }
261 GrEffectEdgeType et = (GrEffectEdgeType)edgeType;
262 effect.reset(GrConicEffect::Create(et, *tt.target()->caps()));
263 if (!effect) {
264 continue;
265 }
266 }
267
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000268 SkScalar x = SkScalarMul(col, w);
269 SkScalar y = SkScalarMul(row, h);
270 SkPoint controlPts[] = {
271 {x + baseControlPts[0].fX, y + baseControlPts[0].fY},
272 {x + baseControlPts[1].fX, y + baseControlPts[1].fY},
273 {x + baseControlPts[2].fX, y + baseControlPts[2].fY}
274 };
275 SkConic dst[4];
276 SkScalar klmEqs[9];
277 int cnt = chop_conic(controlPts, dst, weight);
278 GrPathUtils::getConicKLM(controlPts, weight, klmEqs);
279
280 SkPaint ctrlPtPaint;
281 ctrlPtPaint.setColor(rand.nextU() | 0xFF000000);
282 for (int i = 0; i < 3; ++i) {
283 canvas->drawCircle(controlPts[i].fX, controlPts[i].fY, 6.f, ctrlPtPaint);
284 }
285
286 SkPaint polyPaint;
287 polyPaint.setColor(0xffA0A0A0);
288 polyPaint.setStrokeWidth(0);
289 polyPaint.setStyle(SkPaint::kStroke_Style);
290 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, controlPts, polyPaint);
291
292 SkPaint choppedPtPaint;
293 choppedPtPaint.setColor(~ctrlPtPaint.getColor() | 0xFF000000);
294
295 for (int c = 0; c < cnt; ++c) {
296 SkPoint* pts = dst[c].fPts;
297 for (int i = 0; i < 3; ++i) {
298 canvas->drawCircle(pts[i].fX, pts[i].fY, 3.f, choppedPtPaint);
299 }
300
301 SkRect bounds;
302 //SkPoint bPts[] = {{0.f, 0.f}, {800.f, 800.f}};
303 //bounds.set(bPts, 2);
304 bounds.set(pts, 3);
305
306 SkPaint boundsPaint;
307 boundsPaint.setColor(0xff808080);
308 boundsPaint.setStrokeWidth(0);
309 boundsPaint.setStyle(SkPaint::kStroke_Style);
310 canvas->drawRect(bounds, boundsPaint);
311
312 Vertex verts[4];
313 verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
314 bounds.fRight, bounds.fBottom,
315 sizeof(Vertex));
316 for (int v = 0; v < 4; ++v) {
317 verts[v].fKLM[0] = eval_line(verts[v].fPosition, klmEqs + 0, 1.f);
318 verts[v].fKLM[1] = eval_line(verts[v].fPosition, klmEqs + 3, 1.f);
319 verts[v].fKLM[2] = eval_line(verts[v].fPosition, klmEqs + 6, 1.f);
320 }
321
322 GrTestTarget tt;
323 context->getTestTarget(&tt);
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000324 SkASSERT(NULL != tt.target());
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000325 GrDrawState* drawState = tt.target()->drawState();
326 drawState->setVertexAttribs<kAttribs>(2);
327
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000328 drawState->addCoverageEffect(effect, 1);
329 drawState->setRenderTarget(rt);
330 drawState->setColor(0xff000000);
331
332 tt.target()->setVertexSourceToArray(verts, 4);
333 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
334 tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
335 }
336 ++col;
337 if (numCols == col) {
338 col = 0;
339 ++row;
340 }
341 }
342 }
343 }
344
345private:
346 // Uses the max curvature function for quads to estimate
347 // where to chop the conic. If the max curvature is not
348 // found along the curve segment it will return 1 and
349 // dst[0] is the original conic. If it returns 2 the dst[0]
350 // and dst[1] are the two new conics.
351 int split_conic(const SkPoint src[3], SkConic dst[2], const SkScalar weight) {
352 SkScalar t = SkFindQuadMaxCurvature(src);
353 if (t == 0) {
354 if (dst) {
355 dst[0].set(src, weight);
356 }
357 return 1;
358 } else {
359 if (dst) {
360 SkConic conic;
361 conic.set(src, weight);
362 conic.chopAt(t, dst);
363 }
364 return 2;
365 }
366 }
367
368 // Calls split_conic on the entire conic and then once more on each subsection.
369 // Most cases will result in either 1 conic (chop point is not within t range)
370 // or 3 points (split once and then one subsection is split again).
371 int chop_conic(const SkPoint src[3], SkConic dst[4], const SkScalar weight) {
372 SkConic dstTemp[2];
373 int conicCnt = split_conic(src, dstTemp, weight);
374 if (2 == conicCnt) {
375 int conicCnt2 = split_conic(dstTemp[0].fPts, dst, dstTemp[0].fW);
376 conicCnt = conicCnt2 + split_conic(dstTemp[1].fPts, &dst[conicCnt2], dstTemp[1].fW);
377 } else {
378 dst[0] = dstTemp[0];
379 }
380 return conicCnt;
381 }
382
383 typedef GM INHERITED;
384};
385
386//////////////////////////////////////////////////////////////////////////////
387/**
388 * This GM directly exercises effects that draw Bezier quad curves in the GPU backend.
389 */
390class BezierQuadEffects : public GM {
391public:
392 BezierQuadEffects() {
393 this->setBGColor(0xFFFFFFFF);
394 }
395
396protected:
397 virtual SkString onShortName() SK_OVERRIDE {
398 return SkString("bezier_quad_effects");
399 }
400
401 virtual SkISize onISize() SK_OVERRIDE {
tfarinaf5393182014-06-09 23:59:03 -0700402 return SkISize::Make(800, 800);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000403 }
404
405 virtual uint32_t onGetFlags() const SK_OVERRIDE {
406 // This is a GPU-specific GM.
407 return kGPUOnly_Flag;
408 }
409
410
411 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
reed@google.com9c135db2014-03-12 18:28:35 +0000412 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000413 if (NULL == rt) {
414 return;
415 }
416 GrContext* context = rt->getContext();
417 if (NULL == context) {
418 return;
419 }
420
421 struct Vertex {
422 SkPoint fPosition;
423 float fUV[4]; // The last two values are ignored. The effect expects a vec4f.
424 };
425
426 static const int kNumQuads = 5;
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000427 SkRandom rand;
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000428
429 int numCols = SkScalarCeilToInt(SkScalarSqrt(SkIntToScalar(kNumQuads*3)));
430 int numRows = SkScalarCeilToInt(SkIntToScalar(kNumQuads*3) / numCols);
431 SkScalar w = SkIntToScalar(rt->width()) / numCols;
432 SkScalar h = SkIntToScalar(rt->height()) / numRows;
433 int row = 0;
434 int col = 0;
435
436 for (int i = 0; i < kNumQuads; ++i) {
437 SkPoint baseControlPts[] = {
438 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
439 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
440 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}
441 };
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000442 for(int edgeType = 0; edgeType < kGrEffectEdgeTypeCnt; ++edgeType) {
bsalomon83d081a2014-07-08 09:56:10 -0700443 SkAutoTUnref<GrEffect> effect;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000444 { // scope to contain GrTestTarget
445 GrTestTarget tt;
446 context->getTestTarget(&tt);
447 if (NULL == tt.target()) {
448 continue;
449 }
450 GrEffectEdgeType et = (GrEffectEdgeType)edgeType;
451 effect.reset(GrQuadEffect::Create(et, *tt.target()->caps()));
452 if (!effect) {
453 continue;
454 }
455 }
456
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000457 SkScalar x = SkScalarMul(col, w);
458 SkScalar y = SkScalarMul(row, h);
459 SkPoint controlPts[] = {
460 {x + baseControlPts[0].fX, y + baseControlPts[0].fY},
461 {x + baseControlPts[1].fX, y + baseControlPts[1].fY},
462 {x + baseControlPts[2].fX, y + baseControlPts[2].fY}
463 };
464 SkPoint chopped[5];
465 int cnt = SkChopQuadAtMaxCurvature(controlPts, chopped);
466
467 SkPaint ctrlPtPaint;
468 ctrlPtPaint.setColor(rand.nextU() | 0xFF000000);
469 for (int i = 0; i < 3; ++i) {
470 canvas->drawCircle(controlPts[i].fX, controlPts[i].fY, 6.f, ctrlPtPaint);
471 }
472
473 SkPaint polyPaint;
474 polyPaint.setColor(0xffA0A0A0);
475 polyPaint.setStrokeWidth(0);
476 polyPaint.setStyle(SkPaint::kStroke_Style);
477 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, controlPts, polyPaint);
478
479 SkPaint choppedPtPaint;
480 choppedPtPaint.setColor(~ctrlPtPaint.getColor() | 0xFF000000);
481
482 for (int c = 0; c < cnt; ++c) {
483 SkPoint* pts = chopped + 2 * c;
484
485 for (int i = 0; i < 3; ++i) {
486 canvas->drawCircle(pts[i].fX, pts[i].fY, 3.f, choppedPtPaint);
487 }
488
489 SkRect bounds;
490 bounds.set(pts, 3);
491
492 SkPaint boundsPaint;
493 boundsPaint.setColor(0xff808080);
494 boundsPaint.setStrokeWidth(0);
495 boundsPaint.setStyle(SkPaint::kStroke_Style);
496 canvas->drawRect(bounds, boundsPaint);
497
498 Vertex verts[4];
499 verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
500 bounds.fRight, bounds.fBottom,
501 sizeof(Vertex));
502
503 GrPathUtils::QuadUVMatrix DevToUV(pts);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000504 DevToUV.apply<4, sizeof(Vertex), sizeof(SkPoint)>(verts);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000505
506 GrTestTarget tt;
507 context->getTestTarget(&tt);
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000508 SkASSERT(NULL != tt.target());
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000509 GrDrawState* drawState = tt.target()->drawState();
510 drawState->setVertexAttribs<kAttribs>(2);
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000511
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000512 drawState->addCoverageEffect(effect, 1);
513 drawState->setRenderTarget(rt);
514 drawState->setColor(0xff000000);
515
516 tt.target()->setVertexSourceToArray(verts, 4);
517 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
518 tt.target()->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 4, 6);
519 }
520 ++col;
521 if (numCols == col) {
522 col = 0;
523 ++row;
524 }
525 }
526 }
527 }
528
529private:
530 typedef GM INHERITED;
531};
532
533DEF_GM( return SkNEW(BezierCubicEffects); )
534DEF_GM( return SkNEW(BezierConicEffects); )
535DEF_GM( return SkNEW(BezierQuadEffects); )
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000536
537}
538
539#endif