Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(169)

Side by Side Diff: gm/beziereffects.cpp

Issue 23361024: Add GMs for gpu Bezier shaders (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/gpu/effects/GrBezierEffect.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2013 Google Inc. 3 * Copyright 2013 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 // This test only works with the GPU backend. 9 // This test only works with the GPU backend.
10 10
11 #include "gm.h" 11 #include "gm.h"
12 12
13 #if SK_SUPPORT_GPU && 0 // Can be enabled when cubic effect is checked in. 13 #if SK_SUPPORT_GPU && 1 // Can be enabled when cubic effect is checked in.
bsalomon 2013/08/23 17:21:12 Let's just remove the everything on this line afte
14 14
15 #include "GrContext.h" 15 #include "GrContext.h"
16 #include "GrPathUtils.h" 16 #include "GrPathUtils.h"
17 #include "GrTest.h" 17 #include "GrTest.h"
18 #include "SkColorPriv.h" 18 #include "SkColorPriv.h"
19 #include "SkDevice.h" 19 #include "SkDevice.h"
20 #include "SkGeometry.h"
21
22 #include "effects/GrBezierEffect.h"
20 23
21 // Position & KLM line eq values. These are the vertex attributes for Bezier cur ves. The last value 24 // Position & KLM line eq values. These are the vertex attributes for Bezier cur ves. The last value
22 // of the Vec4f is ignored. 25 // of the Vec4f is ignored.
23 extern const GrVertexAttrib kAttribs[] = { 26 extern const GrVertexAttrib kAttribs[] = {
24 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, 27 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
25 {kVec4f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding} 28 {kVec4f_GrVertexAttribType, sizeof(GrPoint), kEffect_GrVertexAttribBinding}
26 }; 29 };
27 30
28 static inline SkScalar eval_line(const SkPoint& p, const SkScalar lineEq[3], SkS calar sign) { 31 static inline SkScalar eval_line(const SkPoint& p, const SkScalar lineEq[3], SkS calar sign) {
29 return sign * (lineEq[0] * p.fX + lineEq[1] * p.fY + lineEq[2]); 32 return sign * (lineEq[0] * p.fX + lineEq[1] * p.fY + lineEq[2]);
30 } 33 }
31 34
32 namespace skiagm { 35 namespace skiagm {
33 /** 36 /**
34 * This GM directly exercises effects that draw Bezier curves in the GPU backend . 37 * This GM directly exercises effects that draw Bezier curves in the GPU backend .
35 */ 38 */
36 class BezierEffects : public GM { 39 class BezierCubicEffects : public GM {
37 public: 40 public:
38 BezierEffects() { 41 BezierCubicEffects() {
39 this->setBGColor(0xFFFFFFFF); 42 this->setBGColor(0xFFFFFFFF);
40 } 43 }
41 44
42 protected: 45 protected:
43 virtual SkString onShortName() SK_OVERRIDE { 46 virtual SkString onShortName() SK_OVERRIDE {
44 return SkString("bezier_effects"); 47 return SkString("bezier_cubic_effects");
45 } 48 }
46 49
47 virtual SkISize onISize() SK_OVERRIDE { 50 virtual SkISize onISize() SK_OVERRIDE {
48 return make_isize(800, 800); 51 return make_isize(800, 800);
49 } 52 }
50 53
51 virtual uint32_t onGetFlags() const SK_OVERRIDE { 54 virtual uint32_t onGetFlags() const SK_OVERRIDE {
52 // This is a GPU-specific GM. 55 // This is a GPU-specific GM.
53 return kGPUOnly_Flag; 56 return kGPUOnly_Flag;
54 } 57 }
55 58
56 59
57 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { 60 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
58 SkDevice* device = canvas->getTopDevice(); 61 SkDevice* device = canvas->getTopDevice();
59 GrRenderTarget* rt = device->accessRenderTarget(); 62 GrRenderTarget* rt = device->accessRenderTarget();
60 if (NULL == rt) { 63 if (NULL == rt) {
61 return; 64 return;
62 } 65 }
63 GrContext* context = rt->getContext(); 66 GrContext* context = rt->getContext();
64 if (NULL == context) { 67 if (NULL == context) {
65 return; 68 return;
66 } 69 }
67 70
68 struct Vertex { 71 struct Vertex {
69 SkPoint fPosition; 72 SkPoint fPosition;
70 float fKLM[4]; // The last value is ignored. The effect expects a vec4f. 73 float fKLM[4]; // The last value is ignored. The effect expects a vec4f.
71 }; 74 };
72 75
73 static const int kNumCubics = 10; 76 static const int kNumCubics = 15;
74 SkMWCRandom rand; 77 SkMWCRandom rand;
75 78
76 int numCols = SkScalarCeilToInt(SkScalarSqrt(SkIntToScalar(kNumCubics))) ; 79 // Mult by 3 for each edge effect type
77 int numRows = SkScalarCeilToInt(SkIntToScalar(kNumCubics) / numCols); 80 int numCols = SkScalarCeilToInt(SkScalarSqrt(SkIntToScalar(kNumCubics*3) ));
81 int numRows = SkScalarCeilToInt(SkIntToScalar(kNumCubics*3) / numCols);
78 SkScalar w = SkIntToScalar(rt->width()) / numCols; 82 SkScalar w = SkIntToScalar(rt->width()) / numCols;
79 SkScalar h = SkIntToScalar(rt->height()) / numRows; 83 SkScalar h = SkIntToScalar(rt->height()) / numRows;
80 int row = 0; 84 int row = 0;
81 int col = 0; 85 int col = 0;
82 86
83 for (int i = 0; i < kNumCubics; ++i) { 87 for (int i = 0; i < kNumCubics; ++i) {
84 SkScalar x = SkScalarMul(col, w); 88 SkPoint baseControlPts[] = {
85 SkScalar y = SkScalarMul(row, h); 89 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
86 SkPoint controlPts[] = { 90 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
87 {x + rand.nextRangeF(0, w), y + rand.nextRangeF(0, h)}, 91 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
88 {x + rand.nextRangeF(0, w), y + rand.nextRangeF(0, h)}, 92 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}
89 {x + rand.nextRangeF(0, w), y + rand.nextRangeF(0, h)},
90 {x + rand.nextRangeF(0, w), y + rand.nextRangeF(0, h)}
91 }; 93 };
92 SkPoint chopped[10]; 94 for(int edgeType = kFillAA_GrBezierEdgeType; edgeType < 3; ++edgeTyp e) {
93 SkScalar klmEqs[9]; 95 SkScalar x = SkScalarMul(col, w);
94 SkScalar klmSigns[3]; 96 SkScalar y = SkScalarMul(row, h);
95 int cnt = GrPathUtils::chopCubicAtLoopIntersection(controlPts, 97 SkPoint controlPts[] = {
96 chopped, 98 {x + baseControlPts[0].fX, y + baseControlPts[0].fY},
97 klmEqs, 99 {x + baseControlPts[1].fX, y + baseControlPts[1].fY},
98 klmSigns, 100 {x + baseControlPts[2].fX, y + baseControlPts[2].fY},
99 controlPts); 101 {x + baseControlPts[3].fX, y + baseControlPts[3].fY}
100 102 };
101 SkPaint ctrlPtPaint; 103 SkPoint chopped[10];
102 ctrlPtPaint.setColor(rand.nextU() | 0xFF000000); 104 SkScalar klmEqs[9];
103 for (int i = 0; i < 4; ++i) { 105 SkScalar klmSigns[3];
104 canvas->drawCircle(controlPts[i].fX, controlPts[i].fY, 6.f, ctrl PtPaint); 106 int cnt = GrPathUtils::chopCubicAtLoopIntersection(controlPts,
105 } 107 chopped,
106 108 klmEqs,
107 SkPaint polyPaint; 109 klmSigns);
108 polyPaint.setColor(0xffA0A0A0); 110
109 polyPaint.setStrokeWidth(0); 111 SkPaint ctrlPtPaint;
110 polyPaint.setStyle(SkPaint::kStroke_Style); 112 ctrlPtPaint.setColor(rand.nextU() | 0xFF000000);
111 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, controlPts, poly Paint);
112
113 SkPaint choppedPtPaint;
114 choppedPtPaint.setColor(~ctrlPtPaint.getColor() | 0xFF000000);
115
116 for (int c = 0; c < cnt; ++c) {
117 SkPoint* pts = chopped + 3 * c;
118
119 for (int i = 0; i < 4; ++i) { 113 for (int i = 0; i < 4; ++i) {
120 canvas->drawCircle(pts[i].fX, pts[i].fY, 3.f, choppedPtPaint ); 114 canvas->drawCircle(controlPts[i].fX, controlPts[i].fY, 6.f, ctrlPtPaint);
121 } 115 }
122 116
123 SkRect bounds; 117 SkPaint polyPaint;
124 bounds.set(pts, 4); 118 polyPaint.setColor(0xffA0A0A0);
125 119 polyPaint.setStrokeWidth(0);
126 SkPaint boundsPaint; 120 polyPaint.setStyle(SkPaint::kStroke_Style);
127 boundsPaint.setColor(0xff808080); 121 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, controlPts, polyPaint);
128 boundsPaint.setStrokeWidth(0); 122
129 boundsPaint.setStyle(SkPaint::kStroke_Style); 123 SkPaint choppedPtPaint;
130 canvas->drawRect(bounds, boundsPaint); 124 choppedPtPaint.setColor(~ctrlPtPaint.getColor() | 0xFF000000);
131 125
132 Vertex verts[4]; 126 for (int c = 0; c < cnt; ++c) {
133 verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop, 127 SkPoint* pts = chopped + 3 * c;
134 bounds.fRight, bounds.fBottom, 128
135 sizeof(Vertex)); 129 for (int i = 0; i < 4; ++i) {
136 for (int v = 0; v < 4; ++v) { 130 canvas->drawCircle(pts[i].fX, pts[i].fY, 3.f, choppedPtP aint);
137 verts[v].fKLM[0] = eval_line(verts[v].fPosition, klmEqs + 0, klmSigns[c]); 131 }
138 verts[v].fKLM[1] = eval_line(verts[v].fPosition, klmEqs + 3, klmSigns[c]); 132
139 verts[v].fKLM[2] = eval_line(verts[v].fPosition, klmEqs + 6, 1.f); 133 SkRect bounds;
140 } 134 bounds.set(pts, 4);
141 135
142 GrTestTarget tt; 136 SkPaint boundsPaint;
143 context->getTestTarget(&tt); 137 boundsPaint.setColor(0xff808080);
144 if (NULL == tt.target()) { 138 boundsPaint.setStrokeWidth(0);
145 continue; 139 boundsPaint.setStyle(SkPaint::kStroke_Style);
146 } 140 canvas->drawRect(bounds, boundsPaint);
147 GrDrawState* drawState = tt.target()->drawState(); 141
148 drawState->setVertexAttribs<kAttribs>(2); 142 Vertex verts[4];
149 SkAutoTUnref<GrEffectRef> effect(HairCubicEdgeEffect::Create()); 143 verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
150 if (!effect) { 144 bounds.fRight, bounds.fBottom,
151 continue; 145 sizeof(Vertex));
152 } 146 for (int v = 0; v < 4; ++v) {
153 drawState->addCoverageEffect(effect, 1); 147 verts[v].fKLM[0] = eval_line(verts[v].fPosition, klmEqs + 0, klmSigns[c]);
154 drawState->setRenderTarget(rt); 148 verts[v].fKLM[1] = eval_line(verts[v].fPosition, klmEqs + 3, klmSigns[c]);
155 drawState->setColor(0xff000000); 149 verts[v].fKLM[2] = eval_line(verts[v].fPosition, klmEqs + 6, 1.f);
156 150 }
157 tt.target()->setVertexSourceToArray(verts, 4); 151
158 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer( )); 152 GrTestTarget tt;
159 tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6); 153 context->getTestTarget(&tt);
160 } 154 if (NULL == tt.target()) {
161 ++col; 155 continue;
162 if (numCols == col) { 156 }
163 col = 0; 157 GrDrawState* drawState = tt.target()->drawState();
164 ++row; 158 drawState->setVertexAttribs<kAttribs>(2);
159
160 SkAutoTUnref<GrEffectRef> effect(GrCubicEffect::Create(
161 GrBezierEdgeType(edgeType), *tt.target()->caps()));
162 if (!effect) {
163 continue;
164 }
165 drawState->addCoverageEffect(effect, 1);
166 drawState->setRenderTarget(rt);
167 drawState->setColor(0xff000000);
168
169 tt.target()->setVertexSourceToArray(verts, 4);
170 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuf fer());
171 tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
172 }
173 ++col;
174 if (numCols == col) {
175 col = 0;
176 ++row;
177 }
165 } 178 }
166 } 179 }
167 } 180 }
168 181
169 private: 182 private:
170 typedef GM INHERITED; 183 typedef GM INHERITED;
171 }; 184 };
172 185
173 ////////////////////////////////////////////////////////////////////////////// 186 //////////////////////////////////////////////////////////////////////////////
174 187
175 DEF_GM( return SkNEW(BezierEffects); ) 188 /**
189 * This GM directly exercises effects that draw Bezier curves in the GPU backend .
190 */
191 class BezierConicEffects : public GM {
192 public:
193 BezierConicEffects() {
194 this->setBGColor(0xFFFFFFFF);
195 }
196
197 protected:
198 virtual SkString onShortName() SK_OVERRIDE {
199 return SkString("bezier_conic_effects");
200 }
201
202 virtual SkISize onISize() SK_OVERRIDE {
203 return make_isize(800, 800);
204 }
205
206 virtual uint32_t onGetFlags() const SK_OVERRIDE {
207 // This is a GPU-specific GM.
208 return kGPUOnly_Flag;
209 }
210
211
212 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
213 SkDevice* device = canvas->getTopDevice();
214 GrRenderTarget* rt = device->accessRenderTarget();
215 if (NULL == rt) {
216 return;
217 }
218 GrContext* context = rt->getContext();
219 if (NULL == context) {
220 return;
221 }
222
223 struct Vertex {
224 SkPoint fPosition;
225 float fKLM[4]; // The last value is ignored. The effect expects a vec4f.
226 };
227
228 static const int kNumConics = 10;
229 SkMWCRandom rand;
230
231 // Mult by 3 for each edge effect type
232 int numCols = SkScalarCeilToInt(SkScalarSqrt(SkIntToScalar(kNumConics*3) ));
233 int numRows = SkScalarCeilToInt(SkIntToScalar(kNumConics*3) / numCols);
234 SkScalar w = SkIntToScalar(rt->width()) / numCols;
235 SkScalar h = SkIntToScalar(rt->height()) / numRows;
236 int row = 0;
237 int col = 0;
238
239 for (int i = 0; i < kNumConics; ++i) {
240 SkPoint baseControlPts[] = {
241 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
242 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
243 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}
244 };
245 SkScalar weight = rand.nextRangeF(0.f, 2.f);
246 for(int edgeType = kFillAA_GrBezierEdgeType; edgeType < 3; ++edgeTyp e) {
247 SkScalar x = SkScalarMul(col, w);
248 SkScalar y = SkScalarMul(row, h);
249 SkPoint controlPts[] = {
250 {x + baseControlPts[0].fX, y + baseControlPts[0].fY},
251 {x + baseControlPts[1].fX, y + baseControlPts[1].fY},
252 {x + baseControlPts[2].fX, y + baseControlPts[2].fY}
253 };
254 SkConic dst[4];
255 SkScalar klmEqs[9];
256 int cnt = chop_conic(controlPts, dst, weight);
257 GrPathUtils::getConicKLM(controlPts, weight, klmEqs);
258
259 SkPaint ctrlPtPaint;
260 ctrlPtPaint.setColor(rand.nextU() | 0xFF000000);
261 for (int i = 0; i < 3; ++i) {
262 canvas->drawCircle(controlPts[i].fX, controlPts[i].fY, 6.f, ctrlPtPaint);
263 }
264
265 SkPaint polyPaint;
266 polyPaint.setColor(0xffA0A0A0);
267 polyPaint.setStrokeWidth(0);
268 polyPaint.setStyle(SkPaint::kStroke_Style);
269 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, controlPts, polyPaint);
270
271 SkPaint choppedPtPaint;
272 choppedPtPaint.setColor(~ctrlPtPaint.getColor() | 0xFF000000);
273
274 for (int c = 0; c < cnt; ++c) {
275 SkPoint* pts = dst[c].fPts;
276 for (int i = 0; i < 3; ++i) {
277 canvas->drawCircle(pts[i].fX, pts[i].fY, 3.f, choppedPtP aint);
278 }
279
280 SkRect bounds;
281 //SkPoint bPts[] = {{0.f, 0.f}, {800.f, 800.f}};
282 //bounds.set(bPts, 2);
283 bounds.set(pts, 3);
284
285 SkPaint boundsPaint;
286 boundsPaint.setColor(0xff808080);
287 boundsPaint.setStrokeWidth(0);
288 boundsPaint.setStyle(SkPaint::kStroke_Style);
289 canvas->drawRect(bounds, boundsPaint);
290
291 Vertex verts[4];
292 verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
293 bounds.fRight, bounds.fBottom,
294 sizeof(Vertex));
295 for (int v = 0; v < 4; ++v) {
296 verts[v].fKLM[0] = eval_line(verts[v].fPosition, klmEqs + 0, 1.f);
297 verts[v].fKLM[1] = eval_line(verts[v].fPosition, klmEqs + 3, 1.f);
298 verts[v].fKLM[2] = eval_line(verts[v].fPosition, klmEqs + 6, 1.f);
299 }
300
301 GrTestTarget tt;
302 context->getTestTarget(&tt);
303 if (NULL == tt.target()) {
304 continue;
305 }
306 GrDrawState* drawState = tt.target()->drawState();
307 drawState->setVertexAttribs<kAttribs>(2);
308
309 SkAutoTUnref<GrEffectRef> effect(GrConicEffect::Create(
310 GrBezierEdgeType(edgeType), *tt.target()->caps()));
311 if (!effect) {
312 continue;
313 }
314 drawState->addCoverageEffect(effect, 1);
315 drawState->setRenderTarget(rt);
316 drawState->setColor(0xff000000);
317
318 tt.target()->setVertexSourceToArray(verts, 4);
319 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuf fer());
320 tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
321 }
322 ++col;
323 if (numCols == col) {
324 col = 0;
325 ++row;
326 }
327 }
328 }
329 }
330
331 private:
332 // Uses the max curvature function for quads to estimate
333 // where to chop the conic. If the max curvature is not
334 // found along the curve segment it will return 1 and
335 // dst[0] is the original conic. If it returns 2 the dst[0]
336 // and dst[1] are the two new conics.
337 int split_conic(const SkPoint src[3], SkConic dst[2], const SkScalar weight) {
338 SkScalar t = SkFindQuadMaxCurvature(src);
339 if (t == 0) {
340 if (dst) {
341 dst[0].set(src, weight);
342 }
343 return 1;
344 } else {
345 if (dst) {
346 SkConic conic;
347 conic.set(src, weight);
348 conic.chopAt(t, dst);
349 }
350 return 2;
351 }
352 }
353
354 // Calls split_conic on the entire conic and then once more on each subsecti on.
355 // Most cases will result in either 1 conic (chop point is not within t rang e)
356 // or 3 points (split once and then one subsection is split again).
357 int chop_conic(const SkPoint src[3], SkConic dst[4], const SkScalar weight) {
358 SkConic dstTemp[2];
359 int conicCnt = split_conic(src, dstTemp, weight);
360 if (2 == conicCnt) {
361 int conicCnt2 = split_conic(dstTemp[0].fPts, dst, dstTemp[0].fW);
362 conicCnt = conicCnt2 + split_conic(dstTemp[1].fPts, &dst[conicCnt2], dstTemp[1].fW);
363 } else {
364 dst[0] = dstTemp[0];
365 }
366 return conicCnt;
367 }
368
369 typedef GM INHERITED;
370 };
371
372 //////////////////////////////////////////////////////////////////////////////
373 /**
374 * This GM directly exercises effects that draw Bezier quad curves in the GPU ba ckend.
375 */
376 class BezierQuadEffects : public GM {
377 public:
378 BezierQuadEffects() {
379 this->setBGColor(0xFFFFFFFF);
380 }
381
382 protected:
383 virtual SkString onShortName() SK_OVERRIDE {
384 return SkString("bezier_quad_effects");
385 }
386
387 virtual SkISize onISize() SK_OVERRIDE {
388 return make_isize(800, 800);
389 }
390
391 virtual uint32_t onGetFlags() const SK_OVERRIDE {
392 // This is a GPU-specific GM.
393 return kGPUOnly_Flag;
394 }
395
396
397 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
398 SkDevice* device = canvas->getTopDevice();
399 GrRenderTarget* rt = device->accessRenderTarget();
400 if (NULL == rt) {
401 return;
402 }
403 GrContext* context = rt->getContext();
404 if (NULL == context) {
405 return;
406 }
407
408 struct Vertex {
409 SkPoint fPosition;
410 float fUV[4]; // The last two values are ignored. The effect expec ts a vec4f.
411 };
412
413 static const int kNumQuads = 5;
414 SkMWCRandom rand;
415
416 int numCols = SkScalarCeilToInt(SkScalarSqrt(SkIntToScalar(kNumQuads*3)) );
417 int numRows = SkScalarCeilToInt(SkIntToScalar(kNumQuads*3) / numCols);
418 SkScalar w = SkIntToScalar(rt->width()) / numCols;
419 SkScalar h = SkIntToScalar(rt->height()) / numRows;
420 int row = 0;
421 int col = 0;
422
423 for (int i = 0; i < kNumQuads; ++i) {
424 SkPoint baseControlPts[] = {
425 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
426 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)},
427 {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}
428 };
429 for(int edgeType = kFillAA_GrBezierEdgeType; edgeType < 3; ++edgeTyp e) {
430 SkScalar x = SkScalarMul(col, w);
431 SkScalar y = SkScalarMul(row, h);
432 SkPoint controlPts[] = {
433 {x + baseControlPts[0].fX, y + baseControlPts[0].fY},
434 {x + baseControlPts[1].fX, y + baseControlPts[1].fY},
435 {x + baseControlPts[2].fX, y + baseControlPts[2].fY}
436 };
437 SkPoint chopped[5];
438 int cnt = SkChopQuadAtMaxCurvature(controlPts, chopped);
439
440 SkPaint ctrlPtPaint;
441 ctrlPtPaint.setColor(rand.nextU() | 0xFF000000);
442 for (int i = 0; i < 3; ++i) {
443 canvas->drawCircle(controlPts[i].fX, controlPts[i].fY, 6.f, ctrlPtPaint);
444 }
445
446 SkPaint polyPaint;
447 polyPaint.setColor(0xffA0A0A0);
448 polyPaint.setStrokeWidth(0);
449 polyPaint.setStyle(SkPaint::kStroke_Style);
450 canvas->drawPoints(SkCanvas::kPolygon_PointMode, 3, controlPts, polyPaint);
451
452 SkPaint choppedPtPaint;
453 choppedPtPaint.setColor(~ctrlPtPaint.getColor() | 0xFF000000);
454
455 for (int c = 0; c < cnt; ++c) {
456 SkPoint* pts = chopped + 2 * c;
457
458 for (int i = 0; i < 3; ++i) {
459 canvas->drawCircle(pts[i].fX, pts[i].fY, 3.f, choppedPtP aint);
460 }
461
462 SkRect bounds;
463 bounds.set(pts, 3);
464
465 SkPaint boundsPaint;
466 boundsPaint.setColor(0xff808080);
467 boundsPaint.setStrokeWidth(0);
468 boundsPaint.setStyle(SkPaint::kStroke_Style);
469 canvas->drawRect(bounds, boundsPaint);
470
471 Vertex verts[4];
472 verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
473 bounds.fRight, bounds.fBottom,
474 sizeof(Vertex));
475
476 GrPathUtils::QuadUVMatrix DevToUV(pts);
477 DevToUV.apply<4, sizeof(Vertex), sizeof(GrPoint)>(verts);
478
479 GrTestTarget tt;
480 context->getTestTarget(&tt);
481 if (NULL == tt.target()) {
482 continue;
483 }
484 GrDrawState* drawState = tt.target()->drawState();
485 drawState->setVertexAttribs<kAttribs>(2);
486 SkAutoTUnref<GrEffectRef> effect(GrQuadEffect::Create(
487 GrBezierEdgeType(edgeType), *tt.target()->caps()));
488 if (!effect) {
489 continue;
490 }
491 drawState->addCoverageEffect(effect, 1);
492 drawState->setRenderTarget(rt);
493 drawState->setColor(0xff000000);
494
495 tt.target()->setVertexSourceToArray(verts, 4);
496 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuf fer());
497 tt.target()->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 4 , 6);
498 }
499 ++col;
500 if (numCols == col) {
501 col = 0;
502 ++row;
503 }
504 }
505 }
506 }
507
508 private:
509 typedef GM INHERITED;
510 };
511
512 DEF_GM( return SkNEW(BezierCubicEffects); )
513 DEF_GM( return SkNEW(BezierConicEffects); )
514 DEF_GM( return SkNEW(BezierQuadEffects); )
176 515
177 } 516 }
178 517
179 #endif 518 #endif
OLDNEW
« no previous file with comments | « no previous file | src/gpu/effects/GrBezierEffect.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698