Initialize written paths and strokerecs lazily during GPU drawPath

Initialize SkPaths and SkStrokeRecs lazily during GPU drawPath calls.
The constructors seem to appear in some profiler results on ARM (~1%).

R=bsalomon@google.com, robertphillips@google.com

Author: kkinnunen@nvidia.com

Review URL: https://codereview.chromium.org/118143002

git-svn-id: http://skia.googlecode.com/svn/trunk@13069 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
commit-bot@chromium.org 2014-01-14 18:42:34 +00:00
parent 46de153d4e
commit f0c41e24d5
2 changed files with 20 additions and 17 deletions

View File

@ -1134,7 +1134,7 @@ void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const SkStrok
} }
void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path, void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path,
const SkStrokeRec& stroke) { const SkStrokeRec& origStroke) {
SkASSERT(!path.isEmpty()); SkASSERT(!path.isEmpty());
// An Assumption here is that path renderer would use some form of tweaking // An Assumption here is that path renderer would use some form of tweaking
@ -1151,18 +1151,18 @@ void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath&
GrPathRendererChain::kColor_DrawType; GrPathRendererChain::kColor_DrawType;
const SkPath* pathPtr = &path; const SkPath* pathPtr = &path;
SkPath tmpPath; SkTLazy<SkPath> tmpPath;
SkStrokeRec strokeRec(stroke); SkTCopyOnFirstWrite<SkStrokeRec> stroke(origStroke);
// Try a 1st time without stroking the path and without allowing the SW renderer // Try a 1st time without stroking the path and without allowing the SW renderer
GrPathRenderer* pr = this->getPathRenderer(*pathPtr, strokeRec, target, false, type); GrPathRenderer* pr = this->getPathRenderer(*pathPtr, *stroke, target, false, type);
if (NULL == pr) { if (NULL == pr) {
if (!GrPathRenderer::IsStrokeHairlineOrEquivalent(strokeRec, this->getMatrix(), NULL)) { if (!GrPathRenderer::IsStrokeHairlineOrEquivalent(*stroke, this->getMatrix(), NULL)) {
// It didn't work the 1st time, so try again with the stroked path // It didn't work the 1st time, so try again with the stroked path
if (strokeRec.applyToPath(&tmpPath, *pathPtr)) { if (stroke->applyToPath(tmpPath.init(), *pathPtr)) {
pathPtr = &tmpPath; pathPtr = tmpPath.get();
strokeRec.setFillStyle(); stroke.writable()->setFillStyle();
if (pathPtr->isEmpty()) { if (pathPtr->isEmpty()) {
return; return;
} }
@ -1170,7 +1170,7 @@ void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath&
} }
// This time, allow SW renderer // This time, allow SW renderer
pr = this->getPathRenderer(*pathPtr, strokeRec, target, true, type); pr = this->getPathRenderer(*pathPtr, *stroke, target, true, type);
} }
if (NULL == pr) { if (NULL == pr) {
@ -1180,7 +1180,7 @@ void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath&
return; return;
} }
pr->drawPath(*pathPtr, strokeRec, target, useCoverageAA); pr->drawPath(*pathPtr, *stroke, target, useCoverageAA);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -877,13 +877,14 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
// where the original path can in fact be modified in place (even though // where the original path can in fact be modified in place (even though
// its parameter type is const). // its parameter type is const).
SkPath* pathPtr = const_cast<SkPath*>(&origSrcPath); SkPath* pathPtr = const_cast<SkPath*>(&origSrcPath);
SkPath tmpPath, effectPath; SkTLazy<SkPath> tmpPath;
SkTLazy<SkPath> effectPath;
if (prePathMatrix) { if (prePathMatrix) {
SkPath* result = pathPtr; SkPath* result = pathPtr;
if (!pathIsMutable) { if (!pathIsMutable) {
result = &tmpPath; result = tmpPath.init();
pathIsMutable = true; pathIsMutable = true;
} }
// should I push prePathMatrix on our MV stack temporarily, instead // should I push prePathMatrix on our MV stack temporarily, instead
@ -897,22 +898,24 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
SkStrokeRec stroke(paint); SkStrokeRec stroke(paint);
SkPathEffect* pathEffect = paint.getPathEffect(); SkPathEffect* pathEffect = paint.getPathEffect();
const SkRect* cullRect = NULL; // TODO: what is our bounds? const SkRect* cullRect = NULL; // TODO: what is our bounds?
if (pathEffect && pathEffect->filterPath(&effectPath, *pathPtr, &stroke, if (pathEffect && pathEffect->filterPath(effectPath.init(), *pathPtr, &stroke,
cullRect)) { cullRect)) {
pathPtr = &effectPath; pathPtr = effectPath.get();
pathIsMutable = true;
} }
if (paint.getMaskFilter()) { if (paint.getMaskFilter()) {
if (!stroke.isHairlineStyle()) { if (!stroke.isHairlineStyle()) {
if (stroke.applyToPath(&tmpPath, *pathPtr)) { SkPath* strokedPath = pathIsMutable ? pathPtr : tmpPath.init();
pathPtr = &tmpPath; if (stroke.applyToPath(strokedPath, *pathPtr)) {
pathPtr = strokedPath;
pathIsMutable = true; pathIsMutable = true;
stroke.setFillStyle(); stroke.setFillStyle();
} }
} }
// avoid possibly allocating a new path in transform if we can // avoid possibly allocating a new path in transform if we can
SkPath* devPathPtr = pathIsMutable ? pathPtr : &tmpPath; SkPath* devPathPtr = pathIsMutable ? pathPtr : tmpPath.init();
// transform the path into device space // transform the path into device space
pathPtr->transform(fContext->getMatrix(), devPathPtr); pathPtr->transform(fContext->getMatrix(), devPathPtr);