From 0cc2f85a19d50b45573d71d8c9d6ee1292c9fd3a Mon Sep 17 00:00:00 2001 From: robertphillips Date: Wed, 24 Feb 2016 13:36:56 -0800 Subject: [PATCH] Hide GrDrawTarget from GrOvalRenderer GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1731413002 Review URL: https://codereview.chromium.org/1731413002 --- src/gpu/GrDrawContext.cpp | 137 ++++++++++++++++++++++------ src/gpu/GrOvalRenderer.cpp | 218 +++++++++++---------------------------------- src/gpu/GrOvalRenderer.h | 71 ++++++--------- 3 files changed, 188 insertions(+), 238 deletions(-) diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp index 67013ff..e8761e9 100644 --- a/src/gpu/GrDrawContext.cpp +++ b/src/gpu/GrDrawContext.cpp @@ -23,6 +23,8 @@ #include "batches/GrRectBatchFactory.h" #include "batches/GrNinePatch.h" // TODO Factory +#include "effects/GrRRectEffect.h" + #include "text/GrAtlasTextContext.h" #include "text/GrStencilAndCoverTextContext.h" @@ -494,13 +496,17 @@ void GrDrawContext::drawRRect(const GrClip& clip, GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); GrColor color = paint.getColor(); - if (!GrOvalRenderer::DrawRRect(this->getDrawTarget(), - pipelineBuilder, - color, - viewMatrix, - paint.isAntiAlias(), - rrect, - strokeInfo)) { + GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); + SkAutoTUnref batch(GrOvalRenderer::CreateRRectBatch(pipelineBuilder, + color, + viewMatrix, + paint.isAntiAlias(), + rrect, + strokeInfo, + shaderCaps)); + if (batch) { + this->getDrawTarget()->drawBatch(pipelineBuilder, batch); + } else { SkPath path; path.setIsVolatile(true); path.addRRect(rrect); @@ -511,6 +517,77 @@ void GrDrawContext::drawRRect(const GrClip& clip, /////////////////////////////////////////////////////////////////////////////// +static bool draw_drrect(GrDrawTarget* drawTarget, + const GrPipelineBuilder& pipelineBuilder, + GrColor color, + const SkMatrix& viewMatrix, + bool useAA, + const SkRRect& origOuter, + const SkRRect& origInner, + GrShaderCaps* shaderCaps) { + bool applyAA = useAA && !pipelineBuilder.getRenderTarget()->isUnifiedMultisampled(); + GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; + if (!origInner.isEmpty()) { + SkTCopyOnFirstWrite inner(origInner); + if (!viewMatrix.isIdentity()) { + if (!origInner.transform(viewMatrix, inner.writable())) { + return false; + } + } + GrPrimitiveEdgeType edgeType = applyAA ? + kInverseFillAA_GrProcessorEdgeType : + kInverseFillBW_GrProcessorEdgeType; + // TODO this needs to be a geometry processor + GrFragmentProcessor* fp = GrRRectEffect::Create(edgeType, *inner); + if (nullptr == fp) { + return false; + } + arfps.set(&pipelineBuilder); + arfps.addCoverageFragmentProcessor(fp)->unref(); + } + + SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle); + SkAutoTUnref batch(GrOvalRenderer::CreateRRectBatch(pipelineBuilder, color, + viewMatrix, useAA, origOuter, + fillRec, shaderCaps)); + if (batch) { + drawTarget->drawBatch(pipelineBuilder, batch); + return true; + } + + SkASSERT(!origOuter.isEmpty()); + SkTCopyOnFirstWrite outer(origOuter); + if (!viewMatrix.isIdentity()) { + if (!origOuter.transform(viewMatrix, outer.writable())) { + return false; + } + } + GrPrimitiveEdgeType edgeType = applyAA ? kFillAA_GrProcessorEdgeType : + kFillBW_GrProcessorEdgeType; + SkAutoTUnref effect(GrRRectEffect::Create(edgeType, *outer)); + if (!effect) { + return false; + } + if (!arfps.isSet()) { + arfps.set(&pipelineBuilder); + } + + SkMatrix invert; + if (!viewMatrix.invert(&invert)) { + return false; + } + + arfps.addCoverageFragmentProcessor(effect); + SkRect bounds = outer->getBounds(); + if (applyAA) { + bounds.outset(SK_ScalarHalf, SK_ScalarHalf); + } + batch.reset(GrRectBatchFactory::CreateNonAAFill(color, SkMatrix::I(), bounds, + nullptr, &invert)); + drawTarget->drawBatch(pipelineBuilder, batch); + return true; +} + void GrDrawContext::drawDRRect(const GrClip& clip, const GrPaint& paint, const SkMatrix& viewMatrix, @@ -529,13 +606,10 @@ void GrDrawContext::drawDRRect(const GrClip& clip, GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); GrColor color = paint.getColor(); - if (!GrOvalRenderer::DrawDRRect(this->getDrawTarget(), - pipelineBuilder, - color, - viewMatrix, - paint.isAntiAlias(), - outer, - inner)) { + + if (!draw_drrect(this->getDrawTarget(), pipelineBuilder, + color, viewMatrix, paint.isAntiAlias(), + outer, inner, fContext->caps()->shaderCaps())) { SkPath path; path.setIsVolatile(true); path.addRRect(inner); @@ -571,13 +645,17 @@ void GrDrawContext::drawOval(const GrClip& clip, GrPipelineBuilder pipelineBuilder(paint, fRenderTarget, clip); GrColor color = paint.getColor(); - if (!GrOvalRenderer::DrawOval(this->getDrawTarget(), - pipelineBuilder, - color, - viewMatrix, - paint.isAntiAlias(), - oval, - strokeInfo)) { + GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); + SkAutoTUnref batch(GrOvalRenderer::CreateOvalBatch(pipelineBuilder, + color, + viewMatrix, + paint.isAntiAlias(), + oval, + strokeInfo, + shaderCaps)); + if (batch) { + this->getDrawTarget()->drawBatch(pipelineBuilder, batch); + } else { SkPath path; path.setIsVolatile(true); path.addOval(oval); @@ -729,13 +807,16 @@ void GrDrawContext::drawPath(const GrClip& clip, bool isOval = path.isOval(&ovalRect); if (isOval && !path.isInverseFillType()) { - if (GrOvalRenderer::DrawOval(this->getDrawTarget(), - pipelineBuilder, - color, - viewMatrix, - paint.isAntiAlias(), - ovalRect, - strokeInfo)) { + GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); + SkAutoTUnref batch(GrOvalRenderer::CreateOvalBatch(pipelineBuilder, + color, + viewMatrix, + paint.isAntiAlias(), + ovalRect, + strokeInfo, + shaderCaps)); + if (batch) { + this->getDrawTarget()->drawBatch(pipelineBuilder, batch); return; } } diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp index 02019c1..1c41f27 100644 --- a/src/gpu/GrOvalRenderer.cpp +++ b/src/gpu/GrOvalRenderer.cpp @@ -9,19 +9,14 @@ #include "GrBatchFlushState.h" #include "GrBatchTest.h" -#include "GrDrawTarget.h" #include "GrGeometryProcessor.h" #include "GrInvariantOutput.h" #include "GrPipelineBuilder.h" #include "GrProcessor.h" #include "GrResourceProvider.h" -#include "GrVertexBuffer.h" #include "SkRRect.h" #include "SkStrokeRec.h" -#include "SkTLazy.h" -#include "batches/GrRectBatchFactory.h" #include "batches/GrVertexBatch.h" -#include "effects/GrRRectEffect.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLGeometryProcessor.h" #include "glsl/GrGLSLProgramDataManager.h" @@ -585,35 +580,34 @@ const GrGeometryProcessor* DIEllipseEdgeEffect::TestCreate(GrProcessorTestData* /////////////////////////////////////////////////////////////////////////////// -bool GrOvalRenderer::DrawOval(GrDrawTarget* target, - const GrPipelineBuilder& pipelineBuilder, - GrColor color, - const SkMatrix& viewMatrix, - bool useAA, - const SkRect& oval, - const SkStrokeRec& stroke) { +GrDrawBatch* GrOvalRenderer::CreateOvalBatch(const GrPipelineBuilder& pipelineBuilder, + GrColor color, + const SkMatrix& viewMatrix, + bool useAA, + const SkRect& oval, + const SkStrokeRec& stroke, + GrShaderCaps* shaderCaps) { bool useCoverageAA = useAA && !pipelineBuilder.getRenderTarget()->isUnifiedMultisampled(); - if (!useCoverageAA) { - return false; + return nullptr; } // we can draw circles if (SkScalarNearlyEqual(oval.width(), oval.height()) && circle_stays_circle(viewMatrix)) { - DrawCircle(target, pipelineBuilder, color, viewMatrix, useCoverageAA, oval, stroke); + return CreateCircleBatch(color, viewMatrix, oval, stroke); + } + // if we have shader derivative support, render as device-independent - } else if (target->caps()->shaderCaps()->shaderDerivativeSupport()) { - return DrawDIEllipse(target, pipelineBuilder, color, viewMatrix, useCoverageAA, oval, - stroke); + if (shaderCaps->shaderDerivativeSupport()) { + return CreateDIEllipseBatch(color, viewMatrix, oval, stroke); + } + // otherwise axis-aligned ellipses only - } else if (viewMatrix.rectStaysRect()) { - return DrawEllipse(target, pipelineBuilder, color, viewMatrix, useCoverageAA, oval, - stroke); - } else { - return false; + if (viewMatrix.rectStaysRect()) { + return CreateEllipseBatch(color, viewMatrix, oval, stroke); } - return true; + return nullptr; } /////////////////////////////////////////////////////////////////////////////// @@ -788,7 +782,6 @@ private: static GrDrawBatch* create_circle_batch(GrColor color, const SkMatrix& viewMatrix, - bool useCoverageAA, const SkRect& circle, const SkStrokeRec& stroke) { SkPoint center = SkPoint::Make(circle.centerX(), circle.centerY()); @@ -836,16 +829,11 @@ static GrDrawBatch* create_circle_batch(GrColor color, return CircleBatch::Create(geometry); } -void GrOvalRenderer::DrawCircle(GrDrawTarget* target, - const GrPipelineBuilder& pipelineBuilder, - GrColor color, - const SkMatrix& viewMatrix, - bool useCoverageAA, - const SkRect& circle, - const SkStrokeRec& stroke) { - SkAutoTUnref batch(create_circle_batch(color, viewMatrix, useCoverageAA, circle, - stroke)); - target->drawBatch(pipelineBuilder, batch); +GrDrawBatch* GrOvalRenderer::CreateCircleBatch(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& circle, + const SkStrokeRec& stroke) { + return create_circle_batch(color, viewMatrix, circle, stroke); } /////////////////////////////////////////////////////////////////////////////// @@ -1013,16 +1001,9 @@ private: static GrDrawBatch* create_ellipse_batch(GrColor color, const SkMatrix& viewMatrix, - bool useCoverageAA, const SkRect& ellipse, const SkStrokeRec& stroke) { -#ifdef SK_DEBUG - { - // we should have checked for this previously - bool isAxisAlignedEllipse = viewMatrix.rectStaysRect(); - SkASSERT(useCoverageAA && isAxisAlignedEllipse); - } -#endif + SkASSERT(viewMatrix.rectStaysRect()); // do any matrix crunching before we reset the draw state for device coords SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY()); @@ -1098,21 +1079,11 @@ static GrDrawBatch* create_ellipse_batch(GrColor color, return EllipseBatch::Create(geometry); } -bool GrOvalRenderer::DrawEllipse(GrDrawTarget* target, - const GrPipelineBuilder& pipelineBuilder, - GrColor color, - const SkMatrix& viewMatrix, - bool useCoverageAA, - const SkRect& ellipse, - const SkStrokeRec& stroke) { - SkAutoTUnref batch(create_ellipse_batch(color, viewMatrix, useCoverageAA, ellipse, - stroke)); - if (!batch) { - return false; - } - - target->drawBatch(pipelineBuilder, batch); - return true; +GrDrawBatch* GrOvalRenderer::CreateEllipseBatch(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& ellipse, + const SkStrokeRec& stroke) { + return create_ellipse_batch(color, viewMatrix, ellipse, stroke); } ///////////////////////////////////////////////////////////////////////////////////////////////// @@ -1275,7 +1246,6 @@ private: static GrDrawBatch* create_diellipse_batch(GrColor color, const SkMatrix& viewMatrix, - bool useCoverageAA, const SkRect& ellipse, const SkStrokeRec& stroke) { SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY()); @@ -1351,20 +1321,11 @@ static GrDrawBatch* create_diellipse_batch(GrColor color, return DIEllipseBatch::Create(geometry, devBounds); } -bool GrOvalRenderer::DrawDIEllipse(GrDrawTarget* target, - const GrPipelineBuilder& pipelineBuilder, - GrColor color, - const SkMatrix& viewMatrix, - bool useCoverageAA, - const SkRect& ellipse, - const SkStrokeRec& stroke) { - SkAutoTUnref batch(create_diellipse_batch(color, viewMatrix, useCoverageAA, - ellipse, stroke)); - if (!batch) { - return false; - } - target->drawBatch(pipelineBuilder, batch); - return true; +GrDrawBatch* GrOvalRenderer::CreateDIEllipseBatch(GrColor color, + const SkMatrix& viewMatrix, + const SkRect& ellipse, + const SkStrokeRec& stroke) { + return create_diellipse_batch(color, viewMatrix, ellipse, stroke); } /////////////////////////////////////////////////////////////////////////////// @@ -1410,72 +1371,6 @@ static const GrIndexBuffer* ref_rrect_index_buffer(bool strokeOnly, } } -bool GrOvalRenderer::DrawDRRect(GrDrawTarget* target, - const GrPipelineBuilder& pipelineBuilder, - GrColor color, - const SkMatrix& viewMatrix, - bool useAA, - const SkRRect& origOuter, - const SkRRect& origInner) { - bool applyAA = useAA && !pipelineBuilder.getRenderTarget()->isUnifiedMultisampled(); - GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; - if (!origInner.isEmpty()) { - SkTCopyOnFirstWrite inner(origInner); - if (!viewMatrix.isIdentity()) { - if (!origInner.transform(viewMatrix, inner.writable())) { - return false; - } - } - GrPrimitiveEdgeType edgeType = applyAA ? - kInverseFillAA_GrProcessorEdgeType : - kInverseFillBW_GrProcessorEdgeType; - // TODO this needs to be a geometry processor - GrFragmentProcessor* fp = GrRRectEffect::Create(edgeType, *inner); - if (nullptr == fp) { - return false; - } - arfps.set(&pipelineBuilder); - arfps.addCoverageFragmentProcessor(fp)->unref(); - } - - SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle); - if (DrawRRect(target, pipelineBuilder, color, viewMatrix, useAA, origOuter, fillRec)) { - return true; - } - - SkASSERT(!origOuter.isEmpty()); - SkTCopyOnFirstWrite outer(origOuter); - if (!viewMatrix.isIdentity()) { - if (!origOuter.transform(viewMatrix, outer.writable())) { - return false; - } - } - GrPrimitiveEdgeType edgeType = applyAA ? kFillAA_GrProcessorEdgeType : - kFillBW_GrProcessorEdgeType; - GrFragmentProcessor* effect = GrRRectEffect::Create(edgeType, *outer); - if (nullptr == effect) { - return false; - } - if (!arfps.isSet()) { - arfps.set(&pipelineBuilder); - } - - SkMatrix invert; - if (!viewMatrix.invert(&invert)) { - return false; - } - - arfps.addCoverageFragmentProcessor(effect)->unref(); - SkRect bounds = outer->getBounds(); - if (applyAA) { - bounds.outset(SK_ScalarHalf, SK_ScalarHalf); - } - SkAutoTUnref batch(GrRectBatchFactory::CreateNonAAFill(color, SkMatrix::I(), - bounds, nullptr, &invert)); - target->drawBatch(pipelineBuilder, batch); - return true; -} - /////////////////////////////////////////////////////////////////////////////////////////////////// class RRectCircleRendererBatch : public GrVertexBatch { @@ -1995,36 +1890,30 @@ static GrDrawBatch* create_rrect_batch(GrColor color, } } -bool GrOvalRenderer::DrawRRect(GrDrawTarget* target, - const GrPipelineBuilder& pipelineBuilder, - GrColor color, - const SkMatrix& viewMatrix, - bool useAA, - const SkRRect& rrect, - const SkStrokeRec& stroke) { - if (rrect.isOval()) { - return DrawOval(target, pipelineBuilder, color, viewMatrix, useAA, rrect.getBounds(), - stroke); - } - +GrDrawBatch* GrOvalRenderer::CreateRRectBatch(const GrPipelineBuilder& pipelineBuilder, + GrColor color, + const SkMatrix& viewMatrix, + bool useAA, + const SkRRect& rrect, + const SkStrokeRec& stroke, + GrShaderCaps* shaderCaps) { bool useCoverageAA = useAA && !pipelineBuilder.getRenderTarget()->isUnifiedMultisampled(); // only anti-aliased rrects for now if (!useCoverageAA) { - return false; + return nullptr; } - if (!viewMatrix.rectStaysRect() || !rrect.isSimple()) { - return false; + if (rrect.isOval()) { + return CreateOvalBatch(pipelineBuilder, color, viewMatrix, useAA, + rrect.getBounds(), stroke, shaderCaps); } - SkAutoTUnref batch(create_rrect_batch(color, viewMatrix, rrect, stroke)); - if (!batch) { - return false; + if (!viewMatrix.rectStaysRect() || !rrect.isSimple()) { + return nullptr; } - target->drawBatch(pipelineBuilder, batch); - return true; + return create_rrect_batch(color, viewMatrix, rrect, stroke); } /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -2034,27 +1923,22 @@ bool GrOvalRenderer::DrawRRect(GrDrawTarget* target, DRAW_BATCH_TEST_DEFINE(CircleBatch) { SkMatrix viewMatrix = GrTest::TestMatrix(random); GrColor color = GrRandomColor(random); - bool useCoverageAA = random->nextBool(); SkRect circle = GrTest::TestSquare(random); - return create_circle_batch(color, viewMatrix, useCoverageAA, circle, - GrTest::TestStrokeRec(random)); + return create_circle_batch(color, viewMatrix, circle, GrTest::TestStrokeRec(random)); } DRAW_BATCH_TEST_DEFINE(EllipseBatch) { SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); GrColor color = GrRandomColor(random); SkRect ellipse = GrTest::TestSquare(random); - return create_ellipse_batch(color, viewMatrix, true, ellipse, - GrTest::TestStrokeRec(random)); + return create_ellipse_batch(color, viewMatrix, ellipse, GrTest::TestStrokeRec(random)); } DRAW_BATCH_TEST_DEFINE(DIEllipseBatch) { SkMatrix viewMatrix = GrTest::TestMatrix(random); GrColor color = GrRandomColor(random); - bool useCoverageAA = random->nextBool(); SkRect ellipse = GrTest::TestSquare(random); - return create_diellipse_batch(color, viewMatrix, useCoverageAA, ellipse, - GrTest::TestStrokeRec(random)); + return create_diellipse_batch(color, viewMatrix, ellipse, GrTest::TestStrokeRec(random)); } DRAW_BATCH_TEST_DEFINE(RRectBatch) { diff --git a/src/gpu/GrOvalRenderer.h b/src/gpu/GrOvalRenderer.h index d591ffe..d343980 100644 --- a/src/gpu/GrOvalRenderer.h +++ b/src/gpu/GrOvalRenderer.h @@ -10,8 +10,9 @@ #include "GrPaint.h" -class GrDrawTarget; +class GrDrawBatch; class GrPipelineBuilder; +class GrShaderCaps; struct SkRect; class SkStrokeRec; @@ -20,52 +21,36 @@ class SkStrokeRec; */ class GrOvalRenderer { public: - static bool DrawOval(GrDrawTarget*, - const GrPipelineBuilder&, - GrColor, - const SkMatrix& viewMatrix, - bool useAA, - const SkRect& oval, - const SkStrokeRec& stroke); - static bool DrawRRect(GrDrawTarget*, - const GrPipelineBuilder&, - GrColor, - const SkMatrix& viewMatrix, - bool useAA, - const SkRRect& rrect, - const SkStrokeRec& stroke); - static bool DrawDRRect(GrDrawTarget* target, - const GrPipelineBuilder&, - GrColor, - const SkMatrix& viewMatrix, - bool useAA, - const SkRRect& outer, - const SkRRect& inner); + static GrDrawBatch* CreateOvalBatch(const GrPipelineBuilder&, + GrColor, + const SkMatrix& viewMatrix, + bool useAA, + const SkRect& oval, + const SkStrokeRec& stroke, + GrShaderCaps* shaderCaps); + static GrDrawBatch* CreateRRectBatch(const GrPipelineBuilder&, + GrColor, + const SkMatrix& viewMatrix, + bool useAA, + const SkRRect& rrect, + const SkStrokeRec& stroke, + GrShaderCaps* shaderCaps); private: GrOvalRenderer(); - static bool DrawEllipse(GrDrawTarget* target, - const GrPipelineBuilder&, - GrColor, - const SkMatrix& viewMatrix, - bool useCoverageAA, - const SkRect& ellipse, - const SkStrokeRec& stroke); - static bool DrawDIEllipse(GrDrawTarget* target, - const GrPipelineBuilder&, - GrColor, - const SkMatrix& viewMatrix, - bool useCoverageAA, - const SkRect& ellipse, - const SkStrokeRec& stroke); - static void DrawCircle(GrDrawTarget* target, - const GrPipelineBuilder&, - GrColor, - const SkMatrix& viewMatrix, - bool useCoverageAA, - const SkRect& circle, - const SkStrokeRec& stroke); + static GrDrawBatch* CreateEllipseBatch(GrColor, + const SkMatrix& viewMatrix, + const SkRect& ellipse, + const SkStrokeRec& stroke); + static GrDrawBatch* CreateDIEllipseBatch(GrColor, + const SkMatrix& viewMatrix, + const SkRect& ellipse, + const SkStrokeRec& stroke); + static GrDrawBatch* CreateCircleBatch(GrColor, + const SkMatrix& viewMatrix, + const SkRect& circle, + const SkStrokeRec& stroke); }; #endif // GrOvalRenderer_DEFINED -- 2.7.4