OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 "GrAARectRenderer.h" | 8 #include "GrAARectRenderer.h" |
9 #include "GrRefCnt.h" | 9 #include "GrRefCnt.h" |
10 #include "GrGpu.h" | 10 #include "GrGpu.h" |
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
628 target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer()); | 628 target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer()); |
629 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6); | 629 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6); |
630 target->resetIndexSource(); | 630 target->resetIndexSource(); |
631 } | 631 } |
632 | 632 |
633 void GrAARectRenderer::strokeAARect(GrGpu* gpu, | 633 void GrAARectRenderer::strokeAARect(GrGpu* gpu, |
634 GrDrawTarget* target, | 634 GrDrawTarget* target, |
635 const GrRect& rect, | 635 const GrRect& rect, |
636 const SkMatrix& combinedMatrix, | 636 const SkMatrix& combinedMatrix, |
637 const GrRect& devRect, | 637 const GrRect& devRect, |
638 const GrVec& devStrokeSize, | 638 SkScalar width, |
639 bool useVertexCoverage) { | 639 bool useVertexCoverage) { |
640 GrDrawState* drawState = target->drawState(); | 640 GrVec devStrokeSize; |
| 641 if (width > 0) { |
| 642 devStrokeSize.set(width, width); |
| 643 combinedMatrix.mapVectors(&devStrokeSize, 1); |
| 644 devStrokeSize.setAbs(devStrokeSize); |
| 645 } else { |
| 646 devStrokeSize.set(SK_Scalar1, SK_Scalar1); |
| 647 } |
641 | 648 |
642 const SkScalar dx = devStrokeSize.fX; | 649 const SkScalar dx = devStrokeSize.fX; |
643 const SkScalar dy = devStrokeSize.fY; | 650 const SkScalar dy = devStrokeSize.fY; |
644 const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf); | 651 const SkScalar rx = SkScalarMul(dx, SK_ScalarHalf); |
645 const SkScalar ry = SkScalarMul(dy, SK_ScalarHalf); | 652 const SkScalar ry = SkScalarMul(dy, SK_ScalarHalf); |
646 | 653 |
647 // Temporarily #if'ed out. We don't want to pass in the devRect but | 654 // Temporarily #if'ed out. We don't want to pass in the devRect but |
648 // right now it is computed in GrContext::apply_aa_to_rect and we don't | 655 // right now it is computed in GrContext::apply_aa_to_rect and we don't |
649 // want to throw away the work | 656 // want to throw away the work |
650 #if 0 | 657 #if 0 |
651 SkRect devRect; | 658 SkRect devRect; |
652 combinedMatrix.mapRect(&devRect, rect); | 659 combinedMatrix.mapRect(&devRect, rect); |
653 #endif | 660 #endif |
654 | 661 |
655 SkScalar spare; | 662 SkScalar spare; |
656 { | 663 { |
657 SkScalar w = devRect.width() - dx; | 664 SkScalar w = devRect.width() - dx; |
658 SkScalar h = devRect.height() - dy; | 665 SkScalar h = devRect.height() - dy; |
659 spare = GrMin(w, h); | 666 spare = GrMin(w, h); |
660 } | 667 } |
661 | 668 |
| 669 GrRect devOutside(devRect); |
| 670 devOutside.outset(rx, ry); |
| 671 |
662 if (spare <= 0) { | 672 if (spare <= 0) { |
663 GrRect r(devRect); | 673 this->fillAARect(gpu, target, devOutside, SkMatrix::I(), |
664 r.outset(rx, ry); | 674 devOutside, useVertexCoverage); |
665 this->fillAARect(gpu, target, r, SkMatrix::I(), r, useVertexCoverage); | |
666 return; | 675 return; |
667 } | 676 } |
668 | 677 |
| 678 SkRect devInside(devRect); |
| 679 devInside.inset(rx, ry); |
| 680 |
| 681 this->geometryStrokeAARect(gpu, target, devOutside, devInside, useVertexCove
rage); |
| 682 } |
| 683 |
| 684 void GrAARectRenderer::geometryStrokeAARect(GrGpu* gpu, |
| 685 GrDrawTarget* target, |
| 686 const SkRect& devOutside, |
| 687 const SkRect& devInside, |
| 688 bool useVertexCoverage) { |
| 689 GrDrawState* drawState = target->drawState(); |
| 690 |
669 set_aa_rect_vertex_attributes(drawState, useVertexCoverage); | 691 set_aa_rect_vertex_attributes(drawState, useVertexCoverage); |
670 | 692 |
671 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0); | 693 GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0); |
672 if (!geo.succeeded()) { | 694 if (!geo.succeeded()) { |
673 GrPrintf("Failed to get space for vertices!\n"); | 695 GrPrintf("Failed to get space for vertices!\n"); |
674 return; | 696 return; |
675 } | 697 } |
676 GrIndexBuffer* indexBuffer = this->aaStrokeRectIndexBuffer(gpu); | 698 GrIndexBuffer* indexBuffer = this->aaStrokeRectIndexBuffer(gpu); |
677 if (NULL == indexBuffer) { | 699 if (NULL == indexBuffer) { |
678 GrPrintf("Failed to create index buffer!\n"); | 700 GrPrintf("Failed to create index buffer!\n"); |
679 return; | 701 return; |
680 } | 702 } |
681 | 703 |
682 intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); | 704 intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); |
683 size_t vsize = drawState->getVertexSize(); | 705 size_t vsize = drawState->getVertexSize(); |
684 GrAssert(sizeof(GrPoint) + sizeof(GrColor) == vsize); | 706 GrAssert(sizeof(GrPoint) + sizeof(GrColor) == vsize); |
685 | 707 |
686 // We create vertices for four nested rectangles. There are two ramps from 0
to full | 708 // We create vertices for four nested rectangles. There are two ramps from 0
to full |
687 // coverage, one on the exterior of the stroke and the other on the interior
. | 709 // coverage, one on the exterior of the stroke and the other on the interior
. |
688 // The following pointers refer to the four rects, from outermost to innermo
st. | 710 // The following pointers refer to the four rects, from outermost to innermo
st. |
689 GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts); | 711 GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts); |
690 GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize); | 712 GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize); |
691 GrPoint* fan2Pos = reinterpret_cast<GrPoint*>(verts + 8 * vsize); | 713 GrPoint* fan2Pos = reinterpret_cast<GrPoint*>(verts + 8 * vsize); |
692 GrPoint* fan3Pos = reinterpret_cast<GrPoint*>(verts + 12 * vsize); | 714 GrPoint* fan3Pos = reinterpret_cast<GrPoint*>(verts + 12 * vsize); |
693 | 715 |
694 set_inset_fan(fan0Pos, vsize, devRect, | 716 // outermost |
695 -rx - SK_ScalarHalf, -ry - SK_ScalarHalf); | 717 set_inset_fan(fan0Pos, vsize, devOutside, -SK_ScalarHalf, -SK_ScalarHalf); |
696 set_inset_fan(fan1Pos, vsize, devRect, | 718 set_inset_fan(fan1Pos, vsize, devOutside, SK_ScalarHalf, SK_ScalarHalf); |
697 -rx + SK_ScalarHalf, -ry + SK_ScalarHalf); | 719 set_inset_fan(fan2Pos, vsize, devInside, -SK_ScalarHalf, -SK_ScalarHalf); |
698 set_inset_fan(fan2Pos, vsize, devRect, | 720 // innermost |
699 rx - SK_ScalarHalf, ry - SK_ScalarHalf); | 721 set_inset_fan(fan3Pos, vsize, devInside, SK_ScalarHalf, SK_ScalarHalf); |
700 set_inset_fan(fan3Pos, vsize, devRect, | |
701 rx + SK_ScalarHalf, ry + SK_ScalarHalf); | |
702 | 722 |
703 // The outermost rect has 0 coverage | 723 // The outermost rect has 0 coverage |
704 verts += sizeof(GrPoint); | 724 verts += sizeof(GrPoint); |
705 for (int i = 0; i < 4; ++i) { | 725 for (int i = 0; i < 4; ++i) { |
706 *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; | 726 *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; |
707 } | 727 } |
708 | 728 |
709 // The inner two rects have full coverage | 729 // The inner two rects have full coverage |
710 GrColor innerColor; | 730 GrColor innerColor; |
711 if (useVertexCoverage) { | 731 if (useVertexCoverage) { |
712 innerColor = 0xffffffff; | 732 innerColor = 0xffffffff; |
713 } else { | 733 } else { |
714 innerColor = target->getDrawState().getColor(); | 734 innerColor = target->getDrawState().getColor(); |
715 } | 735 } |
716 verts += 4 * vsize; | 736 verts += 4 * vsize; |
717 for (int i = 0; i < 8; ++i) { | 737 for (int i = 0; i < 8; ++i) { |
718 *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor; | 738 *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor; |
719 } | 739 } |
720 | 740 |
721 // The innermost rect has full coverage | 741 // The innermost rect has 0 coverage |
722 verts += 8 * vsize; | 742 verts += 8 * vsize; |
723 for (int i = 0; i < 4; ++i) { | 743 for (int i = 0; i < 4; ++i) { |
724 *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; | 744 *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; |
725 } | 745 } |
726 | 746 |
727 target->setIndexSourceToBuffer(indexBuffer); | 747 target->setIndexSourceToBuffer(indexBuffer); |
728 target->drawIndexed(kTriangles_GrPrimitiveType, | 748 target->drawIndexed(kTriangles_GrPrimitiveType, |
729 0, 0, 16, aaStrokeRectIndexCount()); | 749 0, 0, 16, aaStrokeRectIndexCount()); |
730 } | 750 } |
| 751 |
| 752 void GrAARectRenderer::fillAANestedRects(GrGpu* gpu, |
| 753 GrDrawTarget* target, |
| 754 const SkRect rects[2], |
| 755 const SkMatrix& combinedMatrix, |
| 756 bool useVertexCoverage) { |
| 757 SkASSERT(combinedMatrix.rectStaysRect()); |
| 758 SkASSERT(!rects[1].isEmpty()); |
| 759 |
| 760 SkRect devOutside, devInside; |
| 761 combinedMatrix.mapRect(&devOutside, rects[0]); |
| 762 // can't call mapRect for devInside since it calls sort |
| 763 combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2)
; |
| 764 |
| 765 if (devInside.isEmpty()) { |
| 766 this->fillAARect(gpu, target, devOutside, SkMatrix::I(), devOutside, use
VertexCoverage); |
| 767 return; |
| 768 } |
| 769 |
| 770 this->geometryStrokeAARect(gpu, target, devOutside, devInside, useVertexCove
rage); |
| 771 } |
OLD | NEW |