Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Side by Side Diff: src/gpu/GrContext.cpp

Issue 38573007: Do not apply hairline optimization for paths if nv_path_rendering is used (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: address review comments Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
OLDNEW
« src/core/SkDrawProcs.h ('K') | « src/core/SkDrawProcs.h ('k') | src/gpu/SkGpuDevice.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698