Initialize written paths and strokerecs lazily during GPU drawPath
authorcommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 14 Jan 2014 18:42:34 +0000 (18:42 +0000)
committercommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 14 Jan 2014 18:42:34 +0000 (18:42 +0000)
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

src/gpu/GrContext.cpp
src/gpu/SkGpuDevice.cpp

index 127d9ec97b56cacef7523edb93d1696609ff5e3f..bb0f4fa9fab3ee573311c91a219f9ab9abb98aca 100644 (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,
-                                 const SkStrokeRec& stroke) {
+                                 const SkStrokeRec& origStroke) {
     SkASSERT(!path.isEmpty());
 
     // 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;
 
     const SkPath* pathPtr = &path;
-    SkPath tmpPath;
-    SkStrokeRec strokeRec(stroke);
+    SkTLazy<SkPath> tmpPath;
+    SkTCopyOnFirstWrite<SkStrokeRec> stroke(origStroke);
 
     // 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 (!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
-            if (strokeRec.applyToPath(&tmpPath, *pathPtr)) {
-                pathPtr = &tmpPath;
-                strokeRec.setFillStyle();
+            if (stroke->applyToPath(tmpPath.init(), *pathPtr)) {
+                pathPtr = tmpPath.get();
+                stroke.writable()->setFillStyle();
                 if (pathPtr->isEmpty()) {
                     return;
                 }
@@ -1170,7 +1170,7 @@ void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath&
         }
 
         // This time, allow SW renderer
-        pr = this->getPathRenderer(*pathPtr, strokeRec, target, true, type);
+        pr = this->getPathRenderer(*pathPtr, *stroke, target, true, type);
     }
 
     if (NULL == pr) {
@@ -1180,7 +1180,7 @@ void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath&
         return;
     }
 
-    pr->drawPath(*pathPtr, strokeRec, target, useCoverageAA);
+    pr->drawPath(*pathPtr, *stroke, target, useCoverageAA);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
index 36e76e99409e2975d9581e44a2ce038dc68c0787..5ba174cafcc53e9f483b7844c1f1d98b173629ac 100644 (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
     // its parameter type is const).
     SkPath* pathPtr = const_cast<SkPath*>(&origSrcPath);
-    SkPath  tmpPath, effectPath;
+    SkTLazy<SkPath> tmpPath;
+    SkTLazy<SkPath> effectPath;
 
     if (prePathMatrix) {
         SkPath* result = pathPtr;
 
         if (!pathIsMutable) {
-            result = &tmpPath;
+            result = tmpPath.init();
             pathIsMutable = true;
         }
         // 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);
     SkPathEffect* pathEffect = paint.getPathEffect();
     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)) {
-        pathPtr = &effectPath;
+        pathPtr = effectPath.get();
+        pathIsMutable = true;
     }
 
     if (paint.getMaskFilter()) {
         if (!stroke.isHairlineStyle()) {
-            if (stroke.applyToPath(&tmpPath, *pathPtr)) {
-                pathPtr = &tmpPath;
+            SkPath* strokedPath = pathIsMutable ? pathPtr : tmpPath.init();
+            if (stroke.applyToPath(strokedPath, *pathPtr)) {
+                pathPtr = strokedPath;
                 pathIsMutable = true;
                 stroke.setFillStyle();
             }
         }
 
         // 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
         pathPtr->transform(fContext->getMatrix(), devPathPtr);