| 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 |