blob: b25ba7e723a5665c69aaa58d1570474ebcecc2ae [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
mtklein72c9faa2015-01-09 10:06:39 -080047 uint32_t onGetFlags() const SK_OVERRIDE {
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000048 // This is a GPU-specific GM.
49 return kGPUOnly_Flag;
50 }
51
52
mtklein72c9faa2015-01-09 10:06:39 -080053 void onDraw(SkCanvas* canvas) SK_OVERRIDE {
reed@google.com9c135db2014-03-12 18:28:35 +000054 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000055 if (NULL == rt) {
56 return;
57 }
58 GrContext* context = rt->getContext();
59 if (NULL == context) {
60 return;
61 }
62
63 struct Vertex {
64 SkPoint fPosition;
65 float fKLM[4]; // The last value is ignored. The effect expects a vec4f.
66 };
67
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000068 static const int kNumCubics = 15;
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +000069 SkRandom rand;
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000070
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000071 // Mult by 3 for each edge effect type
72 int numCols = SkScalarCeilToInt(SkScalarSqrt(SkIntToScalar(kNumCubics*3)));
73 int numRows = SkScalarCeilToInt(SkIntToScalar(kNumCubics*3) / numCols);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000074 SkScalar w = SkIntToScalar(rt->width()) / numCols;
75 SkScalar h = SkIntToScalar(rt->height()) / numRows;
76 int row = 0;
77 int col = 0;
78
79 for (int i = 0; i < kNumCubics; ++i) {
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +000080 SkPoint baseControlPts[] = {
81 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
82 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
83 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
84 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}
commit-bot@chromium.org78a10782013-08-21 19:27:48 +000085 };
joshualittb0a8a372014-09-23 09:50:21 -070086 for(int edgeType = 0; edgeType < kGrProcessorEdgeTypeCnt; ++edgeType) {
87 SkAutoTUnref<GrGeometryProcessor> gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +000088 { // scope to contain GrTestTarget
89 GrTestTarget tt;
90 context->getTestTarget(&tt);
91 if (NULL == tt.target()) {
92 continue;
93 }
joshualittb0a8a372014-09-23 09:50:21 -070094 GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)edgeType;
joshualitt8059eb92014-12-29 15:10:07 -080095 gp.reset(GrCubicEffect::Create(0xff000000, SkMatrix::I(), et,
96 *tt.target()->caps()));
joshualittb0a8a372014-09-23 09:50:21 -070097 if (!gp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +000098 continue;
99 }
100 }
101
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000102 SkScalar x = SkScalarMul(col, w);
103 SkScalar y = SkScalarMul(row, h);
104 SkPoint controlPts[] = {
105 {x + baseControlPts[0].fX, y + baseControlPts[0].fY},
106 {x + baseControlPts[1].fX, y + baseControlPts[1].fY},
107 {x + baseControlPts[2].fX, y + baseControlPts[2].fY},
108 {x + baseControlPts[3].fX, y + baseControlPts[3].fY}
109 };
110 SkPoint chopped[10];
111 SkScalar klmEqs[9];
112 SkScalar klmSigns[3];
113 int cnt = GrPathUtils::chopCubicAtLoopIntersection(controlPts,
114 chopped,
115 klmEqs,
116 klmSigns);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000117
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000118 SkPaint ctrlPtPaint;
119 ctrlPtPaint.setColor(rand.nextU() | 0xFF000000);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000120 for (int i = 0; i < 4; ++i) {
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000121 canvas->drawCircle(controlPts[i].fX, controlPts[i].fY, 6.f, ctrlPtPaint);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000122 }
123
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000124 SkPaint polyPaint;
125 polyPaint.setColor(0xffA0A0A0);
126 polyPaint.setStrokeWidth(0);
127 polyPaint.setStyle(SkPaint::kStroke_Style);
128 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, controlPts, polyPaint);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000129
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000130 SkPaint choppedPtPaint;
131 choppedPtPaint.setColor(~ctrlPtPaint.getColor() | 0xFF000000);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000132
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000133 for (int c = 0; c < cnt; ++c) {
134 SkPoint* pts = chopped + 3 * c;
135
136 for (int i = 0; i < 4; ++i) {
137 canvas->drawCircle(pts[i].fX, pts[i].fY, 3.f, choppedPtPaint);
138 }
139
140 SkRect bounds;
141 bounds.set(pts, 4);
142
143 SkPaint boundsPaint;
144 boundsPaint.setColor(0xff808080);
145 boundsPaint.setStrokeWidth(0);
146 boundsPaint.setStyle(SkPaint::kStroke_Style);
147 canvas->drawRect(bounds, boundsPaint);
148
joshualitt50408ad2014-11-03 12:31:14 -0800149 GrTestTarget tt;
150 context->getTestTarget(&tt);
151 SkASSERT(tt.target());
152
joshualitt9853cce2014-11-17 14:22:48 -0800153 GrDrawState ds;
joshualitt50408ad2014-11-03 12:31:14 -0800154
joshualitt2dd1ae02014-12-03 06:24:10 -0800155 GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, gp->getVertexStride(), 0);
156 SkASSERT(gp->getVertexStride() == sizeof(Vertex));
joshualitt50408ad2014-11-03 12:31:14 -0800157 Vertex* verts = reinterpret_cast<Vertex*>(geo.vertices());
158
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000159 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
joshualitt9853cce2014-11-17 14:22:48 -0800168 ds.setRenderTarget(rt);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000169
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000170 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
joshualitt56995b52014-12-11 15:44:02 -0800171 tt.target()->drawIndexed(&ds, gp, kTriangleFan_GrPrimitiveType, 0, 0,4,6);
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000172 }
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000173 ++col;
174 if (numCols == col) {
175 col = 0;
176 ++row;
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000177 }
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000178 }
179 }
180 }
181
182private:
183 typedef GM INHERITED;
184};
185
186//////////////////////////////////////////////////////////////////////////////
187
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000188/**
189 * This GM directly exercises effects that draw Bezier curves in the GPU backend.
190 */
191class BezierConicEffects : public GM {
192public:
193 BezierConicEffects() {
194 this->setBGColor(0xFFFFFFFF);
195 }
196
197protected:
mtklein72c9faa2015-01-09 10:06:39 -0800198 SkString onShortName() SK_OVERRIDE {
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000199 return SkString("bezier_conic_effects");
200 }
201
mtklein72c9faa2015-01-09 10:06:39 -0800202 SkISize onISize() SK_OVERRIDE {
tfarinaf5393182014-06-09 23:59:03 -0700203 return SkISize::Make(800, 800);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000204 }
205
mtklein72c9faa2015-01-09 10:06:39 -0800206 uint32_t onGetFlags() const SK_OVERRIDE {
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000207 // This is a GPU-specific GM.
208 return kGPUOnly_Flag;
209 }
210
211
mtklein72c9faa2015-01-09 10:06:39 -0800212 void onDraw(SkCanvas* canvas) SK_OVERRIDE {
reed@google.com9c135db2014-03-12 18:28:35 +0000213 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000214 if (NULL == rt) {
215 return;
216 }
217 GrContext* context = rt->getContext();
218 if (NULL == context) {
219 return;
220 }
221
222 struct Vertex {
223 SkPoint fPosition;
224 float fKLM[4]; // The last value is ignored. The effect expects a vec4f.
225 };
226
227 static const int kNumConics = 10;
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000228 SkRandom rand;
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000229
230 // Mult by 3 for each edge effect type
231 int numCols = SkScalarCeilToInt(SkScalarSqrt(SkIntToScalar(kNumConics*3)));
232 int numRows = SkScalarCeilToInt(SkIntToScalar(kNumConics*3) / numCols);
233 SkScalar w = SkIntToScalar(rt->width()) / numCols;
234 SkScalar h = SkIntToScalar(rt->height()) / numRows;
235 int row = 0;
236 int col = 0;
237
238 for (int i = 0; i < kNumConics; ++i) {
239 SkPoint baseControlPts[] = {
240 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
241 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
242 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}
243 };
244 SkScalar weight = rand.nextRangeF(0.f, 2.f);
joshualittb0a8a372014-09-23 09:50:21 -0700245 for(int edgeType = 0; edgeType < kGrProcessorEdgeTypeCnt; ++edgeType) {
246 SkAutoTUnref<GrGeometryProcessor> gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000247 { // scope to contain GrTestTarget
248 GrTestTarget tt;
249 context->getTestTarget(&tt);
250 if (NULL == tt.target()) {
251 continue;
252 }
joshualittb0a8a372014-09-23 09:50:21 -0700253 GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)edgeType;
joshualitt8059eb92014-12-29 15:10:07 -0800254 gp.reset(GrConicEffect::Create(0xff000000, SkMatrix::I(), et,
255 *tt.target()->caps(), SkMatrix::I()));
joshualittb0a8a372014-09-23 09:50:21 -0700256 if (!gp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000257 continue;
258 }
259 }
260
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000261 SkScalar x = SkScalarMul(col, w);
262 SkScalar y = SkScalarMul(row, h);
263 SkPoint controlPts[] = {
264 {x + baseControlPts[0].fX, y + baseControlPts[0].fY},
265 {x + baseControlPts[1].fX, y + baseControlPts[1].fY},
266 {x + baseControlPts[2].fX, y + baseControlPts[2].fY}
267 };
268 SkConic dst[4];
269 SkScalar klmEqs[9];
270 int cnt = chop_conic(controlPts, dst, weight);
271 GrPathUtils::getConicKLM(controlPts, weight, klmEqs);
272
273 SkPaint ctrlPtPaint;
274 ctrlPtPaint.setColor(rand.nextU() | 0xFF000000);
275 for (int i = 0; i < 3; ++i) {
276 canvas->drawCircle(controlPts[i].fX, controlPts[i].fY, 6.f, ctrlPtPaint);
277 }
278
279 SkPaint polyPaint;
280 polyPaint.setColor(0xffA0A0A0);
281 polyPaint.setStrokeWidth(0);
282 polyPaint.setStyle(SkPaint::kStroke_Style);
283 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, controlPts, polyPaint);
284
285 SkPaint choppedPtPaint;
286 choppedPtPaint.setColor(~ctrlPtPaint.getColor() | 0xFF000000);
287
288 for (int c = 0; c < cnt; ++c) {
289 SkPoint* pts = dst[c].fPts;
290 for (int i = 0; i < 3; ++i) {
291 canvas->drawCircle(pts[i].fX, pts[i].fY, 3.f, choppedPtPaint);
292 }
293
294 SkRect bounds;
295 //SkPoint bPts[] = {{0.f, 0.f}, {800.f, 800.f}};
296 //bounds.set(bPts, 2);
297 bounds.set(pts, 3);
298
299 SkPaint boundsPaint;
300 boundsPaint.setColor(0xff808080);
301 boundsPaint.setStrokeWidth(0);
302 boundsPaint.setStyle(SkPaint::kStroke_Style);
303 canvas->drawRect(bounds, boundsPaint);
304
joshualitt50408ad2014-11-03 12:31:14 -0800305 GrTestTarget tt;
306 context->getTestTarget(&tt);
307 SkASSERT(tt.target());
308
joshualitt9853cce2014-11-17 14:22:48 -0800309 GrDrawState ds;
joshualitt50408ad2014-11-03 12:31:14 -0800310
joshualitt2dd1ae02014-12-03 06:24:10 -0800311 GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, gp->getVertexStride(), 0);
312 SkASSERT(gp->getVertexStride() == sizeof(Vertex));
joshualitt50408ad2014-11-03 12:31:14 -0800313 Vertex* verts = reinterpret_cast<Vertex*>(geo.vertices());
314
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000315 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
joshualitt9853cce2014-11-17 14:22:48 -0800324 ds.setRenderTarget(rt);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000325
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000326 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
joshualitt56995b52014-12-11 15:44:02 -0800327 tt.target()->drawIndexed(&ds, gp, kTriangleFan_GrPrimitiveType, 0, 0,4,6);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000328 }
329 ++col;
330 if (numCols == col) {
331 col = 0;
332 ++row;
333 }
334 }
335 }
336 }
337
338private:
339 // Uses the max curvature function for quads to estimate
340 // where to chop the conic. If the max curvature is not
341 // found along the curve segment it will return 1 and
342 // dst[0] is the original conic. If it returns 2 the dst[0]
343 // and dst[1] are the two new conics.
344 int split_conic(const SkPoint src[3], SkConic dst[2], const SkScalar weight) {
345 SkScalar t = SkFindQuadMaxCurvature(src);
346 if (t == 0) {
347 if (dst) {
348 dst[0].set(src, weight);
349 }
350 return 1;
351 } else {
352 if (dst) {
353 SkConic conic;
354 conic.set(src, weight);
355 conic.chopAt(t, dst);
356 }
357 return 2;
358 }
359 }
360
361 // Calls split_conic on the entire conic and then once more on each subsection.
362 // Most cases will result in either 1 conic (chop point is not within t range)
363 // or 3 points (split once and then one subsection is split again).
364 int chop_conic(const SkPoint src[3], SkConic dst[4], const SkScalar weight) {
365 SkConic dstTemp[2];
366 int conicCnt = split_conic(src, dstTemp, weight);
367 if (2 == conicCnt) {
368 int conicCnt2 = split_conic(dstTemp[0].fPts, dst, dstTemp[0].fW);
369 conicCnt = conicCnt2 + split_conic(dstTemp[1].fPts, &dst[conicCnt2], dstTemp[1].fW);
370 } else {
371 dst[0] = dstTemp[0];
372 }
373 return conicCnt;
374 }
375
376 typedef GM INHERITED;
377};
378
379//////////////////////////////////////////////////////////////////////////////
380/**
381 * This GM directly exercises effects that draw Bezier quad curves in the GPU backend.
382 */
383class BezierQuadEffects : public GM {
384public:
385 BezierQuadEffects() {
386 this->setBGColor(0xFFFFFFFF);
387 }
388
389protected:
mtklein72c9faa2015-01-09 10:06:39 -0800390 SkString onShortName() SK_OVERRIDE {
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000391 return SkString("bezier_quad_effects");
392 }
393
mtklein72c9faa2015-01-09 10:06:39 -0800394 SkISize onISize() SK_OVERRIDE {
tfarinaf5393182014-06-09 23:59:03 -0700395 return SkISize::Make(800, 800);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000396 }
397
mtklein72c9faa2015-01-09 10:06:39 -0800398 uint32_t onGetFlags() const SK_OVERRIDE {
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000399 // This is a GPU-specific GM.
400 return kGPUOnly_Flag;
401 }
402
403
mtklein72c9faa2015-01-09 10:06:39 -0800404 void onDraw(SkCanvas* canvas) SK_OVERRIDE {
reed@google.com9c135db2014-03-12 18:28:35 +0000405 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000406 if (NULL == rt) {
407 return;
408 }
409 GrContext* context = rt->getContext();
410 if (NULL == context) {
411 return;
412 }
413
414 struct Vertex {
415 SkPoint fPosition;
416 float fUV[4]; // The last two values are ignored. The effect expects a vec4f.
417 };
418
419 static const int kNumQuads = 5;
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000420 SkRandom rand;
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000421
422 int numCols = SkScalarCeilToInt(SkScalarSqrt(SkIntToScalar(kNumQuads*3)));
423 int numRows = SkScalarCeilToInt(SkIntToScalar(kNumQuads*3) / numCols);
424 SkScalar w = SkIntToScalar(rt->width()) / numCols;
425 SkScalar h = SkIntToScalar(rt->height()) / numRows;
426 int row = 0;
427 int col = 0;
428
429 for (int i = 0; i < kNumQuads; ++i) {
430 SkPoint baseControlPts[] = {
431 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
432 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
433 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}
434 };
joshualittb0a8a372014-09-23 09:50:21 -0700435 for(int edgeType = 0; edgeType < kGrProcessorEdgeTypeCnt; ++edgeType) {
436 SkAutoTUnref<GrGeometryProcessor> gp;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000437 { // scope to contain GrTestTarget
438 GrTestTarget tt;
439 context->getTestTarget(&tt);
440 if (NULL == tt.target()) {
441 continue;
442 }
joshualittb0a8a372014-09-23 09:50:21 -0700443 GrPrimitiveEdgeType et = (GrPrimitiveEdgeType)edgeType;
joshualitt8059eb92014-12-29 15:10:07 -0800444 gp.reset(GrQuadEffect::Create(0xff000000, SkMatrix::I(), et,
445 *tt.target()->caps(), SkMatrix::I()));
joshualittb0a8a372014-09-23 09:50:21 -0700446 if (!gp) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000447 continue;
448 }
449 }
450
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000451 SkScalar x = SkScalarMul(col, w);
452 SkScalar y = SkScalarMul(row, h);
453 SkPoint controlPts[] = {
454 {x + baseControlPts[0].fX, y + baseControlPts[0].fY},
455 {x + baseControlPts[1].fX, y + baseControlPts[1].fY},
456 {x + baseControlPts[2].fX, y + baseControlPts[2].fY}
457 };
458 SkPoint chopped[5];
459 int cnt = SkChopQuadAtMaxCurvature(controlPts, chopped);
460
461 SkPaint ctrlPtPaint;
462 ctrlPtPaint.setColor(rand.nextU() | 0xFF000000);
463 for (int i = 0; i < 3; ++i) {
464 canvas->drawCircle(controlPts[i].fX, controlPts[i].fY, 6.f, ctrlPtPaint);
465 }
466
467 SkPaint polyPaint;
468 polyPaint.setColor(0xffA0A0A0);
469 polyPaint.setStrokeWidth(0);
470 polyPaint.setStyle(SkPaint::kStroke_Style);
471 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, controlPts, polyPaint);
472
473 SkPaint choppedPtPaint;
474 choppedPtPaint.setColor(~ctrlPtPaint.getColor() | 0xFF000000);
475
476 for (int c = 0; c < cnt; ++c) {
477 SkPoint* pts = chopped + 2 * c;
478
479 for (int i = 0; i < 3; ++i) {
480 canvas->drawCircle(pts[i].fX, pts[i].fY, 3.f, choppedPtPaint);
481 }
482
483 SkRect bounds;
484 bounds.set(pts, 3);
485
486 SkPaint boundsPaint;
487 boundsPaint.setColor(0xff808080);
488 boundsPaint.setStrokeWidth(0);
489 boundsPaint.setStyle(SkPaint::kStroke_Style);
490 canvas->drawRect(bounds, boundsPaint);
491
joshualitt50408ad2014-11-03 12:31:14 -0800492 GrTestTarget tt;
493 context->getTestTarget(&tt);
494 SkASSERT(tt.target());
495
joshualitt9853cce2014-11-17 14:22:48 -0800496 GrDrawState ds;
joshualitt50408ad2014-11-03 12:31:14 -0800497
joshualitt2dd1ae02014-12-03 06:24:10 -0800498 GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, gp->getVertexStride(), 0);
499 SkASSERT(gp->getVertexStride() == sizeof(Vertex));
joshualitt50408ad2014-11-03 12:31:14 -0800500 Vertex* verts = reinterpret_cast<Vertex*>(geo.vertices());
501
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000502 verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
503 bounds.fRight, bounds.fBottom,
504 sizeof(Vertex));
505
506 GrPathUtils::QuadUVMatrix DevToUV(pts);
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000507 DevToUV.apply<4, sizeof(Vertex), sizeof(SkPoint)>(verts);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000508
joshualitt9853cce2014-11-17 14:22:48 -0800509 ds.setRenderTarget(rt);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000510
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000511 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
joshualitt56995b52014-12-11 15:44:02 -0800512 tt.target()->drawIndexed(&ds, gp, kTriangles_GrPrimitiveType, 0, 0, 4, 6);
commit-bot@chromium.org53a0b6c2013-08-23 18:05:01 +0000513 }
514 ++col;
515 if (numCols == col) {
516 col = 0;
517 ++row;
518 }
519 }
520 }
521 }
522
523private:
524 typedef GM INHERITED;
525};
526
527DEF_GM( return SkNEW(BezierCubicEffects); )
528DEF_GM( return SkNEW(BezierConicEffects); )
529DEF_GM( return SkNEW(BezierQuadEffects); )
commit-bot@chromium.org78a10782013-08-21 19:27:48 +0000530
531}
532
533#endif