Restrict query bounds for reduce clip to dev bounds
Review URL: https://codereview.chromium.org/1467253002
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index 9b78cdf..fa9d189 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -317,8 +317,18 @@
}
case GrClip::kClipStack_ClipType: {
clipSpaceRTIBounds.offset(clip.origin());
+ SkIRect clipSpaceReduceQueryBounds;
+ if (devBounds) {
+ SkIRect devIBounds = devBounds->roundOut();
+ devIBounds.offset(clip.origin());
+ if (!clipSpaceReduceQueryBounds.intersect(clipSpaceRTIBounds, devIBounds)) {
+ return false;
+ }
+ } else {
+ clipSpaceReduceQueryBounds = clipSpaceRTIBounds;
+ }
GrReducedClip::ReduceClipStack(*clip.clipStack(),
- clipSpaceRTIBounds,
+ clipSpaceReduceQueryBounds,
&elements,
&genID,
&initialState,
diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp
index 6718699..1137c57 100644
--- a/src/gpu/GrDrawContext.cpp
+++ b/src/gpu/GrDrawContext.cpp
@@ -409,8 +409,10 @@
viewMatrix.mapRect(&bounds);
// If we don't have AA then we outset for a half pixel in each direction to account for
- // snapping
- if (!paint.isAntiAlias()) {
+ // snapping. We also do this for the "hair" primitive types: lines and points since they have
+ // a 1 pixel thickness in device space.
+ if (!paint.isAntiAlias() || GrIsPrimTypeLines(primitiveType) ||
+ kPoints_GrPrimitiveType == primitiveType) {
bounds.outset(0.5f, 0.5f);
}
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index f2ed17c..062a42f 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -508,6 +508,8 @@
return;
}
// 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())) {
GrBATCH_INFO("\t\tIntersects with (%s, B%u)\n", candidate->name(),
candidate->uniqueID());
diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp
index 9a6a614..cbfd896 100644
--- a/src/gpu/GrReducedClip.cpp
+++ b/src/gpu/GrReducedClip.cpp
@@ -416,10 +416,9 @@
} else {
if (stackBounds.contains(scalarQueryBounds)) {
*initialState = kAllOut_InitialState;
- if (requiresAA) {
- *requiresAA = false;
- }
- return;
+ // We know that the bounding box contains all the pixels that are outside the clip,
+ // but we don't know that *all* the pixels in the box are outside the clip. So
+ // proceed to walking the stack.
}
if (tighterBounds) {
*tighterBounds = queryBounds;
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) {