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" |
11 | 11 |
12 #include "effects/GrSingleTextureEffect.h" | 12 #include "effects/GrSingleTextureEffect.h" |
13 #include "effects/GrConfigConversionEffect.h" | 13 #include "effects/GrConfigConversionEffect.h" |
14 | 14 |
15 #include "GrAARectRenderer.h" | 15 #include "GrAARectRenderer.h" |
16 #include "GrBufferAllocPool.h" | 16 #include "GrBufferAllocPool.h" |
17 #include "GrGpu.h" | 17 #include "GrGpu.h" |
18 #include "GrDrawTargetCaps.h" | 18 #include "GrDrawTargetCaps.h" |
19 #include "GrIndexBuffer.h" | 19 #include "GrIndexBuffer.h" |
20 #include "GrInOrderDrawBuffer.h" | 20 #include "GrInOrderDrawBuffer.h" |
21 #include "GrLayerCache.h" | 21 #include "GrLayerCache.h" |
22 #include "GrOvalRenderer.h" | 22 #include "GrOvalRenderer.h" |
23 #include "GrPathRenderer.h" | 23 #include "GrPathRenderer.h" |
24 #include "GrPaintStyle.h" | |
24 #include "GrPathUtils.h" | 25 #include "GrPathUtils.h" |
25 #include "GrResourceCache.h" | 26 #include "GrResourceCache.h" |
26 #include "GrSoftwarePathRenderer.h" | 27 #include "GrSoftwarePathRenderer.h" |
27 #include "GrStencilBuffer.h" | 28 #include "GrStencilBuffer.h" |
28 #include "GrTextStrike.h" | 29 #include "GrTextStrike.h" |
29 #include "GrTracing.h" | 30 #include "GrTracing.h" |
31 #include "SkDashPathPriv.h" | |
30 #include "SkGr.h" | 32 #include "SkGr.h" |
31 #include "SkRTConf.h" | 33 #include "SkRTConf.h" |
32 #include "SkRRect.h" | 34 #include "SkRRect.h" |
33 #include "SkStrokeRec.h" | 35 #include "SkStrokeRec.h" |
34 #include "SkTLazy.h" | 36 #include "SkTLazy.h" |
35 #include "SkTLS.h" | 37 #include "SkTLS.h" |
36 #include "SkTraceEvent.h" | 38 #include "SkTraceEvent.h" |
37 | 39 |
38 // It can be useful to set this to false to test whether a bug is caused by usin g the | 40 // It can be useful to set this to false to test whether a bug is caused by usin g the |
39 // InOrderDrawBuffer, to compare performance of using/not using InOrderDrawBuffe r, or to make | 41 // InOrderDrawBuffer, to compare performance of using/not using InOrderDrawBuffe r, or to make |
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
768 } | 770 } |
769 } | 771 } |
770 | 772 |
771 static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& po int) { | 773 static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& po int) { |
772 return point.fX >= rect.fLeft && point.fX <= rect.fRight && | 774 return point.fX >= rect.fLeft && point.fX <= rect.fRight && |
773 point.fY >= rect.fTop && point.fY <= rect.fBottom; | 775 point.fY >= rect.fTop && point.fY <= rect.fBottom; |
774 } | 776 } |
775 | 777 |
776 void GrContext::drawRect(const GrPaint& paint, | 778 void GrContext::drawRect(const GrPaint& paint, |
777 const SkRect& rect, | 779 const SkRect& rect, |
778 const SkStrokeRec* stroke, | 780 const GrPaintStyle* style, |
779 const SkMatrix* matrix) { | 781 const SkMatrix* matrix) { |
780 AutoRestoreEffects are; | 782 AutoRestoreEffects are; |
781 AutoCheckFlush acf(this); | 783 AutoCheckFlush acf(this); |
782 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf ); | 784 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf ); |
783 | 785 |
784 GR_CREATE_TRACE_MARKER("GrContext::drawRect", target); | 786 GR_CREATE_TRACE_MARKER("GrContext::drawRect", target); |
785 | 787 |
788 SkStrokeRec* stroke = style ? style->getStrokeRec() : NULL; | |
789 | |
790 if (style && style->hasDashInfo()) { | |
791 const SkPathEffect::DashInfo* info = style->getDashInfo(); | |
792 SkTLazy<SkPath> effectPath; | |
793 SkPath path; | |
794 path.addRect(rect); | |
795 SkPath* pathPtr = &path; | |
796 const SkRect* cullRect = NULL; | |
797 if (SkDashPath::FilterDashPath(effectPath.init(), path, stroke, cullRect , *info)) { | |
bsalomon
2014/06/04 19:05:05
I think this should just call drawPath with the un
egdaniel
2014/06/05 17:18:15
done
| |
798 pathPtr = effectPath.get(); | |
799 } | |
800 this->drawPath(paint, *pathPtr, *style); | |
801 return; | |
802 } | |
803 | |
786 SkScalar width = stroke == NULL ? -1 : stroke->getWidth(); | 804 SkScalar width = stroke == NULL ? -1 : stroke->getWidth(); |
787 SkMatrix combinedMatrix = target->drawState()->getViewMatrix(); | 805 SkMatrix combinedMatrix = target->drawState()->getViewMatrix(); |
788 if (NULL != matrix) { | 806 if (NULL != matrix) { |
789 combinedMatrix.preConcat(*matrix); | 807 combinedMatrix.preConcat(*matrix); |
790 } | 808 } |
791 | 809 |
792 // Check if this is a full RT draw and can be replaced with a clear. We don' t bother checking | 810 // Check if this is a full RT draw and can be replaced with a clear. We don' t bother checking |
793 // cases where the RT is fully inside a stroke. | 811 // cases where the RT is fully inside a stroke. |
794 if (width < 0) { | 812 if (width < 0) { |
795 SkRect rtRect; | 813 SkRect rtRect; |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
999 target->resetIndexSource(); | 1017 target->resetIndexSource(); |
1000 } else { | 1018 } else { |
1001 target->drawNonIndexed(primitiveType, 0, vertexCount); | 1019 target->drawNonIndexed(primitiveType, 0, vertexCount); |
1002 } | 1020 } |
1003 } | 1021 } |
1004 | 1022 |
1005 /////////////////////////////////////////////////////////////////////////////// | 1023 /////////////////////////////////////////////////////////////////////////////// |
1006 | 1024 |
1007 void GrContext::drawRRect(const GrPaint& paint, | 1025 void GrContext::drawRRect(const GrPaint& paint, |
1008 const SkRRect& rrect, | 1026 const SkRRect& rrect, |
1009 const SkStrokeRec& stroke) { | 1027 const GrPaintStyle& style) { |
1010 if (rrect.isEmpty()) { | 1028 if (rrect.isEmpty()) { |
1011 return; | 1029 return; |
1012 } | 1030 } |
1013 | 1031 |
1014 AutoRestoreEffects are; | 1032 AutoRestoreEffects are; |
1015 AutoCheckFlush acf(this); | 1033 AutoCheckFlush acf(this); |
1016 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf ); | 1034 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf ); |
1017 | 1035 |
1018 GR_CREATE_TRACE_MARKER("GrContext::drawRRect", target); | 1036 GR_CREATE_TRACE_MARKER("GrContext::drawRRect", target); |
1019 | 1037 |
1020 if (!fOvalRenderer->drawRRect(target, this, paint.isAntiAlias(), rrect, stro ke)) { | 1038 SkStrokeRec* stroke = style.getStrokeRec(); |
1039 | |
1040 if (style.hasDashInfo()) { | |
1041 const SkPathEffect::DashInfo* info = style.getDashInfo(); | |
1042 SkTLazy<SkPath> effectPath; | |
1021 SkPath path; | 1043 SkPath path; |
1022 path.addRRect(rrect); | 1044 path.addRRect(rrect); |
1023 this->internalDrawPath(target, paint.isAntiAlias(), path, stroke); | 1045 SkPath* pathPtr = &path; |
1046 const SkRect* cullRect = NULL; | |
1047 if (SkDashPath::FilterDashPath(effectPath.init(), path, stroke, cullRect , *info)) { | |
1048 pathPtr = effectPath.get(); | |
1049 } | |
1050 this->drawPath(paint, *pathPtr, style); | |
1051 return; | |
1052 } | |
1053 | |
1054 if (!fOvalRenderer->drawRRect(target, this, paint.isAntiAlias(), rrect, *str oke)) { | |
1055 SkPath path; | |
1056 path.addRRect(rrect); | |
1057 this->internalDrawPath(target, paint.isAntiAlias(), path, *stroke); | |
1024 } | 1058 } |
1025 } | 1059 } |
1026 | 1060 |
1027 /////////////////////////////////////////////////////////////////////////////// | 1061 /////////////////////////////////////////////////////////////////////////////// |
1028 | 1062 |
1029 void GrContext::drawDRRect(const GrPaint& paint, | 1063 void GrContext::drawDRRect(const GrPaint& paint, |
1030 const SkRRect& outer, | 1064 const SkRRect& outer, |
1031 const SkRRect& inner) { | 1065 const SkRRect& inner) { |
1032 if (outer.isEmpty()) { | 1066 if (outer.isEmpty()) { |
1033 return; | 1067 return; |
(...skipping 13 matching lines...) Expand all Loading... | |
1047 | 1081 |
1048 SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle); | 1082 SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle); |
1049 this->internalDrawPath(target, paint.isAntiAlias(), path, fillRec); | 1083 this->internalDrawPath(target, paint.isAntiAlias(), path, fillRec); |
1050 } | 1084 } |
1051 } | 1085 } |
1052 | 1086 |
1053 /////////////////////////////////////////////////////////////////////////////// | 1087 /////////////////////////////////////////////////////////////////////////////// |
1054 | 1088 |
1055 void GrContext::drawOval(const GrPaint& paint, | 1089 void GrContext::drawOval(const GrPaint& paint, |
1056 const SkRect& oval, | 1090 const SkRect& oval, |
1057 const SkStrokeRec& stroke) { | 1091 const GrPaintStyle& style) { |
1058 if (oval.isEmpty()) { | 1092 if (oval.isEmpty()) { |
1059 return; | 1093 return; |
1060 } | 1094 } |
1061 | 1095 |
1062 AutoRestoreEffects are; | 1096 AutoRestoreEffects are; |
1063 AutoCheckFlush acf(this); | 1097 AutoCheckFlush acf(this); |
1064 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf ); | 1098 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf ); |
1065 | 1099 |
1066 GR_CREATE_TRACE_MARKER("GrContext::drawOval", target); | 1100 GR_CREATE_TRACE_MARKER("GrContext::drawOval", target); |
1067 | 1101 |
1068 if (!fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), oval, stroke )) { | 1102 SkStrokeRec* stroke = style.getStrokeRec(); |
1103 | |
1104 if (style.hasDashInfo()) { | |
1105 const SkPathEffect::DashInfo* info = style.getDashInfo(); | |
1106 SkTLazy<SkPath> effectPath; | |
1069 SkPath path; | 1107 SkPath path; |
1070 path.addOval(oval); | 1108 path.addOval(oval); |
1071 this->internalDrawPath(target, paint.isAntiAlias(), path, stroke); | 1109 SkPath* pathPtr = &path; |
1110 const SkRect* cullRect = NULL; | |
1111 if (SkDashPath::FilterDashPath(effectPath.init(), path, stroke, cullRect , *info)) { | |
1112 pathPtr = effectPath.get(); | |
1113 } | |
1114 this->drawPath(paint, *pathPtr, style); | |
1115 return; | |
1116 } | |
1117 | |
1118 if (!fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), oval, *strok e)) { | |
1119 SkPath path; | |
1120 path.addOval(oval); | |
1121 this->internalDrawPath(target, paint.isAntiAlias(), path, *stroke); | |
1072 } | 1122 } |
1073 } | 1123 } |
1074 | 1124 |
1075 // Can 'path' be drawn as a pair of filled nested rectangles? | 1125 // Can 'path' be drawn as a pair of filled nested rectangles? |
1076 static bool is_nested_rects(GrDrawTarget* target, | 1126 static bool is_nested_rects(GrDrawTarget* target, |
1077 const SkPath& path, | 1127 const SkPath& path, |
1078 const SkStrokeRec& stroke, | 1128 const SkStrokeRec& stroke, |
1079 SkRect rects[2], | 1129 SkRect rects[2], |
1080 bool* useVertexCoverage) { | 1130 bool* useVertexCoverage) { |
1081 SkASSERT(stroke.isFillStyle()); | 1131 SkASSERT(stroke.isFillStyle()); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1120 for (int i = 1; i < 4; ++i) { | 1170 for (int i = 1; i < 4; ++i) { |
1121 SkScalar temp = SkScalarAbs(outer[i] - inner[i]); | 1171 SkScalar temp = SkScalarAbs(outer[i] - inner[i]); |
1122 if (!SkScalarNearlyEqual(margin, temp)) { | 1172 if (!SkScalarNearlyEqual(margin, temp)) { |
1123 return false; | 1173 return false; |
1124 } | 1174 } |
1125 } | 1175 } |
1126 | 1176 |
1127 return true; | 1177 return true; |
1128 } | 1178 } |
1129 | 1179 |
1130 void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const SkStrok eRec& stroke) { | 1180 void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const GrPaint Style& style) { |
1131 | 1181 |
1132 if (path.isEmpty()) { | 1182 if (path.isEmpty()) { |
1133 if (path.isInverseFillType()) { | 1183 if (path.isInverseFillType()) { |
1134 this->drawPaint(paint); | 1184 this->drawPaint(paint); |
1135 } | 1185 } |
1136 return; | 1186 return; |
1137 } | 1187 } |
1138 | 1188 |
1139 // Note that internalDrawPath may sw-rasterize the path into a scratch textu re. | 1189 // Note that internalDrawPath may sw-rasterize the path into a scratch textu re. |
1140 // Scratch textures can be recycled after they are returned to the texture | 1190 // Scratch textures can be recycled after they are returned to the texture |
1141 // cache. This presents a potential hazard for buffered drawing. However, | 1191 // cache. This presents a potential hazard for buffered drawing. However, |
1142 // the writePixels that uploads to the scratch will perform a flush so we're | 1192 // the writePixels that uploads to the scratch will perform a flush so we're |
1143 // OK. | 1193 // OK. |
1144 AutoRestoreEffects are; | 1194 AutoRestoreEffects are; |
1145 AutoCheckFlush acf(this); | 1195 AutoCheckFlush acf(this); |
1146 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf ); | 1196 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf ); |
1147 GrDrawState* drawState = target->drawState(); | 1197 GrDrawState* drawState = target->drawState(); |
1148 | 1198 |
1149 GR_CREATE_TRACE_MARKER("GrContext::drawPath", target); | 1199 GR_CREATE_TRACE_MARKER("GrContext::drawPath", target); |
1150 | 1200 |
1201 const SkStrokeRec* stroke = style.getStrokeRec(); | |
1202 | |
1151 bool useCoverageAA = paint.isAntiAlias() && !drawState->getRenderTarget()->i sMultisampled(); | 1203 bool useCoverageAA = paint.isAntiAlias() && !drawState->getRenderTarget()->i sMultisampled(); |
1152 | 1204 |
1153 if (useCoverageAA && stroke.getWidth() < 0 && !path.isConvex()) { | 1205 if (useCoverageAA && stroke->getWidth() < 0 && !path.isConvex()) { |
1154 // Concave AA paths are expensive - try to avoid them for special cases | 1206 // Concave AA paths are expensive - try to avoid them for special cases |
1155 bool useVertexCoverage; | 1207 bool useVertexCoverage; |
1156 SkRect rects[2]; | 1208 SkRect rects[2]; |
1157 | 1209 |
1158 if (is_nested_rects(target, path, stroke, rects, &useVertexCoverage)) { | 1210 if (is_nested_rects(target, path, *stroke, rects, &useVertexCoverage)) { |
1159 SkMatrix origViewMatrix = drawState->getViewMatrix(); | 1211 SkMatrix origViewMatrix = drawState->getViewMatrix(); |
1160 GrDrawState::AutoViewMatrixRestore avmr; | 1212 GrDrawState::AutoViewMatrixRestore avmr; |
1161 if (!avmr.setIdentity(target->drawState())) { | 1213 if (!avmr.setIdentity(target->drawState())) { |
1162 return; | 1214 return; |
1163 } | 1215 } |
1164 | 1216 |
1165 fAARectRenderer->fillAANestedRects(this->getGpu(), target, | 1217 fAARectRenderer->fillAANestedRects(this->getGpu(), target, |
1166 rects, | 1218 rects, |
1167 origViewMatrix, | 1219 origViewMatrix, |
1168 useVertexCoverage); | 1220 useVertexCoverage); |
1169 return; | 1221 return; |
1170 } | 1222 } |
1171 } | 1223 } |
1172 | 1224 |
1173 SkRect ovalRect; | 1225 SkRect ovalRect; |
1174 bool isOval = path.isOval(&ovalRect); | 1226 bool isOval = path.isOval(&ovalRect); |
1175 | 1227 |
1176 if (!isOval || path.isInverseFillType() | 1228 if (!isOval || path.isInverseFillType() |
1177 || !fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), ovalRect, stroke)) { | 1229 || !fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), ovalRect, *stroke)) { |
1178 this->internalDrawPath(target, paint.isAntiAlias(), path, stroke); | 1230 this->internalDrawPath(target, paint.isAntiAlias(), path, *stroke); |
1179 } | 1231 } |
1180 } | 1232 } |
1181 | 1233 |
1182 void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path, | 1234 void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path, |
1183 const SkStrokeRec& origStroke) { | 1235 const SkStrokeRec& origStroke) { |
1184 SkASSERT(!path.isEmpty()); | 1236 SkASSERT(!path.isEmpty()); |
1185 | 1237 |
1186 GR_CREATE_TRACE_MARKER("GrContext::internalDrawPath", target); | 1238 GR_CREATE_TRACE_MARKER("GrContext::internalDrawPath", target); |
1187 | 1239 |
1188 | 1240 |
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1838 SkSafeRef(resource); | 1890 SkSafeRef(resource); |
1839 return resource; | 1891 return resource; |
1840 } | 1892 } |
1841 | 1893 |
1842 /////////////////////////////////////////////////////////////////////////////// | 1894 /////////////////////////////////////////////////////////////////////////////// |
1843 #if GR_CACHE_STATS | 1895 #if GR_CACHE_STATS |
1844 void GrContext::printCacheStats() const { | 1896 void GrContext::printCacheStats() const { |
1845 fResourceCache->printStats(); | 1897 fResourceCache->printStats(); |
1846 } | 1898 } |
1847 #endif | 1899 #endif |
OLD | NEW |