OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrAAStrokeRectBatch.h" | 8 #include "GrAAStrokeRectBatch.h" |
9 | 9 |
10 #include "GrBatchFlushState.h" | 10 #include "GrBatchFlushState.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
46 class AAStrokeRectBatch : public GrVertexBatch { | 46 class AAStrokeRectBatch : public GrVertexBatch { |
47 public: | 47 public: |
48 DEFINE_BATCH_CLASS_ID | 48 DEFINE_BATCH_CLASS_ID |
49 | 49 |
50 // TODO support AA rotated stroke rects by copying around view matrices | 50 // TODO support AA rotated stroke rects by copying around view matrices |
51 struct Geometry { | 51 struct Geometry { |
52 SkRect fDevOutside; | 52 SkRect fDevOutside; |
53 SkRect fDevOutsideAssist; | 53 SkRect fDevOutsideAssist; |
54 SkRect fDevInside; | 54 SkRect fDevInside; |
55 GrColor fColor; | 55 GrColor fColor; |
56 bool fDegenerate; | |
56 }; | 57 }; |
57 | 58 |
58 static AAStrokeRectBatch* Create(const SkMatrix& viewMatrix, bool miterStrok e) { | 59 static AAStrokeRectBatch* Create(const SkMatrix& viewMatrix, bool miterStrok e) { |
59 return new AAStrokeRectBatch(viewMatrix, miterStroke); | 60 return new AAStrokeRectBatch(viewMatrix, miterStroke); |
60 } | 61 } |
61 | 62 |
62 const char* name() const override { return "AAStrokeRect"; } | 63 const char* name() const override { return "AAStrokeRect"; } |
63 | 64 |
64 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { | 65 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { |
65 // When this is called on a batch, there is only one geometry bundle | 66 // When this is called on a batch, there is only one geometry bundle |
66 out->setKnownFourComponents(fGeoData[0].fColor); | 67 out->setKnownFourComponents(fGeoData[0].fColor); |
67 } | 68 } |
68 | 69 |
69 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { | 70 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { |
70 out->setUnknownSingleComponent(); | 71 out->setUnknownSingleComponent(); |
71 } | 72 } |
72 | 73 |
73 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 74 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
74 | 75 |
75 bool canAppend(const SkMatrix& viewMatrix, bool miterStroke) { | 76 bool canAppend(const SkMatrix& viewMatrix, bool miterStroke) { |
76 return fViewMatrix.cheapEqualTo(viewMatrix) && fMiterStroke == miterStro ke; | 77 return fViewMatrix.cheapEqualTo(viewMatrix) && fMiterStroke == miterStro ke; |
77 } | 78 } |
78 | 79 |
79 void append(GrColor color, const SkRect& devOutside, const SkRect& devOutsid eAssist, | 80 void append(GrColor color, const SkRect& devOutside, const SkRect& devOutsid eAssist, |
80 const SkRect& devInside) { | 81 const SkRect& devInside, bool degenerate) { |
81 Geometry& geometry = fGeoData.push_back(); | 82 Geometry& geometry = fGeoData.push_back(); |
82 geometry.fColor = color; | 83 geometry.fColor = color; |
83 geometry.fDevOutside = devOutside; | 84 geometry.fDevOutside = devOutside; |
84 geometry.fDevOutsideAssist = devOutsideAssist; | 85 geometry.fDevOutsideAssist = devOutsideAssist; |
85 geometry.fDevInside = devInside; | 86 geometry.fDevInside = devInside; |
87 geometry.fDegenerate = degenerate; | |
86 } | 88 } |
87 | 89 |
88 void appendAndUpdateBounds(GrColor color, const SkRect& devOutside, | 90 void appendAndUpdateBounds(GrColor color, const SkRect& devOutside, |
89 const SkRect& devOutsideAssist, const SkRect& dev Inside) { | 91 const SkRect& devOutsideAssist, const SkRect& dev Inside, |
90 this->append(color, devOutside, devOutsideAssist, devInside); | 92 bool degenerate) { |
93 this->append(color, devOutside, devOutsideAssist, devInside, degenerate) ; | |
91 | 94 |
92 SkRect bounds; | 95 SkRect bounds; |
93 this->updateBounds(&bounds, fGeoData.back()); | 96 this->updateBounds(&bounds, fGeoData.back()); |
94 this->joinBounds(bounds); | 97 this->joinBounds(bounds); |
95 } | 98 } |
96 | 99 |
97 void init() { this->updateBounds(&fBounds, fGeoData[0]); } | 100 void init() { this->updateBounds(&fBounds, fGeoData[0]); } |
98 | 101 |
99 private: | 102 private: |
100 void updateBounds(SkRect* bounds, const Geometry& geo) { | 103 void updateBounds(SkRect* bounds, const Geometry& geo) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
138 void generateAAStrokeRectGeometry(void* vertices, | 141 void generateAAStrokeRectGeometry(void* vertices, |
139 size_t offset, | 142 size_t offset, |
140 size_t vertexStride, | 143 size_t vertexStride, |
141 int outerVertexNum, | 144 int outerVertexNum, |
142 int innerVertexNum, | 145 int innerVertexNum, |
143 GrColor color, | 146 GrColor color, |
144 const SkRect& devOutside, | 147 const SkRect& devOutside, |
145 const SkRect& devOutsideAssist, | 148 const SkRect& devOutsideAssist, |
146 const SkRect& devInside, | 149 const SkRect& devInside, |
147 bool miterStroke, | 150 bool miterStroke, |
151 bool degenerate, | |
148 bool tweakAlphaForCoverage) const; | 152 bool tweakAlphaForCoverage) const; |
149 | 153 |
150 struct BatchTracker { | 154 struct BatchTracker { |
151 GrColor fColor; | 155 GrColor fColor; |
152 bool fUsesLocalCoords; | 156 bool fUsesLocalCoords; |
153 bool fColorIgnored; | 157 bool fColorIgnored; |
154 bool fCoverageIgnored; | 158 bool fCoverageIgnored; |
155 bool fCanTweakAlphaForCoverage; | 159 bool fCanTweakAlphaForCoverage; |
156 }; | 160 }; |
157 | 161 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
219 this->generateAAStrokeRectGeometry(vertices, | 223 this->generateAAStrokeRectGeometry(vertices, |
220 i * verticesPerInstance * vertexStrid e, | 224 i * verticesPerInstance * vertexStrid e, |
221 vertexStride, | 225 vertexStride, |
222 outerVertexNum, | 226 outerVertexNum, |
223 innerVertexNum, | 227 innerVertexNum, |
224 args.fColor, | 228 args.fColor, |
225 args.fDevOutside, | 229 args.fDevOutside, |
226 args.fDevOutsideAssist, | 230 args.fDevOutsideAssist, |
227 args.fDevInside, | 231 args.fDevInside, |
228 fMiterStroke, | 232 fMiterStroke, |
233 args.fDegenerate, | |
229 canTweakAlphaForCoverage); | 234 canTweakAlphaForCoverage); |
230 } | 235 } |
231 helper.recordDraw(target); | 236 helper.recordDraw(target); |
232 } | 237 } |
233 | 238 |
234 const GrIndexBuffer* AAStrokeRectBatch::GetIndexBuffer(GrResourceProvider* resou rceProvider, | 239 const GrIndexBuffer* AAStrokeRectBatch::GetIndexBuffer(GrResourceProvider* resou rceProvider, |
235 bool miterStroke) { | 240 bool miterStroke) { |
236 | 241 |
237 if (miterStroke) { | 242 if (miterStroke) { |
238 static const uint16_t gMiterIndices[] = { | 243 static const uint16_t gMiterIndices[] = { |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
349 } | 354 } |
350 | 355 |
351 if (this->color() != that->color()) { | 356 if (this->color() != that->color()) { |
352 fBatch.fColor = GrColor_ILLEGAL; | 357 fBatch.fColor = GrColor_ILLEGAL; |
353 } | 358 } |
354 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); | 359 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); |
355 this->joinBounds(that->bounds()); | 360 this->joinBounds(that->bounds()); |
356 return true; | 361 return true; |
357 } | 362 } |
358 | 363 |
364 static void setup_scale(int* scale, SkScalar inset) { | |
365 if (inset < SK_ScalarHalf) { | |
366 *scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf)); | |
367 SkASSERT(*scale >= 0 && *scale <= 255); | |
368 } else { | |
369 *scale = 0xff; | |
370 } | |
371 } | |
372 | |
359 void AAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices, | 373 void AAStrokeRectBatch::generateAAStrokeRectGeometry(void* vertices, |
360 size_t offset, | 374 size_t offset, |
361 size_t vertexStride, | 375 size_t vertexStride, |
362 int outerVertexNum, | 376 int outerVertexNum, |
363 int innerVertexNum, | 377 int innerVertexNum, |
364 GrColor color, | 378 GrColor color, |
365 const SkRect& devOutside, | 379 const SkRect& devOutside, |
366 const SkRect& devOutsideAss ist, | 380 const SkRect& devOutsideAss ist, |
367 const SkRect& devInside, | 381 const SkRect& devInside, |
368 bool miterStroke, | 382 bool miterStroke, |
383 bool degenerate, | |
369 bool tweakAlphaForCoverage) const { | 384 bool tweakAlphaForCoverage) const { |
370 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + offset; | 385 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + offset; |
371 | 386 |
372 // We create vertices for four nested rectangles. There are two ramps from 0 to full | 387 // We create vertices for four nested rectangles. There are two ramps from 0 to full |
373 // coverage, one on the exterior of the stroke and the other on the interior . | 388 // coverage, one on the exterior of the stroke and the other on the interior . |
374 // The following pointers refer to the four rects, from outermost to innermo st. | 389 // The following pointers refer to the four rects, from outermost to innermo st. |
375 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); | 390 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); |
376 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + outerVertexNum * verte xStride); | 391 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + outerVertexNum * verte xStride); |
377 SkPoint* fan2Pos = reinterpret_cast<SkPoint*>(verts + 2 * outerVertexNum * v ertexStride); | 392 SkPoint* fan2Pos = reinterpret_cast<SkPoint*>(verts + 2 * outerVertexNum * v ertexStride); |
378 SkPoint* fan3Pos = reinterpret_cast<SkPoint*>(verts + | 393 SkPoint* fan3Pos = reinterpret_cast<SkPoint*>(verts + |
(...skipping 15 matching lines...) Expand all Loading... | |
394 SkASSERT(inset >= 0); | 409 SkASSERT(inset >= 0); |
395 #else | 410 #else |
396 SkScalar inset = SK_ScalarHalf; | 411 SkScalar inset = SK_ScalarHalf; |
397 #endif | 412 #endif |
398 | 413 |
399 if (miterStroke) { | 414 if (miterStroke) { |
400 // outermost | 415 // outermost |
401 set_inset_fan(fan0Pos, vertexStride, devOutside, -SK_ScalarHalf, -SK_Sca larHalf); | 416 set_inset_fan(fan0Pos, vertexStride, devOutside, -SK_ScalarHalf, -SK_Sca larHalf); |
402 // inner two | 417 // inner two |
403 set_inset_fan(fan1Pos, vertexStride, devOutside, inset, inset); | 418 set_inset_fan(fan1Pos, vertexStride, devOutside, inset, inset); |
404 set_inset_fan(fan2Pos, vertexStride, devInside, -inset, -inset); | 419 if (!degenerate) { |
405 // innermost | 420 set_inset_fan(fan2Pos, vertexStride, devInside, -inset, -inset); |
406 set_inset_fan(fan3Pos, vertexStride, devInside, SK_ScalarHalf, SK_Sca larHalf); | 421 // innermost |
422 set_inset_fan(fan3Pos, vertexStride, devInside, SK_ScalarHalf, SK _ScalarHalf); | |
423 } else { | |
424 // When the interior rect has become degenerate we smoosh to a singl e point | |
425 SkASSERT(devInside.fLeft == devInside.fRight && | |
426 devInside.fTop == devInside.fBottom); | |
427 fan2Pos->setRectFan(devInside.fLeft, devInside.fTop, | |
428 devInside.fRight, devInside.fBottom, vertexStrid e); | |
429 fan3Pos->setRectFan(devInside.fLeft, devInside.fTop, | |
430 devInside.fRight, devInside.fBottom, vertexStrid e); | |
431 } | |
407 } else { | 432 } else { |
408 SkPoint* fan0AssistPos = reinterpret_cast<SkPoint*>(verts + 4 * vertexSt ride); | 433 SkPoint* fan0AssistPos = reinterpret_cast<SkPoint*>(verts + 4 * vertexSt ride); |
409 SkPoint* fan1AssistPos = reinterpret_cast<SkPoint*>(verts + | 434 SkPoint* fan1AssistPos = reinterpret_cast<SkPoint*>(verts + |
410 (outerVertexNum + 4) * | 435 (outerVertexNum + 4) * |
411 vertexStride); | 436 vertexStride); |
412 // outermost | 437 // outermost |
413 set_inset_fan(fan0Pos, vertexStride, devOutside, -SK_ScalarHalf, -SK_Sca larHalf); | 438 set_inset_fan(fan0Pos, vertexStride, devOutside, -SK_ScalarHalf, -SK_Sca larHalf); |
414 set_inset_fan(fan0AssistPos, vertexStride, devOutsideAssist, -SK_ScalarH alf, | 439 set_inset_fan(fan0AssistPos, vertexStride, devOutsideAssist, -SK_ScalarH alf, |
415 -SK_ScalarHalf); | 440 -SK_ScalarHalf); |
416 // outer one of the inner two | 441 // outer one of the inner two |
417 set_inset_fan(fan1Pos, vertexStride, devOutside, inset, inset); | 442 set_inset_fan(fan1Pos, vertexStride, devOutside, inset, inset); |
418 set_inset_fan(fan1AssistPos, vertexStride, devOutsideAssist, inset, in set); | 443 set_inset_fan(fan1AssistPos, vertexStride, devOutsideAssist, inset, in set); |
419 // inner one of the inner two | 444 if (!degenerate) { |
420 set_inset_fan(fan2Pos, vertexStride, devInside, -inset, -inset); | 445 // inner one of the inner two |
421 // innermost | 446 set_inset_fan(fan2Pos, vertexStride, devInside, -inset, -inset); |
422 set_inset_fan(fan3Pos, vertexStride, devInside, SK_ScalarHalf, SK_Sca larHalf); | 447 // innermost |
448 set_inset_fan(fan3Pos, vertexStride, devInside, SK_ScalarHalf, SK _ScalarHalf); | |
449 } else { | |
450 // When the interior rect has become degenerate we smoosh to a singl e point | |
451 SkASSERT(devInside.fLeft == devInside.fRight && | |
452 devInside.fTop == devInside.fBottom); | |
453 fan2Pos->setRectFan(devInside.fLeft, devInside.fTop, | |
454 devInside.fRight, devInside.fBottom, vertexStrid e); | |
455 fan3Pos->setRectFan(devInside.fLeft, devInside.fTop, | |
456 devInside.fRight, devInside.fBottom, vertexStrid e); | |
457 } | |
423 } | 458 } |
424 | 459 |
425 // Make verts point to vertex color and then set all the color and coverage vertex attrs | 460 // Make verts point to vertex color and then set all the color and coverage vertex attrs |
426 // values. The outermost rect has 0 coverage | 461 // values. The outermost rect has 0 coverage |
427 verts += sizeof(SkPoint); | 462 verts += sizeof(SkPoint); |
428 for (int i = 0; i < outerVertexNum; ++i) { | 463 for (int i = 0; i < outerVertexNum; ++i) { |
429 if (tweakAlphaForCoverage) { | 464 if (tweakAlphaForCoverage) { |
430 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0; | 465 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0; |
431 } else { | 466 } else { |
432 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; | 467 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; |
433 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor) ) = 0; | 468 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor) ) = 0; |
434 } | 469 } |
435 } | 470 } |
436 | 471 |
437 // scale is the coverage for the the inner two rects. | 472 // scale is the coverage for the the inner two rects. |
438 int scale; | 473 int scale; |
439 if (inset < SK_ScalarHalf) { | 474 if (!degenerate) { |
440 scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf)); | 475 setup_scale(&scale, inset); |
441 SkASSERT(scale >= 0 && scale <= 255); | |
442 } else { | 476 } else { |
robertphillips
2015/09/21 19:57:39
typo degenrate
can -> need to ?
| |
443 scale = 0xff; | 477 // If we are degenrate, we can scale the coverage over the entire rect a nd not just the |
478 // inset | |
479 // TODO use real devRect here | |
robertphillips
2015/09/21 19:57:39
So devOutsideAssist.width() shouldn't appear in th
joshualitt
2015/09/21 21:18:58
correct, it is always = devrect
| |
480 SkScalar aaInset = SkMinScalar(devOutside.width(), SK_Scalar1); | |
481 aaInset = SK_ScalarHalf * SkMinScalar(aaInset, SkTMax(devOutside.height( ), | |
482 devOutsideAssist.h eight())); | |
483 setup_scale(&scale, aaInset); | |
444 } | 484 } |
445 | 485 |
446 float innerCoverage = GrNormalizeByteToFloat(scale); | 486 float innerCoverage = GrNormalizeByteToFloat(scale); |
447 GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale); | 487 GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale); |
448 | 488 |
449 verts += outerVertexNum * vertexStride; | 489 verts += outerVertexNum * vertexStride; |
450 for (int i = 0; i < outerVertexNum + innerVertexNum; ++i) { | 490 for (int i = 0; i < outerVertexNum + innerVertexNum; ++i) { |
451 if (tweakAlphaForCoverage) { | 491 if (tweakAlphaForCoverage) { |
452 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; | 492 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; |
453 } else { | 493 } else { |
454 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; | 494 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; |
455 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor) ) = | 495 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor) ) = |
456 innerCoverage; | 496 innerCoverage; |
457 } | 497 } |
458 } | 498 } |
459 | 499 |
460 // The innermost rect has 0 coverage | 500 // The innermost rect has 0 coverage, unless we are degenerate, in which cas e we must apply the |
501 // scaled coverage | |
461 verts += (outerVertexNum + innerVertexNum) * vertexStride; | 502 verts += (outerVertexNum + innerVertexNum) * vertexStride; |
503 if (!degenerate) { | |
504 scale = 0; | |
505 } | |
462 for (int i = 0; i < innerVertexNum; ++i) { | 506 for (int i = 0; i < innerVertexNum; ++i) { |
463 if (tweakAlphaForCoverage) { | 507 if (tweakAlphaForCoverage) { |
464 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0; | 508 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scale; |
465 } else { | 509 } else { |
466 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; | 510 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; |
467 *reinterpret_cast<GrColor*>(verts + i * vertexStride + sizeof(GrColo r)) = 0; | 511 *reinterpret_cast<GrColor*>(verts + i * vertexStride + sizeof(GrColo r)) = scale; |
468 } | 512 } |
469 } | 513 } |
470 } | 514 } |
471 | 515 |
472 namespace GrAAStrokeRectBatch { | 516 namespace GrAAStrokeRectBatch { |
473 | 517 |
474 GrDrawBatch* Create(GrColor color, | 518 GrDrawBatch* Create(GrColor color, |
475 const SkMatrix& viewMatrix, | 519 const SkMatrix& viewMatrix, |
476 const SkRect& devOutside, | 520 const SkRect& devOutside, |
477 const SkRect& devOutsideAssist, | 521 const SkRect& devOutsideAssist, |
478 const SkRect& devInside, | 522 const SkRect& devInside, |
479 bool miterStroke) { | 523 bool miterStroke, |
524 bool degenerate) { | |
480 AAStrokeRectBatch* batch = AAStrokeRectBatch::Create(viewMatrix, miterStroke ); | 525 AAStrokeRectBatch* batch = AAStrokeRectBatch::Create(viewMatrix, miterStroke ); |
481 batch->append(color, devOutside, devOutsideAssist, devInside); | 526 batch->append(color, devOutside, devOutsideAssist, devInside, degenerate); |
482 batch->init(); | 527 batch->init(); |
483 return batch; | 528 return batch; |
484 } | 529 } |
485 | 530 |
486 bool Append(GrBatch* origBatch, | 531 bool Append(GrBatch* origBatch, |
487 GrColor color, | 532 GrColor color, |
488 const SkMatrix& viewMatrix, | 533 const SkMatrix& viewMatrix, |
489 const SkRect& devOutside, | 534 const SkRect& devOutside, |
490 const SkRect& devOutsideAssist, | 535 const SkRect& devOutsideAssist, |
491 const SkRect& devInside, | 536 const SkRect& devInside, |
492 bool miterStroke) { | 537 bool miterStroke, |
538 bool degenerate) { | |
493 AAStrokeRectBatch* batch = origBatch->cast<AAStrokeRectBatch>(); | 539 AAStrokeRectBatch* batch = origBatch->cast<AAStrokeRectBatch>(); |
494 | 540 |
495 // we can't batch across vm changes | 541 // we can't batch across vm changes |
496 if (!batch->canAppend(viewMatrix, miterStroke)) { | 542 if (!batch->canAppend(viewMatrix, miterStroke)) { |
497 return false; | 543 return false; |
498 } | 544 } |
499 | 545 |
500 batch->appendAndUpdateBounds(color, devOutside, devOutsideAssist, devInside) ; | 546 batch->appendAndUpdateBounds(color, devOutside, devOutsideAssist, devInside, degenerate); |
501 return true; | 547 return true; |
502 } | 548 } |
503 | 549 |
504 }; | 550 }; |
505 | 551 |
506 //////////////////////////////////////////////////////////////////////////////// /////////////////// | 552 //////////////////////////////////////////////////////////////////////////////// /////////////////// |
507 | 553 |
508 #ifdef GR_TEST_UTILS | 554 #ifdef GR_TEST_UTILS |
509 | 555 |
510 #include "GrBatchTest.h" | 556 #include "GrBatchTest.h" |
511 | 557 |
512 DRAW_BATCH_TEST_DEFINE(AAStrokeRectBatch) { | 558 DRAW_BATCH_TEST_DEFINE(AAStrokeRectBatch) { |
513 bool miterStroke = random->nextBool(); | 559 bool miterStroke = random->nextBool(); |
560 bool degenerate = random->nextBool(); | |
514 | 561 |
515 // Create mock stroke rect | 562 // Create mock stroke rect |
516 SkRect outside = GrTest::TestRect(random); | 563 SkRect outside = GrTest::TestRect(random); |
517 SkScalar minDim = SkMinScalar(outside.width(), outside.height()); | 564 SkScalar minDim = SkMinScalar(outside.width(), outside.height()); |
518 SkScalar strokeWidth = minDim * 0.1f; | 565 SkScalar strokeWidth = minDim * 0.1f; |
519 SkRect outsideAssist = outside; | 566 SkRect outsideAssist = outside; |
520 outsideAssist.outset(strokeWidth, strokeWidth); | 567 outsideAssist.outset(strokeWidth, strokeWidth); |
521 SkRect inside = outside; | 568 SkRect inside = outside; |
522 inside.inset(strokeWidth, strokeWidth); | 569 inside.inset(strokeWidth, strokeWidth); |
523 | 570 |
524 GrColor color = GrRandomColor(random); | 571 GrColor color = GrRandomColor(random); |
525 | 572 |
526 return GrAAStrokeRectBatch::Create(color, GrTest::TestMatrix(random), outsid e, outsideAssist, | 573 return GrAAStrokeRectBatch::Create(color, GrTest::TestMatrix(random), outsid e, outsideAssist, |
527 inside, miterStroke); | 574 inside, degenerate, miterStroke); |
528 } | 575 } |
529 | 576 |
530 #endif | 577 #endif |
OLD | NEW |