aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar csmartdalton <csmartdalton@google.com>2016-07-12 14:45:23 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-07-12 14:45:23 -0700
commit86de59f4a99b5f54be0483c60ff0335be55b2bdf (patch)
tree6e5ee4d8a40a412c2e905635a890c5237fca1259 /src/gpu
parentf119796f95f336d5b29f06f369b15b48a6a0df45 (diff)
Pre-crop filled rects to avoid scissor
Updates GrDrawContext to crop filled rects to the clip bounds before creating batches for them. Also adds clipping logic to ignore scissor when the draw falls completely inside. These two changes combined reduce API traffic and improve batching. In the future this can and should be improved by switching to floating point clip boundaries, thus allowing us to throw out non pixel aligned rectangle clips as well. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2132073002 Committed: https://skia.googlesource.com/skia/+/7969838702135b9f127bd738728da61bc49b050a Review-Url: https://codereview.chromium.org/2132073002
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrClip.cpp12
-rw-r--r--src/gpu/GrClipMaskManager.cpp14
-rw-r--r--src/gpu/GrDrawContext.cpp86
3 files changed, 91 insertions, 21 deletions
diff --git a/src/gpu/GrClip.cpp b/src/gpu/GrClip.cpp
index b0577c5122..ab2acb9834 100644
--- a/src/gpu/GrClip.cpp
+++ b/src/gpu/GrClip.cpp
@@ -54,12 +54,14 @@ bool GrFixedClip::apply(GrContext*, const GrPipelineBuilder& pipelineBuilder,
if (devBounds && !devBounds->intersects(SkRect::Make(tightScissor))) {
return false;
}
- if (fHasStencilClip) {
- out->makeScissoredStencil(tightScissor, &fDeviceBounds);
- } else {
- out->makeScissored(tightScissor);
+ if (!devBounds || !CanIgnoreScissor(fScissorState.rect(), *devBounds)) {
+ if (fHasStencilClip) {
+ out->makeScissoredStencil(tightScissor, &fDeviceBounds);
+ } else {
+ out->makeScissored(tightScissor);
+ }
+ return true;
}
- return true;
}
out->makeStencil(fHasStencilClip, fDeviceBounds);
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index c591bf1182..d710fef9b3 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -268,7 +268,7 @@ bool GrClipMaskManager::SetupClipping(GrContext* context,
} else {
SkIRect scissorSpaceIBounds(clipSpaceIBounds);
scissorSpaceIBounds.offset(-clip.origin());
- if (!SkRect::Make(scissorSpaceIBounds).contains(devBounds)) {
+ if (!GrClip::CanIgnoreScissor(scissorSpaceIBounds, devBounds)) {
out->makeScissored(scissorSpaceIBounds);
}
return true;
@@ -302,11 +302,11 @@ bool GrClipMaskManager::SetupClipping(GrContext* context,
&clipFP)) {
SkIRect scissorSpaceIBounds(clipSpaceIBounds);
scissorSpaceIBounds.offset(-clip.origin());
- if (!SkRect::Make(scissorSpaceIBounds).contains(devBounds)) {
+ if (GrClip::CanIgnoreScissor(scissorSpaceIBounds, devBounds)) {
+ out->makeFPBased(std::move(clipFP), SkRect::Make(scissorSpaceIBounds));
+ } else {
out->makeScissoredFPBased(std::move(clipFP), scissorSpaceIBounds);
- return true;
}
- out->makeFPBased(std::move(clipFP), SkRect::Make(scissorSpaceIBounds));
return true;
}
}
@@ -369,7 +369,11 @@ bool GrClipMaskManager::SetupClipping(GrContext* context,
// use both stencil and scissor test to the bounds for the final draw.
SkIRect scissorSpaceIBounds(clipSpaceIBounds);
scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset);
- out->makeScissoredStencil(scissorSpaceIBounds);
+ if (GrClip::CanIgnoreScissor(scissorSpaceIBounds, devBounds)) {
+ out->makeStencil(true, devBounds);
+ } else {
+ out->makeScissoredStencil(scissorSpaceIBounds);
+ }
return true;
}
diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp
index a86e01e72b..8f012cd658 100644
--- a/src/gpu/GrDrawContext.cpp
+++ b/src/gpu/GrDrawContext.cpp
@@ -270,17 +270,70 @@ static bool should_apply_coverage_aa(const GrPaint& paint, GrRenderTarget* rt,
}
}
+// Attempts to crop a rect and optional local rect to the clip boundaries.
+// Returns false if the draw can be skipped entirely.
+static bool crop_filled_rect(const GrRenderTarget* rt, const GrClip& clip,
+ const SkMatrix& viewMatrix, SkRect* rect,
+ SkRect* localRect = nullptr) {
+ if (!viewMatrix.rectStaysRect()) {
+ return true;
+ }
+
+ SkMatrix inverseViewMatrix;
+ if (!viewMatrix.invert(&inverseViewMatrix)) {
+ return false;
+ }
+
+ SkIRect clipDevBounds;
+ SkRect clipBounds;
+ SkASSERT(inverseViewMatrix.rectStaysRect());
+
+ clip.getConservativeBounds(rt->width(), rt->height(), &clipDevBounds);
+ inverseViewMatrix.mapRect(&clipBounds, SkRect::Make(clipDevBounds));
+
+ if (localRect) {
+ if (!rect->intersects(clipBounds)) {
+ return false;
+ }
+ const SkScalar dx = localRect->width() / rect->width();
+ const SkScalar dy = localRect->height() / rect->height();
+ if (clipBounds.fLeft > rect->fLeft) {
+ localRect->fLeft += (clipBounds.fLeft - rect->fLeft) * dx;
+ rect->fLeft = clipBounds.fLeft;
+ }
+ if (clipBounds.fTop > rect->fTop) {
+ localRect->fTop += (clipBounds.fTop - rect->fTop) * dy;
+ rect->fTop = clipBounds.fTop;
+ }
+ if (clipBounds.fRight < rect->fRight) {
+ localRect->fRight -= (rect->fRight - clipBounds.fRight) * dx;
+ rect->fRight = clipBounds.fRight;
+ }
+ if (clipBounds.fBottom < rect->fBottom) {
+ localRect->fBottom -= (rect->fBottom - clipBounds.fBottom) * dy;
+ rect->fBottom = clipBounds.fBottom;
+ }
+ return true;
+ }
+
+ return rect->intersect(clipBounds);
+}
+
bool GrDrawContext::drawFilledRect(const GrClip& clip,
const GrPaint& paint,
const SkMatrix& viewMatrix,
const SkRect& rect,
const GrUserStencilSettings* ss) {
+ SkRect croppedRect = rect;
+ if (!crop_filled_rect(fRenderTarget.get(), clip, viewMatrix, &croppedRect)) {
+ return true;
+ }
SkAutoTUnref<GrDrawBatch> batch;
bool useHWAA;
if (InstancedRendering* ir = this->getDrawTarget()->instancedRendering()) {
- batch.reset(ir->recordRect(rect, viewMatrix, paint.getColor(),
+ batch.reset(ir->recordRect(croppedRect, viewMatrix, paint.getColor(),
paint.isAntiAlias(), fInstancedPipelineInfo,
&useHWAA));
if (batch) {
@@ -297,10 +350,10 @@ bool GrDrawContext::drawFilledRect(const GrClip& clip,
// The fill path can handle rotation but not skew.
if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
SkRect devBoundRect;
- viewMatrix.mapRect(&devBoundRect, rect);
+ viewMatrix.mapRect(&devBoundRect, croppedRect);
batch.reset(GrRectBatchFactory::CreateAAFill(paint.getColor(), viewMatrix,
- rect, devBoundRect));
+ croppedRect, devBoundRect));
if (batch) {
GrPipelineBuilder pipelineBuilder(paint, useHWAA);
if (ss) {
@@ -311,7 +364,7 @@ bool GrDrawContext::drawFilledRect(const GrClip& clip,
}
}
} else {
- this->drawNonAAFilledRect(clip, paint, viewMatrix, rect, nullptr, nullptr, ss);
+ this->drawNonAAFilledRect(clip, paint, viewMatrix, croppedRect, nullptr, nullptr, ss);
return true;
}
@@ -522,12 +575,18 @@ void GrDrawContext::fillRectToRect(const GrClip& clip,
SkDEBUGCODE(this->validate();)
GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::fillRectToRect");
+ SkRect croppedRect = rectToDraw;
+ SkRect croppedLocalRect = localRect;
+ if (!crop_filled_rect(fRenderTarget.get(), clip, viewMatrix, &croppedRect, &croppedLocalRect)) {
+ return;
+ }
+
AutoCheckFlush acf(fDrawingManager);
SkAutoTUnref<GrDrawBatch> batch;
bool useHWAA;
if (InstancedRendering* ir = this->getDrawTarget()->instancedRendering()) {
- batch.reset(ir->recordRect(rectToDraw, viewMatrix, paint.getColor(), localRect,
+ batch.reset(ir->recordRect(croppedRect, viewMatrix, paint.getColor(), croppedLocalRect,
paint.isAntiAlias(), fInstancedPipelineInfo, &useHWAA));
if (batch) {
GrPipelineBuilder pipelineBuilder(paint, useHWAA);
@@ -538,15 +597,15 @@ void GrDrawContext::fillRectToRect(const GrClip& clip,
if (should_apply_coverage_aa(paint, fRenderTarget.get(), &useHWAA) &&
view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
- batch.reset(GrAAFillRectBatch::CreateWithLocalRect(paint.getColor(), viewMatrix, rectToDraw,
- localRect));
+ batch.reset(GrAAFillRectBatch::CreateWithLocalRect(paint.getColor(), viewMatrix,
+ croppedRect, croppedLocalRect));
if (batch) {
GrPipelineBuilder pipelineBuilder(paint, useHWAA);
this->drawBatch(pipelineBuilder, clip, batch);
return;
}
} else {
- this->drawNonAAFilledRect(clip, paint, viewMatrix, rectToDraw, &localRect,
+ this->drawNonAAFilledRect(clip, paint, viewMatrix, croppedRect, &croppedLocalRect,
nullptr, nullptr);
}
@@ -562,12 +621,17 @@ void GrDrawContext::fillRectWithLocalMatrix(const GrClip& clip,
SkDEBUGCODE(this->validate();)
GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::fillRectWithLocalMatrix");
+ SkRect croppedRect = rectToDraw;
+ if (!crop_filled_rect(fRenderTarget.get(), clip, viewMatrix, &croppedRect)) {
+ return;
+ }
+
AutoCheckFlush acf(fDrawingManager);
SkAutoTUnref<GrDrawBatch> batch;
bool useHWAA;
if (InstancedRendering* ir = this->getDrawTarget()->instancedRendering()) {
- batch.reset(ir->recordRect(rectToDraw, viewMatrix, paint.getColor(), localMatrix,
+ batch.reset(ir->recordRect(croppedRect, viewMatrix, paint.getColor(), localMatrix,
paint.isAntiAlias(), fInstancedPipelineInfo, &useHWAA));
if (batch) {
GrPipelineBuilder pipelineBuilder(paint, useHWAA);
@@ -579,11 +643,11 @@ void GrDrawContext::fillRectWithLocalMatrix(const GrClip& clip,
if (should_apply_coverage_aa(paint, fRenderTarget.get(), &useHWAA) &&
view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
batch.reset(GrAAFillRectBatch::Create(paint.getColor(), viewMatrix, localMatrix,
- rectToDraw));
+ croppedRect));
GrPipelineBuilder pipelineBuilder(paint, useHWAA);
this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
} else {
- this->drawNonAAFilledRect(clip, paint, viewMatrix, rectToDraw, nullptr,
+ this->drawNonAAFilledRect(clip, paint, viewMatrix, croppedRect, nullptr,
&localMatrix, nullptr);
}