Restrict query bounds for reduce clip to dev bounds

Review URL: https://codereview.chromium.org/1467253002
This commit is contained in:
bsalomon 2015-11-23 11:14:20 -08:00 committed by Commit bot
parent 266f24aa94
commit db4758c75f
7 changed files with 44 additions and 10 deletions

View File

@ -317,8 +317,18 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
}
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,

View File

@ -409,8 +409,10 @@ void GrDrawContext::drawVertices(const GrClip& clip,
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);
}

View File

@ -508,6 +508,8 @@ void GrDrawTarget::recordBatch(GrBatch* batch) {
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());

View File

@ -416,10 +416,9 @@ void GrReducedClip::ReduceClipStack(const SkClipStack& stack,
} 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;

View File

@ -264,6 +264,15 @@ private:
// 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);
}

View File

@ -31,6 +31,10 @@ class GrBatchFlushState;
* 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

View File

@ -1592,9 +1592,17 @@ private:
, 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) {