Index: src/gpu/GrDrawTarget.cpp |
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp |
index 86e0c82f225f1a6cf32e54602cb50c3c2375af82..356c480da8cda1c2d345dbcf17ede21a2623dcae 100644 |
--- a/src/gpu/GrDrawTarget.cpp |
+++ b/src/gpu/GrDrawTarget.cpp |
@@ -281,13 +281,41 @@ void GrDrawTarget::reset() { |
} |
} |
+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 @@ bool GrDrawTarget::copySurface(GrSurface* dst, |
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 @@ void GrDrawTarget::recordBatch(GrBatch* batch) { |
// 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 @@ void GrDrawTarget::forwardCombine() { |
// 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; |