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 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 for (int i = 0; i < innerVertexNum; ++i) { | 509 for (int i = 0; i < innerVertexNum; ++i) { |
510 if (tweakAlphaForCoverage) { | 510 if (tweakAlphaForCoverage) { |
511 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; | 511 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; |
512 } else { | 512 } else { |
513 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; | 513 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; |
514 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)
) = innerCoverage; | 514 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)
) = innerCoverage; |
515 } | 515 } |
516 } | 516 } |
517 } | 517 } |
518 | 518 |
519 inline static bool is_miter(const SkStrokeRec& stroke) { | 519 // We support all hairlines, bevels, and miters, but not round joins. Also, chec
k whether the miter |
| 520 // limit makes a miter join effectively beveled. |
| 521 inline static bool allowed_stroke(const SkStrokeRec& stroke, bool* isMiter) { |
| 522 SkASSERT(stroke.getStyle() == SkStrokeRec::kStroke_Style || |
| 523 stroke.getStyle() == SkStrokeRec::kHairline_Style); |
520 // For hairlines, make bevel and round joins appear the same as mitered ones
. | 524 // For hairlines, make bevel and round joins appear the same as mitered ones
. |
521 // small miter limit means right angles show bevel... | 525 if (!stroke.getWidth()) { |
522 if ((stroke.getWidth() > 0) && (stroke.getJoin() != SkPaint::kMiter_Join || | 526 *isMiter = true; |
523 stroke.getMiter() < SK_ScalarSqrt2)) { | 527 return true; |
524 return false; | |
525 } | 528 } |
526 return true; | 529 if (stroke.getJoin() == SkPaint::kBevel_Join) { |
| 530 *isMiter = false; |
| 531 return true; |
| 532 } |
| 533 if (stroke.getJoin() == SkPaint::kMiter_Join) { |
| 534 *isMiter = stroke.getMiter() >= SK_ScalarSqrt2; |
| 535 return true; |
| 536 } |
| 537 return false; |
527 } | 538 } |
528 | 539 |
529 static void compute_rects(SkRect* devOutside, SkRect* devOutsideAssist, SkRect*
devInside, | 540 static void compute_rects(SkRect* devOutside, SkRect* devOutsideAssist, SkRect*
devInside, |
530 bool* isDegenerate, const SkMatrix& viewMatrix, const
SkRect& rect, | 541 bool* isDegenerate, const SkMatrix& viewMatrix, const
SkRect& rect, |
531 SkScalar strokeWidth, bool miterStroke) { | 542 SkScalar strokeWidth, bool miterStroke) { |
532 SkRect devRect; | 543 SkRect devRect; |
533 viewMatrix.mapRect(&devRect, rect); | 544 viewMatrix.mapRect(&devRect, rect); |
534 | 545 |
535 SkVector devStrokeSize; | 546 SkVector devStrokeSize; |
536 if (strokeWidth > 0) { | 547 if (strokeWidth > 0) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 AAStrokeRectBatch* batch = AAStrokeRectBatch::Create(viewMatrix, true); | 600 AAStrokeRectBatch* batch = AAStrokeRectBatch::Create(viewMatrix, true); |
590 batch->append(color, devOutside, devOutside, devInside, false); | 601 batch->append(color, devOutside, devOutside, devInside, false); |
591 batch->init(); | 602 batch->init(); |
592 return batch; | 603 return batch; |
593 } | 604 } |
594 | 605 |
595 GrDrawBatch* Create(GrColor color, | 606 GrDrawBatch* Create(GrColor color, |
596 const SkMatrix& viewMatrix, | 607 const SkMatrix& viewMatrix, |
597 const SkRect& rect, | 608 const SkRect& rect, |
598 const SkStrokeRec& stroke) { | 609 const SkStrokeRec& stroke) { |
599 bool isMiterStroke = is_miter(stroke); | 610 bool isMiterStroke; |
| 611 if (!allowed_stroke(stroke, &isMiterStroke)) { |
| 612 return nullptr; |
| 613 } |
600 AAStrokeRectBatch* batch = AAStrokeRectBatch::Create(viewMatrix, isMiterStro
ke); | 614 AAStrokeRectBatch* batch = AAStrokeRectBatch::Create(viewMatrix, isMiterStro
ke); |
601 | 615 |
602 SkRect devOutside, devOutsideAssist, devInside; | 616 SkRect devOutside, devOutsideAssist, devInside; |
603 bool isDegenerate; | 617 bool isDegenerate; |
604 compute_rects(&devOutside, &devOutsideAssist, &devInside, &isDegenerate, vie
wMatrix, | 618 compute_rects(&devOutside, &devOutsideAssist, &devInside, &isDegenerate, vie
wMatrix, |
605 rect, stroke.getWidth(), isMiterStroke); | 619 rect, stroke.getWidth(), isMiterStroke); |
606 | 620 |
607 batch->append(color, devOutside, devOutsideAssist, devInside, isDegenerate); | 621 batch->append(color, devOutside, devOutsideAssist, devInside, isDegenerate); |
608 batch->init(); | 622 batch->init(); |
609 return batch; | 623 return batch; |
610 } | 624 } |
611 | 625 |
612 bool Append(GrBatch* origBatch, | |
613 GrColor color, | |
614 const SkMatrix& viewMatrix, | |
615 const SkRect& rect, | |
616 const SkStrokeRec& stroke) { | |
617 AAStrokeRectBatch* batch = origBatch->cast<AAStrokeRectBatch>(); | |
618 | |
619 // we can't batch across vm changes | |
620 bool isMiterStroke = is_miter(stroke); | |
621 if (!batch->canAppend(viewMatrix, isMiterStroke)) { | |
622 return false; | |
623 } | |
624 | |
625 SkRect devOutside, devOutsideAssist, devInside; | |
626 bool isDegenerate; | |
627 compute_rects(&devOutside, &devOutsideAssist, &devInside, &isDegenerate, vie
wMatrix, | |
628 rect, stroke.getWidth(), isMiterStroke); | |
629 | |
630 batch->appendAndUpdateBounds(color, devOutside, devOutsideAssist, devInside,
isDegenerate); | |
631 return true; | |
632 } | |
633 | |
634 }; | 626 }; |
635 | 627 |
636 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 628 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
637 | 629 |
638 #ifdef GR_TEST_UTILS | 630 #ifdef GR_TEST_UTILS |
639 | 631 |
640 #include "GrBatchTest.h" | 632 #include "GrBatchTest.h" |
641 | 633 |
642 DRAW_BATCH_TEST_DEFINE(AAStrokeRectBatch) { | 634 DRAW_BATCH_TEST_DEFINE(AAStrokeRectBatch) { |
643 bool miterStroke = random->nextBool(); | 635 bool miterStroke = random->nextBool(); |
644 | 636 |
645 // Create either a empty rect or a non-empty rect. | 637 // Create either a empty rect or a non-empty rect. |
646 SkRect rect = random->nextBool() ? SkRect::MakeXYWH(10, 10, 50, 40) : | 638 SkRect rect = random->nextBool() ? SkRect::MakeXYWH(10, 10, 50, 40) : |
647 SkRect::MakeXYWH(6, 7, 0, 0); | 639 SkRect::MakeXYWH(6, 7, 0, 0); |
648 SkScalar minDim = SkMinScalar(rect.width(), rect.height()); | 640 SkScalar minDim = SkMinScalar(rect.width(), rect.height()); |
649 SkScalar strokeWidth = random->nextUScalar1() * minDim; | 641 SkScalar strokeWidth = random->nextUScalar1() * minDim; |
650 | 642 |
651 GrColor color = GrRandomColor(random); | 643 GrColor color = GrRandomColor(random); |
652 | 644 |
653 SkStrokeRec rec(SkStrokeRec::kFill_InitStyle); | 645 SkStrokeRec rec(SkStrokeRec::kFill_InitStyle); |
654 rec.setStrokeStyle(strokeWidth); | 646 rec.setStrokeStyle(strokeWidth); |
655 rec.setStrokeParams(SkPaint::kButt_Cap, | 647 rec.setStrokeParams(SkPaint::kButt_Cap, |
656 miterStroke ? SkPaint::kMiter_Join : SkPaint::kBevel_Joi
n, | 648 miterStroke ? SkPaint::kMiter_Join : SkPaint::kBevel_Joi
n, |
657 1.f); | 649 1.f); |
658 SkMatrix matrix = GrTest::TestMatrixRectStaysRect(random); | 650 SkMatrix matrix = GrTest::TestMatrixRectStaysRect(random); |
659 return GrAAStrokeRectBatch::Create(color, matrix, rect, rec); | 651 return GrAAStrokeRectBatch::Create(color, matrix, rect, rec); |
660 } | 652 } |
661 | 653 |
662 #endif | 654 #endif |
OLD | NEW |