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

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 problems 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
« no previous file with comments | « src/gpu/GrAAHairLinePathRenderer.cpp ('k') | src/gpu/GrDefaultPathRenderer.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
(...skipping 25 matching lines...) Expand all
36 SK_DEFINE_INST_COUNT(GrDrawState) 36 SK_DEFINE_INST_COUNT(GrDrawState)
37 37
38 // It can be useful to set this to false to test whether a bug is caused by usin g the 38 // 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 39 // InOrderDrawBuffer, to compare performance of using/not using InOrderDrawBuffe r, or to make
40 // debugging simpler. 40 // debugging simpler.
41 SK_CONF_DECLARE(bool, c_Defer, "gpu.deferContext", true, 41 SK_CONF_DECLARE(bool, c_Defer, "gpu.deferContext", true,
42 "Defers rendering in GrContext via GrInOrderDrawBuffer."); 42 "Defers rendering in GrContext via GrInOrderDrawBuffer.");
43 43
44 #define BUFFERED_DRAW (c_Defer ? kYes_BufferedDraw : kNo_BufferedDraw) 44 #define BUFFERED_DRAW (c_Defer ? kYes_BufferedDraw : kNo_BufferedDraw)
45 45
46 // When we're using coverage AA but the blend is incompatible (given gpu
47 // limitations) should we disable AA or draw wrong?
48 #define DISABLE_COVERAGE_AA_FOR_BLEND 1
49
50 #ifdef SK_DEBUG 46 #ifdef SK_DEBUG
51 // change this to a 1 to see notifications when partial coverage fails 47 // change this to a 1 to see notifications when partial coverage fails
52 #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0 48 #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0
53 #else 49 #else
54 #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0 50 #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0
55 #endif 51 #endif
56 52
57 static const size_t MAX_RESOURCE_CACHE_COUNT = GR_DEFAULT_RESOURCE_CACHE_COUNT_L IMIT; 53 static const size_t MAX_RESOURCE_CACHE_COUNT = GR_DEFAULT_RESOURCE_CACHE_COUNT_L IMIT;
58 static const size_t MAX_RESOURCE_CACHE_BYTES = GR_DEFAULT_RESOURCE_CACHE_MB_LIMI T * 1024 * 1024; 54 static const size_t MAX_RESOURCE_CACHE_BYTES = GR_DEFAULT_RESOURCE_CACHE_MB_LIMI T * 1024 * 1024;
59 55
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after
688 } 684 }
689 685
690 #ifdef SK_DEVELOPER 686 #ifdef SK_DEVELOPER
691 void GrContext::dumpFontCache() const { 687 void GrContext::dumpFontCache() const {
692 fFontCache->dump(); 688 fFontCache->dump();
693 } 689 }
694 #endif 690 #endif
695 691
696 //////////////////////////////////////////////////////////////////////////////// 692 ////////////////////////////////////////////////////////////////////////////////
697 693
698 namespace {
699 inline bool disable_coverage_aa_for_blend(GrDrawTarget* target) {
700 return DISABLE_COVERAGE_AA_FOR_BLEND && !target->canApplyCoverage();
701 }
702 }
703
704 ////////////////////////////////////////////////////////////////////////////////
705
706 /* create a triangle strip that strokes the specified triangle. There are 8 694 /* create a triangle strip that strokes the specified triangle. There are 8
707 unique vertices, but we repreat the last 2 to close up. Alternatively we 695 unique vertices, but we repreat the last 2 to close up. Alternatively we
708 could use an indices array, and then only send 8 verts, but not sure that 696 could use an indices array, and then only send 8 verts, but not sure that
709 would be faster. 697 would be faster.
710 */ 698 */
711 static void setStrokeRectStrip(GrPoint verts[10], SkRect rect, 699 static void setStrokeRectStrip(GrPoint verts[10], SkRect rect,
712 SkScalar width) { 700 SkScalar width) {
713 const SkScalar rad = SkScalarHalf(width); 701 const SkScalar rad = SkScalarHalf(width);
714 rect.sort(); 702 rect.sort();
715 703
(...skipping 23 matching lines...) Expand all
739 // we use a simple coverage ramp to do aa on axis-aligned rects 727 // we use a simple coverage ramp to do aa on axis-aligned rects
740 // we check if the rect will be axis-aligned, and the rect won't land on 728 // we check if the rect will be axis-aligned, and the rect won't land on
741 // integer coords. 729 // integer coords.
742 730
743 // we are keeping around the "tweak the alpha" trick because 731 // we are keeping around the "tweak the alpha" trick because
744 // it is our only hope for the fixed-pipe implementation. 732 // it is our only hope for the fixed-pipe implementation.
745 // In a shader implementation we can give a separate coverage input 733 // In a shader implementation we can give a separate coverage input
746 // TODO: remove this ugliness when we drop the fixed-pipe impl 734 // TODO: remove this ugliness when we drop the fixed-pipe impl
747 *useVertexCoverage = false; 735 *useVertexCoverage = false;
748 if (!target->getDrawState().canTweakAlphaForCoverage()) { 736 if (!target->getDrawState().canTweakAlphaForCoverage()) {
749 if (disable_coverage_aa_for_blend(target)) { 737 if (target->shouldDisableCoverageAAForBlend()) {
750 #ifdef SK_DEBUG 738 #ifdef SK_DEBUG
751 //GrPrintf("Turning off AA to correctly apply blend.\n"); 739 //GrPrintf("Turning off AA to correctly apply blend.\n");
752 #endif 740 #endif
753 return false; 741 return false;
754 } else { 742 } else {
755 *useVertexCoverage = true; 743 *useVertexCoverage = true;
756 } 744 }
757 } 745 }
758 const GrDrawState& drawState = target->getDrawState(); 746 const GrDrawState& drawState = target->getDrawState();
759 if (drawState.getRenderTarget()->isMultisampled()) { 747 if (drawState.getRenderTarget()->isMultisampled()) {
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 const SkRRect& rect, 1015 const SkRRect& rect,
1028 const SkStrokeRec& stroke) { 1016 const SkStrokeRec& stroke) {
1029 if (rect.isEmpty()) { 1017 if (rect.isEmpty()) {
1030 return; 1018 return;
1031 } 1019 }
1032 1020
1033 AutoRestoreEffects are; 1021 AutoRestoreEffects are;
1034 AutoCheckFlush acf(this); 1022 AutoCheckFlush acf(this);
1035 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf ); 1023 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf );
1036 1024
1037 bool useAA = paint.isAntiAlias() && 1025 if (!fOvalRenderer->drawSimpleRRect(target, this, paint.isAntiAlias(), rect, stroke)) {
1038 !target->getDrawState().getRenderTarget()->isMultisampled() &&
1039 !disable_coverage_aa_for_blend(target);
1040
1041 if (!fOvalRenderer->drawSimpleRRect(target, this, useAA, rect, stroke)) {
1042 SkPath path; 1026 SkPath path;
1043 path.addRRect(rect); 1027 path.addRRect(rect);
1044 this->internalDrawPath(target, useAA, path, stroke); 1028 this->internalDrawPath(target, paint.isAntiAlias(), path, stroke);
1045 } 1029 }
1046 } 1030 }
1047 1031
1048 /////////////////////////////////////////////////////////////////////////////// 1032 ///////////////////////////////////////////////////////////////////////////////
1049 1033
1050 void GrContext::drawOval(const GrPaint& paint, 1034 void GrContext::drawOval(const GrPaint& paint,
1051 const SkRect& oval, 1035 const SkRect& oval,
1052 const SkStrokeRec& stroke) { 1036 const SkStrokeRec& stroke) {
1053 if (oval.isEmpty()) { 1037 if (oval.isEmpty()) {
1054 return; 1038 return;
1055 } 1039 }
1056 1040
1057 AutoRestoreEffects are; 1041 AutoRestoreEffects are;
1058 AutoCheckFlush acf(this); 1042 AutoCheckFlush acf(this);
1059 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf ); 1043 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf );
1060 1044
1061 bool useAA = paint.isAntiAlias() && 1045 if (!fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), oval, stroke )) {
1062 !target->getDrawState().getRenderTarget()->isMultisampled() &&
1063 !disable_coverage_aa_for_blend(target);
1064
1065 if (!fOvalRenderer->drawOval(target, this, useAA, oval, stroke)) {
1066 SkPath path; 1046 SkPath path;
1067 path.addOval(oval); 1047 path.addOval(oval);
1068 this->internalDrawPath(target, useAA, path, stroke); 1048 this->internalDrawPath(target, paint.isAntiAlias(), path, stroke);
1069 } 1049 }
1070 } 1050 }
1071 1051
1072 // Can 'path' be drawn as a pair of filled nested rectangles? 1052 // Can 'path' be drawn as a pair of filled nested rectangles?
1073 static bool is_nested_rects(GrDrawTarget* target, 1053 static bool is_nested_rects(GrDrawTarget* target,
1074 const SkPath& path, 1054 const SkPath& path,
1075 const SkStrokeRec& stroke, 1055 const SkStrokeRec& stroke,
1076 SkRect rects[2], 1056 SkRect rects[2],
1077 bool* useVertexCoverage) { 1057 bool* useVertexCoverage) {
1078 SkASSERT(stroke.isFillStyle()); 1058 SkASSERT(stroke.isFillStyle());
1079 1059
1080 if (path.isInverseFillType()) { 1060 if (path.isInverseFillType()) {
1081 return false; 1061 return false;
1082 } 1062 }
1083 1063
1084 const GrDrawState& drawState = target->getDrawState(); 1064 const GrDrawState& drawState = target->getDrawState();
1085 1065
1086 // TODO: this restriction could be lifted if we were willing to apply 1066 // TODO: this restriction could be lifted if we were willing to apply
1087 // the matrix to all the points individually rather than just to the rect 1067 // the matrix to all the points individually rather than just to the rect
1088 if (!drawState.getViewMatrix().preservesAxisAlignment()) { 1068 if (!drawState.getViewMatrix().preservesAxisAlignment()) {
1089 return false; 1069 return false;
1090 } 1070 }
1091 1071
1092 *useVertexCoverage = false; 1072 *useVertexCoverage = false;
1093 if (!target->getDrawState().canTweakAlphaForCoverage()) { 1073 if (!target->getDrawState().canTweakAlphaForCoverage()) {
1094 if (disable_coverage_aa_for_blend(target)) { 1074 if (target->shouldDisableCoverageAAForBlend()) {
1095 return false; 1075 return false;
1096 } else { 1076 } else {
1097 *useVertexCoverage = true; 1077 *useVertexCoverage = true;
1098 } 1078 }
1099 } 1079 }
1100 1080
1101 SkPath::Direction dirs[2]; 1081 SkPath::Direction dirs[2];
1102 if (!path.isNestedRects(rects, dirs)) { 1082 if (!path.isNestedRects(rects, dirs)) {
1103 return false; 1083 return false;
1104 } 1084 }
(...skipping 29 matching lines...) Expand all
1134 } 1114 }
1135 1115
1136 // Note that internalDrawPath may sw-rasterize the path into a scratch textu re. 1116 // Note that internalDrawPath may sw-rasterize the path into a scratch textu re.
1137 // Scratch textures can be recycled after they are returned to the texture 1117 // Scratch textures can be recycled after they are returned to the texture
1138 // cache. This presents a potential hazard for buffered drawing. However, 1118 // cache. This presents a potential hazard for buffered drawing. However,
1139 // the writePixels that uploads to the scratch will perform a flush so we're 1119 // the writePixels that uploads to the scratch will perform a flush so we're
1140 // OK. 1120 // OK.
1141 AutoRestoreEffects are; 1121 AutoRestoreEffects are;
1142 AutoCheckFlush acf(this); 1122 AutoCheckFlush acf(this);
1143 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf ); 1123 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf );
1124 GrDrawState* drawState = target->drawState();
1144 1125
1145 bool useAA = paint.isAntiAlias() && !target->getDrawState().getRenderTarget( )->isMultisampled(); 1126 bool useCoverageAA = paint.isAntiAlias() && !drawState->getRenderTarget()->i sMultisampled();
1146 if (useAA && stroke.getWidth() < 0 && !path.isConvex()) { 1127
1128 if (useCoverageAA && stroke.getWidth() < 0 && !path.isConvex()) {
1147 // Concave AA paths are expensive - try to avoid them for special cases 1129 // Concave AA paths are expensive - try to avoid them for special cases
1148 bool useVertexCoverage; 1130 bool useVertexCoverage;
1149 SkRect rects[2]; 1131 SkRect rects[2];
1150 1132
1151 if (is_nested_rects(target, path, stroke, rects, &useVertexCoverage)) { 1133 if (is_nested_rects(target, path, stroke, rects, &useVertexCoverage)) {
1152 SkMatrix origViewMatrix = target->getDrawState().getViewMatrix(); 1134 SkMatrix origViewMatrix = drawState->getViewMatrix();
1153 GrDrawState::AutoViewMatrixRestore avmr; 1135 GrDrawState::AutoViewMatrixRestore avmr;
1154 if (!avmr.setIdentity(target->drawState())) { 1136 if (!avmr.setIdentity(target->drawState())) {
1155 return; 1137 return;
1156 } 1138 }
1157 1139
1158 fAARectRenderer->fillAANestedRects(this->getGpu(), target, 1140 fAARectRenderer->fillAANestedRects(this->getGpu(), target,
1159 rects, 1141 rects,
1160 origViewMatrix, 1142 origViewMatrix,
1161 useVertexCoverage); 1143 useVertexCoverage);
1162 return; 1144 return;
1163 } 1145 }
1164 } 1146 }
1165 1147
1166 SkRect ovalRect; 1148 SkRect ovalRect;
1167 bool isOval = path.isOval(&ovalRect); 1149 bool isOval = path.isOval(&ovalRect);
1168 1150
1169 if (!isOval || path.isInverseFillType() 1151 if (!isOval || path.isInverseFillType()
1170 || !fOvalRenderer->drawOval(target, this, useAA, ovalRect, stroke)) { 1152 || !fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), ovalRect, stroke)) {
1171 this->internalDrawPath(target, useAA, path, stroke); 1153 this->internalDrawPath(target, paint.isAntiAlias(), path, stroke);
1172 } 1154 }
1173 } 1155 }
1174 1156
1175 void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path, 1157 void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path,
1176 const SkStrokeRec& stroke) { 1158 const SkStrokeRec& stroke) {
1177 SkASSERT(!path.isEmpty()); 1159 SkASSERT(!path.isEmpty());
1178 1160
1179 // An Assumption here is that path renderer would use some form of tweaking 1161 // An Assumption here is that path renderer would use some form of tweaking
1180 // the src color (either the input alpha or in the frag shader) to implement 1162 // the src color (either the input alpha or in the frag shader) to implement
1181 // aa. If we have some future driver-mojo path AA that can do the right 1163 // aa. If we have some future driver-mojo path AA that can do the right
1182 // thing WRT to the blend then we'll need some query on the PR. 1164 // thing WRT to the blend then we'll need some query on the PR.
1183 if (disable_coverage_aa_for_blend(target)) { 1165 bool useCoverageAA = useAA &&
1184 #ifdef SK_DEBUG 1166 !target->getDrawState().getRenderTarget()->isMultisampled() &&
1185 //GrPrintf("Turning off AA to correctly apply blend.\n"); 1167 !target->shouldDisableCoverageAAForBlend();
1186 #endif
1187 useAA = false;
1188 }
1189 1168
1190 GrPathRendererChain::DrawType type = useAA ? GrPathRendererChain::kColorAnti Alias_DrawType : 1169
1191 GrPathRendererChain::kColor_Dra wType; 1170 GrPathRendererChain::DrawType type =
1171 useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType :
1172 GrPathRendererChain::kColor_DrawType;
1192 1173
1193 const SkPath* pathPtr = &path; 1174 const SkPath* pathPtr = &path;
1194 SkPath tmpPath; 1175 SkPath tmpPath;
1195 SkStrokeRec strokeRec(stroke); 1176 SkStrokeRec strokeRec(stroke);
1196 1177
1197 // Try a 1st time without stroking the path and without allowing the SW rend erer 1178 // Try a 1st time without stroking the path and without allowing the SW rend erer
1198 GrPathRenderer* pr = this->getPathRenderer(*pathPtr, strokeRec, target, fals e, type); 1179 GrPathRenderer* pr = this->getPathRenderer(*pathPtr, strokeRec, target, fals e, type);
1199 1180
1200 if (NULL == pr) { 1181 if (NULL == pr) {
1201 if (!strokeRec.isHairlineStyle()) { 1182 if (!GrPathRenderer::IsStrokeHairlineOrEquivalent(strokeRec, this->getMa trix(), NULL)) {
1202 // It didn't work the 1st time, so try again with the stroked path 1183 // It didn't work the 1st time, so try again with the stroked path
1203 if (strokeRec.applyToPath(&tmpPath, *pathPtr)) { 1184 if (strokeRec.applyToPath(&tmpPath, *pathPtr)) {
1204 pathPtr = &tmpPath; 1185 pathPtr = &tmpPath;
1205 strokeRec.setFillStyle(); 1186 strokeRec.setFillStyle();
1187 if (pathPtr->isEmpty()) {
1188 return;
1189 }
1206 } 1190 }
1207 } 1191 }
1208 if (pathPtr->isEmpty()) {
1209 return;
1210 }
1211 1192
1212 // This time, allow SW renderer 1193 // This time, allow SW renderer
1213 pr = this->getPathRenderer(*pathPtr, strokeRec, target, true, type); 1194 pr = this->getPathRenderer(*pathPtr, strokeRec, target, true, type);
1214 } 1195 }
1215 1196
1216 if (NULL == pr) { 1197 if (NULL == pr) {
1217 #ifdef SK_DEBUG 1198 #ifdef SK_DEBUG
1218 GrPrintf("Unable to find path renderer compatible with path.\n"); 1199 GrPrintf("Unable to find path renderer compatible with path.\n");
1219 #endif 1200 #endif
1220 return; 1201 return;
1221 } 1202 }
1222 1203
1223 pr->drawPath(*pathPtr, strokeRec, target, useAA); 1204 pr->drawPath(*pathPtr, strokeRec, target, useCoverageAA);
1224 } 1205 }
1225 1206
1226 //////////////////////////////////////////////////////////////////////////////// 1207 ////////////////////////////////////////////////////////////////////////////////
1227 1208
1228 void GrContext::flush(int flagsBitfield) { 1209 void GrContext::flush(int flagsBitfield) {
1229 if (NULL == fDrawBuffer) { 1210 if (NULL == fDrawBuffer) {
1230 return; 1211 return;
1231 } 1212 }
1232 1213
1233 if (kDiscard_FlushBit & flagsBitfield) { 1214 if (kDiscard_FlushBit & flagsBitfield) {
(...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after
1829 } 1810 }
1830 return path; 1811 return path;
1831 } 1812 }
1832 1813
1833 /////////////////////////////////////////////////////////////////////////////// 1814 ///////////////////////////////////////////////////////////////////////////////
1834 #if GR_CACHE_STATS 1815 #if GR_CACHE_STATS
1835 void GrContext::printCacheStats() const { 1816 void GrContext::printCacheStats() const {
1836 fTextureCache->printStats(); 1817 fTextureCache->printStats();
1837 } 1818 }
1838 #endif 1819 #endif
OLDNEW
« no previous file with comments | « src/gpu/GrAAHairLinePathRenderer.cpp ('k') | src/gpu/GrDefaultPathRenderer.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698