OLD | NEW |
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 | 13 #if SK_SUPPORT_GPU |
14 | 14 |
15 #include "GrBatchTarget.h" | |
16 #include "GrBufferAllocPool.h" | |
17 #include "GrContext.h" | 15 #include "GrContext.h" |
18 #include "GrPathUtils.h" | 16 #include "GrPathUtils.h" |
19 #include "GrTest.h" | 17 #include "GrTest.h" |
20 #include "GrTestBatch.h" | |
21 #include "SkColorPriv.h" | 18 #include "SkColorPriv.h" |
22 #include "SkDevice.h" | 19 #include "SkDevice.h" |
23 #include "SkGeometry.h" | 20 #include "SkGeometry.h" |
24 | 21 |
25 #include "effects/GrBezierEffect.h" | 22 #include "effects/GrBezierEffect.h" |
26 | 23 |
27 static inline SkScalar eval_line(const SkPoint& p, const SkScalar lineEq[3], SkS
calar sign) { | 24 static inline SkScalar eval_line(const SkPoint& p, const SkScalar lineEq[3], SkS
calar sign) { |
28 return sign * (lineEq[0] * p.fX + lineEq[1] * p.fY + lineEq[2]); | 25 return sign * (lineEq[0] * p.fX + lineEq[1] * p.fY + lineEq[2]); |
29 } | 26 } |
30 | 27 |
31 namespace skiagm { | 28 namespace skiagm { |
32 | |
33 class BezierCubicOrConicTestBatch : public GrTestBatch { | |
34 public: | |
35 struct Geometry : public GrTestBatch::Geometry { | |
36 SkRect fBounds; | |
37 }; | |
38 | |
39 const char* name() const SK_OVERRIDE { return "BezierCubicOrConicTestBatch";
} | |
40 | |
41 static GrBatch* Create(const GrGeometryProcessor* gp, const Geometry& geo, | |
42 const SkScalar klmEqs[9], SkScalar sign) { | |
43 return SkNEW_ARGS(BezierCubicOrConicTestBatch, (gp, geo, klmEqs, sign)); | |
44 } | |
45 | |
46 private: | |
47 BezierCubicOrConicTestBatch(const GrGeometryProcessor* gp, const Geometry& g
eo, | |
48 const SkScalar klmEqs[9], SkScalar sign) | |
49 : INHERITED(gp) { | |
50 for (int i = 0; i < 9; i++) { | |
51 fKlmEqs[i] = klmEqs[i]; | |
52 } | |
53 | |
54 fGeometry = geo; | |
55 fSign = sign; | |
56 } | |
57 | |
58 struct Vertex { | |
59 SkPoint fPosition; | |
60 float fKLM[4]; // The last value is ignored. The effect expects a vec4
f. | |
61 }; | |
62 | |
63 Geometry* geoData(int index) SK_OVERRIDE { | |
64 SkASSERT(0 == index); | |
65 return &fGeometry; | |
66 } | |
67 | |
68 void onGenerateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeli
ne) SK_OVERRIDE { | |
69 size_t vertexStride = this->geometryProcessor()->getVertexStride(); | |
70 | |
71 const GrVertexBuffer* vertexBuffer; | |
72 int firstVertex; | |
73 | |
74 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, | |
75 kVertsPerCubic, | |
76 &vertexBuffer, | |
77 &firstVertex); | |
78 | |
79 SkASSERT(vertexStride == sizeof(Vertex)); | |
80 Vertex* verts = reinterpret_cast<Vertex*>(vertices); | |
81 | |
82 verts[0].fPosition.setRectFan(fGeometry.fBounds.fLeft, fGeometry.fBounds
.fTop, | |
83 fGeometry.fBounds.fRight, fGeometry.fBound
s.fBottom, | |
84 sizeof(Vertex)); | |
85 for (int v = 0; v < 4; ++v) { | |
86 verts[v].fKLM[0] = eval_line(verts[v].fPosition, fKlmEqs + 0, fSign)
; | |
87 verts[v].fKLM[1] = eval_line(verts[v].fPosition, fKlmEqs + 3, fSign)
; | |
88 verts[v].fKLM[2] = eval_line(verts[v].fPosition, fKlmEqs + 6, 1.f); | |
89 } | |
90 | |
91 GrDrawTarget::DrawInfo drawInfo; | |
92 drawInfo.setPrimitiveType(kTriangleFan_GrPrimitiveType); | |
93 drawInfo.setVertexBuffer(vertexBuffer); | |
94 drawInfo.setStartVertex(firstVertex); | |
95 drawInfo.setVertexCount(kVertsPerCubic); | |
96 drawInfo.setStartIndex(0); | |
97 drawInfo.setIndexCount(kIndicesPerCubic); | |
98 drawInfo.setIndexBuffer(batchTarget->quadIndexBuffer()); | |
99 batchTarget->draw(drawInfo); | |
100 } | |
101 | |
102 Geometry fGeometry; | |
103 SkScalar fKlmEqs[9]; | |
104 SkScalar fSign; | |
105 | |
106 static const int kVertsPerCubic = 4; | |
107 static const int kIndicesPerCubic = 6; | |
108 | |
109 typedef GrTestBatch INHERITED; | |
110 }; | |
111 | |
112 /** | 29 /** |
113 * This GM directly exercises effects that draw Bezier curves in the GPU backend
. | 30 * This GM directly exercises effects that draw Bezier curves in the GPU backend
. |
114 */ | 31 */ |
115 class BezierCubicEffects : public GM { | 32 class BezierCubicEffects : public GM { |
116 public: | 33 public: |
117 BezierCubicEffects() { | 34 BezierCubicEffects() { |
118 this->setBGColor(0xFFFFFFFF); | 35 this->setBGColor(0xFFFFFFFF); |
119 } | 36 } |
120 | 37 |
121 protected: | 38 protected: |
122 SkString onShortName() SK_OVERRIDE { | 39 SkString onShortName() SK_OVERRIDE { |
123 return SkString("bezier_cubic_effects"); | 40 return SkString("bezier_cubic_effects"); |
124 } | 41 } |
125 | 42 |
126 SkISize onISize() SK_OVERRIDE { | 43 SkISize onISize() SK_OVERRIDE { |
127 return SkISize::Make(800, 800); | 44 return SkISize::Make(800, 800); |
128 } | 45 } |
129 | 46 |
| 47 |
130 void onDraw(SkCanvas* canvas) SK_OVERRIDE { | 48 void onDraw(SkCanvas* canvas) SK_OVERRIDE { |
131 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget
(); | 49 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget
(); |
132 if (NULL == rt) { | 50 if (NULL == rt) { |
133 this->drawGpuOnlyMessage(canvas); | 51 this->drawGpuOnlyMessage(canvas); |
134 return; | 52 return; |
135 } | 53 } |
136 GrContext* context = rt->getContext(); | 54 GrContext* context = rt->getContext(); |
137 if (NULL == context) { | 55 if (NULL == context) { |
138 return; | 56 return; |
139 } | 57 } |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 boundsPaint.setColor(0xff808080); | 140 boundsPaint.setColor(0xff808080); |
223 boundsPaint.setStrokeWidth(0); | 141 boundsPaint.setStrokeWidth(0); |
224 boundsPaint.setStyle(SkPaint::kStroke_Style); | 142 boundsPaint.setStyle(SkPaint::kStroke_Style); |
225 canvas->drawRect(bounds, boundsPaint); | 143 canvas->drawRect(bounds, boundsPaint); |
226 | 144 |
227 GrTestTarget tt; | 145 GrTestTarget tt; |
228 context->getTestTarget(&tt); | 146 context->getTestTarget(&tt); |
229 SkASSERT(tt.target()); | 147 SkASSERT(tt.target()); |
230 | 148 |
231 GrPipelineBuilder pipelineBuilder; | 149 GrPipelineBuilder pipelineBuilder; |
| 150 |
| 151 GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, gp->ge
tVertexStride(), 0); |
| 152 SkASSERT(gp->getVertexStride() == sizeof(Vertex)); |
| 153 Vertex* verts = reinterpret_cast<Vertex*>(geo.vertices()); |
| 154 |
| 155 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 |
232 pipelineBuilder.setRenderTarget(rt); | 164 pipelineBuilder.setRenderTarget(rt); |
233 | 165 |
234 BezierCubicOrConicTestBatch::Geometry geometry; | 166 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuf
fer()); |
235 geometry.fColor = gp->color(); | 167 tt.target()->drawIndexed(&pipelineBuilder, gp, kTriangleFan_
GrPrimitiveType, |
236 geometry.fBounds = bounds; | 168 0, 0,4,6); |
237 | |
238 SkAutoTUnref<GrBatch> batch(BezierCubicOrConicTestBatch::Cre
ate(gp, geometry, klmEqs, | |
239 klm
Signs[c])); | |
240 | |
241 tt.target()->drawBatch(&pipelineBuilder, batch, NULL); | |
242 } | 169 } |
243 ++col; | 170 ++col; |
244 if (numCols == col) { | 171 if (numCols == col) { |
245 col = 0; | 172 col = 0; |
246 ++row; | 173 ++row; |
247 } | 174 } |
248 } | 175 } |
249 } | 176 } |
250 } | 177 } |
251 | 178 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 boundsPaint.setColor(0xff808080); | 293 boundsPaint.setColor(0xff808080); |
367 boundsPaint.setStrokeWidth(0); | 294 boundsPaint.setStrokeWidth(0); |
368 boundsPaint.setStyle(SkPaint::kStroke_Style); | 295 boundsPaint.setStyle(SkPaint::kStroke_Style); |
369 canvas->drawRect(bounds, boundsPaint); | 296 canvas->drawRect(bounds, boundsPaint); |
370 | 297 |
371 GrTestTarget tt; | 298 GrTestTarget tt; |
372 context->getTestTarget(&tt); | 299 context->getTestTarget(&tt); |
373 SkASSERT(tt.target()); | 300 SkASSERT(tt.target()); |
374 | 301 |
375 GrPipelineBuilder pipelineBuilder; | 302 GrPipelineBuilder pipelineBuilder; |
| 303 |
| 304 GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, gp->ge
tVertexStride(), 0); |
| 305 SkASSERT(gp->getVertexStride() == sizeof(Vertex)); |
| 306 Vertex* verts = reinterpret_cast<Vertex*>(geo.vertices()); |
| 307 |
| 308 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 |
376 pipelineBuilder.setRenderTarget(rt); | 317 pipelineBuilder.setRenderTarget(rt); |
377 | 318 |
378 BezierCubicOrConicTestBatch::Geometry geometry; | 319 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuf
fer()); |
379 geometry.fColor = gp->color(); | 320 tt.target()->drawIndexed(&pipelineBuilder, gp, kTriangleFan_
GrPrimitiveType, |
380 geometry.fBounds = bounds; | 321 0, 0,4,6); |
381 | |
382 SkAutoTUnref<GrBatch> batch(BezierCubicOrConicTestBatch::Cre
ate(gp, geometry, klmEqs, | |
383 1.f
)); | |
384 | |
385 tt.target()->drawBatch(&pipelineBuilder, batch, NULL); | |
386 } | 322 } |
387 ++col; | 323 ++col; |
388 if (numCols == col) { | 324 if (numCols == col) { |
389 col = 0; | 325 col = 0; |
390 ++row; | 326 ++row; |
391 } | 327 } |
392 } | 328 } |
393 } | 329 } |
394 } | 330 } |
395 | 331 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 } else { | 364 } else { |
429 dst[0] = dstTemp[0]; | 365 dst[0] = dstTemp[0]; |
430 } | 366 } |
431 return conicCnt; | 367 return conicCnt; |
432 } | 368 } |
433 | 369 |
434 typedef GM INHERITED; | 370 typedef GM INHERITED; |
435 }; | 371 }; |
436 | 372 |
437 ////////////////////////////////////////////////////////////////////////////// | 373 ////////////////////////////////////////////////////////////////////////////// |
438 | |
439 class BezierQuadTestBatch : public GrTestBatch { | |
440 public: | |
441 struct Geometry : public GrTestBatch::Geometry { | |
442 SkRect fBounds; | |
443 }; | |
444 | |
445 const char* name() const SK_OVERRIDE { return "BezierQuadTestBatch"; } | |
446 | |
447 static GrBatch* Create(const GrGeometryProcessor* gp, const Geometry& geo, | |
448 const GrPathUtils::QuadUVMatrix& devToUV) { | |
449 return SkNEW_ARGS(BezierQuadTestBatch, (gp, geo, devToUV)); | |
450 } | |
451 | |
452 private: | |
453 BezierQuadTestBatch(const GrGeometryProcessor* gp, const Geometry& geo, | |
454 const GrPathUtils::QuadUVMatrix& devToUV) | |
455 : INHERITED(gp) | |
456 , fGeometry(geo) | |
457 , fDevToUV(devToUV) { | |
458 } | |
459 | |
460 struct Vertex { | |
461 SkPoint fPosition; | |
462 float fKLM[4]; // The last value is ignored. The effect expects a vec4
f. | |
463 }; | |
464 | |
465 Geometry* geoData(int index) SK_OVERRIDE { | |
466 SkASSERT(0 == index); | |
467 return &fGeometry; | |
468 } | |
469 | |
470 void onGenerateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeli
ne) SK_OVERRIDE { | |
471 size_t vertexStride = this->geometryProcessor()->getVertexStride(); | |
472 | |
473 const GrVertexBuffer* vertexBuffer; | |
474 int firstVertex; | |
475 | |
476 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, | |
477 kVertsPerCubic, | |
478 &vertexBuffer, | |
479 &firstVertex); | |
480 | |
481 SkASSERT(vertexStride == sizeof(Vertex)); | |
482 Vertex* verts = reinterpret_cast<Vertex*>(vertices); | |
483 | |
484 verts[0].fPosition.setRectFan(fGeometry.fBounds.fLeft, fGeometry.fBounds
.fTop, | |
485 fGeometry.fBounds.fRight, fGeometry.fBound
s.fBottom, | |
486 sizeof(Vertex)); | |
487 | |
488 fDevToUV.apply<4, sizeof(Vertex), sizeof(SkPoint)>(verts); | |
489 | |
490 | |
491 GrDrawTarget::DrawInfo drawInfo; | |
492 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); | |
493 drawInfo.setVertexBuffer(vertexBuffer); | |
494 drawInfo.setStartVertex(firstVertex); | |
495 drawInfo.setVertexCount(kVertsPerCubic); | |
496 drawInfo.setStartIndex(0); | |
497 drawInfo.setIndexCount(kIndicesPerCubic); | |
498 drawInfo.setIndexBuffer(batchTarget->quadIndexBuffer()); | |
499 batchTarget->draw(drawInfo); | |
500 } | |
501 | |
502 Geometry fGeometry; | |
503 GrPathUtils::QuadUVMatrix fDevToUV; | |
504 | |
505 static const int kVertsPerCubic = 4; | |
506 static const int kIndicesPerCubic = 6; | |
507 | |
508 typedef GrTestBatch INHERITED; | |
509 }; | |
510 | |
511 /** | 374 /** |
512 * This GM directly exercises effects that draw Bezier quad curves in the GPU ba
ckend. | 375 * This GM directly exercises effects that draw Bezier quad curves in the GPU ba
ckend. |
513 */ | 376 */ |
514 class BezierQuadEffects : public GM { | 377 class BezierQuadEffects : public GM { |
515 public: | 378 public: |
516 BezierQuadEffects() { | 379 BezierQuadEffects() { |
517 this->setBGColor(0xFFFFFFFF); | 380 this->setBGColor(0xFFFFFFFF); |
518 } | 381 } |
519 | 382 |
520 protected: | 383 protected: |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 boundsPaint.setColor(0xff808080); | 477 boundsPaint.setColor(0xff808080); |
615 boundsPaint.setStrokeWidth(0); | 478 boundsPaint.setStrokeWidth(0); |
616 boundsPaint.setStyle(SkPaint::kStroke_Style); | 479 boundsPaint.setStyle(SkPaint::kStroke_Style); |
617 canvas->drawRect(bounds, boundsPaint); | 480 canvas->drawRect(bounds, boundsPaint); |
618 | 481 |
619 GrTestTarget tt; | 482 GrTestTarget tt; |
620 context->getTestTarget(&tt); | 483 context->getTestTarget(&tt); |
621 SkASSERT(tt.target()); | 484 SkASSERT(tt.target()); |
622 | 485 |
623 GrPipelineBuilder pipelineBuilder; | 486 GrPipelineBuilder pipelineBuilder; |
| 487 |
| 488 GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, gp->ge
tVertexStride(), 0); |
| 489 SkASSERT(gp->getVertexStride() == sizeof(Vertex)); |
| 490 Vertex* verts = reinterpret_cast<Vertex*>(geo.vertices()); |
| 491 |
| 492 verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop, |
| 493 bounds.fRight, bounds.fBottom, |
| 494 sizeof(Vertex)); |
| 495 |
| 496 GrPathUtils::QuadUVMatrix DevToUV(pts); |
| 497 DevToUV.apply<4, sizeof(Vertex), sizeof(SkPoint)>(verts); |
| 498 |
624 pipelineBuilder.setRenderTarget(rt); | 499 pipelineBuilder.setRenderTarget(rt); |
625 | 500 |
626 GrPathUtils::QuadUVMatrix DevToUV(pts); | 501 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuf
fer()); |
627 | 502 tt.target()->drawIndexed(&pipelineBuilder, gp, kTriangles_Gr
PrimitiveType, |
628 BezierQuadTestBatch::Geometry geometry; | 503 0, 0, 4, 6); |
629 geometry.fColor = gp->color(); | |
630 geometry.fBounds = bounds; | |
631 | |
632 SkAutoTUnref<GrBatch> batch(BezierQuadTestBatch::Create(gp,
geometry, DevToUV)); | |
633 | |
634 tt.target()->drawBatch(&pipelineBuilder, batch, NULL); | |
635 } | 504 } |
636 ++col; | 505 ++col; |
637 if (numCols == col) { | 506 if (numCols == col) { |
638 col = 0; | 507 col = 0; |
639 ++row; | 508 ++row; |
640 } | 509 } |
641 } | 510 } |
642 } | 511 } |
643 } | 512 } |
644 | 513 |
645 private: | 514 private: |
646 typedef GM INHERITED; | 515 typedef GM INHERITED; |
647 }; | 516 }; |
648 | 517 |
649 DEF_GM( return SkNEW(BezierCubicEffects); ) | 518 DEF_GM( return SkNEW(BezierCubicEffects); ) |
650 DEF_GM( return SkNEW(BezierConicEffects); ) | 519 DEF_GM( return SkNEW(BezierConicEffects); ) |
651 DEF_GM( return SkNEW(BezierQuadEffects); ) | 520 DEF_GM( return SkNEW(BezierQuadEffects); ) |
652 | 521 |
653 } | 522 } |
654 | 523 |
655 #endif | 524 #endif |
OLD | NEW |