Chromium Code Reviews| 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 |