| 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 701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 712 verts[2].set(rect.fRight - rad, rect.fTop + rad); | 712 verts[2].set(rect.fRight - rad, rect.fTop + rad); |
| 713 verts[3].set(rect.fRight + rad, rect.fTop - rad); | 713 verts[3].set(rect.fRight + rad, rect.fTop - rad); |
| 714 verts[4].set(rect.fRight - rad, rect.fBottom - rad); | 714 verts[4].set(rect.fRight - rad, rect.fBottom - rad); |
| 715 verts[5].set(rect.fRight + rad, rect.fBottom + rad); | 715 verts[5].set(rect.fRight + rad, rect.fBottom + rad); |
| 716 verts[6].set(rect.fLeft + rad, rect.fBottom - rad); | 716 verts[6].set(rect.fLeft + rad, rect.fBottom - rad); |
| 717 verts[7].set(rect.fLeft - rad, rect.fBottom + rad); | 717 verts[7].set(rect.fLeft - rad, rect.fBottom + rad); |
| 718 verts[8] = verts[0]; | 718 verts[8] = verts[0]; |
| 719 verts[9] = verts[1]; | 719 verts[9] = verts[1]; |
| 720 } | 720 } |
| 721 | 721 |
| 722 static bool isIRect(const SkRect& r) { | |
| 723 return SkScalarIsInt(r.fLeft) && SkScalarIsInt(r.fTop) && | |
| 724 SkScalarIsInt(r.fRight) && SkScalarIsInt(r.fBottom); | |
| 725 } | |
| 726 | |
| 727 static bool apply_aa_to_rect(GrDrawTarget* target, | 722 static bool apply_aa_to_rect(GrDrawTarget* target, |
| 728 const SkRect& rect, | 723 const SkRect& rect, |
| 729 SkScalar strokeWidth, | 724 SkScalar strokeWidth, |
| 730 const SkMatrix& combinedMatrix, | 725 const SkMatrix& combinedMatrix, |
| 731 SkRect* devBoundRect, | 726 SkRect* devBoundRect) { |
| 732 bool* useVertexCoverage) { | 727 if (!target->getDrawState().canTweakAlphaForCoverage() && |
| 733 // we use a simple coverage ramp to do aa on axis-aligned rects | 728 target->shouldDisableCoverageAAForBlend()) { |
| 734 // we check if the rect will be axis-aligned, and the rect won't land on | |
| 735 // integer coords. | |
| 736 | |
| 737 // we are keeping around the "tweak the alpha" trick because | |
| 738 // it is our only hope for the fixed-pipe implementation. | |
| 739 // In a shader implementation we can give a separate coverage input | |
| 740 // TODO: remove this ugliness when we drop the fixed-pipe impl | |
| 741 *useVertexCoverage = false; | |
| 742 if (!target->getDrawState().canTweakAlphaForCoverage()) { | |
| 743 if (target->shouldDisableCoverageAAForBlend()) { | |
| 744 #ifdef SK_DEBUG | 729 #ifdef SK_DEBUG |
| 745 //GrPrintf("Turning off AA to correctly apply blend.\n"); | 730 //GrPrintf("Turning off AA to correctly apply blend.\n"); |
| 746 #endif | 731 #endif |
| 747 return false; | 732 return false; |
| 748 } else { | |
| 749 *useVertexCoverage = true; | |
| 750 } | |
| 751 } | 733 } |
| 752 const GrDrawState& drawState = target->getDrawState(); | 734 const GrDrawState& drawState = target->getDrawState(); |
| 753 if (drawState.getRenderTarget()->isMultisampled()) { | 735 if (drawState.getRenderTarget()->isMultisampled()) { |
| 754 return false; | 736 return false; |
| 755 } | 737 } |
| 756 | 738 |
| 757 #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) | 739 #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) |
| 758 if (strokeWidth >= 0) { | 740 if (strokeWidth >= 0) { |
| 759 #endif | 741 #endif |
| 760 if (!combinedMatrix.preservesAxisAlignment()) { | 742 if (!combinedMatrix.preservesAxisAlignment()) { |
| 761 return false; | 743 return false; |
| 762 } | 744 } |
| 763 | 745 |
| 764 #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) | 746 #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) |
| 765 } else { | 747 } else { |
| 766 if (!combinedMatrix.preservesRightAngles()) { | 748 if (!combinedMatrix.preservesRightAngles()) { |
| 767 return false; | 749 return false; |
| 768 } | 750 } |
| 769 } | 751 } |
| 770 #endif | 752 #endif |
| 771 | 753 |
| 772 combinedMatrix.mapRect(devBoundRect, rect); | 754 combinedMatrix.mapRect(devBoundRect, rect); |
| 773 | 755 |
| 774 if (strokeWidth < 0) { | 756 return true; |
| 775 return !isIRect(*devBoundRect); | |
| 776 } else { | |
| 777 return true; | |
| 778 } | |
| 779 } | 757 } |
| 780 | 758 |
| 781 static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& po
int) { | 759 static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& po
int) { |
| 782 return point.fX >= rect.fLeft && point.fX <= rect.fRight && | 760 return point.fX >= rect.fLeft && point.fX <= rect.fRight && |
| 783 point.fY >= rect.fTop && point.fY <= rect.fBottom; | 761 point.fY >= rect.fTop && point.fY <= rect.fBottom; |
| 784 } | 762 } |
| 785 | 763 |
| 786 void GrContext::drawRect(const GrPaint& paint, | 764 void GrContext::drawRect(const GrPaint& paint, |
| 787 const SkRect& rect, | 765 const SkRect& rect, |
| 788 const GrStrokeInfo* strokeInfo) { | 766 const GrStrokeInfo* strokeInfo) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 833 GrColor clearColor; | 811 GrColor clearColor; |
| 834 if (paint.isOpaqueAndConstantColor(&clearColor)) { | 812 if (paint.isOpaqueAndConstantColor(&clearColor)) { |
| 835 target->clear(NULL, clearColor, true); | 813 target->clear(NULL, clearColor, true); |
| 836 return; | 814 return; |
| 837 } | 815 } |
| 838 } | 816 } |
| 839 } | 817 } |
| 840 } | 818 } |
| 841 | 819 |
| 842 SkRect devBoundRect; | 820 SkRect devBoundRect; |
| 843 bool useVertexCoverage; | |
| 844 bool needAA = paint.isAntiAlias() && | 821 bool needAA = paint.isAntiAlias() && |
| 845 !target->getDrawState().getRenderTarget()->isMultisampled(); | 822 !target->getDrawState().getRenderTarget()->isMultisampled(); |
| 846 bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix, &devBoun
dRect, | 823 bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix, &devBoun
dRect); |
| 847 &useVertexCoverage); | |
| 848 | 824 |
| 849 const SkStrokeRec& strokeRec = strokeInfo->getStrokeRec(); | 825 const SkStrokeRec& strokeRec = strokeInfo->getStrokeRec(); |
| 850 | 826 |
| 851 if (doAA) { | 827 if (doAA) { |
| 852 GrDrawState::AutoViewMatrixRestore avmr; | 828 GrDrawState::AutoViewMatrixRestore avmr; |
| 853 if (!avmr.setIdentity(target->drawState())) { | 829 if (!avmr.setIdentity(target->drawState())) { |
| 854 return; | 830 return; |
| 855 } | 831 } |
| 856 if (width >= 0) { | 832 if (width >= 0) { |
| 857 fAARectRenderer->strokeAARect(this->getGpu(), target, rect, | 833 fAARectRenderer->strokeAARect(this->getGpu(), target, rect, |
| 858 matrix, devBoundRect, | 834 matrix, devBoundRect, |
| 859 strokeRec, useVertexCoverage); | 835 strokeRec); |
| 860 } else { | 836 } else { |
| 861 // filled AA rect | 837 // filled AA rect |
| 862 fAARectRenderer->fillAARect(this->getGpu(), target, | 838 fAARectRenderer->fillAARect(this->getGpu(), target, |
| 863 rect, matrix, devBoundRect, | 839 rect, matrix, devBoundRect); |
| 864 useVertexCoverage); | |
| 865 } | 840 } |
| 866 return; | 841 return; |
| 867 } | 842 } |
| 868 | 843 |
| 869 if (width >= 0) { | 844 if (width >= 0) { |
| 870 // TODO: consider making static vertex buffers for these cases. | 845 // TODO: consider making static vertex buffers for these cases. |
| 871 // Hairline could be done by just adding closing vertex to | 846 // Hairline could be done by just adding closing vertex to |
| 872 // unitSquareVertexBuffer() | 847 // unitSquareVertexBuffer() |
| 873 | 848 |
| 874 static const int worstCaseVertCount = 10; | 849 static const int worstCaseVertCount = 10; |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1110 SkPath path; | 1085 SkPath path; |
| 1111 path.addOval(oval); | 1086 path.addOval(oval); |
| 1112 this->internalDrawPath(target, paint.isAntiAlias(), path, strokeInfo); | 1087 this->internalDrawPath(target, paint.isAntiAlias(), path, strokeInfo); |
| 1113 } | 1088 } |
| 1114 } | 1089 } |
| 1115 | 1090 |
| 1116 // Can 'path' be drawn as a pair of filled nested rectangles? | 1091 // Can 'path' be drawn as a pair of filled nested rectangles? |
| 1117 static bool is_nested_rects(GrDrawTarget* target, | 1092 static bool is_nested_rects(GrDrawTarget* target, |
| 1118 const SkPath& path, | 1093 const SkPath& path, |
| 1119 const SkStrokeRec& stroke, | 1094 const SkStrokeRec& stroke, |
| 1120 SkRect rects[2], | 1095 SkRect rects[2]) { |
| 1121 bool* useVertexCoverage) { | |
| 1122 SkASSERT(stroke.isFillStyle()); | 1096 SkASSERT(stroke.isFillStyle()); |
| 1123 | 1097 |
| 1124 if (path.isInverseFillType()) { | 1098 if (path.isInverseFillType()) { |
| 1125 return false; | 1099 return false; |
| 1126 } | 1100 } |
| 1127 | 1101 |
| 1128 const GrDrawState& drawState = target->getDrawState(); | 1102 const GrDrawState& drawState = target->getDrawState(); |
| 1129 | 1103 |
| 1130 // TODO: this restriction could be lifted if we were willing to apply | 1104 // TODO: this restriction could be lifted if we were willing to apply |
| 1131 // the matrix to all the points individually rather than just to the rect | 1105 // the matrix to all the points individually rather than just to the rect |
| 1132 if (!drawState.getViewMatrix().preservesAxisAlignment()) { | 1106 if (!drawState.getViewMatrix().preservesAxisAlignment()) { |
| 1133 return false; | 1107 return false; |
| 1134 } | 1108 } |
| 1135 | 1109 |
| 1136 *useVertexCoverage = false; | 1110 if (!target->getDrawState().canTweakAlphaForCoverage() && |
| 1137 if (!target->getDrawState().canTweakAlphaForCoverage()) { | 1111 target->shouldDisableCoverageAAForBlend()) { |
| 1138 if (target->shouldDisableCoverageAAForBlend()) { | 1112 return false; |
| 1139 return false; | |
| 1140 } else { | |
| 1141 *useVertexCoverage = true; | |
| 1142 } | |
| 1143 } | 1113 } |
| 1144 | 1114 |
| 1145 SkPath::Direction dirs[2]; | 1115 SkPath::Direction dirs[2]; |
| 1146 if (!path.isNestedRects(rects, dirs)) { | 1116 if (!path.isNestedRects(rects, dirs)) { |
| 1147 return false; | 1117 return false; |
| 1148 } | 1118 } |
| 1149 | 1119 |
| 1150 if (SkPath::kWinding_FillType == path.getFillType() && dirs[0] == dirs[1]) { | 1120 if (SkPath::kWinding_FillType == path.getFillType() && dirs[0] == dirs[1]) { |
| 1151 // The two rects need to be wound opposite to each other | 1121 // The two rects need to be wound opposite to each other |
| 1152 return false; | 1122 return false; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1226 GrDrawState* drawState = target->drawState(); | 1196 GrDrawState* drawState = target->drawState(); |
| 1227 | 1197 |
| 1228 GR_CREATE_TRACE_MARKER1("GrContext::drawPath", target, "Is Convex", path.isC
onvex()); | 1198 GR_CREATE_TRACE_MARKER1("GrContext::drawPath", target, "Is Convex", path.isC
onvex()); |
| 1229 | 1199 |
| 1230 const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec(); | 1200 const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec(); |
| 1231 | 1201 |
| 1232 bool useCoverageAA = paint.isAntiAlias() && !drawState->getRenderTarget()->i
sMultisampled(); | 1202 bool useCoverageAA = paint.isAntiAlias() && !drawState->getRenderTarget()->i
sMultisampled(); |
| 1233 | 1203 |
| 1234 if (useCoverageAA && strokeRec.getWidth() < 0 && !path.isConvex()) { | 1204 if (useCoverageAA && strokeRec.getWidth() < 0 && !path.isConvex()) { |
| 1235 // Concave AA paths are expensive - try to avoid them for special cases | 1205 // Concave AA paths are expensive - try to avoid them for special cases |
| 1236 bool useVertexCoverage; | |
| 1237 SkRect rects[2]; | 1206 SkRect rects[2]; |
| 1238 | 1207 |
| 1239 if (is_nested_rects(target, path, strokeRec, rects, &useVertexCoverage))
{ | 1208 if (is_nested_rects(target, path, strokeRec, rects)) { |
| 1240 SkMatrix origViewMatrix = drawState->getViewMatrix(); | 1209 SkMatrix origViewMatrix = drawState->getViewMatrix(); |
| 1241 GrDrawState::AutoViewMatrixRestore avmr; | 1210 GrDrawState::AutoViewMatrixRestore avmr; |
| 1242 if (!avmr.setIdentity(target->drawState())) { | 1211 if (!avmr.setIdentity(target->drawState())) { |
| 1243 return; | 1212 return; |
| 1244 } | 1213 } |
| 1245 | 1214 |
| 1246 fAARectRenderer->fillAANestedRects(this->getGpu(), target, | 1215 fAARectRenderer->fillAANestedRects(this->getGpu(), target, rects, or
igViewMatrix); |
| 1247 rects, | |
| 1248 origViewMatrix, | |
| 1249 useVertexCoverage); | |
| 1250 return; | 1216 return; |
| 1251 } | 1217 } |
| 1252 } | 1218 } |
| 1253 | 1219 |
| 1254 SkRect ovalRect; | 1220 SkRect ovalRect; |
| 1255 bool isOval = path.isOval(&ovalRect); | 1221 bool isOval = path.isOval(&ovalRect); |
| 1256 | 1222 |
| 1257 if (!isOval || path.isInverseFillType() | 1223 if (!isOval || path.isInverseFillType() |
| 1258 || !fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), ovalRect,
strokeRec)) { | 1224 || !fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), ovalRect,
strokeRec)) { |
| 1259 this->internalDrawPath(target, paint.isAntiAlias(), path, strokeInfo); | 1225 this->internalDrawPath(target, paint.isAntiAlias(), path, strokeInfo); |
| (...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1754 #if GR_DEBUG_PARTIAL_COVERAGE_CHECK | 1720 #if GR_DEBUG_PARTIAL_COVERAGE_CHECK |
| 1755 if ((paint->hasMask() || 0xff != paint->fCoverage) && | 1721 if ((paint->hasMask() || 0xff != paint->fCoverage) && |
| 1756 !fDrawState->couldApplyCoverage(fGpu->caps())) { | 1722 !fDrawState->couldApplyCoverage(fGpu->caps())) { |
| 1757 GrPrintf("Partial pixel coverage will be incorrectly blended.\n"); | 1723 GrPrintf("Partial pixel coverage will be incorrectly blended.\n"); |
| 1758 } | 1724 } |
| 1759 #endif | 1725 #endif |
| 1760 if (fDrawState->getBlendOpts() & GrDrawState::kSkipDraw_BlendOptFlag) { | 1726 if (fDrawState->getBlendOpts() & GrDrawState::kSkipDraw_BlendOptFlag) { |
| 1761 are->set(NULL); | 1727 are->set(NULL); |
| 1762 return NULL; | 1728 return NULL; |
| 1763 } | 1729 } |
| 1730 // Clear any vertex attributes configured for the previous use of the |
| 1731 // GrDrawState which can effect which blend optimizations are in effect. |
| 1732 fDrawState->setDefaultVertexAttribs(); |
| 1764 } else { | 1733 } else { |
| 1765 fDrawState->reset(fViewMatrix); | 1734 fDrawState->reset(fViewMatrix); |
| 1766 fDrawState->setRenderTarget(fRenderTarget.get()); | 1735 fDrawState->setRenderTarget(fRenderTarget.get()); |
| 1767 } | 1736 } |
| 1768 GrDrawTarget* target; | 1737 GrDrawTarget* target; |
| 1769 if (kYes_BufferedDraw == buffered) { | 1738 if (kYes_BufferedDraw == buffered) { |
| 1770 fLastDrawWasBuffered = kYes_BufferedDraw; | 1739 fLastDrawWasBuffered = kYes_BufferedDraw; |
| 1771 target = fDrawBuffer; | 1740 target = fDrawBuffer; |
| 1772 } else { | 1741 } else { |
| 1773 SkASSERT(kNo_BufferedDraw == buffered); | 1742 SkASSERT(kNo_BufferedDraw == buffered); |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1947 fDrawBuffer->removeGpuTraceMarker(marker); | 1916 fDrawBuffer->removeGpuTraceMarker(marker); |
| 1948 } | 1917 } |
| 1949 } | 1918 } |
| 1950 | 1919 |
| 1951 /////////////////////////////////////////////////////////////////////////////// | 1920 /////////////////////////////////////////////////////////////////////////////// |
| 1952 #if GR_CACHE_STATS | 1921 #if GR_CACHE_STATS |
| 1953 void GrContext::printCacheStats() const { | 1922 void GrContext::printCacheStats() const { |
| 1954 fResourceCache->printStats(); | 1923 fResourceCache->printStats(); |
| 1955 } | 1924 } |
| 1956 #endif | 1925 #endif |
| OLD | NEW |