| 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 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 | 984 |
| 983 if (NULL != indices) { | 985 if (NULL != indices) { |
| 984 target->setIndexSourceToArray(indices, indexCount); | 986 target->setIndexSourceToArray(indices, indexCount); |
| 985 target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); | 987 target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); |
| 986 } else { | 988 } else { |
| 987 target->drawNonIndexed(primitiveType, 0, vertexCount); | 989 target->drawNonIndexed(primitiveType, 0, vertexCount); |
| 988 } | 990 } |
| 989 } | 991 } |
| 990 | 992 |
| 991 /////////////////////////////////////////////////////////////////////////////// | 993 /////////////////////////////////////////////////////////////////////////////// |
| 992 namespace { | |
| 993 | |
| 994 struct CircleVertex { | |
| 995 GrPoint fPos; | |
| 996 GrPoint fCenter; | |
| 997 SkScalar fOuterRadius; | |
| 998 SkScalar fInnerRadius; | |
| 999 }; | |
| 1000 | |
| 1001 struct EllipseVertex { | |
| 1002 GrPoint fPos; | |
| 1003 GrPoint fCenter; | |
| 1004 SkScalar fOuterXRadius; | |
| 1005 SkScalar fOuterXYRatio; | |
| 1006 SkScalar fInnerXRadius; | |
| 1007 SkScalar fInnerXYRatio; | |
| 1008 }; | |
| 1009 | |
| 1010 inline bool circleStaysCircle(const SkMatrix& m) { | |
| 1011 return m.isSimilarity(); | |
| 1012 } | |
| 1013 | |
| 1014 } | |
| 1015 | 994 |
| 1016 void GrContext::drawOval(const GrPaint& paint, | 995 void GrContext::drawOval(const GrPaint& paint, |
| 1017 const GrRect& oval, | 996 const GrRect& oval, |
| 1018 const SkStrokeRec& stroke) { | 997 const SkStrokeRec& stroke) { |
| 1019 | 998 |
| 1020 bool isCircle; | 999 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW); |
| 1021 if (!canDrawOval(paint, oval, &isCircle)) { | 1000 GrDrawState::AutoStageDisable atr(fDrawState); |
| 1001 |
| 1002 if (!fOvalRenderer->drawOval(target, this, paint, oval, stroke)) { |
| 1022 SkPath path; | 1003 SkPath path; |
| 1023 path.addOval(oval); | 1004 path.addOval(oval); |
| 1024 this->drawPath(paint, path, stroke); | 1005 this->internalDrawPath(target, paint, path, stroke); |
| 1025 return; | |
| 1026 } | 1006 } |
| 1027 | |
| 1028 if (isCircle) { | |
| 1029 this->internalDrawCircle(paint, oval, stroke); | |
| 1030 } else { | |
| 1031 this->internalDrawOval(paint, oval, stroke); | |
| 1032 } | |
| 1033 } | |
| 1034 | |
| 1035 bool GrContext::canDrawOval(const GrPaint& paint, const GrRect& oval, bool* isCi
rcle) const { | |
| 1036 GrAssert(isCircle != NULL); | |
| 1037 | |
| 1038 if (!paint.isAntiAlias()) { | |
| 1039 return false; | |
| 1040 } | |
| 1041 | |
| 1042 // we can draw circles | |
| 1043 *isCircle = SkScalarNearlyEqual(oval.width(), oval.height()) | |
| 1044 && circleStaysCircle(this->getMatrix()); | |
| 1045 // and axis-aligned ellipses only | |
| 1046 bool isAxisAlignedEllipse = this->getMatrix().rectStaysRect(); | |
| 1047 | |
| 1048 return *isCircle || isAxisAlignedEllipse; | |
| 1049 } | |
| 1050 | |
| 1051 void GrContext::internalDrawOval(const GrPaint& paint, | |
| 1052 const GrRect& oval, | |
| 1053 const SkStrokeRec& stroke) { | |
| 1054 #ifdef SK_DEBUG | |
| 1055 { | |
| 1056 // we should have checked for this previously | |
| 1057 bool isAxisAlignedEllipse = this->getMatrix().rectStaysRect(); | |
| 1058 SkASSERT(paint.isAntiAlias() && isAxisAlignedEllipse); | |
| 1059 } | |
| 1060 #endif | |
| 1061 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW); | |
| 1062 | |
| 1063 GrDrawState* drawState = target->drawState(); | |
| 1064 GrDrawState::AutoStageDisable atr(fDrawState); | |
| 1065 | |
| 1066 const GrRenderTarget* rt = drawState->getRenderTarget(); | |
| 1067 if (NULL == rt) { | |
| 1068 return; | |
| 1069 } | |
| 1070 | |
| 1071 const SkMatrix vm = drawState->getViewMatrix(); | |
| 1072 | |
| 1073 GrDrawState::AutoDeviceCoordDraw adcd(drawState); | |
| 1074 if (!adcd.succeeded()) { | |
| 1075 return; | |
| 1076 } | |
| 1077 | |
| 1078 // position + edge | |
| 1079 static const GrVertexAttrib kVertexAttribs[] = { | |
| 1080 {kVec2f_GrVertexAttribType, 0}, | |
| 1081 {kVec2f_GrVertexAttribType, sizeof(GrPoint)}, | |
| 1082 {kVec4f_GrVertexAttribType, 2*sizeof(GrPoint)} | |
| 1083 }; | |
| 1084 drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs)); | |
| 1085 drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0); | |
| 1086 GrAssert(sizeof(EllipseVertex) == drawState->getVertexSize()); | |
| 1087 | |
| 1088 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); | |
| 1089 if (!geo.succeeded()) { | |
| 1090 GrPrintf("Failed to get space for vertices!\n"); | |
| 1091 return; | |
| 1092 } | |
| 1093 | |
| 1094 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); | |
| 1095 | |
| 1096 GrPoint center = GrPoint::Make(oval.centerX(), oval.centerY()); | |
| 1097 vm.mapPoints(¢er, 1); | |
| 1098 | |
| 1099 SkStrokeRec::Style style = stroke.getStyle(); | |
| 1100 bool isStroked = (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairl
ine_Style == style); | |
| 1101 enum { | |
| 1102 // the edge effects share this stage with glyph rendering | |
| 1103 // (kGlyphMaskStage in GrTextContext) && SW path rendering | |
| 1104 // (kPathMaskStage in GrSWMaskHelper) | |
| 1105 kEdgeEffectStage = GrPaint::kTotalStages, | |
| 1106 }; | |
| 1107 drawState->setAttribBindings(GrDrawState::kDefault_AttribBindings); | |
| 1108 | |
| 1109 GrEffectRef* effect = GrEllipseEdgeEffect::Create(isStroked); | |
| 1110 static const int kEllipseCenterAttrIndex = 1; | |
| 1111 static const int kEllipseEdgeAttrIndex = 2; | |
| 1112 drawState->setEffect(kEdgeEffectStage, effect, | |
| 1113 kEllipseCenterAttrIndex, kEllipseEdgeAttrIndex)->unref(
); | |
| 1114 | |
| 1115 SkRect xformedRect; | |
| 1116 vm.mapRect(&xformedRect, oval); | |
| 1117 | |
| 1118 SkScalar xRadius = SkScalarHalf(xformedRect.width()); | |
| 1119 SkScalar yRadius = SkScalarHalf(xformedRect.height()); | |
| 1120 SkScalar innerXRadius = 0.0f; | |
| 1121 SkScalar innerRatio = 1.0f; | |
| 1122 | |
| 1123 if (SkStrokeRec::kFill_Style != style) { | |
| 1124 SkScalar strokeWidth = stroke.getWidth(); | |
| 1125 | |
| 1126 // do (potentially) anisotropic mapping | |
| 1127 SkVector scaledStroke; | |
| 1128 scaledStroke.set(strokeWidth, strokeWidth); | |
| 1129 vm.mapVectors(&scaledStroke, 1); | |
| 1130 | |
| 1131 if (SkScalarNearlyZero(scaledStroke.length())) { | |
| 1132 scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf); | |
| 1133 } else { | |
| 1134 scaledStroke.scale(0.5f); | |
| 1135 } | |
| 1136 | |
| 1137 // this is legit only if scale & translation (which should be the case a
t the moment) | |
| 1138 if (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairline_Style
== style) { | |
| 1139 SkScalar innerYRadius = SkMaxScalar(0, yRadius - scaledStroke.fY); | |
| 1140 if (innerYRadius > SK_ScalarNearlyZero) { | |
| 1141 innerXRadius = SkMaxScalar(0, xRadius - scaledStroke.fX); | |
| 1142 innerRatio = innerXRadius/innerYRadius; | |
| 1143 } | |
| 1144 } | |
| 1145 xRadius += scaledStroke.fX; | |
| 1146 yRadius += scaledStroke.fY; | |
| 1147 } | |
| 1148 | |
| 1149 SkScalar outerRatio = SkScalarDiv(xRadius, yRadius); | |
| 1150 | |
| 1151 for (int i = 0; i < 4; ++i) { | |
| 1152 verts[i].fCenter = center; | |
| 1153 verts[i].fOuterXRadius = xRadius + 0.5f; | |
| 1154 verts[i].fOuterXYRatio = outerRatio; | |
| 1155 verts[i].fInnerXRadius = innerXRadius - 0.5f; | |
| 1156 verts[i].fInnerXYRatio = innerRatio; | |
| 1157 } | |
| 1158 | |
| 1159 SkScalar L = -xRadius; | |
| 1160 SkScalar R = +xRadius; | |
| 1161 SkScalar T = -yRadius; | |
| 1162 SkScalar B = +yRadius; | |
| 1163 | |
| 1164 // We've extended the outer x radius out half a pixel to antialias. | |
| 1165 // Expand the drawn rect here so all the pixels will be captured. | |
| 1166 L += center.fX - SK_ScalarHalf; | |
| 1167 R += center.fX + SK_ScalarHalf; | |
| 1168 T += center.fY - SK_ScalarHalf; | |
| 1169 B += center.fY + SK_ScalarHalf; | |
| 1170 | |
| 1171 verts[0].fPos = SkPoint::Make(L, T); | |
| 1172 verts[1].fPos = SkPoint::Make(R, T); | |
| 1173 verts[2].fPos = SkPoint::Make(L, B); | |
| 1174 verts[3].fPos = SkPoint::Make(R, B); | |
| 1175 | |
| 1176 target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4); | |
| 1177 } | |
| 1178 | |
| 1179 void GrContext::internalDrawCircle(const GrPaint& paint, | |
| 1180 const GrRect& circle, | |
| 1181 const SkStrokeRec& stroke) { | |
| 1182 | |
| 1183 SkScalar radius = SkScalarHalf(circle.width()); | |
| 1184 | |
| 1185 SkScalar strokeWidth = stroke.getWidth(); | |
| 1186 SkStrokeRec::Style style = stroke.getStyle(); | |
| 1187 | |
| 1188 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW); | |
| 1189 | |
| 1190 GrDrawState* drawState = target->drawState(); | |
| 1191 GrDrawState::AutoStageDisable atr(fDrawState); | |
| 1192 | |
| 1193 const GrRenderTarget* rt = drawState->getRenderTarget(); | |
| 1194 if (NULL == rt) { | |
| 1195 return; | |
| 1196 } | |
| 1197 | |
| 1198 const SkMatrix vm = drawState->getViewMatrix(); | |
| 1199 | |
| 1200 GrDrawState::AutoDeviceCoordDraw adcd(drawState); | |
| 1201 if (!adcd.succeeded()) { | |
| 1202 return; | |
| 1203 } | |
| 1204 | |
| 1205 // position + edge | |
| 1206 static const GrVertexAttrib kVertexAttribs[] = { | |
| 1207 {kVec2f_GrVertexAttribType, 0}, | |
| 1208 {kVec4f_GrVertexAttribType, sizeof(GrPoint)} | |
| 1209 }; | |
| 1210 drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs)); | |
| 1211 drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0); | |
| 1212 GrAssert(sizeof(CircleVertex) == drawState->getVertexSize()); | |
| 1213 | |
| 1214 GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0); | |
| 1215 if (!geo.succeeded()) { | |
| 1216 GrPrintf("Failed to get space for vertices!\n"); | |
| 1217 return; | |
| 1218 } | |
| 1219 | |
| 1220 CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices()); | |
| 1221 | |
| 1222 GrPoint center = GrPoint::Make(circle.centerX(), circle.centerY()); | |
| 1223 vm.mapPoints(¢er, 1); | |
| 1224 | |
| 1225 bool isStroked = (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairl
ine_Style == style); | |
| 1226 enum { | |
| 1227 // the edge effects share this stage with glyph rendering | |
| 1228 // (kGlyphMaskStage in GrTextContext) && SW path rendering | |
| 1229 // (kPathMaskStage in GrSWMaskHelper) | |
| 1230 kEdgeEffectStage = GrPaint::kTotalStages, | |
| 1231 }; | |
| 1232 drawState->setAttribBindings(GrDrawState::kDefault_AttribBindings); | |
| 1233 | |
| 1234 GrEffectRef* effect = GrCircleEdgeEffect::Create(isStroked); | |
| 1235 static const int kCircleEdgeAttrIndex = 1; | |
| 1236 drawState->setEffect(kEdgeEffectStage, effect, kCircleEdgeAttrIndex)->unref(
); | |
| 1237 | |
| 1238 radius = vm.mapRadius(radius); | |
| 1239 | |
| 1240 SkScalar innerRadius = -2.0f; | |
| 1241 SkScalar outerRadius = radius; | |
| 1242 SkScalar halfWidth = 0; | |
| 1243 if (style != SkStrokeRec::kFill_Style) { | |
| 1244 strokeWidth = vm.mapRadius(strokeWidth); | |
| 1245 if (SkScalarNearlyZero(strokeWidth)) { | |
| 1246 halfWidth = SK_ScalarHalf; | |
| 1247 } else { | |
| 1248 halfWidth = SkScalarHalf(strokeWidth); | |
| 1249 } | |
| 1250 | |
| 1251 outerRadius += halfWidth; | |
| 1252 if (isStroked) { | |
| 1253 innerRadius = SkMaxScalar(0, radius - halfWidth); | |
| 1254 } | |
| 1255 } | |
| 1256 | |
| 1257 for (int i = 0; i < 4; ++i) { | |
| 1258 verts[i].fCenter = center; | |
| 1259 verts[i].fOuterRadius = outerRadius + 0.5f; | |
| 1260 verts[i].fInnerRadius = innerRadius - 0.5f; | |
| 1261 } | |
| 1262 | |
| 1263 SkScalar L = -outerRadius; | |
| 1264 SkScalar R = +outerRadius; | |
| 1265 SkScalar T = -outerRadius; | |
| 1266 SkScalar B = +outerRadius; | |
| 1267 | |
| 1268 // We've extended the outer radius out half a pixel to antialias. | |
| 1269 // Expand the drawn rect here so all the pixels will be captured. | |
| 1270 L += center.fX - SK_ScalarHalf; | |
| 1271 R += center.fX + SK_ScalarHalf; | |
| 1272 T += center.fY - SK_ScalarHalf; | |
| 1273 B += center.fY + SK_ScalarHalf; | |
| 1274 | |
| 1275 verts[0].fPos = SkPoint::Make(L, T); | |
| 1276 verts[1].fPos = SkPoint::Make(R, T); | |
| 1277 verts[2].fPos = SkPoint::Make(L, B); | |
| 1278 verts[3].fPos = SkPoint::Make(R, B); | |
| 1279 | |
| 1280 target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4); | |
| 1281 } | 1007 } |
| 1282 | 1008 |
| 1283 void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const SkStrok
eRec& stroke) { | 1009 void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const SkStrok
eRec& stroke) { |
| 1284 | 1010 |
| 1285 if (path.isEmpty()) { | 1011 if (path.isEmpty()) { |
| 1286 if (path.isInverseFillType()) { | 1012 if (path.isInverseFillType()) { |
| 1287 this->drawPaint(paint); | 1013 this->drawPaint(paint); |
| 1288 } | 1014 } |
| 1289 return; | 1015 return; |
| 1290 } | 1016 } |
| 1291 | 1017 |
| 1292 SkRect ovalRect; | 1018 // Note that internalDrawPath may sw-rasterize the path into a scratch textu
re. |
| 1293 bool isOval = path.isOval(&ovalRect); | |
| 1294 | |
| 1295 bool isCircle; | |
| 1296 if (isOval && !path.isInverseFillType() && this->canDrawOval(paint, ovalRect
, &isCircle)) { | |
| 1297 if (isCircle) { | |
| 1298 this->internalDrawCircle(paint, ovalRect, stroke); | |
| 1299 } else { | |
| 1300 this->internalDrawOval(paint, ovalRect, stroke); | |
| 1301 } | |
| 1302 return; | |
| 1303 } | |
| 1304 | |
| 1305 this->internalDrawPath(paint, path, stroke); | |
| 1306 } | |
| 1307 | |
| 1308 void GrContext::internalDrawPath(const GrPaint& paint, const SkPath& path, | |
| 1309 const SkStrokeRec& stroke) { | |
| 1310 | |
| 1311 // Note that below we may sw-rasterize the path into a scratch texture. | |
| 1312 // Scratch textures can be recycled after they are returned to the texture | 1019 // Scratch textures can be recycled after they are returned to the texture |
| 1313 // cache. This presents a potential hazard for buffered drawing. However, | 1020 // cache. This presents a potential hazard for buffered drawing. However, |
| 1314 // the writePixels that uploads to the scratch will perform a flush so we're | 1021 // the writePixels that uploads to the scratch will perform a flush so we're |
| 1315 // OK. | 1022 // OK. |
| 1316 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW); | 1023 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW); |
| 1317 GrDrawState::AutoStageDisable atr(fDrawState); | 1024 GrDrawState::AutoStageDisable atr(fDrawState); |
| 1318 | 1025 |
| 1026 SkRect ovalRect; |
| 1027 bool isOval = path.isOval(&ovalRect); |
| 1028 |
| 1029 if (!isOval || path.isInverseFillType() |
| 1030 || !fOvalRenderer->drawOval(target, this, paint, ovalRect, stroke)) { |
| 1031 this->internalDrawPath(target, paint, path, stroke); |
| 1032 } |
| 1033 } |
| 1034 |
| 1035 void GrContext::internalDrawPath(GrDrawTarget* target, const GrPaint& paint, con
st SkPath& path, |
| 1036 const SkStrokeRec& stroke) { |
| 1037 |
| 1319 bool prAA = paint.isAntiAlias() && !this->getRenderTarget()->isMultisampled(
); | 1038 bool prAA = paint.isAntiAlias() && !this->getRenderTarget()->isMultisampled(
); |
| 1320 | 1039 |
| 1321 // An Assumption here is that path renderer would use some form of tweaking | 1040 // An Assumption here is that path renderer would use some form of tweaking |
| 1322 // the src color (either the input alpha or in the frag shader) to implement | 1041 // the src color (either the input alpha or in the frag shader) to implement |
| 1323 // aa. If we have some future driver-mojo path AA that can do the right | 1042 // aa. If we have some future driver-mojo path AA that can do the right |
| 1324 // thing WRT to the blend then we'll need some query on the PR. | 1043 // thing WRT to the blend then we'll need some query on the PR. |
| 1325 if (disable_coverage_aa_for_blend(target)) { | 1044 if (disable_coverage_aa_for_blend(target)) { |
| 1326 #if GR_DEBUG | 1045 #if GR_DEBUG |
| 1327 //GrPrintf("Turning off AA to correctly apply blend.\n"); | 1046 //GrPrintf("Turning off AA to correctly apply blend.\n"); |
| 1328 #endif | 1047 #endif |
| (...skipping 759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2088 return srcTexture; | 1807 return srcTexture; |
| 2089 } | 1808 } |
| 2090 } | 1809 } |
| 2091 | 1810 |
| 2092 /////////////////////////////////////////////////////////////////////////////// | 1811 /////////////////////////////////////////////////////////////////////////////// |
| 2093 #if GR_CACHE_STATS | 1812 #if GR_CACHE_STATS |
| 2094 void GrContext::printCacheStats() const { | 1813 void GrContext::printCacheStats() const { |
| 2095 fTextureCache->printStats(); | 1814 fTextureCache->printStats(); |
| 2096 } | 1815 } |
| 2097 #endif | 1816 #endif |
| OLD | NEW |