blob: 0e811d9c0501f0b4ba3b3fe15248d4f7cd19ae6a [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},
joshualittb0a8a372014-09-23 09:50:21 -070029 {kVec4f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_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 };
joshualittb0a8a372014-09-23 09:50:21 -070095 for(int edgeType = 0; edgeType < kGrProcessorEdgeTypeCnt; ++edgeType) {
96 SkAutoTUnref<GrGeometryProcessor> gp;
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 }
joshualittb0a8a372014-09-23 09:50:21 -0700103 GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)edgeType;
104 gp.reset(GrCubicEffect::Create(et, *tt.target()->caps()));
105 if (!gp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000106 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
joshualitt50408ad2014-11-03 12:31:14 -0800157 GrTestTarget tt;
158 context->getTestTarget(&tt);
159 SkASSERT(tt.target());
160
161 GrDrawState* drawState = tt.target()->drawState();
162 drawState->setVertexAttribs<kAttribs>(2, sizeof(Vertex));
163
164 GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, 0);
165 Vertex* verts = reinterpret_cast<Vertex*>(geo.vertices());
166
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000167 verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
168 bounds.fRight, bounds.fBottom,
169 sizeof(Vertex));
170 for (int v = 0; v < 4; ++v) {
171 verts[v].fKLM[0] = eval_line(verts[v].fPosition, klmEqs + 0, klmSigns[c]);
172 verts[v].fKLM[1] = eval_line(verts[v].fPosition, klmEqs + 3, klmSigns[c]);
173 verts[v].fKLM[2] = eval_line(verts[v].fPosition, klmEqs + 6, 1.f);
174 }
175
joshualittb0a8a372014-09-23 09:50:21 -0700176 drawState->setGeometryProcessor(gp);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000177 drawState->setRenderTarget(rt);
178 drawState->setColor(0xff000000);
179
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000180 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
181 tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000182 }
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000183 ++col;
184 if (numCols == col) {
185 col = 0;
186 ++row;
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000187 }
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000188 }
189 }
190 }
191
192private:
193 typedef GM INHERITED;
194};
195
196//////////////////////////////////////////////////////////////////////////////
197
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000198/**
199 * This GM directly exercises effects that draw Bezier curves in the GPU backend.
200 */
201class BezierConicEffects : public GM {
202public:
203 BezierConicEffects() {
204 this->setBGColor(0xFFFFFFFF);
205 }
206
207protected:
208 virtual SkString onShortName() SK_OVERRIDE {
209 return SkString("bezier_conic_effects");
210 }
211
212 virtual SkISize onISize() SK_OVERRIDE {
tfarinaf5393182014-06-09 23:59:03 -0700213 return SkISize::Make(800, 800);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000214 }
215
216 virtual uint32_t onGetFlags() const SK_OVERRIDE {
217 // This is a GPU-specific GM.
218 return kGPUOnly_Flag;
219 }
220
221
222 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
reed@google.com9c135db2014-03-12 18:28:35 +0000223 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000224 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);
joshualittb0a8a372014-09-23 09:50:21 -0700255 for(int edgeType = 0; edgeType < kGrProcessorEdgeTypeCnt; ++edgeType) {
256 SkAutoTUnref<GrGeometryProcessor> gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000257 { // scope to contain GrTestTarget
258 GrTestTarget tt;
259 context->getTestTarget(&tt);
260 if (NULL == tt.target()) {
261 continue;
262 }
joshualittb0a8a372014-09-23 09:50:21 -0700263 GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)edgeType;
264 gp.reset(GrConicEffect::Create(et, *tt.target()->caps()));
265 if (!gp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000266 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
joshualitt50408ad2014-11-03 12:31:14 -0800314 GrTestTarget tt;
315 context->getTestTarget(&tt);
316 SkASSERT(tt.target());
317
318 GrDrawState* drawState = tt.target()->drawState();
319 drawState->setVertexAttribs<kAttribs>(2, sizeof(Vertex));
320
321 GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, 0);
322 Vertex* verts = reinterpret_cast<Vertex*>(geo.vertices());
323
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000324 verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
325 bounds.fRight, bounds.fBottom,
326 sizeof(Vertex));
327 for (int v = 0; v < 4; ++v) {
328 verts[v].fKLM[0] = eval_line(verts[v].fPosition, klmEqs + 0, 1.f);
329 verts[v].fKLM[1] = eval_line(verts[v].fPosition, klmEqs + 3, 1.f);
330 verts[v].fKLM[2] = eval_line(verts[v].fPosition, klmEqs + 6, 1.f);
331 }
332
joshualittb0a8a372014-09-23 09:50:21 -0700333 drawState->setGeometryProcessor(gp);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000334 drawState->setRenderTarget(rt);
335 drawState->setColor(0xff000000);
336
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000337 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
338 tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
339 }
340 ++col;
341 if (numCols == col) {
342 col = 0;
343 ++row;
344 }
345 }
346 }
347 }
348
349private:
350 // Uses the max curvature function for quads to estimate
351 // where to chop the conic. If the max curvature is not
352 // found along the curve segment it will return 1 and
353 // dst[0] is the original conic. If it returns 2 the dst[0]
354 // and dst[1] are the two new conics.
355 int split_conic(const SkPoint src[3], SkConic dst[2], const SkScalar weight) {
356 SkScalar t = SkFindQuadMaxCurvature(src);
357 if (t == 0) {
358 if (dst) {
359 dst[0].set(src, weight);
360 }
361 return 1;
362 } else {
363 if (dst) {
364 SkConic conic;
365 conic.set(src, weight);
366 conic.chopAt(t, dst);
367 }
368 return 2;
369 }
370 }
371
372 // Calls split_conic on the entire conic and then once more on each subsection.
373 // Most cases will result in either 1 conic (chop point is not within t range)
374 // or 3 points (split once and then one subsection is split again).
375 int chop_conic(const SkPoint src[3], SkConic dst[4], const SkScalar weight) {
376 SkConic dstTemp[2];
377 int conicCnt = split_conic(src, dstTemp, weight);
378 if (2 == conicCnt) {
379 int conicCnt2 = split_conic(dstTemp[0].fPts, dst, dstTemp[0].fW);
380 conicCnt = conicCnt2 + split_conic(dstTemp[1].fPts, &dst[conicCnt2], dstTemp[1].fW);
381 } else {
382 dst[0] = dstTemp[0];
383 }
384 return conicCnt;
385 }
386
387 typedef GM INHERITED;
388};
389
390//////////////////////////////////////////////////////////////////////////////
391/**
392 * This GM directly exercises effects that draw Bezier quad curves in the GPU backend.
393 */
394class BezierQuadEffects : public GM {
395public:
396 BezierQuadEffects() {
397 this->setBGColor(0xFFFFFFFF);
398 }
399
400protected:
401 virtual SkString onShortName() SK_OVERRIDE {
402 return SkString("bezier_quad_effects");
403 }
404
405 virtual SkISize onISize() SK_OVERRIDE {
tfarinaf5393182014-06-09 23:59:03 -0700406 return SkISize::Make(800, 800);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000407 }
408
409 virtual uint32_t onGetFlags() const SK_OVERRIDE {
410 // This is a GPU-specific GM.
411 return kGPUOnly_Flag;
412 }
413
414
415 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
reed@google.com9c135db2014-03-12 18:28:35 +0000416 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000417 if (NULL == rt) {
418 return;
419 }
420 GrContext* context = rt->getContext();
421 if (NULL == context) {
422 return;
423 }
424
425 struct Vertex {
426 SkPoint fPosition;
427 float fUV[4]; // The last two values are ignored. The effect expects a vec4f.
428 };
429
430 static const int kNumQuads = 5;
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000431 SkRandom rand;
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000432
433 int numCols = SkScalarCeilToInt(SkScalarSqrt(SkIntToScalar(kNumQuads*3)));
434 int numRows = SkScalarCeilToInt(SkIntToScalar(kNumQuads*3) / numCols);
435 SkScalar w = SkIntToScalar(rt->width()) / numCols;
436 SkScalar h = SkIntToScalar(rt->height()) / numRows;
437 int row = 0;
438 int col = 0;
439
440 for (int i = 0; i < kNumQuads; ++i) {
441 SkPoint baseControlPts[] = {
442 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
443 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
444 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}
445 };
joshualittb0a8a372014-09-23 09:50:21 -0700446 for(int edgeType = 0; edgeType < kGrProcessorEdgeTypeCnt; ++edgeType) {
447 SkAutoTUnref<GrGeometryProcessor> gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000448 { // scope to contain GrTestTarget
449 GrTestTarget tt;
450 context->getTestTarget(&tt);
451 if (NULL == tt.target()) {
452 continue;
453 }
joshualittb0a8a372014-09-23 09:50:21 -0700454 GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)edgeType;
455 gp.reset(GrQuadEffect::Create(et, *tt.target()->caps()));
456 if (!gp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000457 continue;
458 }
459 }
460
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000461 SkScalar x = SkScalarMul(col, w);
462 SkScalar y = SkScalarMul(row, h);
463 SkPoint controlPts[] = {
464 {x + baseControlPts[0].fX, y + baseControlPts[0].fY},
465 {x + baseControlPts[1].fX, y + baseControlPts[1].fY},
466 {x + baseControlPts[2].fX, y + baseControlPts[2].fY}
467 };
468 SkPoint chopped[5];
469 int cnt = SkChopQuadAtMaxCurvature(controlPts, chopped);
470
471 SkPaint ctrlPtPaint;
472 ctrlPtPaint.setColor(rand.nextU() | 0xFF000000);
473 for (int i = 0; i < 3; ++i) {
474 canvas->drawCircle(controlPts[i].fX, controlPts[i].fY, 6.f, ctrlPtPaint);
475 }
476
477 SkPaint polyPaint;
478 polyPaint.setColor(0xffA0A0A0);
479 polyPaint.setStrokeWidth(0);
480 polyPaint.setStyle(SkPaint::kStroke_Style);
481 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, controlPts, polyPaint);
482
483 SkPaint choppedPtPaint;
484 choppedPtPaint.setColor(~ctrlPtPaint.getColor() | 0xFF000000);
485
486 for (int c = 0; c < cnt; ++c) {
487 SkPoint* pts = chopped + 2 * c;
488
489 for (int i = 0; i < 3; ++i) {
490 canvas->drawCircle(pts[i].fX, pts[i].fY, 3.f, choppedPtPaint);
491 }
492
493 SkRect bounds;
494 bounds.set(pts, 3);
495
496 SkPaint boundsPaint;
497 boundsPaint.setColor(0xff808080);
498 boundsPaint.setStrokeWidth(0);
499 boundsPaint.setStyle(SkPaint::kStroke_Style);
500 canvas->drawRect(bounds, boundsPaint);
501
joshualitt50408ad2014-11-03 12:31:14 -0800502 GrTestTarget tt;
503 context->getTestTarget(&tt);
504 SkASSERT(tt.target());
505
506 GrDrawState* drawState = tt.target()->drawState();
507 drawState->setVertexAttribs<kAttribs>(2, sizeof(Vertex));
508
509 GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, 0);
510 Vertex* verts = reinterpret_cast<Vertex*>(geo.vertices());
511
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000512 verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
513 bounds.fRight, bounds.fBottom,
514 sizeof(Vertex));
515
516 GrPathUtils::QuadUVMatrix DevToUV(pts);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000517 DevToUV.apply<4, sizeof(Vertex), sizeof(SkPoint)>(verts);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000518
joshualittb0a8a372014-09-23 09:50:21 -0700519 drawState->setGeometryProcessor(gp);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000520 drawState->setRenderTarget(rt);
521 drawState->setColor(0xff000000);
522
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000523 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
524 tt.target()->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 4, 6);
525 }
526 ++col;
527 if (numCols == col) {
528 col = 0;
529 ++row;
530 }
531 }
532 }
533 }
534
535private:
536 typedef GM INHERITED;
537};
538
539DEF_GM( return SkNEW(BezierCubicEffects); )
540DEF_GM( return SkNEW(BezierConicEffects); )
541DEF_GM( return SkNEW(BezierQuadEffects); )
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000542
543}
544
545#endif