Consolidate handling of infinitely thin primitives and aa bloat handing WRT batch bounds.

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2127673002

Review-Url: https://codereview.chromium.org/2127673002
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 86e0c82..356c480 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -281,13 +281,41 @@
     }
 }
 
+static void batch_bounds(SkRect* bounds, const GrBatch* batch) {
+    *bounds = batch->bounds();
+    if (batch->hasZeroArea()) {
+        if (batch->hasAABloat()) {
+            bounds->outset(0.5f, 0.5f);
+        } else {
+            // We don't know which way the particular GPU will snap lines or points at integer
+            // coords. So we ensure that the bounds is large enough for either snap.
+            SkRect before = *bounds;
+            bounds->roundOut(bounds);
+            if (bounds->fLeft == before.fLeft) {
+                bounds->fLeft -= 1;
+            }
+            if (bounds->fTop == before.fTop) {
+                bounds->fTop -= 1;
+            }
+            if (bounds->fRight == before.fRight) {
+                bounds->fRight += 1;
+            }
+            if (bounds->fBottom == before.fBottom) {
+                bounds->fBottom += 1;
+            }
+        }
+    }
+}
+
 void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder,
                              GrDrawContext* drawContext,
                              const GrClip& clip,
                              GrDrawBatch* batch) {
     // Setup clip
     GrAppliedClip appliedClip;
-    if (!clip.apply(fContext, pipelineBuilder, drawContext, &batch->bounds(), &appliedClip)) {
+    SkRect bounds;
+    batch_bounds(&bounds, batch);
+    if (!clip.apply(fContext, pipelineBuilder, drawContext, &bounds, &appliedClip)) {
         return;
     }
 
@@ -469,10 +497,17 @@
     return true;
 }
 
-template <class Left, class Right> static bool intersect(const Left& a, const Right& b) {
-    SkASSERT(a.fLeft <= a.fRight && a.fTop <= a.fBottom &&
-             b.fLeft <= b.fRight && b.fTop <= b.fBottom);
-    return a.fLeft < b.fRight && b.fLeft < a.fRight && a.fTop < b.fBottom && b.fTop < a.fBottom;
+static inline bool exclusive_no_intersection(const SkRect& a, const SkRect& b) {
+    return a.fRight <= b.fLeft || a.fBottom <= b.fTop ||
+           b.fRight <= a.fLeft || b.fBottom <= a.fTop;
+}
+
+static inline bool can_reorder(const GrBatch* a, const GrBatch* b) {
+    SkRect ra;
+    SkRect rb;
+    batch_bounds(&ra, a);
+    batch_bounds(&rb, a);
+    return exclusive_no_intersection(ra, rb);
 }
 
 void GrDrawTarget::recordBatch(GrBatch* batch) {
@@ -512,7 +547,7 @@
             // Stop going backwards if we would cause a painter's order violation.
             // TODO: The bounds used here do not fully consider the clip. It may be advantageous
             // to clip each batch's bounds to the clip.
-            if (intersect(candidate->bounds(), batch->bounds())) {
+            if (!can_reorder(candidate, batch)) {
                 GrBATCH_INFO("\t\tIntersects with (%s, B%u)\n", candidate->name(),
                     candidate->uniqueID());
                 break;
@@ -558,7 +593,7 @@
             // Stop going traversing if we would cause a painter's order violation.
             // TODO: The bounds used here do not fully consider the clip. It may be advantageous
             // to clip each batch's bounds to the clip.
-            if (intersect(candidate->bounds(), batch->bounds())) {
+            if (!can_reorder(candidate, batch)) {
                 GrBATCH_INFO("\t\tIntersects with (%s, B%u)\n", candidate->name(),
                              candidate->uniqueID());
                 break;