Restrict query bounds for reduce clip to dev bounds

Review URL: https://codereview.chromium.org/1467253002
diff --git a/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
index e6cf035..659f9d4 100644
--- a/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
+++ b/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
@@ -264,6 +264,15 @@
 
         // compute bounds
         fBounds = geometry.fPath.getBounds();
+        SkScalar w = geometry.fStrokeWidth;
+        if (w > 0) {
+            w /= 2;
+            // If the miter limit is < 1 then we effectively fallback to bevel joins.
+            if (SkPaint::kMiter_Join == geometry.fJoin && w > 1.f) {
+                w *= geometry.fMiterLimit;
+            }
+            fBounds.outset(w, w);
+        }
         geometry.fViewMatrix.mapRect(&fBounds);
     }
 
diff --git a/src/gpu/batches/GrBatch.h b/src/gpu/batches/GrBatch.h
index c5fc80c..03e396a 100644
--- a/src/gpu/batches/GrBatch.h
+++ b/src/gpu/batches/GrBatch.h
@@ -31,6 +31,10 @@
  * If there are any possible optimizations which might require knowing more about the full state of
  * the draw, ie whether or not the GrBatch is allowed to tweak alpha for coverage, then this
  * information will be communicated to the GrBatch prior to geometry generation.
+ *
+ * The bounds of the batch must contain all the vertices in device space *irrespective* of the clip.
+ * The bounds are used in determining which clip elements must be applied and thus the bounds cannot
+ * in turn depend upon the clip.
  */
 #define GR_BATCH_SPEW 0
 #if GR_BATCH_SPEW
diff --git a/src/gpu/batches/GrTessellatingPathRenderer.cpp b/src/gpu/batches/GrTessellatingPathRenderer.cpp
index 901d383..a3a8883 100644
--- a/src/gpu/batches/GrTessellatingPathRenderer.cpp
+++ b/src/gpu/batches/GrTessellatingPathRenderer.cpp
@@ -1592,9 +1592,17 @@
       , fColor(color)
       , fPath(path)
       , fStroke(stroke)
-      , fViewMatrix(viewMatrix)
-      , fClipBounds(clipBounds) {
-        fBounds = path.getBounds();
+      , fViewMatrix(viewMatrix) {
+        const SkRect& pathBounds = path.getBounds();
+        fClipBounds = clipBounds;
+        // Because the clip bounds are used to add a contour for inverse fills, they must also
+        // include the path bounds.
+        fClipBounds.join(pathBounds);
+        if (path.isInverseFillType()) {
+            fBounds = fClipBounds;
+        } else {
+            fBounds = path.getBounds();
+        }
         if (!stroke.isFillStyle()) {
             SkScalar radius = SkScalarHalf(stroke.getWidth());
             if (stroke.getJoin() == SkPaint::kMiter_Join) {