Index: src/gpu/GrDrawContext.cpp |
diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp |
index 430ae886f39c603eceb0645d57c73f844c23dcdf..defe76a7c97d2e8eecce7f2ff25274127a48cd1c 100644 |
--- a/src/gpu/GrDrawContext.cpp |
+++ b/src/gpu/GrDrawContext.cpp |
@@ -274,15 +274,45 @@ static bool should_apply_coverage_aa(const GrPaint& paint, GrRenderTarget* rt, |
} |
} |
-GrDrawBatch* GrDrawContext::getFillRectBatch(const GrPaint& paint, |
- const SkMatrix& viewMatrix, |
- const SkRect& rect, |
- bool* useHWAA) { |
+enum class TrimResult { |
+ kSkipDraw, |
+ kDidTrim, |
+ kDidNotTrim |
+}; |
+ |
+static TrimResult trim_fill_rect(const GrClip& clip, const GrRenderTarget* rt, |
+ const SkMatrix& viewMatrix, SkRect* rect) { |
+ SkMatrix inverseVM; |
+ if (viewMatrix.rectStaysRect() && viewMatrix.invert(&inverseVM)) { |
+ SkASSERT(inverseVM.rectStaysRect()); |
+ SkIRect clipDevBounds; |
+ clip.getConservativeBounds(rt->width(), rt->height(), &clipDevBounds); |
+ SkRect clipUserSpaceBounds; |
+ inverseVM.mapRect(&clipUserSpaceBounds, SkRect::Make(clipDevBounds)); |
+ if (!rect->intersect(clipUserSpaceBounds)) { |
+ return TrimResult::kSkipDraw; |
+ } |
+ return TrimResult::kDidTrim; |
+ } |
+ return TrimResult::kDidNotTrim; |
+} |
+ |
+bool GrDrawContext::getFillRectBatch(const GrClip& clip, |
+ const GrPaint& paint, |
+ const SkMatrix& viewMatrix, |
+ const SkRect& rect, |
+ SkAutoTUnref<GrDrawBatch>* batch, |
+ bool* useHWAA) { |
+ SkRect trimRect = rect; |
+ if (TrimResult::kSkipDraw == trim_fill_rect(clip, fRenderTarget.get(), viewMatrix, &trimRect)) { |
+ return false; |
+ } |
+ |
if (InstancedRendering* ir = this->getDrawTarget()->instancedRendering()) { |
- if (GrDrawBatch* batch = ir->recordRect(rect, viewMatrix, paint.getColor(), |
- paint.isAntiAlias(), fInstancedPipelineInfo, |
- useHWAA)) { |
- return batch; |
+ batch->reset(ir->recordRect(trimRect, viewMatrix, paint.getColor(), paint.isAntiAlias(), |
+ fInstancedPipelineInfo, useHWAA)); |
+ if (batch) { |
+ return true; |
} |
} |
@@ -290,17 +320,17 @@ GrDrawBatch* GrDrawContext::getFillRectBatch(const GrPaint& paint, |
// The fill path can handle rotation but not skew. |
if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) { |
SkRect devBoundRect; |
- viewMatrix.mapRect(&devBoundRect, rect); |
- return GrRectBatchFactory::CreateAAFill(paint.getColor(), viewMatrix, |
- rect, devBoundRect); |
+ viewMatrix.mapRect(&devBoundRect, trimRect); |
+ batch->reset(GrRectBatchFactory::CreateAAFill(paint.getColor(), viewMatrix, trimRect, |
+ devBoundRect)); |
} |
} else { |
// filled BW rect |
- return GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMatrix, rect, |
- nullptr, nullptr); |
+ batch->reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMatrix, trimRect, |
+ nullptr, nullptr)); |
} |
- return nullptr; |
+ return true; |
} |
void GrDrawContext::drawRect(const GrClip& clip, |
@@ -351,7 +381,9 @@ void GrDrawContext::drawRect(const GrClip& clip, |
} |
} |
} |
- batch.reset(this->getFillRectBatch(paint, viewMatrix, rect, &useHWAA)); |
+ if (!this->getFillRectBatch(clip, paint, viewMatrix, rect, &batch, &useHWAA)) { |
+ return; |
+ } |
} else if (stroke.getStyle() == SkStrokeRec::kStroke_Style || |
stroke.getStyle() == SkStrokeRec::kHairline_Style) { |
if ((!rect.width() || !rect.height()) && |
@@ -486,8 +518,10 @@ bool GrDrawContextPriv::drawAndStencilRect(const GrFixedClip& clip, |
paint.setCoverageSetOpXPFactory(op, invert); |
bool useHWAA; |
- SkAutoTUnref<GrDrawBatch> batch( |
- fDrawContext->getFillRectBatch(paint, viewMatrix, rect, &useHWAA)); |
+ SkAutoTUnref<GrDrawBatch> batch; |
+ if (!fDrawContext->getFillRectBatch(clip, paint, viewMatrix, rect, &batch, &useHWAA)) { |
+ return true; |
+ } |
if (batch) { |
GrPipelineBuilder pipelineBuilder(paint, useHWAA); |
pipelineBuilder.setUserStencil(ss); |
@@ -516,8 +550,23 @@ void GrDrawContext::fillRectToRect(const GrClip& clip, |
SkAutoTUnref<GrDrawBatch> batch; |
bool useHWAA; |
+ SkRect trimRect = rectToDraw; |
+ TrimResult trimResult = trim_fill_rect(clip, fRenderTarget.get(), viewMatrix, &trimRect); |
+ if (TrimResult::kSkipDraw == trimResult) { |
+ return; |
+ } |
+ SkRect trimLocalRect = localRect; |
+ if (TrimResult::kDidTrim == trimResult) { |
+ SkScalar dx = localRect.width() / rectToDraw.width(); |
+ SkScalar dy = localRect.height() / rectToDraw.height(); |
+ trimLocalRect.fLeft += (trimRect.fLeft - rectToDraw.fLeft) * dx; |
+ trimLocalRect.fTop += (trimRect.fTop - rectToDraw.fTop) * dy; |
+ trimLocalRect.fRight -= (rectToDraw.fRight - trimRect.fRight) * dx; |
+ trimLocalRect.fTop -= (rectToDraw.fTop - trimRect.fTop) * dy; |
+ } |
+ |
if (InstancedRendering* ir = this->getDrawTarget()->instancedRendering()) { |
- batch.reset(ir->recordRect(rectToDraw, viewMatrix, paint.getColor(), localRect, |
+ batch.reset(ir->recordRect(trimRect, viewMatrix, paint.getColor(), trimLocalRect, |
paint.isAntiAlias(), fInstancedPipelineInfo, &useHWAA)); |
if (batch) { |
GrPipelineBuilder pipelineBuilder(paint, useHWAA); |
@@ -528,11 +577,11 @@ 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, trimRect, |
+ trimLocalRect)); |
} else { |
- batch.reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMatrix, rectToDraw, |
- &localRect, nullptr)); |
+ batch.reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMatrix, trimRect, |
+ &trimLocalRect, nullptr)); |
} |
if (batch) { |
@@ -555,8 +604,13 @@ void GrDrawContext::fillRectWithLocalMatrix(const GrClip& clip, |
SkAutoTUnref<GrDrawBatch> batch; |
bool useHWAA; |
+ SkRect trimRect = rectToDraw; |
+ if (TrimResult::kSkipDraw == trim_fill_rect(clip, fRenderTarget.get(), viewMatrix, &trimRect)) { |
+ return; |
+ } |
+ |
if (InstancedRendering* ir = this->getDrawTarget()->instancedRendering()) { |
- batch.reset(ir->recordRect(rectToDraw, viewMatrix, paint.getColor(), localMatrix, |
+ batch.reset(ir->recordRect(trimRect, viewMatrix, paint.getColor(), localMatrix, |
paint.isAntiAlias(), fInstancedPipelineInfo, &useHWAA)); |
if (batch) { |
GrPipelineBuilder pipelineBuilder(paint, useHWAA); |
@@ -567,10 +621,9 @@ 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)); |
+ batch.reset(GrAAFillRectBatch::Create(paint.getColor(), viewMatrix, localMatrix, trimRect)); |
} else { |
- batch.reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMatrix, rectToDraw, |
+ batch.reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMatrix, trimRect, |
nullptr, &localMatrix)); |
} |