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" |
15 #include "GrContext.h" | 17 #include "GrContext.h" |
16 #include "GrPathUtils.h" | 18 #include "GrPathUtils.h" |
17 #include "GrTest.h" | 19 #include "GrTest.h" |
| 20 #include "GrTestBatch.h" |
18 #include "SkColorPriv.h" | 21 #include "SkColorPriv.h" |
19 #include "SkDevice.h" | 22 #include "SkDevice.h" |
20 #include "SkGeometry.h" | 23 #include "SkGeometry.h" |
21 | 24 |
22 #include "effects/GrBezierEffect.h" | 25 #include "effects/GrBezierEffect.h" |
23 | 26 |
24 static inline SkScalar eval_line(const SkPoint& p, const SkScalar lineEq[3], SkS
calar sign) { | 27 static inline SkScalar eval_line(const SkPoint& p, const SkScalar lineEq[3], SkS
calar sign) { |
25 return sign * (lineEq[0] * p.fX + lineEq[1] * p.fY + lineEq[2]); | 28 return sign * (lineEq[0] * p.fX + lineEq[1] * p.fY + lineEq[2]); |
26 } | 29 } |
27 | 30 |
28 namespace skiagm { | 31 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 |
29 /** | 112 /** |
30 * This GM directly exercises effects that draw Bezier curves in the GPU backend
. | 113 * This GM directly exercises effects that draw Bezier curves in the GPU backend
. |
31 */ | 114 */ |
32 class BezierCubicEffects : public GM { | 115 class BezierCubicEffects : public GM { |
33 public: | 116 public: |
34 BezierCubicEffects() { | 117 BezierCubicEffects() { |
35 this->setBGColor(0xFFFFFFFF); | 118 this->setBGColor(0xFFFFFFFF); |
36 } | 119 } |
37 | 120 |
38 protected: | 121 protected: |
39 SkString onShortName() SK_OVERRIDE { | 122 SkString onShortName() SK_OVERRIDE { |
40 return SkString("bezier_cubic_effects"); | 123 return SkString("bezier_cubic_effects"); |
41 } | 124 } |
42 | 125 |
43 SkISize onISize() SK_OVERRIDE { | 126 SkISize onISize() SK_OVERRIDE { |
44 return SkISize::Make(800, 800); | 127 return SkISize::Make(800, 800); |
45 } | 128 } |
46 | 129 |
47 | |
48 void onDraw(SkCanvas* canvas) SK_OVERRIDE { | 130 void onDraw(SkCanvas* canvas) SK_OVERRIDE { |
49 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget
(); | 131 GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget
(); |
50 if (NULL == rt) { | 132 if (NULL == rt) { |
51 this->drawGpuOnlyMessage(canvas); | 133 this->drawGpuOnlyMessage(canvas); |
52 return; | 134 return; |
53 } | 135 } |
54 GrContext* context = rt->getContext(); | 136 GrContext* context = rt->getContext(); |
55 if (NULL == context) { | 137 if (NULL == context) { |
56 return; | 138 return; |
57 } | 139 } |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 boundsPaint.setColor(0xff808080); | 222 boundsPaint.setColor(0xff808080); |
141 boundsPaint.setStrokeWidth(0); | 223 boundsPaint.setStrokeWidth(0); |
142 boundsPaint.setStyle(SkPaint::kStroke_Style); | 224 boundsPaint.setStyle(SkPaint::kStroke_Style); |
143 canvas->drawRect(bounds, boundsPaint); | 225 canvas->drawRect(bounds, boundsPaint); |
144 | 226 |
145 GrTestTarget tt; | 227 GrTestTarget tt; |
146 context->getTestTarget(&tt); | 228 context->getTestTarget(&tt); |
147 SkASSERT(tt.target()); | 229 SkASSERT(tt.target()); |
148 | 230 |
149 GrPipelineBuilder pipelineBuilder; | 231 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 | |
164 pipelineBuilder.setRenderTarget(rt); | 232 pipelineBuilder.setRenderTarget(rt); |
165 | 233 |
166 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuf
fer()); | 234 BezierCubicOrConicTestBatch::Geometry geometry; |
167 tt.target()->drawIndexed(&pipelineBuilder, gp, kTriangleFan_
GrPrimitiveType, | 235 geometry.fColor = gp->color(); |
168 0, 0,4,6); | 236 geometry.fBounds = bounds; |
| 237 |
| 238 SkAutoTUnref<GrBatch> batch(BezierCubicOrConicTestBatch::Cre
ate(gp, geometry, klmEqs, |
| 239 klm
Signs[c])); |
| 240 |
| 241 tt.target()->drawBatch(&pipelineBuilder, batch, NULL); |
169 } | 242 } |
170 ++col; | 243 ++col; |
171 if (numCols == col) { | 244 if (numCols == col) { |
172 col = 0; | 245 col = 0; |
173 ++row; | 246 ++row; |
174 } | 247 } |
175 } | 248 } |
176 } | 249 } |
177 } | 250 } |
178 | 251 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 boundsPaint.setColor(0xff808080); | 366 boundsPaint.setColor(0xff808080); |
294 boundsPaint.setStrokeWidth(0); | 367 boundsPaint.setStrokeWidth(0); |
295 boundsPaint.setStyle(SkPaint::kStroke_Style); | 368 boundsPaint.setStyle(SkPaint::kStroke_Style); |
296 canvas->drawRect(bounds, boundsPaint); | 369 canvas->drawRect(bounds, boundsPaint); |
297 | 370 |
298 GrTestTarget tt; | 371 GrTestTarget tt; |
299 context->getTestTarget(&tt); | 372 context->getTestTarget(&tt); |
300 SkASSERT(tt.target()); | 373 SkASSERT(tt.target()); |
301 | 374 |
302 GrPipelineBuilder pipelineBuilder; | 375 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 | |
317 pipelineBuilder.setRenderTarget(rt); | 376 pipelineBuilder.setRenderTarget(rt); |
318 | 377 |
319 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuf
fer()); | 378 BezierCubicOrConicTestBatch::Geometry geometry; |
320 tt.target()->drawIndexed(&pipelineBuilder, gp, kTriangleFan_
GrPrimitiveType, | 379 geometry.fColor = gp->color(); |
321 0, 0,4,6); | 380 geometry.fBounds = bounds; |
| 381 |
| 382 SkAutoTUnref<GrBatch> batch(BezierCubicOrConicTestBatch::Cre
ate(gp, geometry, klmEqs, |
| 383 1.f
)); |
| 384 |
| 385 tt.target()->drawBatch(&pipelineBuilder, batch, NULL); |
322 } | 386 } |
323 ++col; | 387 ++col; |
324 if (numCols == col) { | 388 if (numCols == col) { |
325 col = 0; | 389 col = 0; |
326 ++row; | 390 ++row; |
327 } | 391 } |
328 } | 392 } |
329 } | 393 } |
330 } | 394 } |
331 | 395 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 } else { | 428 } else { |
365 dst[0] = dstTemp[0]; | 429 dst[0] = dstTemp[0]; |
366 } | 430 } |
367 return conicCnt; | 431 return conicCnt; |
368 } | 432 } |
369 | 433 |
370 typedef GM INHERITED; | 434 typedef GM INHERITED; |
371 }; | 435 }; |
372 | 436 |
373 ////////////////////////////////////////////////////////////////////////////// | 437 ////////////////////////////////////////////////////////////////////////////// |
| 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 |
374 /** | 511 /** |
375 * This GM directly exercises effects that draw Bezier quad curves in the GPU ba
ckend. | 512 * This GM directly exercises effects that draw Bezier quad curves in the GPU ba
ckend. |
376 */ | 513 */ |
377 class BezierQuadEffects : public GM { | 514 class BezierQuadEffects : public GM { |
378 public: | 515 public: |
379 BezierQuadEffects() { | 516 BezierQuadEffects() { |
380 this->setBGColor(0xFFFFFFFF); | 517 this->setBGColor(0xFFFFFFFF); |
381 } | 518 } |
382 | 519 |
383 protected: | 520 protected: |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 boundsPaint.setColor(0xff808080); | 614 boundsPaint.setColor(0xff808080); |
478 boundsPaint.setStrokeWidth(0); | 615 boundsPaint.setStrokeWidth(0); |
479 boundsPaint.setStyle(SkPaint::kStroke_Style); | 616 boundsPaint.setStyle(SkPaint::kStroke_Style); |
480 canvas->drawRect(bounds, boundsPaint); | 617 canvas->drawRect(bounds, boundsPaint); |
481 | 618 |
482 GrTestTarget tt; | 619 GrTestTarget tt; |
483 context->getTestTarget(&tt); | 620 context->getTestTarget(&tt); |
484 SkASSERT(tt.target()); | 621 SkASSERT(tt.target()); |
485 | 622 |
486 GrPipelineBuilder pipelineBuilder; | 623 GrPipelineBuilder pipelineBuilder; |
487 | 624 pipelineBuilder.setRenderTarget(rt); |
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 | 625 |
496 GrPathUtils::QuadUVMatrix DevToUV(pts); | 626 GrPathUtils::QuadUVMatrix DevToUV(pts); |
497 DevToUV.apply<4, sizeof(Vertex), sizeof(SkPoint)>(verts); | |
498 | 627 |
499 pipelineBuilder.setRenderTarget(rt); | 628 BezierQuadTestBatch::Geometry geometry; |
| 629 geometry.fColor = gp->color(); |
| 630 geometry.fBounds = bounds; |
500 | 631 |
501 tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuf
fer()); | 632 SkAutoTUnref<GrBatch> batch(BezierQuadTestBatch::Create(gp,
geometry, DevToUV)); |
502 tt.target()->drawIndexed(&pipelineBuilder, gp, kTriangles_Gr
PrimitiveType, | 633 |
503 0, 0, 4, 6); | 634 tt.target()->drawBatch(&pipelineBuilder, batch, NULL); |
504 } | 635 } |
505 ++col; | 636 ++col; |
506 if (numCols == col) { | 637 if (numCols == col) { |
507 col = 0; | 638 col = 0; |
508 ++row; | 639 ++row; |
509 } | 640 } |
510 } | 641 } |
511 } | 642 } |
512 } | 643 } |
513 | 644 |
514 private: | 645 private: |
515 typedef GM INHERITED; | 646 typedef GM INHERITED; |
516 }; | 647 }; |
517 | 648 |
518 DEF_GM( return SkNEW(BezierCubicEffects); ) | 649 DEF_GM( return SkNEW(BezierCubicEffects); ) |
519 DEF_GM( return SkNEW(BezierConicEffects); ) | 650 DEF_GM( return SkNEW(BezierConicEffects); ) |
520 DEF_GM( return SkNEW(BezierQuadEffects); ) | 651 DEF_GM( return SkNEW(BezierQuadEffects); ) |
521 | 652 |
522 } | 653 } |
523 | 654 |
524 #endif | 655 #endif |
OLD | NEW |