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 774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 !this->getRenderTarget()->isMultisampled(); | 785 !this->getRenderTarget()->isMultisampled(); |
786 bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix, | 786 bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix, |
787 &combinedMatrix, &devRect, | 787 &combinedMatrix, &devRect, |
788 &useVertexCoverage); | 788 &useVertexCoverage); |
789 if (doAA) { | 789 if (doAA) { |
790 GrDrawState::AutoDeviceCoordDraw adcd(target->drawState()); | 790 GrDrawState::AutoDeviceCoordDraw adcd(target->drawState()); |
791 if (!adcd.succeeded()) { | 791 if (!adcd.succeeded()) { |
792 return; | 792 return; |
793 } | 793 } |
794 if (width >= 0) { | 794 if (width >= 0) { |
795 GrVec strokeSize; | |
796 if (width > 0) { | |
797 strokeSize.set(width, width); | |
798 combinedMatrix.mapVectors(&strokeSize, 1); | |
799 strokeSize.setAbs(strokeSize); | |
800 } else { | |
801 strokeSize.set(SK_Scalar1, SK_Scalar1); | |
802 } | |
803 fAARectRenderer->strokeAARect(this->getGpu(), target, | 795 fAARectRenderer->strokeAARect(this->getGpu(), target, |
804 rect, combinedMatrix, devRect, | 796 rect, combinedMatrix, devRect, |
805 strokeSize, useVertexCoverage); | 797 width, useVertexCoverage); |
806 } else { | 798 } else { |
807 // filled AA rect | 799 // filled AA rect |
808 fAARectRenderer->fillAARect(this->getGpu(), target, | 800 fAARectRenderer->fillAARect(this->getGpu(), target, |
809 rect, combinedMatrix, devRect, | 801 rect, combinedMatrix, devRect, |
810 useVertexCoverage); | 802 useVertexCoverage); |
811 } | 803 } |
812 return; | 804 return; |
813 } | 805 } |
814 | 806 |
815 if (width >= 0) { | 807 if (width >= 0) { |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
997 !this->getRenderTarget()->isMultisampled() && | 989 !this->getRenderTarget()->isMultisampled() && |
998 !disable_coverage_aa_for_blend(target); | 990 !disable_coverage_aa_for_blend(target); |
999 | 991 |
1000 if (!fOvalRenderer->drawOval(target, this, useAA, oval, stroke)) { | 992 if (!fOvalRenderer->drawOval(target, this, useAA, oval, stroke)) { |
1001 SkPath path; | 993 SkPath path; |
1002 path.addOval(oval); | 994 path.addOval(oval); |
1003 this->internalDrawPath(target, useAA, path, stroke); | 995 this->internalDrawPath(target, useAA, path, stroke); |
1004 } | 996 } |
1005 } | 997 } |
1006 | 998 |
| 999 namespace { |
| 1000 |
| 1001 // Can 'path' be drawn as a pair of filled nested rectangles? |
| 1002 static bool is_nested_rects(GrDrawTarget* target, |
| 1003 const SkPath& path, |
| 1004 const SkStrokeRec& stroke, |
| 1005 SkRect rects[2], |
| 1006 bool* useVertexCoverage) { |
| 1007 SkASSERT(stroke.isFillStyle()); |
| 1008 |
| 1009 if (path.isInverseFillType()) { |
| 1010 return false; |
| 1011 } |
| 1012 |
| 1013 const GrDrawState& drawState = target->getDrawState(); |
| 1014 |
| 1015 // TODO: this restriction could be lifted if we were willing to apply |
| 1016 // the matrix to all the points individually rather than just to the rect |
| 1017 if (!drawState.getViewMatrix().preservesAxisAlignment()) { |
| 1018 return false; |
| 1019 } |
| 1020 |
| 1021 *useVertexCoverage = false; |
| 1022 if (!target->getDrawState().canTweakAlphaForCoverage()) { |
| 1023 if (disable_coverage_aa_for_blend(target)) { |
| 1024 return false; |
| 1025 } else { |
| 1026 *useVertexCoverage = true; |
| 1027 } |
| 1028 } |
| 1029 |
| 1030 SkPath::Direction dirs[2]; |
| 1031 if (!path.isNestedRects(rects, dirs)) { |
| 1032 return false; |
| 1033 } |
| 1034 |
| 1035 if (SkPath::kWinding_FillType == path.getFillType()) { |
| 1036 // The two rects need to be wound opposite to each other |
| 1037 return dirs[0] != dirs[1]; |
| 1038 } else { |
| 1039 return true; |
| 1040 } |
| 1041 } |
| 1042 |
| 1043 }; |
| 1044 |
1007 void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const SkStrok
eRec& stroke) { | 1045 void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const SkStrok
eRec& stroke) { |
1008 | 1046 |
1009 if (path.isEmpty()) { | 1047 if (path.isEmpty()) { |
1010 if (path.isInverseFillType()) { | 1048 if (path.isInverseFillType()) { |
1011 this->drawPaint(paint); | 1049 this->drawPaint(paint); |
1012 } | 1050 } |
1013 return; | 1051 return; |
1014 } | 1052 } |
1015 | 1053 |
1016 // Note that internalDrawPath may sw-rasterize the path into a scratch textu
re. | 1054 // Note that internalDrawPath may sw-rasterize the path into a scratch textu
re. |
1017 // Scratch textures can be recycled after they are returned to the texture | 1055 // Scratch textures can be recycled after they are returned to the texture |
1018 // cache. This presents a potential hazard for buffered drawing. However, | 1056 // cache. This presents a potential hazard for buffered drawing. However, |
1019 // the writePixels that uploads to the scratch will perform a flush so we're | 1057 // the writePixels that uploads to the scratch will perform a flush so we're |
1020 // OK. | 1058 // OK. |
1021 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW); | 1059 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW); |
1022 GrDrawState::AutoStageDisable atr(fDrawState); | 1060 GrDrawState::AutoStageDisable atr(fDrawState); |
1023 | 1061 |
| 1062 bool useAA = paint.isAntiAlias() && !this->getRenderTarget()->isMultisampled
(); |
| 1063 if (useAA && stroke.getWidth() < 0 && !path.isConvex()) { |
| 1064 // Concave AA paths are expensive - try to avoid them for special cases |
| 1065 bool useVertexCoverage; |
| 1066 SkRect rects[2]; |
| 1067 |
| 1068 if (is_nested_rects(target, path, stroke, rects, &useVertexCoverage)) { |
| 1069 GrDrawState::AutoDeviceCoordDraw adcd(target->drawState()); |
| 1070 if (!adcd.succeeded()) { |
| 1071 return; |
| 1072 } |
| 1073 |
| 1074 fAARectRenderer->fillAANestedRects(this->getGpu(), target, |
| 1075 rects, |
| 1076 adcd.getOriginalMatrix(), |
| 1077 useVertexCoverage); |
| 1078 return; |
| 1079 } |
| 1080 } |
| 1081 |
1024 SkRect ovalRect; | 1082 SkRect ovalRect; |
1025 bool isOval = path.isOval(&ovalRect); | 1083 bool isOval = path.isOval(&ovalRect); |
1026 bool useAA = paint.isAntiAlias() && !this->getRenderTarget()->isMultisampled
(); | |
1027 | 1084 |
1028 if (!isOval || path.isInverseFillType() | 1085 if (!isOval || path.isInverseFillType() |
1029 || !fOvalRenderer->drawOval(target, this, useAA, ovalRect, stroke)) { | 1086 || !fOvalRenderer->drawOval(target, this, useAA, ovalRect, stroke)) { |
1030 this->internalDrawPath(target, useAA, path, stroke); | 1087 this->internalDrawPath(target, useAA, path, stroke); |
1031 } | 1088 } |
1032 } | 1089 } |
1033 | 1090 |
1034 void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath&
path, | 1091 void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath&
path, |
1035 const SkStrokeRec& stroke) { | 1092 const SkStrokeRec& stroke) { |
1036 | 1093 |
(...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1804 return srcTexture; | 1861 return srcTexture; |
1805 } | 1862 } |
1806 } | 1863 } |
1807 | 1864 |
1808 /////////////////////////////////////////////////////////////////////////////// | 1865 /////////////////////////////////////////////////////////////////////////////// |
1809 #if GR_CACHE_STATS | 1866 #if GR_CACHE_STATS |
1810 void GrContext::printCacheStats() const { | 1867 void GrContext::printCacheStats() const { |
1811 fTextureCache->printStats(); | 1868 fTextureCache->printStats(); |
1812 } | 1869 } |
1813 #endif | 1870 #endif |
OLD | NEW |