OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 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 | 9 |
10 #include "GrContext.h" | 10 #include "GrContext.h" |
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 } | 674 } |
675 | 675 |
676 static bool isIRect(const SkRect& r) { | 676 static bool isIRect(const SkRect& r) { |
677 return SkScalarIsInt(r.fLeft) && SkScalarIsInt(r.fTop) && | 677 return SkScalarIsInt(r.fLeft) && SkScalarIsInt(r.fTop) && |
678 SkScalarIsInt(r.fRight) && SkScalarIsInt(r.fBottom); | 678 SkScalarIsInt(r.fRight) && SkScalarIsInt(r.fBottom); |
679 } | 679 } |
680 | 680 |
681 static bool apply_aa_to_rect(GrDrawTarget* target, | 681 static bool apply_aa_to_rect(GrDrawTarget* target, |
682 const SkRect& rect, | 682 const SkRect& rect, |
683 SkScalar strokeWidth, | 683 SkScalar strokeWidth, |
684 const SkMatrix* matrix, | 684 const SkMatrix& combinedMatrix, |
685 SkMatrix* combinedMatrix, | 685 SkRect* devBoundRect, |
686 SkRect* devRect, | |
687 bool* useVertexCoverage) { | 686 bool* useVertexCoverage) { |
688 // we use a simple coverage ramp to do aa on axis-aligned rects | 687 // we use a simple coverage ramp to do aa on axis-aligned rects |
689 // we check if the rect will be axis-aligned, and the rect won't land on | 688 // we check if the rect will be axis-aligned, and the rect won't land on |
690 // integer coords. | 689 // integer coords. |
691 | 690 |
692 // we are keeping around the "tweak the alpha" trick because | 691 // we are keeping around the "tweak the alpha" trick because |
693 // it is our only hope for the fixed-pipe implementation. | 692 // it is our only hope for the fixed-pipe implementation. |
694 // In a shader implementation we can give a separate coverage input | 693 // In a shader implementation we can give a separate coverage input |
695 // TODO: remove this ugliness when we drop the fixed-pipe impl | 694 // TODO: remove this ugliness when we drop the fixed-pipe impl |
696 *useVertexCoverage = false; | 695 *useVertexCoverage = false; |
(...skipping 12 matching lines...) Expand all Loading... |
709 return false; | 708 return false; |
710 } | 709 } |
711 | 710 |
712 if (0 == strokeWidth && target->willUseHWAALines()) { | 711 if (0 == strokeWidth && target->willUseHWAALines()) { |
713 return false; | 712 return false; |
714 } | 713 } |
715 | 714 |
716 #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) | 715 #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) |
717 if (strokeWidth >= 0) { | 716 if (strokeWidth >= 0) { |
718 #endif | 717 #endif |
719 if (!drawState.getViewMatrix().preservesAxisAlignment()) { | 718 if (!combinedMatrix.preservesAxisAlignment()) { |
720 return false; | 719 return false; |
721 } | 720 } |
722 | 721 |
723 if (NULL != matrix && !matrix->preservesAxisAlignment()) { | |
724 return false; | |
725 } | |
726 #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) | 722 #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) |
727 } else { | 723 } else { |
728 if (!drawState.getViewMatrix().preservesAxisAlignment() && | 724 if (!combinedMatrix.preservesRightAngles()) { |
729 !drawState.getViewMatrix().preservesRightAngles()) { | |
730 return false; | |
731 } | |
732 | |
733 if (NULL != matrix && !matrix->preservesRightAngles()) { | |
734 return false; | 725 return false; |
735 } | 726 } |
736 } | 727 } |
737 #endif | 728 #endif |
738 | 729 |
739 *combinedMatrix = drawState.getViewMatrix(); | 730 combinedMatrix.mapRect(devBoundRect, rect); |
740 if (NULL != matrix) { | |
741 combinedMatrix->preConcat(*matrix); | |
742 | |
743 #if GR_DEBUG | |
744 #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) | |
745 if (strokeWidth >= 0) { | |
746 #endif | |
747 GrAssert(combinedMatrix->preservesAxisAlignment()); | |
748 #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) | |
749 } else { | |
750 GrAssert(combinedMatrix->preservesRightAngles()); | |
751 } | |
752 #endif | |
753 #endif | |
754 } | |
755 | |
756 combinedMatrix->mapRect(devRect, rect); | |
757 | 731 |
758 if (strokeWidth < 0) { | 732 if (strokeWidth < 0) { |
759 return !isIRect(*devRect); | 733 return !isIRect(*devBoundRect); |
760 } else { | 734 } else { |
761 return true; | 735 return true; |
762 } | 736 } |
763 } | 737 } |
764 | 738 |
| 739 static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& po
int) { |
| 740 return point.fX >= rect.fLeft && point.fX <= rect.fRight && |
| 741 point.fY >= rect.fTop && point.fY <= rect.fBottom; |
| 742 } |
| 743 |
765 void GrContext::drawRect(const GrPaint& paint, | 744 void GrContext::drawRect(const GrPaint& paint, |
766 const SkRect& rect, | 745 const SkRect& rect, |
767 SkScalar width, | 746 SkScalar width, |
768 const SkMatrix* matrix) { | 747 const SkMatrix* matrix) { |
769 SK_TRACE_EVENT0("GrContext::drawRect"); | 748 SK_TRACE_EVENT0("GrContext::drawRect"); |
770 | 749 |
771 AutoRestoreEffects are; | 750 AutoRestoreEffects are; |
772 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are); | 751 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are); |
773 | 752 |
774 SkRect devRect; | 753 SkMatrix combinedMatrix = target->drawState()->getViewMatrix(); |
775 SkMatrix combinedMatrix; | 754 if (NULL != matrix) { |
| 755 combinedMatrix.preConcat(*matrix); |
| 756 } |
| 757 |
| 758 // Check if this is a full RT draw and can be replaced with a clear. We don'
t bother checking |
| 759 // cases where the RT is fully inside a stroke. |
| 760 if (width < 0) { |
| 761 SkRect rtRect; |
| 762 target->getDrawState().getRenderTarget()->getBoundsRect(&rtRect); |
| 763 SkRect clipSpaceRTRect = rtRect; |
| 764 bool checkClip = false; |
| 765 if (NULL != this->getClip()) { |
| 766 checkClip = true; |
| 767 clipSpaceRTRect.offset(SkIntToScalar(this->getClip()->fOrigin.fX), |
| 768 SkIntToScalar(this->getClip()->fOrigin.fY)); |
| 769 } |
| 770 // Does the clip contain the entire RT? |
| 771 if (!checkClip || target->getClip()->fClipStack->quickContains(clipSpace
RTRect)) { |
| 772 SkMatrix invM; |
| 773 if (!combinedMatrix.invert(&invM)) { |
| 774 return; |
| 775 } |
| 776 // Does the rect bound the RT? |
| 777 SkPoint srcSpaceRTQuad[4]; |
| 778 invM.mapRectToQuad(srcSpaceRTQuad, rtRect); |
| 779 if (rect_contains_inclusive(rect, srcSpaceRTQuad[0]) && |
| 780 rect_contains_inclusive(rect, srcSpaceRTQuad[1]) && |
| 781 rect_contains_inclusive(rect, srcSpaceRTQuad[2]) && |
| 782 rect_contains_inclusive(rect, srcSpaceRTQuad[3])) { |
| 783 // Will it blend? |
| 784 GrColor clearColor; |
| 785 if (paint.isOpaqueAndConstantColor(&clearColor)) { |
| 786 target->clear(NULL, clearColor); |
| 787 return; |
| 788 } |
| 789 } |
| 790 } |
| 791 } |
| 792 |
| 793 SkRect devBoundRect; |
776 bool useVertexCoverage; | 794 bool useVertexCoverage; |
777 bool needAA = paint.isAntiAlias() && | 795 bool needAA = paint.isAntiAlias() && |
778 !target->getDrawState().getRenderTarget()->isMultisampled(); | 796 !target->getDrawState().getRenderTarget()->isMultisampled(); |
779 bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix, | 797 bool doAA = needAA && apply_aa_to_rect(target, rect, width, combinedMatrix,
&devBoundRect, |
780 &combinedMatrix, &devRect, | |
781 &useVertexCoverage); | 798 &useVertexCoverage); |
782 if (doAA) { | 799 if (doAA) { |
783 GrDrawState::AutoViewMatrixRestore avmr; | 800 GrDrawState::AutoViewMatrixRestore avmr; |
784 if (!avmr.setIdentity(target->drawState())) { | 801 if (!avmr.setIdentity(target->drawState())) { |
785 return; | 802 return; |
786 } | 803 } |
787 if (width >= 0) { | 804 if (width >= 0) { |
788 fAARectRenderer->strokeAARect(this->getGpu(), target, | 805 fAARectRenderer->strokeAARect(this->getGpu(), target, |
789 rect, combinedMatrix, devRect, | 806 rect, combinedMatrix, devBoundRect, |
790 width, useVertexCoverage); | 807 width, useVertexCoverage); |
791 } else { | 808 } else { |
792 // filled AA rect | 809 // filled AA rect |
793 fAARectRenderer->fillAARect(this->getGpu(), target, | 810 fAARectRenderer->fillAARect(this->getGpu(), target, |
794 rect, combinedMatrix, devRect, | 811 rect, combinedMatrix, devBoundRect, |
795 useVertexCoverage); | 812 useVertexCoverage); |
796 } | 813 } |
797 return; | 814 return; |
798 } | 815 } |
799 | 816 |
800 if (width >= 0) { | 817 if (width >= 0) { |
801 // TODO: consider making static vertex buffers for these cases. | 818 // TODO: consider making static vertex buffers for these cases. |
802 // Hairline could be done by just adding closing vertex to | 819 // Hairline could be done by just adding closing vertex to |
803 // unitSquareVertexBuffer() | 820 // unitSquareVertexBuffer() |
804 | 821 |
(...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1717 return NULL; | 1734 return NULL; |
1718 } | 1735 } |
1719 } | 1736 } |
1720 | 1737 |
1721 /////////////////////////////////////////////////////////////////////////////// | 1738 /////////////////////////////////////////////////////////////////////////////// |
1722 #if GR_CACHE_STATS | 1739 #if GR_CACHE_STATS |
1723 void GrContext::printCacheStats() const { | 1740 void GrContext::printCacheStats() const { |
1724 fTextureCache->printStats(); | 1741 fTextureCache->printStats(); |
1725 } | 1742 } |
1726 #endif | 1743 #endif |
OLD | NEW |