diff options
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrClip.cpp | 12 | ||||
-rw-r--r-- | src/gpu/GrClipMaskManager.cpp | 14 | ||||
-rw-r--r-- | src/gpu/GrDrawContext.cpp | 86 |
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); } |