diff options
Diffstat (limited to 'src/gpu/GrDrawContext.cpp')
-rw-r--r-- | src/gpu/GrDrawContext.cpp | 172 |
1 files changed, 149 insertions, 23 deletions
diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp index 628b4b2fb2..12bb1dec2b 100644 --- a/src/gpu/GrDrawContext.cpp +++ b/src/gpu/GrDrawContext.cpp @@ -9,6 +9,7 @@ #include "GrBatchTest.h" #include "GrColor.h" #include "GrDrawContext.h" +#include "GrDrawContextPriv.h" #include "GrDrawingManager.h" #include "GrOvalRenderer.h" #include "GrPathRenderer.h" @@ -33,8 +34,11 @@ #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == fDrawingManager->getContext()) #define ASSERT_SINGLE_OWNER \ SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);) +#define ASSERT_SINGLE_OWNER_PRIV \ + SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fDrawContext->fSingleOwner);) #define RETURN_IF_ABANDONED if (fDrawingManager->abandoned()) { return; } #define RETURN_FALSE_IF_ABANDONED if (fDrawingManager->abandoned()) { return false; } +#define RETURN_FALSE_IF_ABANDONED_PRIV if (fDrawContext->fDrawingManager->abandoned()) { return false; } #define RETURN_NULL_IF_ABANDONED if (fDrawingManager->abandoned()) { return nullptr; } class AutoCheckFlush { @@ -250,6 +254,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, @@ -303,35 +329,28 @@ void GrDrawContext::drawRect(const GrClip& clip, 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(paint.getColor(), viewMatrix, rect, + batch.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix, rect, *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(paint.getColor(), 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. } - } else if (width >= 0) { - // Non-AA hairlines are snapped to pixel centers to make which pixels are hit deterministic - snapToPixelCenters = (0 == width && !fRenderTarget->isUnifiedMultisampled()); - batch.reset(GrRectBatchFactory::CreateNonAAStroke(paint.getColor(), 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. - } else { - // filled BW rect - batch.reset(GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMatrix, rect, - nullptr, nullptr)); } if (batch) { @@ -353,6 +372,39 @@ void GrDrawContext::drawRect(const GrClip& clip, strokeInfo ? *strokeInfo : GrStrokeInfo::FillInfo()); } +bool GrDrawContextPriv::drawAndStencilRect(const SkIRect* scissorRect, + const GrStencilSettings& ss, + SkRegion::Op op, + bool invert, + bool doAA, + const SkMatrix& viewMatrix, + const SkRect& rect) { + ASSERT_SINGLE_OWNER_PRIV + RETURN_FALSE_IF_ABANDONED_PRIV + SkDEBUGCODE(fDrawContext->validate();) + GR_AUDIT_TRAIL_AUTO_FRAME(fDrawContext->fAuditTrail, "GrDrawContext::stencilRect"); + + AutoCheckFlush acf(fDrawContext->fDrawingManager); + + GrPaint paint; + paint.setAntiAlias(doAA); + paint.setCoverageSetOpXPFactory(op, invert); + + SkAutoTUnref<GrDrawBatch> batch(fDrawContext->getFillRectBatch(paint, viewMatrix, rect)); + if (batch) { + GrPipelineBuilder pipelineBuilder(paint, fDrawContext->fRenderTarget, GrClip::WideOpen()); + pipelineBuilder.setStencil(ss); + + fDrawContext->getDrawTarget()->drawBatch(pipelineBuilder, batch, scissorRect); + return true; + } + + SkPath path; + path.setIsVolatile(true); + path.addRect(rect); + return this->drawAndStencilPath(scissorRect, ss, op, invert, doAA, viewMatrix, path); +} + void GrDrawContext::fillRectToRect(const GrClip& clip, const GrPaint& paint, const SkMatrix& viewMatrix, @@ -801,6 +853,80 @@ void GrDrawContext::drawPath(const GrClip& clip, this->internalDrawPath(clip, paint, viewMatrix, path, strokeInfo); } +bool GrDrawContextPriv::drawAndStencilPath(const SkIRect* scissorRect, + const GrStencilSettings& ss, + SkRegion::Op op, + bool invert, + bool doAA, + const SkMatrix& viewMatrix, + const SkPath& path) { + ASSERT_SINGLE_OWNER_PRIV + RETURN_FALSE_IF_ABANDONED_PRIV + SkDEBUGCODE(fDrawContext->validate();) + GR_AUDIT_TRAIL_AUTO_FRAME(fDrawContext->fAuditTrail, "GrDrawContext::drawPath"); + + if (path.isEmpty() && path.isInverseFillType()) { + this->drawAndStencilRect(scissorRect, ss, op, invert, false, SkMatrix::I(), + SkRect::MakeIWH(fDrawContext->fRenderTarget->width(), + fDrawContext->fRenderTarget->height())); + return true; + } + + AutoCheckFlush acf(fDrawContext->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 && !fDrawContext->fRenderTarget->isUnifiedMultisampled(); + bool isStencilDisabled = true; + bool isStencilBufferMSAA = fDrawContext->fRenderTarget->isStencilBufferMultisampled(); + + const GrPathRendererChain::DrawType type = + useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType + : GrPathRendererChain::kColor_DrawType; + + GrPathRenderer::CanDrawPathArgs canDrawArgs; + canDrawArgs.fShaderCaps = fDrawContext->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 = fDrawContext->fDrawingManager->getPathRenderer(canDrawArgs, false, type); + if (!pr) { + return false; + } + + GrPaint paint; + paint.setCoverageSetOpXPFactory(op, invert); + + // TODO: it is unfortunate that we have to convert this to a GrClip to + // call drawPath. + GrClip clip; + if (scissorRect) { + clip.setIRect(*scissorRect); + } + + GrPipelineBuilder pipelineBuilder(paint, fDrawContext->fRenderTarget, clip); + pipelineBuilder.setStencil(ss); + + GrPathRenderer::DrawPathArgs args; + args.fTarget = fDrawContext->getDrawTarget(); + args.fResourceProvider = fDrawContext->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(const GrClip& clip, const GrPaint& paint, const SkMatrix& viewMatrix, |