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 "GrOvalRenderer.h" | 21 #include "GrOvalRenderer.h" |
22 #include "GrPathRenderer.h" | 22 #include "GrPathRenderer.h" |
23 #include "GrPathUtils.h" | 23 #include "GrPathUtils.h" |
24 #include "GrResourceCache.h" | 24 #include "GrResourceCache.h" |
25 #include "GrSoftwarePathRenderer.h" | 25 #include "GrSoftwarePathRenderer.h" |
26 #include "GrStencilBuffer.h" | 26 #include "GrStencilBuffer.h" |
27 #include "GrTextStrike.h" | 27 #include "GrTextStrike.h" |
28 #include "SkDrawProcs.h" | |
28 #include "SkRTConf.h" | 29 #include "SkRTConf.h" |
29 #include "SkRRect.h" | 30 #include "SkRRect.h" |
30 #include "SkStrokeRec.h" | 31 #include "SkStrokeRec.h" |
31 #include "SkTLazy.h" | 32 #include "SkTLazy.h" |
32 #include "SkTLS.h" | 33 #include "SkTLS.h" |
33 #include "SkTrace.h" | 34 #include "SkTrace.h" |
34 | 35 |
35 SK_DEFINE_INST_COUNT(GrContext) | 36 SK_DEFINE_INST_COUNT(GrContext) |
36 SK_DEFINE_INST_COUNT(GrDrawState) | 37 SK_DEFINE_INST_COUNT(GrDrawState) |
37 | 38 |
(...skipping 992 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1030 AutoCheckFlush acf(this); | 1031 AutoCheckFlush acf(this); |
1031 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf ); | 1032 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf ); |
1032 | 1033 |
1033 bool useAA = paint.isAntiAlias() && | 1034 bool useAA = paint.isAntiAlias() && |
1034 !target->getDrawState().getRenderTarget()->isMultisampled() && | 1035 !target->getDrawState().getRenderTarget()->isMultisampled() && |
1035 !disable_coverage_aa_for_blend(target); | 1036 !disable_coverage_aa_for_blend(target); |
1036 | 1037 |
1037 if (!fOvalRenderer->drawSimpleRRect(target, this, useAA, rect, stroke)) { | 1038 if (!fOvalRenderer->drawSimpleRRect(target, this, useAA, rect, stroke)) { |
1038 SkPath path; | 1039 SkPath path; |
1039 path.addRRect(rect); | 1040 path.addRRect(rect); |
1040 this->internalDrawPath(target, useAA, path, stroke); | 1041 this->internalDrawPath(target, paint, useAA, path, stroke); |
1041 } | 1042 } |
1042 } | 1043 } |
1043 | 1044 |
1044 /////////////////////////////////////////////////////////////////////////////// | 1045 /////////////////////////////////////////////////////////////////////////////// |
1045 | 1046 |
1046 void GrContext::drawOval(const GrPaint& paint, | 1047 void GrContext::drawOval(const GrPaint& paint, |
1047 const SkRect& oval, | 1048 const SkRect& oval, |
1048 const SkStrokeRec& stroke) { | 1049 const SkStrokeRec& stroke) { |
1049 if (oval.isEmpty()) { | 1050 if (oval.isEmpty()) { |
1050 return; | 1051 return; |
1051 } | 1052 } |
1052 | 1053 |
1053 AutoRestoreEffects are; | 1054 AutoRestoreEffects are; |
1054 AutoCheckFlush acf(this); | 1055 AutoCheckFlush acf(this); |
1055 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf ); | 1056 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf ); |
1056 | 1057 |
1057 bool useAA = paint.isAntiAlias() && | 1058 bool useAA = paint.isAntiAlias() && |
1058 !target->getDrawState().getRenderTarget()->isMultisampled() && | 1059 !target->getDrawState().getRenderTarget()->isMultisampled() && |
1059 !disable_coverage_aa_for_blend(target); | 1060 !disable_coverage_aa_for_blend(target); |
1060 | 1061 |
1061 if (!fOvalRenderer->drawOval(target, this, useAA, oval, stroke)) { | 1062 if (!fOvalRenderer->drawOval(target, this, useAA, oval, stroke)) { |
1062 SkPath path; | 1063 SkPath path; |
1063 path.addOval(oval); | 1064 path.addOval(oval); |
1064 this->internalDrawPath(target, useAA, path, stroke); | 1065 this->internalDrawPath(target, paint, useAA, path, stroke); |
1065 } | 1066 } |
1066 } | 1067 } |
1067 | 1068 |
1068 // Can 'path' be drawn as a pair of filled nested rectangles? | 1069 // Can 'path' be drawn as a pair of filled nested rectangles? |
1069 static bool is_nested_rects(GrDrawTarget* target, | 1070 static bool is_nested_rects(GrDrawTarget* target, |
1070 const SkPath& path, | 1071 const SkPath& path, |
1071 const SkStrokeRec& stroke, | 1072 const SkStrokeRec& stroke, |
1072 SkRect rects[2], | 1073 SkRect rects[2], |
1073 bool* useVertexCoverage) { | 1074 bool* useVertexCoverage) { |
1074 SkASSERT(stroke.isFillStyle()); | 1075 SkASSERT(stroke.isFillStyle()); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1130 } | 1131 } |
1131 | 1132 |
1132 // Note that internalDrawPath may sw-rasterize the path into a scratch textu re. | 1133 // Note that internalDrawPath may sw-rasterize the path into a scratch textu re. |
1133 // Scratch textures can be recycled after they are returned to the texture | 1134 // Scratch textures can be recycled after they are returned to the texture |
1134 // cache. This presents a potential hazard for buffered drawing. However, | 1135 // cache. This presents a potential hazard for buffered drawing. However, |
1135 // the writePixels that uploads to the scratch will perform a flush so we're | 1136 // the writePixels that uploads to the scratch will perform a flush so we're |
1136 // OK. | 1137 // OK. |
1137 AutoRestoreEffects are; | 1138 AutoRestoreEffects are; |
1138 AutoCheckFlush acf(this); | 1139 AutoCheckFlush acf(this); |
1139 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf ); | 1140 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf ); |
1141 GrDrawState* drawState = target->drawState(); | |
1140 | 1142 |
1141 bool useAA = paint.isAntiAlias() && !target->getDrawState().getRenderTarget( )->isMultisampled(); | 1143 bool useAA = paint.isAntiAlias() && !drawState->getRenderTarget()->isMultisa mpled(); |
1144 | |
1142 if (useAA && stroke.getWidth() < 0 && !path.isConvex()) { | 1145 if (useAA && stroke.getWidth() < 0 && !path.isConvex()) { |
1143 // Concave AA paths are expensive - try to avoid them for special cases | 1146 // Concave AA paths are expensive - try to avoid them for special cases |
1144 bool useVertexCoverage; | 1147 bool useVertexCoverage; |
1145 SkRect rects[2]; | 1148 SkRect rects[2]; |
1146 | 1149 |
1147 if (is_nested_rects(target, path, stroke, rects, &useVertexCoverage)) { | 1150 if (is_nested_rects(target, path, stroke, rects, &useVertexCoverage)) { |
1148 SkMatrix origViewMatrix = target->getDrawState().getViewMatrix(); | 1151 SkMatrix origViewMatrix = drawState->getViewMatrix(); |
1149 GrDrawState::AutoViewMatrixRestore avmr; | 1152 GrDrawState::AutoViewMatrixRestore avmr; |
1150 if (!avmr.setIdentity(target->drawState())) { | 1153 if (!avmr.setIdentity(target->drawState())) { |
1151 return; | 1154 return; |
1152 } | 1155 } |
1153 | 1156 |
1154 fAARectRenderer->fillAANestedRects(this->getGpu(), target, | 1157 fAARectRenderer->fillAANestedRects(this->getGpu(), target, |
1155 rects, | 1158 rects, |
1156 origViewMatrix, | 1159 origViewMatrix, |
1157 useVertexCoverage); | 1160 useVertexCoverage); |
1158 return; | 1161 return; |
1159 } | 1162 } |
1160 } | 1163 } |
1161 | 1164 |
1162 SkRect ovalRect; | 1165 SkRect ovalRect; |
1163 bool isOval = path.isOval(&ovalRect); | 1166 bool isOval = path.isOval(&ovalRect); |
1164 | 1167 |
1165 if (!isOval || path.isInverseFillType() | 1168 if (!isOval || path.isInverseFillType() |
1166 || !fOvalRenderer->drawOval(target, this, useAA, ovalRect, stroke)) { | 1169 || !fOvalRenderer->drawOval(target, this, useAA, ovalRect, stroke)) { |
1167 this->internalDrawPath(target, useAA, path, stroke); | 1170 this->internalDrawPath(target, paint, useAA, path, stroke); |
1168 } | 1171 } |
1169 } | 1172 } |
1170 | 1173 |
1171 void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path, | 1174 namespace { |
1172 const SkStrokeRec& stroke) { | 1175 // See also: SkDrawTreatAsHairline. |
1176 static inline bool should_convert_to_hairline(const GrPaint& paint, const SkStro keRec& stroke, | |
1177 const SkMatrix& matrix, SkScalar* coverage) { | |
1178 | |
1179 if (stroke.getStyle() != SkStrokeRec::kStroke_Style) { | |
1180 return false; | |
1181 } | |
1182 | |
1183 SkASSERT(0 != stroke.getWidth()); | |
1184 | |
1185 if (!paint.isAntiAlias()) { | |
bsalomon
2013/10/30 14:37:39
Currently GrContext tries to convert the GrPaint t
Kimmo Kinnunen
2013/11/01 14:56:19
Done.
| |
1186 return false; | |
1187 } | |
1188 | |
1189 return SkDrawTreatAAStrokeAsHairline(stroke.getWidth(), matrix, coverage); | |
1190 } | |
1191 } | |
1192 | |
1193 | |
1194 void GrContext::internalDrawPath(GrDrawTarget* target, const GrPaint& paint, boo l useAA, | |
1195 const SkPath& path, const SkStrokeRec& origStro ke) { | |
1173 SkASSERT(!path.isEmpty()); | 1196 SkASSERT(!path.isEmpty()); |
1174 | 1197 |
1175 // An Assumption here is that path renderer would use some form of tweaking | 1198 // An Assumption here is that path renderer would use some form of tweaking |
1176 // the src color (either the input alpha or in the frag shader) to implement | 1199 // the src color (either the input alpha or in the frag shader) to implement |
1177 // aa. If we have some future driver-mojo path AA that can do the right | 1200 // aa. If we have some future driver-mojo path AA that can do the right |
1178 // thing WRT to the blend then we'll need some query on the PR. | 1201 // thing WRT to the blend then we'll need some query on the PR. |
1179 if (disable_coverage_aa_for_blend(target)) { | 1202 if (disable_coverage_aa_for_blend(target)) { |
1180 #ifdef SK_DEBUG | 1203 #ifdef SK_DEBUG |
1181 //GrPrintf("Turning off AA to correctly apply blend.\n"); | 1204 //GrPrintf("Turning off AA to correctly apply blend.\n"); |
1182 #endif | 1205 #endif |
1183 useAA = false; | 1206 useAA = false; |
1184 } | 1207 } |
1185 | 1208 |
1209 SkTCopyOnFirstWrite<SkStrokeRec> stroke(origStroke); | |
1210 // Can we treat a thin stroke as a hairline w/ coverage? If we can, we draw lots faster (raster | |
1211 // device does this same test). | |
1212 | |
1213 // Do not do this if gpu supports path rendering natively and we might be us ing the support (useAA == | |
1214 // false). Hairline renderer is likely to be slow due to program switches. | |
1215 if (useAA || !fGpu->caps()->pathRenderingSupport()) { | |
1216 SkScalar hairlineCoverage; | |
1217 if (should_convert_to_hairline(paint, *stroke, this->getMatrix(), &hairl ineCoverage)) { | |
1218 target->drawState()->setCoverage(SkScalarRoundToInt(hairlineCoverage * paint.getCoverage())); | |
1219 stroke.writable()->setHairlineStyle(); | |
1220 } | |
1221 } | |
1222 | |
1186 GrPathRendererChain::DrawType type = useAA ? GrPathRendererChain::kColorAnti Alias_DrawType : | 1223 GrPathRendererChain::DrawType type = useAA ? GrPathRendererChain::kColorAnti Alias_DrawType : |
1187 GrPathRendererChain::kColor_Dra wType; | 1224 GrPathRendererChain::kColor_Dra wType; |
1188 | 1225 |
1189 const SkPath* pathPtr = &path; | 1226 const SkPath* pathPtr = &path; |
1190 SkPath tmpPath; | 1227 SkPath tmpPath; |
1191 SkStrokeRec strokeRec(stroke); | |
1192 | 1228 |
1193 // Try a 1st time without stroking the path and without allowing the SW rend erer | 1229 // Try a 1st time without stroking the path and without allowing the SW rend erer |
1194 GrPathRenderer* pr = this->getPathRenderer(*pathPtr, strokeRec, target, fals e, type); | 1230 GrPathRenderer* pr = this->getPathRenderer(*pathPtr, *stroke, target, false, type); |
1195 | 1231 |
1196 if (NULL == pr) { | 1232 if (NULL == pr) { |
1197 if (!strokeRec.isHairlineStyle()) { | 1233 if (!stroke->isHairlineStyle()) { |
1198 // It didn't work the 1st time, so try again with the stroked path | 1234 // It didn't work the 1st time, so try again with the stroked path |
1199 if (strokeRec.applyToPath(&tmpPath, *pathPtr)) { | 1235 if (stroke->applyToPath(&tmpPath, *pathPtr)) { |
1200 pathPtr = &tmpPath; | 1236 pathPtr = &tmpPath; |
1201 strokeRec.setFillStyle(); | 1237 stroke.writable()->setFillStyle(); |
1202 } | 1238 } |
1203 } | 1239 } |
1204 if (pathPtr->isEmpty()) { | 1240 if (pathPtr->isEmpty()) { |
1205 return; | 1241 return; |
1206 } | 1242 } |
1207 | 1243 |
1208 // This time, allow SW renderer | 1244 // This time, allow SW renderer |
1209 pr = this->getPathRenderer(*pathPtr, strokeRec, target, true, type); | 1245 pr = this->getPathRenderer(*pathPtr, *stroke, target, true, type); |
1210 } | 1246 } |
1211 | 1247 |
1212 if (NULL == pr) { | 1248 if (NULL == pr) { |
1213 #ifdef SK_DEBUG | 1249 #ifdef SK_DEBUG |
1214 GrPrintf("Unable to find path renderer compatible with path.\n"); | 1250 GrPrintf("Unable to find path renderer compatible with path.\n"); |
1215 #endif | 1251 #endif |
1216 return; | 1252 return; |
1217 } | 1253 } |
1218 | 1254 |
1219 pr->drawPath(*pathPtr, strokeRec, target, useAA); | 1255 pr->drawPath(*pathPtr, *stroke, target, useAA); |
1220 } | 1256 } |
1221 | 1257 |
1222 //////////////////////////////////////////////////////////////////////////////// | 1258 //////////////////////////////////////////////////////////////////////////////// |
1223 | 1259 |
1224 void GrContext::flush(int flagsBitfield) { | 1260 void GrContext::flush(int flagsBitfield) { |
1225 if (NULL == fDrawBuffer) { | 1261 if (NULL == fDrawBuffer) { |
1226 return; | 1262 return; |
1227 } | 1263 } |
1228 | 1264 |
1229 if (kDiscard_FlushBit & flagsBitfield) { | 1265 if (kDiscard_FlushBit & flagsBitfield) { |
(...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1809 return NULL; | 1845 return NULL; |
1810 } | 1846 } |
1811 } | 1847 } |
1812 | 1848 |
1813 /////////////////////////////////////////////////////////////////////////////// | 1849 /////////////////////////////////////////////////////////////////////////////// |
1814 #if GR_CACHE_STATS | 1850 #if GR_CACHE_STATS |
1815 void GrContext::printCacheStats() const { | 1851 void GrContext::printCacheStats() const { |
1816 fTextureCache->printStats(); | 1852 fTextureCache->printStats(); |
1817 } | 1853 } |
1818 #endif | 1854 #endif |
OLD | NEW |