blob: 0ddcc52b95da2de9c37acb51ec594885fb2a37ad [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
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000024static inline SkScalar eval_line(const SkPoint& p, const SkScalar lineEq[3], SkScalar sign) {
25 return sign * (lineEq[0] * p.fX + lineEq[1] * p.fY + lineEq[2]);
26}
27
28namespace skiagm {
29/**
30 * This GM directly exercises effects that draw Bezier curves in the GPU backend.
31 */
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000032class BezierCubicEffects : public GM {
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000033public:
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000034 BezierCubicEffects() {
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000035 this->setBGColor(0xFFFFFFFF);
36 }
37
38protected:
mtklein72c9faa2015-01-09 10:06:39 -080039 SkString onShortName() SK_OVERRIDE {
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000040 return SkString("bezier_cubic_effects");
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000041 }
42
mtklein72c9faa2015-01-09 10:06:39 -080043 SkISize onISize() SK_OVERRIDE {
tfarinaf5393182014-06-09 23:59:03 -070044 return SkISize::Make(800, 800);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000045 }
46
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000047
mtklein72c9faa2015-01-09 10:06:39 -080048 void onDraw(SkCanvas* canvas) SK_OVERRIDE {
reed@google.com9c135db2014-03-12 18:28:35 +000049 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000050 if (NULL == rt) {
bsalomonb62da802015-01-31 07:51:14 -080051 this->drawGpuOnlyMessage(canvas);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000052 return;
53 }
54 GrContext* context = rt->getContext();
55 if (NULL == context) {
56 return;
57 }
58
59 struct Vertex {
60 SkPoint fPosition;
61 float fKLM[4]; // The last value is ignored. The effect expects a vec4f.
62 };
63
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000064 static const int kNumCubics = 15;
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +000065 SkRandom rand;
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000066
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000067 // Mult by 3 for each edge effect type
68 int numCols = SkScalarCeilToInt(SkScalarSqrt(SkIntToScalar(kNumCubics*3)));
69 int numRows = SkScalarCeilToInt(SkIntToScalar(kNumCubics*3) / numCols);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000070 SkScalar w = SkIntToScalar(rt->width()) / numCols;
71 SkScalar h = SkIntToScalar(rt->height()) / numRows;
72 int row = 0;
73 int col = 0;
74
75 for (int i = 0; i < kNumCubics; ++i) {
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000076 SkPoint baseControlPts[] = {
77 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
78 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
79 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
80 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000081 };
joshualittb0a8a372014-09-23 09:50:21 -070082 for(int edgeType = 0; edgeType < kGrProcessorEdgeTypeCnt; ++edgeType) {
83 SkAutoTUnref<GrGeometryProcessor> gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +000084 { // scope to contain GrTestTarget
85 GrTestTarget tt;
86 context->getTestTarget(&tt);
87 if (NULL == tt.target()) {
88 continue;
89 }
joshualittb0a8a372014-09-23 09:50:21 -070090 GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)edgeType;
joshualitt8059eb92014-12-29 15:10:07 -080091 gp.reset(GrCubicEffect::Create(0xff000000, SkMatrix::I(), et,
92 *tt.target()->caps()));
joshualittb0a8a372014-09-23 09:50:21 -070093 if (!gp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +000094 continue;
95 }
96 }
97
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000098 SkScalar x = SkScalarMul(col, w);
99 SkScalar y = SkScalarMul(row, h);
100 SkPoint controlPts[] = {
101 {x + baseControlPts[0].fX, y + baseControlPts[0].fY},
102 {x + baseControlPts[1].fX, y + baseControlPts[1].fY},
103 {x + baseControlPts[2].fX, y + baseControlPts[2].fY},
104 {x + baseControlPts[3].fX, y + baseControlPts[3].fY}
105 };
106 SkPoint chopped[10];
107 SkScalar klmEqs[9];
108 SkScalar klmSigns[3];
109 int cnt = GrPathUtils::chopCubicAtLoopIntersection(controlPts,
110 chopped,
111 klmEqs,
112 klmSigns);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000113
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000114 SkPaint ctrlPtPaint;
115 ctrlPtPaint.setColor(rand.nextU() | 0xFF000000);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000116 for (int i = 0; i < 4; ++i) {
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000117 canvas->drawCircle(controlPts[i].fX, controlPts[i].fY, 6.f, ctrlPtPaint);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000118 }
119
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000120 SkPaint polyPaint;
121 polyPaint.setColor(0xffA0A0A0);
122 polyPaint.setStrokeWidth(0);
123 polyPaint.setStyle(SkPaint::kStroke_Style);
124 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, controlPts, polyPaint);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000125
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000126 SkPaint choppedPtPaint;
127 choppedPtPaint.setColor(~ctrlPtPaint.getColor() | 0xFF000000);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000128
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000129 for (int c = 0; c < cnt; ++c) {
130 SkPoint* pts = chopped + 3 * c;
131
132 for (int i = 0; i < 4; ++i) {
133 canvas->drawCircle(pts[i].fX, pts[i].fY, 3.f, choppedPtPaint);
134 }
135
136 SkRect bounds;
137 bounds.set(pts, 4);
138
139 SkPaint boundsPaint;
140 boundsPaint.setColor(0xff808080);
141 boundsPaint.setStrokeWidth(0);
142 boundsPaint.setStyle(SkPaint::kStroke_Style);
143 canvas->drawRect(bounds, boundsPaint);
144
joshualitt50408ad2014-11-03 12:31:14 -0800145 GrTestTarget tt;
146 context->getTestTarget(&tt);
147 SkASSERT(tt.target());
148
egdaniel8dd688b2015-01-22 10:16:09 -0800149 GrPipelineBuilder pipelineBuilder;
joshualitt50408ad2014-11-03 12:31:14 -0800150
joshualitt2dd1ae02014-12-03 06:24:10 -0800151 GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, gp->getVertexStride(), 0);
152 SkASSERT(gp->getVertexStride() == sizeof(Vertex));
joshualitt50408ad2014-11-03 12:31:14 -0800153 Vertex* verts = reinterpret_cast<Vertex*>(geo.vertices());
154
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000155 verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
156 bounds.fRight, bounds.fBottom,
157 sizeof(Vertex));
158 for (int v = 0; v < 4; ++v) {
159 verts[v].fKLM[0] = eval_line(verts[v].fPosition, klmEqs + 0, klmSigns[c]);
160 verts[v].fKLM[1] = eval_line(verts[v].fPosition, klmEqs + 3, klmSigns[c]);
161 verts[v].fKLM[2] = eval_line(verts[v].fPosition, klmEqs + 6, 1.f);
162 }
163
egdaniel8dd688b2015-01-22 10:16:09 -0800164 pipelineBuilder.setRenderTarget(rt);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000165
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000166 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
egdaniel8dd688b2015-01-22 10:16:09 -0800167 tt.target()->drawIndexed(&pipelineBuilder, gp, kTriangleFan_GrPrimitiveType,
168 0, 0,4,6);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000169 }
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000170 ++col;
171 if (numCols == col) {
172 col = 0;
173 ++row;
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000174 }
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000175 }
176 }
177 }
178
179private:
180 typedef GM INHERITED;
181};
182
183//////////////////////////////////////////////////////////////////////////////
184
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000185/**
186 * This GM directly exercises effects that draw Bezier curves in the GPU backend.
187 */
188class BezierConicEffects : public GM {
189public:
190 BezierConicEffects() {
191 this->setBGColor(0xFFFFFFFF);
192 }
193
194protected:
mtklein72c9faa2015-01-09 10:06:39 -0800195 SkString onShortName() SK_OVERRIDE {
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000196 return SkString("bezier_conic_effects");
197 }
198
mtklein72c9faa2015-01-09 10:06:39 -0800199 SkISize onISize() SK_OVERRIDE {
tfarinaf5393182014-06-09 23:59:03 -0700200 return SkISize::Make(800, 800);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000201 }
202
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000203
mtklein72c9faa2015-01-09 10:06:39 -0800204 void onDraw(SkCanvas* canvas) SK_OVERRIDE {
reed@google.com9c135db2014-03-12 18:28:35 +0000205 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000206 if (NULL == rt) {
bsalomonb62da802015-01-31 07:51:14 -0800207 this->drawGpuOnlyMessage(canvas);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000208 return;
209 }
210 GrContext* context = rt->getContext();
211 if (NULL == context) {
212 return;
213 }
214
215 struct Vertex {
216 SkPoint fPosition;
217 float fKLM[4]; // The last value is ignored. The effect expects a vec4f.
218 };
219
220 static const int kNumConics = 10;
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000221 SkRandom rand;
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000222
223 // Mult by 3 for each edge effect type
224 int numCols = SkScalarCeilToInt(SkScalarSqrt(SkIntToScalar(kNumConics*3)));
225 int numRows = SkScalarCeilToInt(SkIntToScalar(kNumConics*3) / numCols);
226 SkScalar w = SkIntToScalar(rt->width()) / numCols;
227 SkScalar h = SkIntToScalar(rt->height()) / numRows;
228 int row = 0;
229 int col = 0;
230
231 for (int i = 0; i < kNumConics; ++i) {
232 SkPoint baseControlPts[] = {
233 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
234 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
235 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}
236 };
237 SkScalar weight = rand.nextRangeF(0.f, 2.f);
joshualittb0a8a372014-09-23 09:50:21 -0700238 for(int edgeType = 0; edgeType < kGrProcessorEdgeTypeCnt; ++edgeType) {
239 SkAutoTUnref<GrGeometryProcessor> gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000240 { // scope to contain GrTestTarget
241 GrTestTarget tt;
242 context->getTestTarget(&tt);
243 if (NULL == tt.target()) {
244 continue;
245 }
joshualittb0a8a372014-09-23 09:50:21 -0700246 GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)edgeType;
joshualitt8059eb92014-12-29 15:10:07 -0800247 gp.reset(GrConicEffect::Create(0xff000000, SkMatrix::I(), et,
248 *tt.target()->caps(), SkMatrix::I()));
joshualittb0a8a372014-09-23 09:50:21 -0700249 if (!gp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000250 continue;
251 }
252 }
253
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000254 SkScalar x = SkScalarMul(col, w);
255 SkScalar y = SkScalarMul(row, h);
256 SkPoint controlPts[] = {
257 {x + baseControlPts[0].fX, y + baseControlPts[0].fY},
258 {x + baseControlPts[1].fX, y + baseControlPts[1].fY},
259 {x + baseControlPts[2].fX, y + baseControlPts[2].fY}
260 };
261 SkConic dst[4];
262 SkScalar klmEqs[9];
263 int cnt = chop_conic(controlPts, dst, weight);
264 GrPathUtils::getConicKLM(controlPts, weight, klmEqs);
265
266 SkPaint ctrlPtPaint;
267 ctrlPtPaint.setColor(rand.nextU() | 0xFF000000);
268 for (int i = 0; i < 3; ++i) {
269 canvas->drawCircle(controlPts[i].fX, controlPts[i].fY, 6.f, ctrlPtPaint);
270 }
271
272 SkPaint polyPaint;
273 polyPaint.setColor(0xffA0A0A0);
274 polyPaint.setStrokeWidth(0);
275 polyPaint.setStyle(SkPaint::kStroke_Style);
276 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, controlPts, polyPaint);
277
278 SkPaint choppedPtPaint;
279 choppedPtPaint.setColor(~ctrlPtPaint.getColor() | 0xFF000000);
280
281 for (int c = 0; c < cnt; ++c) {
282 SkPoint* pts = dst[c].fPts;
283 for (int i = 0; i < 3; ++i) {
284 canvas->drawCircle(pts[i].fX, pts[i].fY, 3.f, choppedPtPaint);
285 }
286
287 SkRect bounds;
288 //SkPoint bPts[] = {{0.f, 0.f}, {800.f, 800.f}};
289 //bounds.set(bPts, 2);
290 bounds.set(pts, 3);
291
292 SkPaint boundsPaint;
293 boundsPaint.setColor(0xff808080);
294 boundsPaint.setStrokeWidth(0);
295 boundsPaint.setStyle(SkPaint::kStroke_Style);
296 canvas->drawRect(bounds, boundsPaint);
297
joshualitt50408ad2014-11-03 12:31:14 -0800298 GrTestTarget tt;
299 context->getTestTarget(&tt);
300 SkASSERT(tt.target());
301
egdaniel8dd688b2015-01-22 10:16:09 -0800302 GrPipelineBuilder pipelineBuilder;
joshualitt50408ad2014-11-03 12:31:14 -0800303
joshualitt2dd1ae02014-12-03 06:24:10 -0800304 GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, gp->getVertexStride(), 0);
305 SkASSERT(gp->getVertexStride() == sizeof(Vertex));
joshualitt50408ad2014-11-03 12:31:14 -0800306 Vertex* verts = reinterpret_cast<Vertex*>(geo.vertices());
307
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000308 verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
309 bounds.fRight, bounds.fBottom,
310 sizeof(Vertex));
311 for (int v = 0; v < 4; ++v) {
312 verts[v].fKLM[0] = eval_line(verts[v].fPosition, klmEqs + 0, 1.f);
313 verts[v].fKLM[1] = eval_line(verts[v].fPosition, klmEqs + 3, 1.f);
314 verts[v].fKLM[2] = eval_line(verts[v].fPosition, klmEqs + 6, 1.f);
315 }
316
egdaniel8dd688b2015-01-22 10:16:09 -0800317 pipelineBuilder.setRenderTarget(rt);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000318
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000319 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
egdaniel8dd688b2015-01-22 10:16:09 -0800320 tt.target()->drawIndexed(&pipelineBuilder, gp, kTriangleFan_GrPrimitiveType,
321 0, 0,4,6);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000322 }
323 ++col;
324 if (numCols == col) {
325 col = 0;
326 ++row;
327 }
328 }
329 }
330 }
331
332private:
333 // Uses the max curvature function for quads to estimate
334 // where to chop the conic. If the max curvature is not
335 // found along the curve segment it will return 1 and
336 // dst[0] is the original conic. If it returns 2 the dst[0]
337 // and dst[1] are the two new conics.
338 int split_conic(const SkPoint src[3], SkConic dst[2], const SkScalar weight) {
339 SkScalar t = SkFindQuadMaxCurvature(src);
340 if (t == 0) {
341 if (dst) {
342 dst[0].set(src, weight);
343 }
344 return 1;
345 } else {
346 if (dst) {
347 SkConic conic;
348 conic.set(src, weight);
349 conic.chopAt(t, dst);
350 }
351 return 2;
352 }
353 }
354
355 // Calls split_conic on the entire conic and then once more on each subsection.
356 // Most cases will result in either 1 conic (chop point is not within t range)
357 // or 3 points (split once and then one subsection is split again).
358 int chop_conic(const SkPoint src[3], SkConic dst[4], const SkScalar weight) {
359 SkConic dstTemp[2];
360 int conicCnt = split_conic(src, dstTemp, weight);
361 if (2 == conicCnt) {
362 int conicCnt2 = split_conic(dstTemp[0].fPts, dst, dstTemp[0].fW);
363 conicCnt = conicCnt2 + split_conic(dstTemp[1].fPts, &dst[conicCnt2], dstTemp[1].fW);
364 } else {
365 dst[0] = dstTemp[0];
366 }
367 return conicCnt;
368 }
369
370 typedef GM INHERITED;
371};
372
373//////////////////////////////////////////////////////////////////////////////
374/**
375 * This GM directly exercises effects that draw Bezier quad curves in the GPU backend.
376 */
377class BezierQuadEffects : public GM {
378public:
379 BezierQuadEffects() {
380 this->setBGColor(0xFFFFFFFF);
381 }
382
383protected:
mtklein72c9faa2015-01-09 10:06:39 -0800384 SkString onShortName() SK_OVERRIDE {
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000385 return SkString("bezier_quad_effects");
386 }
387
mtklein72c9faa2015-01-09 10:06:39 -0800388 SkISize onISize() SK_OVERRIDE {
tfarinaf5393182014-06-09 23:59:03 -0700389 return SkISize::Make(800, 800);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000390 }
391
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000392
mtklein72c9faa2015-01-09 10:06:39 -0800393 void onDraw(SkCanvas* canvas) SK_OVERRIDE {
reed@google.com9c135db2014-03-12 18:28:35 +0000394 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000395 if (NULL == rt) {
bsalomonb62da802015-01-31 07:51:14 -0800396 this->drawGpuOnlyMessage(canvas);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000397 return;
398 }
399 GrContext* context = rt->getContext();
400 if (NULL == context) {
401 return;
402 }
403
404 struct Vertex {
405 SkPoint fPosition;
406 float fUV[4]; // The last two values are ignored. The effect expects a vec4f.
407 };
408
409 static const int kNumQuads = 5;
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000410 SkRandom rand;
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000411
412 int numCols = SkScalarCeilToInt(SkScalarSqrt(SkIntToScalar(kNumQuads*3)));
413 int numRows = SkScalarCeilToInt(SkIntToScalar(kNumQuads*3) / numCols);
414 SkScalar w = SkIntToScalar(rt->width()) / numCols;
415 SkScalar h = SkIntToScalar(rt->height()) / numRows;
416 int row = 0;
417 int col = 0;
418
419 for (int i = 0; i < kNumQuads; ++i) {
420 SkPoint baseControlPts[] = {
421 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
422 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
423 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}
424 };
joshualittb0a8a372014-09-23 09:50:21 -0700425 for(int edgeType = 0; edgeType < kGrProcessorEdgeTypeCnt; ++edgeType) {
426 SkAutoTUnref<GrGeometryProcessor> gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000427 { // scope to contain GrTestTarget
428 GrTestTarget tt;
429 context->getTestTarget(&tt);
430 if (NULL == tt.target()) {
431 continue;
432 }
joshualittb0a8a372014-09-23 09:50:21 -0700433 GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)edgeType;
joshualitt8059eb92014-12-29 15:10:07 -0800434 gp.reset(GrQuadEffect::Create(0xff000000, SkMatrix::I(), et,
435 *tt.target()->caps(), SkMatrix::I()));
joshualittb0a8a372014-09-23 09:50:21 -0700436 if (!gp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000437 continue;
438 }
439 }
440
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000441 SkScalar x = SkScalarMul(col, w);
442 SkScalar y = SkScalarMul(row, h);
443 SkPoint controlPts[] = {
444 {x + baseControlPts[0].fX, y + baseControlPts[0].fY},
445 {x + baseControlPts[1].fX, y + baseControlPts[1].fY},
446 {x + baseControlPts[2].fX, y + baseControlPts[2].fY}
447 };
448 SkPoint chopped[5];
449 int cnt = SkChopQuadAtMaxCurvature(controlPts, chopped);
450
451 SkPaint ctrlPtPaint;
452 ctrlPtPaint.setColor(rand.nextU() | 0xFF000000);
453 for (int i = 0; i < 3; ++i) {
454 canvas->drawCircle(controlPts[i].fX, controlPts[i].fY, 6.f, ctrlPtPaint);
455 }
456
457 SkPaint polyPaint;
458 polyPaint.setColor(0xffA0A0A0);
459 polyPaint.setStrokeWidth(0);
460 polyPaint.setStyle(SkPaint::kStroke_Style);
461 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, controlPts, polyPaint);
462
463 SkPaint choppedPtPaint;
464 choppedPtPaint.setColor(~ctrlPtPaint.getColor() | 0xFF000000);
465
466 for (int c = 0; c < cnt; ++c) {
467 SkPoint* pts = chopped + 2 * c;
468
469 for (int i = 0; i < 3; ++i) {
470 canvas->drawCircle(pts[i].fX, pts[i].fY, 3.f, choppedPtPaint);
471 }
472
473 SkRect bounds;
474 bounds.set(pts, 3);
475
476 SkPaint boundsPaint;
477 boundsPaint.setColor(0xff808080);
478 boundsPaint.setStrokeWidth(0);
479 boundsPaint.setStyle(SkPaint::kStroke_Style);
480 canvas->drawRect(bounds, boundsPaint);
481
joshualitt50408ad2014-11-03 12:31:14 -0800482 GrTestTarget tt;
483 context->getTestTarget(&tt);
484 SkASSERT(tt.target());
485
egdaniel8dd688b2015-01-22 10:16:09 -0800486 GrPipelineBuilder pipelineBuilder;
joshualitt50408ad2014-11-03 12:31:14 -0800487
joshualitt2dd1ae02014-12-03 06:24:10 -0800488 GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, gp->getVertexStride(), 0);
489 SkASSERT(gp->getVertexStride() == sizeof(Vertex));
joshualitt50408ad2014-11-03 12:31:14 -0800490 Vertex* verts = reinterpret_cast<Vertex*>(geo.vertices());
491
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000492 verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
493 bounds.fRight, bounds.fBottom,
494 sizeof(Vertex));
495
496 GrPathUtils::QuadUVMatrix DevToUV(pts);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000497 DevToUV.apply<4, sizeof(Vertex), sizeof(SkPoint)>(verts);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000498
egdaniel8dd688b2015-01-22 10:16:09 -0800499 pipelineBuilder.setRenderTarget(rt);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000500
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000501 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
egdaniel8dd688b2015-01-22 10:16:09 -0800502 tt.target()->drawIndexed(&pipelineBuilder, gp, kTriangles_GrPrimitiveType,
503 0, 0, 4, 6);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000504 }
505 ++col;
506 if (numCols == col) {
507 col = 0;
508 ++row;
509 }
510 }
511 }
512 }
513
514private:
515 typedef GM INHERITED;
516};
517
518DEF_GM( return SkNEW(BezierCubicEffects); )
519DEF_GM( return SkNEW(BezierConicEffects); )
520DEF_GM( return SkNEW(BezierQuadEffects); )
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000521
522}
523
524#endif