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/GrConvolutionEffect.h" | 12 #include "effects/GrConvolutionEffect.h" |
13 #include "effects/GrSingleTextureEffect.h" | 13 #include "effects/GrSingleTextureEffect.h" |
14 #include "effects/GrConfigConversionEffect.h" | 14 #include "effects/GrConfigConversionEffect.h" |
15 #include "effects/GrCircleEdgeEffect.h" | |
16 #include "effects/GrEllipseEdgeEffect.h" | |
17 | 15 |
18 #include "GrBufferAllocPool.h" | 16 #include "GrBufferAllocPool.h" |
19 #include "GrGpu.h" | 17 #include "GrGpu.h" |
20 #include "GrIndexBuffer.h" | 18 #include "GrIndexBuffer.h" |
21 #include "GrInOrderDrawBuffer.h" | 19 #include "GrInOrderDrawBuffer.h" |
20 #include "GrOvalRenderer.h" | |
22 #include "GrPathRenderer.h" | 21 #include "GrPathRenderer.h" |
23 #include "GrPathUtils.h" | 22 #include "GrPathUtils.h" |
24 #include "GrResourceCache.h" | 23 #include "GrResourceCache.h" |
25 #include "GrSoftwarePathRenderer.h" | 24 #include "GrSoftwarePathRenderer.h" |
26 #include "GrStencilBuffer.h" | 25 #include "GrStencilBuffer.h" |
27 #include "GrTextStrike.h" | 26 #include "GrTextStrike.h" |
28 #include "SkRTConf.h" | 27 #include "SkRTConf.h" |
29 #include "SkStrokeRec.h" | 28 #include "SkStrokeRec.h" |
30 #include "SkTLazy.h" | 29 #include "SkTLazy.h" |
31 #include "SkTLS.h" | 30 #include "SkTLS.h" |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
92 fDrawState = NULL; | 91 fDrawState = NULL; |
93 fGpu = NULL; | 92 fGpu = NULL; |
94 fPathRendererChain = NULL; | 93 fPathRendererChain = NULL; |
95 fSoftwarePathRenderer = NULL; | 94 fSoftwarePathRenderer = NULL; |
96 fTextureCache = NULL; | 95 fTextureCache = NULL; |
97 fFontCache = NULL; | 96 fFontCache = NULL; |
98 fDrawBuffer = NULL; | 97 fDrawBuffer = NULL; |
99 fDrawBufferVBAllocPool = NULL; | 98 fDrawBufferVBAllocPool = NULL; |
100 fDrawBufferIBAllocPool = NULL; | 99 fDrawBufferIBAllocPool = NULL; |
101 fAARectRenderer = NULL; | 100 fAARectRenderer = NULL; |
101 fOvalRenderer = NULL; | |
102 } | 102 } |
103 | 103 |
104 bool GrContext::init(GrBackend backend, GrBackendContext backendContext) { | 104 bool GrContext::init(GrBackend backend, GrBackendContext backendContext) { |
105 GrAssert(NULL == fGpu); | 105 GrAssert(NULL == fGpu); |
106 | 106 |
107 fGpu = GrGpu::Create(backend, backendContext, this); | 107 fGpu = GrGpu::Create(backend, backendContext, this); |
108 if (NULL == fGpu) { | 108 if (NULL == fGpu) { |
109 return false; | 109 return false; |
110 } | 110 } |
111 | 111 |
112 fDrawState = SkNEW(GrDrawState); | 112 fDrawState = SkNEW(GrDrawState); |
113 fGpu->setDrawState(fDrawState); | 113 fGpu->setDrawState(fDrawState); |
114 | 114 |
115 | 115 |
116 fTextureCache = SkNEW_ARGS(GrResourceCache, | 116 fTextureCache = SkNEW_ARGS(GrResourceCache, |
117 (MAX_TEXTURE_CACHE_COUNT, | 117 (MAX_TEXTURE_CACHE_COUNT, |
118 MAX_TEXTURE_CACHE_BYTES)); | 118 MAX_TEXTURE_CACHE_BYTES)); |
119 fFontCache = SkNEW_ARGS(GrFontCache, (fGpu)); | 119 fFontCache = SkNEW_ARGS(GrFontCache, (fGpu)); |
120 | 120 |
121 fLastDrawWasBuffered = kNo_BufferedDraw; | 121 fLastDrawWasBuffered = kNo_BufferedDraw; |
122 | 122 |
123 fAARectRenderer = SkNEW(GrAARectRenderer); | 123 fAARectRenderer = SkNEW(GrAARectRenderer); |
124 fOvalRenderer = SkNEW(GrOvalRenderer); | |
124 | 125 |
125 fDidTestPMConversions = false; | 126 fDidTestPMConversions = false; |
126 | 127 |
127 this->setupDrawBuffer(); | 128 this->setupDrawBuffer(); |
128 | 129 |
129 return true; | 130 return true; |
130 } | 131 } |
131 | 132 |
132 int GrContext::GetThreadInstanceCount() { | 133 int GrContext::GetThreadInstanceCount() { |
133 return THREAD_INSTANCE_COUNT; | 134 return THREAD_INSTANCE_COUNT; |
(...skipping 11 matching lines...) Expand all Loading... | |
145 fGpu->purgeResources(); | 146 fGpu->purgeResources(); |
146 | 147 |
147 delete fTextureCache; | 148 delete fTextureCache; |
148 fTextureCache = NULL; | 149 fTextureCache = NULL; |
149 delete fFontCache; | 150 delete fFontCache; |
150 delete fDrawBuffer; | 151 delete fDrawBuffer; |
151 delete fDrawBufferVBAllocPool; | 152 delete fDrawBufferVBAllocPool; |
152 delete fDrawBufferIBAllocPool; | 153 delete fDrawBufferIBAllocPool; |
153 | 154 |
154 fAARectRenderer->unref(); | 155 fAARectRenderer->unref(); |
156 fOvalRenderer->unref(); | |
155 | 157 |
156 fGpu->unref(); | 158 fGpu->unref(); |
157 GrSafeUnref(fPathRendererChain); | 159 GrSafeUnref(fPathRendererChain); |
158 GrSafeUnref(fSoftwarePathRenderer); | 160 GrSafeUnref(fSoftwarePathRenderer); |
159 fDrawState->unref(); | 161 fDrawState->unref(); |
160 | 162 |
161 --THREAD_INSTANCE_COUNT; | 163 --THREAD_INSTANCE_COUNT; |
162 } | 164 } |
163 | 165 |
164 void GrContext::contextLost() { | 166 void GrContext::contextLost() { |
(...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
987 | 989 |
988 if (NULL != indices) { | 990 if (NULL != indices) { |
989 target->setIndexSourceToArray(indices, indexCount); | 991 target->setIndexSourceToArray(indices, indexCount); |
990 target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); | 992 target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); |
991 } else { | 993 } else { |
992 target->drawNonIndexed(primitiveType, 0, vertexCount); | 994 target->drawNonIndexed(primitiveType, 0, vertexCount); |
993 } | 995 } |
994 } | 996 } |
995 | 997 |
996 /////////////////////////////////////////////////////////////////////////////// | 998 /////////////////////////////////////////////////////////////////////////////// |
997 namespace { | |
998 | |
999 struct CircleVertex { | |
1000 GrPoint fPos; | |
1001 GrPoint fCenter; | |
1002 SkScalar fOuterRadius; | |
1003 SkScalar fInnerRadius; | |
1004 }; | |
1005 | |
1006 struct EllipseVertex { | |
1007 GrPoint fPos; | |
1008 GrPoint fCenter; | |
1009 SkScalar fOuterXRadius; | |
1010 SkScalar fOuterXYRatio; | |
1011 SkScalar fInnerXRadius; | |
1012 SkScalar fInnerXYRatio; | |
1013 }; | |
1014 | |
1015 inline bool circleStaysCircle(const SkMatrix& m) { | |
1016 return m.isSimilarity(); | |
1017 } | |
1018 | |
1019 } | |
1020 | 999 |
1021 void GrContext::drawOval(const GrPaint& paint, | 1000 void GrContext::drawOval(const GrPaint& paint, |
1022 const GrRect& oval, | 1001 const GrRect& oval, |
1023 const SkStrokeRec& stroke) { | 1002 const SkStrokeRec& stroke) { |
1003 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW); | |
1004 GrDrawState::AutoStageDisable atr(fDrawState); | |
1024 | 1005 |
1025 bool isCircle; | 1006 bool isCircle; |
1026 if (!canDrawOval(paint, oval, &isCircle)) { | 1007 if (!fOvalRenderer->canDrawOval(this, paint, oval, &isCircle)) { |
bsalomon
2013/03/21 02:08:53
Would we be able to hide the circle/oval distincti
jvanverth1
2013/03/21 18:42:18
Done. There doesn't seem to be a perf hit, which i
| |
1027 SkPath path; | 1008 SkPath path; |
1028 path.addOval(oval); | 1009 path.addOval(oval); |
1029 this->drawPath(paint, path, stroke); | 1010 this->internalDrawPath(target, paint, path, stroke); |
1030 return; | 1011 return; |
1031 } | 1012 } |
1032 | 1013 |
1033 if (isCircle) { | 1014 if (isCircle) { |
1034 this->internalDrawCircle(paint, oval, stroke); | 1015 fOvalRenderer->drawCircle(target, paint, oval, stroke); |
1035 } else { | 1016 } else { |
1036 this->internalDrawOval(paint, oval, stroke); | 1017 fOvalRenderer->drawEllipse(target, paint, oval, stroke); |
1037 } | 1018 } |
1038 } | 1019 } |
1039 | 1020 |
1040 bool GrContext::canDrawOval(const GrPaint& paint, const GrRect& oval, bool* isCi rcle) const { | |
1041 GrAssert(isCircle != NULL); | |
1042 | |
1043 if (!paint.isAntiAlias()) { | |
1044 return false; | |
1045 } | |
1046 | |
1047 // we can draw circles | |
1048 *isCircle = SkScalarNearlyEqual(oval.width(), oval.height()) | |
1049 && circleStaysCircle(this->getMatrix()); | |
1050 // and axis-aligned ellipses only | |
1051 bool isAxisAlignedEllipse = this->getMatrix().rectStaysRect(); | |
1052 | |
1053 return *isCircle || isAxisAlignedEllipse; | |
1054 } | |
1055 | |
1056 void GrContext::internalDrawOval(const GrPaint& paint, | |
1057 const GrRect& oval, | |
1058 const SkStrokeRec& stroke) { | |
1059 #ifdef SK_DEBUG | |
1060 { | |
1061 // we should have checked for this previously | |
1062 bool isAxisAlignedEllipse = this->getMatrix().rectStaysRect(); | |
1063 SkASSERT(paint.isAntiAlias() && isAxisAlignedEllipse); | |
1064 } | |
1065 #endif | |
1066 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW); | |
1067 | |
1068 GrDrawState* drawState = target->drawState(); | |
1069 GrDrawState::AutoStageDisable atr(fDrawState); | |
1070 | |
1071 const GrRenderTarget* rt = drawState->getRenderTarget(); | |
1072 if (NULL == rt) { | |
1073 return; | |
1074 } | |
1075 | |
1076 const SkMatrix vm = drawState->getViewMatrix(); | |
1077 | |
1078 GrDrawState::AutoDeviceCoordDraw adcd(drawState); | |
1079 if (!adcd.succeeded()) { | |
1080 return; | |
1081 } | |
1082 | |
1083 // position + edge | |
1084 static const GrVertexAttrib kVertexAttribs[] = { | |
1085 {kVec2f_GrVertexAttribType, 0}, | |
1086 {kVec2f_GrVertexAttribType, sizeof(GrPoint)}, | |
1087 {kVec4f_GrVertexAttribType, 2*sizeof(GrPoint)} | |
1088 }; | |
1089 drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs)); | |
1090 drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0); | |
1091 GrAssert(sizeof(EllipseVertex) == drawState->getVertexSize()); | |
1092 | |
1093 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); | |
1094 if (!geo.succeeded()) { | |
1095 GrPrintf("Failed to get space for vertices!\n"); | |
1096 return; | |
1097 } | |
1098 | |
1099 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); | |
1100 | |
1101 GrPoint center = GrPoint::Make(oval.centerX(), oval.centerY()); | |
1102 vm.mapPoints(¢er, 1); | |
1103 | |
1104 SkStrokeRec::Style style = stroke.getStyle(); | |
1105 bool isStroked = (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairl ine_Style == style); | |
1106 enum { | |
1107 // the edge effects share this stage with glyph rendering | |
1108 // (kGlyphMaskStage in GrTextContext) && SW path rendering | |
1109 // (kPathMaskStage in GrSWMaskHelper) | |
1110 kEdgeEffectStage = GrPaint::kTotalStages, | |
1111 }; | |
1112 drawState->setAttribBindings(GrDrawState::kDefault_AttribBindings); | |
1113 | |
1114 GrEffectRef* effect = GrEllipseEdgeEffect::Create(isStroked); | |
1115 static const int kEllipseCenterAttrIndex = 1; | |
1116 static const int kEllipseEdgeAttrIndex = 2; | |
1117 drawState->setEffect(kEdgeEffectStage, effect, | |
1118 kEllipseCenterAttrIndex, kEllipseEdgeAttrIndex)->unref( ); | |
1119 | |
1120 SkRect xformedRect; | |
1121 vm.mapRect(&xformedRect, oval); | |
1122 | |
1123 SkScalar xRadius = SkScalarHalf(xformedRect.width()); | |
1124 SkScalar yRadius = SkScalarHalf(xformedRect.height()); | |
1125 SkScalar innerXRadius = 0.0f; | |
1126 SkScalar innerRatio = 1.0f; | |
1127 | |
1128 if (SkStrokeRec::kFill_Style != style) { | |
1129 SkScalar strokeWidth = stroke.getWidth(); | |
1130 | |
1131 // do (potentially) anisotropic mapping | |
1132 SkVector scaledStroke; | |
1133 scaledStroke.set(strokeWidth, strokeWidth); | |
1134 vm.mapVectors(&scaledStroke, 1); | |
1135 | |
1136 if (SkScalarNearlyZero(scaledStroke.length())) { | |
1137 scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf); | |
1138 } else { | |
1139 scaledStroke.scale(0.5f); | |
1140 } | |
1141 | |
1142 // this is legit only if scale & translation (which should be the case a t the moment) | |
1143 if (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairline_Style == style) { | |
1144 SkScalar innerYRadius = SkMaxScalar(0, yRadius - scaledStroke.fY); | |
1145 if (innerYRadius > SK_ScalarNearlyZero) { | |
1146 innerXRadius = SkMaxScalar(0, xRadius - scaledStroke.fX); | |
1147 innerRatio = innerXRadius/innerYRadius; | |
1148 } | |
1149 } | |
1150 xRadius += scaledStroke.fX; | |
1151 yRadius += scaledStroke.fY; | |
1152 } | |
1153 | |
1154 SkScalar outerRatio = SkScalarDiv(xRadius, yRadius); | |
1155 | |
1156 for (int i = 0; i < 4; ++i) { | |
1157 verts[i].fCenter = center; | |
1158 verts[i].fOuterXRadius = xRadius + 0.5f; | |
1159 verts[i].fOuterXYRatio = outerRatio; | |
1160 verts[i].fInnerXRadius = innerXRadius - 0.5f; | |
1161 verts[i].fInnerXYRatio = innerRatio; | |
1162 } | |
1163 | |
1164 SkScalar L = -xRadius; | |
1165 SkScalar R = +xRadius; | |
1166 SkScalar T = -yRadius; | |
1167 SkScalar B = +yRadius; | |
1168 | |
1169 // We've extended the outer x radius out half a pixel to antialias. | |
1170 // Expand the drawn rect here so all the pixels will be captured. | |
1171 L += center.fX - SK_ScalarHalf; | |
1172 R += center.fX + SK_ScalarHalf; | |
1173 T += center.fY - SK_ScalarHalf; | |
1174 B += center.fY + SK_ScalarHalf; | |
1175 | |
1176 verts[0].fPos = SkPoint::Make(L, T); | |
1177 verts[1].fPos = SkPoint::Make(R, T); | |
1178 verts[2].fPos = SkPoint::Make(L, B); | |
1179 verts[3].fPos = SkPoint::Make(R, B); | |
1180 | |
1181 target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4); | |
1182 } | |
1183 | |
1184 void GrContext::internalDrawCircle(const GrPaint& paint, | |
1185 const GrRect& circle, | |
1186 const SkStrokeRec& stroke) { | |
1187 | |
1188 SkScalar radius = SkScalarHalf(circle.width()); | |
1189 | |
1190 SkScalar strokeWidth = stroke.getWidth(); | |
1191 SkStrokeRec::Style style = stroke.getStyle(); | |
1192 | |
1193 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW); | |
1194 | |
1195 GrDrawState* drawState = target->drawState(); | |
1196 GrDrawState::AutoStageDisable atr(fDrawState); | |
1197 | |
1198 const GrRenderTarget* rt = drawState->getRenderTarget(); | |
1199 if (NULL == rt) { | |
1200 return; | |
1201 } | |
1202 | |
1203 const SkMatrix vm = drawState->getViewMatrix(); | |
1204 | |
1205 GrDrawState::AutoDeviceCoordDraw adcd(drawState); | |
1206 if (!adcd.succeeded()) { | |
1207 return; | |
1208 } | |
1209 | |
1210 // position + edge | |
1211 static const GrVertexAttrib kVertexAttribs[] = { | |
1212 {kVec2f_GrVertexAttribType, 0}, | |
1213 {kVec4f_GrVertexAttribType, sizeof(GrPoint)} | |
1214 }; | |
1215 drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs)); | |
1216 drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0); | |
1217 GrAssert(sizeof(CircleVertex) == drawState->getVertexSize()); | |
1218 | |
1219 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); | |
1220 if (!geo.succeeded()) { | |
1221 GrPrintf("Failed to get space for vertices!\n"); | |
1222 return; | |
1223 } | |
1224 | |
1225 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); | |
1226 | |
1227 GrPoint center = GrPoint::Make(circle.centerX(), circle.centerY()); | |
1228 vm.mapPoints(¢er, 1); | |
1229 | |
1230 bool isStroked = (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairl ine_Style == style); | |
1231 enum { | |
1232 // the edge effects share this stage with glyph rendering | |
1233 // (kGlyphMaskStage in GrTextContext) && SW path rendering | |
1234 // (kPathMaskStage in GrSWMaskHelper) | |
1235 kEdgeEffectStage = GrPaint::kTotalStages, | |
1236 }; | |
1237 drawState->setAttribBindings(GrDrawState::kDefault_AttribBindings); | |
1238 | |
1239 GrEffectRef* effect = GrCircleEdgeEffect::Create(isStroked); | |
1240 static const int kCircleEdgeAttrIndex = 1; | |
1241 drawState->setEffect(kEdgeEffectStage, effect, kCircleEdgeAttrIndex)->unref( ); | |
1242 | |
1243 radius = vm.mapRadius(radius); | |
1244 | |
1245 SkScalar innerRadius = -2.0f; | |
1246 SkScalar outerRadius = radius; | |
1247 SkScalar halfWidth = 0; | |
1248 if (style != SkStrokeRec::kFill_Style) { | |
1249 strokeWidth = vm.mapRadius(strokeWidth); | |
1250 if (SkScalarNearlyZero(strokeWidth)) { | |
1251 halfWidth = SK_ScalarHalf; | |
1252 } else { | |
1253 halfWidth = SkScalarHalf(strokeWidth); | |
1254 } | |
1255 | |
1256 outerRadius += halfWidth; | |
1257 if (isStroked) { | |
1258 innerRadius = SkMaxScalar(0, radius - halfWidth); | |
1259 } | |
1260 } | |
1261 | |
1262 for (int i = 0; i < 4; ++i) { | |
1263 verts[i].fCenter = center; | |
1264 verts[i].fOuterRadius = outerRadius + 0.5f; | |
1265 verts[i].fInnerRadius = innerRadius - 0.5f; | |
1266 } | |
1267 | |
1268 SkScalar L = -outerRadius; | |
1269 SkScalar R = +outerRadius; | |
1270 SkScalar T = -outerRadius; | |
1271 SkScalar B = +outerRadius; | |
1272 | |
1273 // We've extended the outer radius out half a pixel to antialias. | |
1274 // Expand the drawn rect here so all the pixels will be captured. | |
1275 L += center.fX - SK_ScalarHalf; | |
1276 R += center.fX + SK_ScalarHalf; | |
1277 T += center.fY - SK_ScalarHalf; | |
1278 B += center.fY + SK_ScalarHalf; | |
1279 | |
1280 verts[0].fPos = SkPoint::Make(L, T); | |
1281 verts[1].fPos = SkPoint::Make(R, T); | |
1282 verts[2].fPos = SkPoint::Make(L, B); | |
1283 verts[3].fPos = SkPoint::Make(R, B); | |
1284 | |
1285 target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4); | |
1286 } | |
1287 | |
1288 void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const SkStrok eRec& stroke) { | 1021 void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const SkStrok eRec& stroke) { |
1289 | 1022 |
1290 if (path.isEmpty()) { | 1023 if (path.isEmpty()) { |
1291 if (path.isInverseFillType()) { | 1024 if (path.isInverseFillType()) { |
1292 this->drawPaint(paint); | 1025 this->drawPaint(paint); |
1293 } | 1026 } |
1294 return; | 1027 return; |
1295 } | 1028 } |
1296 | 1029 |
1297 SkRect ovalRect; | 1030 // Note that internalDrawPath may sw-rasterize the path into a scratch textu re. |
1298 bool isOval = path.isOval(&ovalRect); | |
1299 | |
1300 bool isCircle; | |
1301 if (isOval && !path.isInverseFillType() && this->canDrawOval(paint, ovalRect , &isCircle)) { | |
1302 if (isCircle) { | |
1303 this->internalDrawCircle(paint, ovalRect, stroke); | |
1304 } else { | |
1305 this->internalDrawOval(paint, ovalRect, stroke); | |
1306 } | |
1307 return; | |
1308 } | |
1309 | |
1310 this->internalDrawPath(paint, path, stroke); | |
1311 } | |
1312 | |
1313 void GrContext::internalDrawPath(const GrPaint& paint, const SkPath& path, | |
1314 const SkStrokeRec& stroke) { | |
1315 | |
1316 // Note that below we may sw-rasterize the path into a scratch texture. | |
1317 // Scratch textures can be recycled after they are returned to the texture | 1031 // Scratch textures can be recycled after they are returned to the texture |
1318 // cache. This presents a potential hazard for buffered drawing. However, | 1032 // cache. This presents a potential hazard for buffered drawing. However, |
1319 // the writePixels that uploads to the scratch will perform a flush so we're | 1033 // the writePixels that uploads to the scratch will perform a flush so we're |
1320 // OK. | 1034 // OK. |
1321 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW); | 1035 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW); |
1322 GrDrawState::AutoStageDisable atr(fDrawState); | 1036 GrDrawState::AutoStageDisable atr(fDrawState); |
1323 | 1037 |
1038 SkRect ovalRect; | |
1039 bool isOval = path.isOval(&ovalRect); | |
1040 | |
1041 bool isCircle; | |
1042 if (isOval && !path.isInverseFillType() && | |
1043 fOvalRenderer->canDrawOval(this, paint, ovalRect, &isCircle)) { | |
1044 | |
1045 if (isCircle) { | |
1046 fOvalRenderer->drawCircle(target, paint, ovalRect, stroke); | |
1047 } else { | |
1048 fOvalRenderer->drawEllipse(target, paint, ovalRect, stroke); | |
1049 } | |
1050 return; | |
1051 } | |
1052 | |
1053 this->internalDrawPath(target, paint, path, stroke); | |
1054 } | |
1055 | |
1056 void GrContext::internalDrawPath(GrDrawTarget* target, const GrPaint& paint, con st SkPath& path, | |
1057 const SkStrokeRec& stroke) { | |
1058 | |
1324 bool prAA = paint.isAntiAlias() && !this->getRenderTarget()->isMultisampled( ); | 1059 bool prAA = paint.isAntiAlias() && !this->getRenderTarget()->isMultisampled( ); |
1325 | 1060 |
1326 // An Assumption here is that path renderer would use some form of tweaking | 1061 // An Assumption here is that path renderer would use some form of tweaking |
1327 // the src color (either the input alpha or in the frag shader) to implement | 1062 // the src color (either the input alpha or in the frag shader) to implement |
1328 // aa. If we have some future driver-mojo path AA that can do the right | 1063 // aa. If we have some future driver-mojo path AA that can do the right |
1329 // thing WRT to the blend then we'll need some query on the PR. | 1064 // thing WRT to the blend then we'll need some query on the PR. |
1330 if (disable_coverage_aa_for_blend(target)) { | 1065 if (disable_coverage_aa_for_blend(target)) { |
1331 #if GR_DEBUG | 1066 #if GR_DEBUG |
1332 //GrPrintf("Turning off AA to correctly apply blend.\n"); | 1067 //GrPrintf("Turning off AA to correctly apply blend.\n"); |
1333 #endif | 1068 #endif |
(...skipping 759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2093 return srcTexture; | 1828 return srcTexture; |
2094 } | 1829 } |
2095 } | 1830 } |
2096 | 1831 |
2097 /////////////////////////////////////////////////////////////////////////////// | 1832 /////////////////////////////////////////////////////////////////////////////// |
2098 #if GR_CACHE_STATS | 1833 #if GR_CACHE_STATS |
2099 void GrContext::printCacheStats() const { | 1834 void GrContext::printCacheStats() const { |
2100 fTextureCache->printStats(); | 1835 fTextureCache->printStats(); |
2101 } | 1836 } |
2102 #endif | 1837 #endif |
OLD | NEW |