Push dash checks into GrContext.

Add class to hold stroke and dash info.

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

Author: egdaniel@google.com

Review URL: https://codereview.chromium.org/311183002
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 7c66fa9..288ea5a 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -17,6 +17,7 @@
 #include "GrDistanceFieldTextContext.h"
 #include "GrLayerCache.h"
 #include "GrPictureUtils.h"
+#include "GrStrokeInfo.h"
 
 #include "SkGrTexturePixelRef.h"
 
@@ -428,9 +429,11 @@
                    (paint.getStrokeJoin() == SkPaint::kRound_Join ||
                     (paint.getStrokeJoin() == SkPaint::kBevel_Join && rect.isEmpty()));
     // another two reasons we might need to call drawPath...
-    if (paint.getMaskFilter() || paint.getPathEffect()) {
+
+    if (paint.getMaskFilter()) {
         usePath = true;
     }
+
     if (!usePath && paint.isAntiAlias() && !fContext->getMatrix().rectStaysRect()) {
 #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
         if (doStroke) {
@@ -447,6 +450,13 @@
         usePath = true;
     }
 
+    GrStrokeInfo strokeInfo(paint);
+
+    const SkPathEffect* pe = paint.getPathEffect();
+    if (!usePath && NULL != pe && !strokeInfo.isDashed()) {
+        usePath = true;
+    }
+
     if (usePath) {
         SkPath path;
         path.addRect(rect);
@@ -456,13 +466,8 @@
 
     GrPaint grPaint;
     SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
-
-    if (!doStroke) {
-        fContext->drawRect(grPaint, rect);
-    } else {
-        SkStrokeRec stroke(paint);
-        fContext->drawRect(grPaint, rect, &stroke);
-    }
+  
+    fContext->drawRect(grPaint, rect, &strokeInfo);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -474,8 +479,8 @@
 
     GrPaint grPaint;
     SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
-
-    SkStrokeRec stroke(paint);
+    
+    GrStrokeInfo strokeInfo(paint);
     if (paint.getMaskFilter()) {
         // try to hit the fast path for drawing filtered round rects
 
@@ -494,7 +499,8 @@
                         return;
                     }
                     if (paint.getMaskFilter()->directFilterRRectMaskGPU(fContext, &grPaint,
-                                                                        stroke, devRRect)) {
+                                                                        strokeInfo.getStrokeRec(),
+                                                                        devRRect)) {
                         return;
                     }
                 }
@@ -504,14 +510,26 @@
 
     }
 
-    if (paint.getMaskFilter() || paint.getPathEffect()) {
+    bool usePath = false;
+
+    if (paint.getMaskFilter()) {
+        usePath = true;
+    } else {
+        const SkPathEffect* pe = paint.getPathEffect();
+        if (NULL != pe && !strokeInfo.isDashed()) {
+            usePath = true;
+        }
+    }
+
+
+    if (usePath) {
         SkPath path;
         path.addRRect(rect);
         this->drawPath(draw, path, paint, NULL, true);
         return;
     }
-
-    fContext->drawRRect(grPaint, rect, stroke);
+    
+    fContext->drawRRect(grPaint, rect, strokeInfo);
 }
 
 void SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
@@ -547,10 +565,17 @@
     CHECK_FOR_ANNOTATION(paint);
     CHECK_SHOULD_DRAW(draw, false);
 
+    GrStrokeInfo strokeInfo(paint);
+
     bool usePath = false;
     // some basic reasons we might need to call drawPath...
-    if (paint.getMaskFilter() || paint.getPathEffect()) {
+    if (paint.getMaskFilter()) {
         usePath = true;
+    } else {
+        const SkPathEffect* pe = paint.getPathEffect();
+        if (NULL != pe && !strokeInfo.isDashed()) {
+            usePath = true;
+        }
     }
 
     if (usePath) {
@@ -562,9 +587,8 @@
 
     GrPaint grPaint;
     SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
-    SkStrokeRec stroke(paint);
 
-    fContext->drawOval(grPaint, oval, stroke);
+    fContext->drawOval(grPaint, oval, strokeInfo);
 }
 
 #include "SkMaskFilter.h"
@@ -640,7 +664,7 @@
 bool create_mask_GPU(GrContext* context,
                      const SkRect& maskRect,
                      const SkPath& devPath,
-                     const SkStrokeRec& stroke,
+                     const GrStrokeInfo& strokeInfo,
                      bool doAA,
                      GrAutoScratchTexture* mask) {
     GrTextureDesc desc;
@@ -685,7 +709,7 @@
     SkMatrix translate;
     translate.setTranslate(-maskRect.fLeft, -maskRect.fTop);
     am.set(context, translate);
-    context->drawPath(tempPaint, devPath, stroke);
+    context->drawPath(tempPaint, devPath, strokeInfo);
     return true;
 }
 
@@ -729,22 +753,25 @@
     // at this point we're done with prePathMatrix
     SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
 
-    SkStrokeRec stroke(paint);
+    GrStrokeInfo strokeInfo(paint);
     SkPathEffect* pathEffect = paint.getPathEffect();
     const SkRect* cullRect = NULL;  // TODO: what is our bounds?
-    if (pathEffect && pathEffect->filterPath(effectPath.init(), *pathPtr, &stroke,
+    SkStrokeRec* strokePtr = strokeInfo.getStrokeRecPtr();
+    if (pathEffect && pathEffect->filterPath(effectPath.init(), *pathPtr, strokePtr,
                                              cullRect)) {
         pathPtr = effectPath.get();
         pathIsMutable = true;
+        strokeInfo.removeDash();
     }
 
+    const SkStrokeRec& stroke = strokeInfo.getStrokeRec();
     if (paint.getMaskFilter()) {
         if (!stroke.isHairlineStyle()) {
             SkPath* strokedPath = pathIsMutable ? pathPtr : tmpPath.init();
             if (stroke.applyToPath(strokedPath, *pathPtr)) {
                 pathPtr = strokedPath;
                 pathIsMutable = true;
-                stroke.setFillStyle();
+                strokeInfo.setFillStyle();
             }
         }
 
@@ -779,7 +806,7 @@
 
             GrAutoScratchTexture mask;
 
-            if (create_mask_GPU(fContext, maskRect, *devPathPtr, stroke,
+            if (create_mask_GPU(fContext, maskRect, *devPathPtr, strokeInfo,
                                 grPaint.isAntiAlias(), &mask)) {
                 GrTexture* filtered;
 
@@ -808,12 +835,12 @@
         // GPU path fails
         SkPaint::Style style = stroke.isHairlineStyle() ? SkPaint::kStroke_Style :
                                                           SkPaint::kFill_Style;
-        draw_with_mask_filter(fContext, *devPathPtr, paint.getMaskFilter(), *draw.fClip, &grPaint,
-                              style);
+        draw_with_mask_filter(fContext, *devPathPtr, paint.getMaskFilter(),
+                              *draw.fClip, &grPaint, style);
         return;
     }
 
-    fContext->drawPath(grPaint, *pathPtr, stroke);
+    fContext->drawPath(grPaint, *pathPtr, strokeInfo);
 }
 
 static const int kBmpSmallTileSize = 1 << 10;