| Index: src/gpu/GrDrawContext.cpp
|
| diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp
|
| index 628b4b2fb2fd4cdeaadd8916dab97a3159d69061..12bb1dec2b47d0188ee25f95aed0e8925e4937b1 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,
|
|
|