Index: src/gpu/GrDrawContext.cpp |
diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp |
index b5c28190f2daa1b352bb6d0318db84cdba4db45f..482889ceee8d9d5445b67e74b1690dbabc194463 100644 |
--- a/src/gpu/GrDrawContext.cpp |
+++ b/src/gpu/GrDrawContext.cpp |
@@ -248,6 +248,28 @@ static bool should_apply_coverage_aa(const GrPaint& paint, GrRenderTarget* rt) { |
return paint.isAntiAlias() && !rt->isUnifiedMultisampled(); |
} |
+GrDrawBatch* GrDrawContext::getFillRectBatch(const GrPaint& paint, |
+ const SkMatrix& viewMatrix, |
+ const SkRect& rect) { |
+ |
+ GrDrawBatch* batch = nullptr; |
+ if (should_apply_coverage_aa(paint, fRenderTarget)) { |
+ // The fill path can handle rotation but not skew. |
+ if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) { |
+ SkRect devBoundRect; |
+ viewMatrix.mapRect(&devBoundRect, rect); |
+ batch = GrRectBatchFactory::CreateAAFill(paint.getColor(), viewMatrix, |
+ rect, devBoundRect); |
+ } |
+ } else { |
+ // filled BW rect |
+ batch = GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMatrix, rect, |
+ nullptr, nullptr); |
+ } |
+ |
+ return batch; |
+} |
+ |
void GrDrawContext::drawRect(const GrClip& clip, |
const GrPaint& paint, |
const SkMatrix& viewMatrix, |
@@ -299,52 +321,83 @@ void GrDrawContext::drawRect(const GrClip& clip, |
} |
} |
- GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
- GrColor color = paint.getColor(); |
- |
+ bool snapToPixelCenters = false; |
SkAutoTUnref<GrDrawBatch> batch; |
- if (should_apply_coverage_aa(paint, fRenderTarget)) { |
- if (width >= 0) { |
+ if (width < 0) { |
+ batch.reset(this->getFillRectBatch(paint, viewMatrix, rect)); |
+ } else { |
+ GrColor color = paint.getColor(); |
+ |
+ if (should_apply_coverage_aa(paint, fRenderTarget)) { |
// The stroke path needs the rect to remain axis aligned (no rotation or skew). |
if (viewMatrix.rectStaysRect()) { |
batch.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix, rect, |
- *strokeInfo)); |
+ *strokeInfo)); |
} |
} else { |
- // The fill path can handle rotation but not skew. |
- if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) { |
- SkRect devBoundRect; |
- viewMatrix.mapRect(&devBoundRect, rect); |
- batch.reset(GrRectBatchFactory::CreateAAFill(color, viewMatrix, rect, |
- devBoundRect)); |
- } |
+ // Non-AA hairlines are snapped to pixel centers to make which pixels are hit |
+ // deterministic |
+ snapToPixelCenters = (0 == width && !fRenderTarget->isUnifiedMultisampled()); |
+ batch.reset(GrRectBatchFactory::CreateNonAAStroke(color, viewMatrix, rect, width, |
+ snapToPixelCenters)); |
+ |
+ // Depending on sub-pixel coordinates and the particular GPU, we may lose a corner of |
+ // hairline rects. We jam all the vertices to pixel centers to avoid this, but not |
+ // when MSAA is enabled because it can cause ugly artifacts. |
} |
- if (!batch) { |
- SkPath path; |
- path.setIsVolatile(true); |
- path.addRect(rect); |
- this->internalDrawPath(&pipelineBuilder, viewMatrix, color, true, path, *strokeInfo); |
- SkASSERT(paint.isAntiAlias()); |
- return; |
- } |
- } else if (width >= 0) { |
- // Non-AA hairlines are snapped to pixel centers to make which pixels are hit deterministic |
- bool snapToPixelCenters = (0 == width && !fRenderTarget->isUnifiedMultisampled()); |
- batch.reset(GrRectBatchFactory::CreateNonAAStroke(color, viewMatrix, rect, width, |
- snapToPixelCenters)); |
- |
- // Depending on sub-pixel coordinates and the particular GPU, we may lose a corner of |
- // hairline rects. We jam all the vertices to pixel centers to avoid this, but not when MSAA |
- // is enabled because it can cause ugly artifacts. |
+ } |
+ |
+ GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
+ if (snapToPixelCenters) { |
pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_Flag, |
snapToPixelCenters); |
- } else { |
- // filled BW rect |
- batch.reset(GrRectBatchFactory::CreateNonAAFill(color, viewMatrix, rect, nullptr, nullptr)); |
} |
+ |
+ if (!batch) { |
+ SkPath path; |
+ path.setIsVolatile(true); |
+ path.addRect(rect); |
+ this->internalDrawPath(&pipelineBuilder, viewMatrix, paint.getColor(), true, |
+ path, strokeInfo ? *strokeInfo : GrStrokeInfo::FillInfo()); |
+ return; |
+ } |
+ |
this->getDrawTarget()->drawBatch(pipelineBuilder, batch); |
} |
+bool GrDrawContext::stencilRect(const SkIRect* scissorRect, |
+ const GrStencilSettings& ss, |
+ SkRegion::Op op, |
+ bool invert, |
+ bool doAA, |
+ const SkMatrix& viewMatrix, |
+ const SkRect& rect) { |
+ ASSERT_SINGLE_OWNER |
+ RETURN_FALSE_IF_ABANDONED |
+ SkDEBUGCODE(this->validate();) |
+ GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::stencilRect"); |
+ |
+ AutoCheckFlush acf(fDrawingManager); |
+ |
+ GrPaint paint; |
+ paint.setAntiAlias(doAA); |
+ paint.setCoverageSetOpXPFactory(op, invert); |
+ |
+ SkAutoTUnref<GrDrawBatch> batch(this->getFillRectBatch(paint, viewMatrix, rect)); |
+ if (batch) { |
+ GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, GrClip::WideOpen()); |
+ pipelineBuilder.setStencil(ss); |
+ |
+ this->getDrawTarget()->drawBatch(pipelineBuilder, batch, scissorRect); |
+ return true; |
+ } |
+ |
+ SkPath path; |
+ path.setIsVolatile(true); |
+ path.addRect(rect); |
+ return this->stencilPath(scissorRect, ss, op, invert, doAA, viewMatrix, path); |
+} |
+ |
void GrDrawContext::fillRectToRect(const GrClip& clip, |
const GrPaint& paint, |
const SkMatrix& viewMatrix, |
@@ -715,6 +768,77 @@ void GrDrawContext::drawPath(const GrClip& clip, |
paint.isAntiAlias(), path, strokeInfo); |
} |
+bool GrDrawContext::stencilPath(const SkIRect* scissorRect, |
+ const GrStencilSettings& ss, |
+ SkRegion::Op op, |
+ bool invert, |
+ bool doAA, |
+ const SkMatrix& viewMatrix, |
+ const SkPath& path) { |
+ ASSERT_SINGLE_OWNER |
+ RETURN_FALSE_IF_ABANDONED |
+ SkDEBUGCODE(this->validate();) |
+ GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawPath"); |
+ |
+ if (path.isEmpty() && path.isInverseFillType()) { |
+ this->stencilRect(scissorRect, ss, op, invert, false, SkMatrix::I(), |
+ SkRect::MakeIWH(fRenderTarget->width(), fRenderTarget->height())); |
+ return true; |
+ } |
+ |
+ AutoCheckFlush acf(fDrawingManager); |
+ |
+ // An Assumption here is that path renderer would use some form of tweaking |
+ // the src color (either the input alpha or in the frag shader) to implement |
+ // aa. If we have some future driver-mojo path AA that can do the right |
+ // thing WRT to the blend then we'll need some query on the PR. |
+ bool useCoverageAA = doAA && !fRenderTarget->isUnifiedMultisampled(); |
+ bool isStencilDisabled = true; |
+ bool isStencilBufferMSAA = fRenderTarget->isStencilBufferMultisampled(); |
+ |
+ const GrPathRendererChain::DrawType type = |
+ useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType |
+ : GrPathRendererChain::kColor_DrawType; |
+ |
+ GrPathRenderer::CanDrawPathArgs canDrawArgs; |
+ canDrawArgs.fShaderCaps = fDrawingManager->getContext()->caps()->shaderCaps(); |
+ canDrawArgs.fViewMatrix = &viewMatrix; |
+ canDrawArgs.fPath = &path; |
+ canDrawArgs.fStroke = &GrStrokeInfo::FillInfo(); |
+ canDrawArgs.fAntiAlias = useCoverageAA; |
+ canDrawArgs.fIsStencilDisabled = isStencilDisabled; |
+ canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA; |
+ |
+ // Don't allow the SW renderer |
+ GrPathRenderer* pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type); |
+ if (!pr) { |
+ return false; |
+ } |
+ |
+ GrPaint paint; |
+ paint.setCoverageSetOpXPFactory(op, invert); |
+ |
+ GrClip clip; |
+ if (scissorRect) { |
+ clip.setScissor(*scissorRect); |
+ } |
+ |
+ GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); |
+ pipelineBuilder.setStencil(ss); |
+ |
+ GrPathRenderer::DrawPathArgs args; |
+ args.fTarget = this->getDrawTarget(); |
+ args.fResourceProvider = fDrawingManager->getContext()->resourceProvider(); |
+ args.fPipelineBuilder = &pipelineBuilder; |
+ args.fColor = GrColor_WHITE; |
+ args.fViewMatrix = &viewMatrix; |
+ args.fPath = &path; |
+ args.fStroke = &GrStrokeInfo::FillInfo(); |
+ args.fAntiAlias = useCoverageAA; |
+ pr->drawPath(args); |
+ return true; |
+} |
+ |
void GrDrawContext::internalDrawPath(GrPipelineBuilder* pipelineBuilder, |
const SkMatrix& viewMatrix, |
GrColor color, |