Also provides the ResourceProvider to onDrawPath which allows the DF PR to no longer require access to GrContext.

Review URL: https://codereview.chromium.org/1265763002
This commit is contained in:
bsalomon 2015-07-31 06:48:27 -07:00 committed by Commit bot
parent 99cab4e308
commit 0aff2fa82a
25 changed files with 415 additions and 503 deletions

View File

@ -678,14 +678,10 @@ GrGeometryProcessor* QuadEdgeEffect::TestCreate(GrProcessorTestData* d) {
///////////////////////////////////////////////////////////////////////////////
bool GrAAConvexPathRenderer::canDrawPath(const GrDrawTarget* target,
const GrPipelineBuilder*,
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& stroke,
bool antiAlias) const {
return (target->caps()->shaderCaps()->shaderDerivativeSupport() && antiAlias &&
stroke.isFillStyle() && !path.isInverseFillType() && path.isConvex());
bool GrAAConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
return (args.fTarget->caps()->shaderCaps()->shaderDerivativeSupport() && args.fAntiAlias &&
args.fStroke->isFillStyle() && !args.fPath->isInverseFillType() &&
args.fPath->isConvex());
}
// extract the result vertices and indices from the GrAAConvexTessellator
@ -988,24 +984,18 @@ private:
SkSTArray<1, Geometry, true> fGeoData;
};
bool GrAAConvexPathRenderer::onDrawPath(GrDrawTarget* target,
GrPipelineBuilder* pipelineBuilder,
GrColor color,
const SkMatrix& vm,
const SkPath& path,
const GrStrokeInfo&,
bool antiAlias) {
if (path.isEmpty()) {
bool GrAAConvexPathRenderer::onDrawPath(const DrawPathArgs& args) {
if (args.fPath->isEmpty()) {
return true;
}
AAConvexPathBatch::Geometry geometry;
geometry.fColor = color;
geometry.fViewMatrix = vm;
geometry.fPath = path;
geometry.fColor = args.fColor;
geometry.fViewMatrix = *args.fViewMatrix;
geometry.fPath = *args.fPath;
SkAutoTUnref<GrBatch> batch(AAConvexPathBatch::Create(geometry));
target->drawBatch(*pipelineBuilder, batch);
args.fTarget->drawBatch(*args.fPipelineBuilder, batch);
return true;

View File

@ -15,21 +15,10 @@ class GrAAConvexPathRenderer : public GrPathRenderer {
public:
GrAAConvexPathRenderer();
virtual bool canDrawPath(const GrDrawTarget*,
const GrPipelineBuilder*,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStrokeInfo&,
bool antiAlias) const override;
private:
bool onCanDrawPath(const CanDrawPathArgs&) const override;
protected:
virtual bool onDrawPath(GrDrawTarget*,
GrPipelineBuilder*,
GrColor,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStrokeInfo&,
bool antiAlias) override;
bool onDrawPath(const DrawPathArgs&) override;
};
#endif

View File

@ -62,10 +62,7 @@ void GrAADistanceFieldPathRenderer::HandleEviction(GrBatchAtlas::AtlasID id, voi
}
////////////////////////////////////////////////////////////////////////////////
GrAADistanceFieldPathRenderer::GrAADistanceFieldPathRenderer(GrContext* context)
: fContext(context)
, fAtlas(NULL) {
}
GrAADistanceFieldPathRenderer::GrAADistanceFieldPathRenderer() : fAtlas(NULL) {}
GrAADistanceFieldPathRenderer::~GrAADistanceFieldPathRenderer() {
PathDataList::Iter iter;
@ -84,34 +81,29 @@ GrAADistanceFieldPathRenderer::~GrAADistanceFieldPathRenderer() {
}
////////////////////////////////////////////////////////////////////////////////
bool GrAADistanceFieldPathRenderer::canDrawPath(const GrDrawTarget* target,
const GrPipelineBuilder* pipelineBuilder,
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& stroke,
bool antiAlias) const {
bool GrAADistanceFieldPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
// TODO: Support inverse fill
// TODO: Support strokes
if (!target->caps()->shaderCaps()->shaderDerivativeSupport() || !antiAlias
|| path.isInverseFillType() || path.isVolatile() || !stroke.isFillStyle()) {
if (!args.fTarget->caps()->shaderCaps()->shaderDerivativeSupport() || !args.fAntiAlias ||
args.fPath->isInverseFillType() || args.fPath->isVolatile() ||
!args.fStroke->isFillStyle()) {
return false;
}
// currently don't support perspective
if (viewMatrix.hasPerspective()) {
if (args.fViewMatrix->hasPerspective()) {
return false;
}
// only support paths smaller than 64x64, scaled to less than 256x256
// the goal is to accelerate rendering of lots of small paths that may be scaling
SkScalar maxScale = viewMatrix.getMaxScale();
const SkRect& bounds = path.getBounds();
SkScalar maxScale = args.fViewMatrix->getMaxScale();
const SkRect& bounds = args.fPath->getBounds();
SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height());
return maxDim < 64.f && maxDim * maxScale < 256.f;
}
GrPathRenderer::StencilSupport
GrAADistanceFieldPathRenderer::onGetStencilSupport(const GrDrawTarget*,
const GrPipelineBuilder*,
@ -537,7 +529,7 @@ private:
PathDataList* fPathList;
};
static GrBatchAtlas* create_atlas(GrContext* context, GrBatchAtlas::EvictionFunc func, void* data) {
static GrBatchAtlas* create_atlas(GrTextureProvider* provider, GrBatchAtlas::EvictionFunc func, void* data) {
GrBatchAtlas* atlas;
// Create a new atlas
GrSurfaceDesc desc;
@ -548,7 +540,7 @@ static GrBatchAtlas* create_atlas(GrContext* context, GrBatchAtlas::EvictionFunc
// We don't want to flush the context so we claim we're in the middle of flushing so as to
// guarantee we do not recieve a texture with pending IO
GrTexture* texture = context->textureProvider()->refScratchTexture(
GrTexture* texture = provider->refScratchTexture(
desc, GrTextureProvider::kApprox_ScratchTexMatch, true);
if (texture) {
atlas = SkNEW_ARGS(GrBatchAtlas, (texture, NUM_PLOTS_X, NUM_PLOTS_Y));
@ -559,35 +551,28 @@ static GrBatchAtlas* create_atlas(GrContext* context, GrBatchAtlas::EvictionFunc
return atlas;
}
bool GrAADistanceFieldPathRenderer::onDrawPath(GrDrawTarget* target,
GrPipelineBuilder* pipelineBuilder,
GrColor color,
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& stroke,
bool antiAlias) {
bool GrAADistanceFieldPathRenderer::onDrawPath(const DrawPathArgs& args) {
// we've already bailed on inverse filled paths, so this is safe
if (path.isEmpty()) {
if (args.fPath->isEmpty()) {
return true;
}
SkASSERT(fContext);
if (!fAtlas) {
fAtlas = create_atlas(fContext, &GrAADistanceFieldPathRenderer::HandleEviction,
(void*)this);
fAtlas = create_atlas(args.fResourceProvider,
&GrAADistanceFieldPathRenderer::HandleEviction, (void*)this);
if (!fAtlas) {
return false;
}
}
AADistanceFieldPathBatch::Geometry geometry(stroke);
geometry.fPath = path;
geometry.fAntiAlias = antiAlias;
AADistanceFieldPathBatch::Geometry geometry(*args.fStroke);
geometry.fPath = *args.fPath;
geometry.fAntiAlias = args.fAntiAlias;
SkAutoTUnref<GrBatch> batch(AADistanceFieldPathBatch::Create(geometry, color, viewMatrix,
fAtlas, &fPathCache, &fPathList));
target->drawBatch(*pipelineBuilder, batch);
SkAutoTUnref<GrBatch> batch(AADistanceFieldPathBatch::Create(geometry, args.fColor,
*args.fViewMatrix, fAtlas,
&fPathCache, &fPathList));
args.fTarget->drawBatch(*args.fPipelineBuilder, batch);
return true;
}
@ -644,8 +629,8 @@ BATCH_TEST_DEFINE(AADistanceFieldPathBatch) {
if (context->uniqueID() != gTestStruct.fContextID) {
gTestStruct.fContextID = context->uniqueID();
gTestStruct.reset();
gTestStruct.fAtlas = create_atlas(context, &PathTestStruct::HandleEviction,
(void*)&gTestStruct);
gTestStruct.fAtlas = create_atlas(context->resourceProvider(),
&PathTestStruct::HandleEviction, (void*)&gTestStruct);
}
SkMatrix viewMatrix = GrTest::TestMatrix(random);

View File

@ -20,31 +20,19 @@ class GrContext;
class GrAADistanceFieldPathRenderer : public GrPathRenderer {
public:
GrAADistanceFieldPathRenderer(GrContext* context);
GrAADistanceFieldPathRenderer();
virtual ~GrAADistanceFieldPathRenderer();
virtual bool canDrawPath(const GrDrawTarget*,
const GrPipelineBuilder*,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStrokeInfo&,
bool antiAlias) const override;
protected:
virtual StencilSupport onGetStencilSupport(const GrDrawTarget*,
const GrPipelineBuilder*,
const SkPath&,
const GrStrokeInfo&) const override;
virtual bool onDrawPath(GrDrawTarget*,
GrPipelineBuilder*,
GrColor,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStrokeInfo&,
bool antiAlias) override;
private:
StencilSupport onGetStencilSupport(const GrDrawTarget*,
const GrPipelineBuilder*,
const SkPath&,
const GrStrokeInfo&) const override;
bool onCanDrawPath(const CanDrawPathArgs&) const override;
bool onDrawPath(const DrawPathArgs&) override;
struct PathData {
struct Key {
uint32_t fGenID;
@ -75,7 +63,6 @@ private:
typedef SkTDynamicHash<PathData, PathData::Key> PathCache;
typedef SkTInternalLList<PathData> PathDataList;
GrContext* fContext;
GrBatchAtlas* fAtlas;
PathCache fPathCache;
PathDataList fPathList;

View File

@ -616,22 +616,17 @@ static void add_line(const SkPoint p[2],
///////////////////////////////////////////////////////////////////////////////
bool GrAAHairLinePathRenderer::canDrawPath(const GrDrawTarget* target,
const GrPipelineBuilder* pipelineBuilder,
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& stroke,
bool antiAlias) const {
if (!antiAlias) {
bool GrAAHairLinePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
if (!args.fAntiAlias) {
return false;
}
if (!IsStrokeHairlineOrEquivalent(stroke, viewMatrix, NULL)) {
if (!IsStrokeHairlineOrEquivalent(*args.fStroke, *args.fViewMatrix, NULL)) {
return false;
}
if (SkPath::kLine_SegmentMask == path.getSegmentMasks() ||
target->caps()->shaderCaps()->shaderDerivativeSupport()) {
if (SkPath::kLine_SegmentMask == args.fPath->getSegmentMasks() ||
args.fTarget->caps()->shaderCaps()->shaderDerivativeSupport()) {
return true;
}
return false;
@ -974,20 +969,14 @@ static GrBatch* create_hairline_batch(GrColor color,
return AAHairlineBatch::Create(geometry);
}
bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
GrPipelineBuilder* pipelineBuilder,
GrColor color,
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& stroke,
bool) {
bool GrAAHairLinePathRenderer::onDrawPath(const DrawPathArgs& args) {
SkIRect devClipBounds;
pipelineBuilder->clip().getConservativeBounds(pipelineBuilder->getRenderTarget(),
&devClipBounds);
args.fPipelineBuilder->clip().getConservativeBounds(args.fPipelineBuilder->getRenderTarget(),
&devClipBounds);
SkAutoTUnref<GrBatch> batch(create_hairline_batch(color, viewMatrix, path, stroke,
devClipBounds));
target->drawBatch(*pipelineBuilder, batch);
SkAutoTUnref<GrBatch> batch(create_hairline_batch(args.fColor, *args.fViewMatrix, *args.fPath,
*args.fStroke, devClipBounds));
args.fTarget->drawBatch(*args.fPipelineBuilder, batch);
return true;
}

View File

@ -15,27 +15,15 @@ class GrAAHairLinePathRenderer : public GrPathRenderer {
public:
static GrPathRenderer* Create() { return SkNEW(GrAAHairLinePathRenderer); }
bool canDrawPath(const GrDrawTarget*,
const GrPipelineBuilder*,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStrokeInfo&,
bool antiAlias) const override;
typedef SkTArray<SkPoint, true> PtArray;
typedef SkTArray<int, true> IntArray;
typedef SkTArray<float, true> FloatArray;
protected:
bool onDrawPath(GrDrawTarget*,
GrPipelineBuilder*,
GrColor,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStrokeInfo&,
bool antiAlias) override;
private:
bool onCanDrawPath(const CanDrawPathArgs&) const override;
bool onDrawPath(const DrawPathArgs&) override;
GrAAHairLinePathRenderer() {}
typedef GrPathRenderer INHERITED;

View File

@ -39,27 +39,23 @@ GrAALinearizingConvexPathRenderer::GrAALinearizingConvexPathRenderer() {
///////////////////////////////////////////////////////////////////////////////
bool GrAALinearizingConvexPathRenderer::canDrawPath(const GrDrawTarget* target,
const GrPipelineBuilder*,
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& stroke,
bool antiAlias) const {
if (!antiAlias) {
bool GrAALinearizingConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
if (!args.fAntiAlias) {
return false;
}
if (path.isInverseFillType()) {
if (args.fPath->isInverseFillType()) {
return false;
}
if (!path.isConvex()) {
if (!args.fPath->isConvex()) {
return false;
}
if (stroke.getStyle() == SkStrokeRec::kStroke_Style) {
return viewMatrix.isSimilarity() && stroke.getWidth() >= 1.0f &&
stroke.getWidth() <= kMaxStrokeWidth && !stroke.isDashed() &&
SkPathPriv::LastVerbIsClose(path) && stroke.getJoin() != SkPaint::Join::kRound_Join;
if (args.fStroke->getStyle() == SkStrokeRec::kStroke_Style) {
return args.fViewMatrix->isSimilarity() && args.fStroke->getWidth() >= 1.0f &&
args.fStroke->getWidth() <= kMaxStrokeWidth && !args.fStroke->isDashed() &&
SkPathPriv::LastVerbIsClose(*args.fPath) &&
args.fStroke->getJoin() != SkPaint::Join::kRound_Join;
}
return stroke.getStyle() == SkStrokeRec::kFill_Style;
return args.fStroke->getStyle() == SkStrokeRec::kFill_Style;
}
// extract the result vertices and indices from the GrAAConvexTessellator
@ -303,26 +299,21 @@ private:
SkSTArray<1, Geometry, true> fGeoData;
};
bool GrAALinearizingConvexPathRenderer::onDrawPath(GrDrawTarget* target,
GrPipelineBuilder* pipelineBuilder,
GrColor color,
const SkMatrix& vm,
const SkPath& path,
const GrStrokeInfo& stroke,
bool antiAlias) {
if (path.isEmpty()) {
bool GrAALinearizingConvexPathRenderer::onDrawPath(const DrawPathArgs& args) {
if (args.fPath->isEmpty()) {
return true;
}
AAFlatteningConvexPathBatch::Geometry geometry;
geometry.fColor = color;
geometry.fViewMatrix = vm;
geometry.fPath = path;
geometry.fStrokeWidth = stroke.isFillStyle() ? -1.0f : stroke.getWidth();
geometry.fJoin = stroke.isFillStyle() ? SkPaint::Join::kMiter_Join : stroke.getJoin();
geometry.fMiterLimit = stroke.getMiter();
geometry.fColor = args.fColor;
geometry.fViewMatrix = *args.fViewMatrix;
geometry.fPath = *args.fPath;
geometry.fStrokeWidth = args.fStroke->isFillStyle() ? -1.0f : args.fStroke->getWidth();
geometry.fJoin = args.fStroke->isFillStyle() ? SkPaint::Join::kMiter_Join :
args.fStroke->getJoin();
geometry.fMiterLimit = args.fStroke->getMiter();
SkAutoTUnref<GrBatch> batch(AAFlatteningConvexPathBatch::Create(geometry));
target->drawBatch(*pipelineBuilder, batch);
args.fTarget->drawBatch(*args.fPipelineBuilder, batch);
return true;
}

View File

@ -15,21 +15,10 @@ class GrAALinearizingConvexPathRenderer : public GrPathRenderer {
public:
GrAALinearizingConvexPathRenderer();
virtual bool canDrawPath(const GrDrawTarget*,
const GrPipelineBuilder*,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStrokeInfo&,
bool antiAlias) const override;
private:
bool onCanDrawPath(const CanDrawPathArgs&) const override;
protected:
virtual bool onDrawPath(GrDrawTarget*,
GrPipelineBuilder*,
GrColor,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStrokeInfo&,
bool antiAlias) override;
bool onDrawPath(const DrawPathArgs&) override;
};
#endif

View File

@ -36,5 +36,5 @@ void GrPathRenderer::AddPathRenderers(GrContext* ctx, GrPathRendererChain* chain
}
chain->addPathRenderer(SkNEW(GrAAConvexPathRenderer))->unref();
chain->addPathRenderer(SkNEW(GrAALinearizingConvexPathRenderer))->unref();
chain->addPathRenderer(SkNEW_ARGS(GrAADistanceFieldPathRenderer, (ctx)))->unref();
chain->addPathRenderer(SkNEW(GrAADistanceFieldPathRenderer))->unref();
}

View File

@ -432,9 +432,16 @@ bool GrClipMaskManager::drawElement(GrPipelineBuilder* pipelineBuilder,
if (NULL == pr) {
return false;
}
pr->drawPath(fClipTarget, pipelineBuilder, color, viewMatrix, path, stroke,
element->isAA());
GrPathRenderer::DrawPathArgs args;
args.fTarget = fClipTarget;
args.fResourceProvider = this->getContext()->resourceProvider();
args.fPipelineBuilder = pipelineBuilder;
args.fColor = color;
args.fViewMatrix = &viewMatrix;
args.fPath = &path;
args.fStroke = &stroke;
args.fAntiAlias = element->isAA();
pr->drawPath(args);
break;
}
}
@ -829,11 +836,26 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
if (!clipPath.isEmpty()) {
if (canRenderDirectToStencil) {
*pipelineBuilder.stencil() = gDrawToStencil;
pr->drawPath(fClipTarget, &pipelineBuilder, GrColor_WHITE,
viewMatrix, clipPath, stroke, false);
GrPathRenderer::DrawPathArgs args;
args.fTarget = fClipTarget;
args.fResourceProvider = this->getContext()->resourceProvider();
args.fPipelineBuilder = &pipelineBuilder;
args.fColor = GrColor_WHITE;
args.fViewMatrix = &viewMatrix;
args.fPath = &clipPath;
args.fStroke = &stroke;
args.fAntiAlias = false;
pr->drawPath(args);
} else {
pr->stencilPath(fClipTarget, &pipelineBuilder, viewMatrix,
clipPath, stroke);
GrPathRenderer::StencilPathArgs args;
args.fTarget = fClipTarget;
args.fResourceProvider = this->getContext()->resourceProvider();
args.fPipelineBuilder = &pipelineBuilder;
args.fViewMatrix = &viewMatrix;
args.fPath = &clipPath;
args.fStroke = &stroke;
pr->stencilPath(args);
}
}
}
@ -853,8 +875,16 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
viewMatrix,
element->getRect());
} else {
pr->drawPath(fClipTarget, &pipelineBuilder, GrColor_WHITE,
viewMatrix, clipPath, stroke, false);
GrPathRenderer::DrawPathArgs args;
args.fTarget = fClipTarget;
args.fResourceProvider = this->getContext()->resourceProvider();
args.fPipelineBuilder = &pipelineBuilder;
args.fColor = GrColor_WHITE;
args.fViewMatrix = &viewMatrix;
args.fPath = &clipPath;
args.fStroke = &stroke;
args.fAntiAlias = false;
pr->drawPath(args);
}
} else {
// The view matrix is setup to do clip space -> stencil space translation, so

View File

@ -10,28 +10,17 @@
#include "GrGpu.h"
#include "effects/GrDashingEffect.h"
bool GrDashLinePathRenderer::canDrawPath(const GrDrawTarget* target,
const GrPipelineBuilder* pipelineBuilder,
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& stroke,
bool antiAlias) const {
bool GrDashLinePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
SkPoint pts[2];
if (stroke.isDashed() && path.isLine(pts)) {
return GrDashingEffect::CanDrawDashLine(pts, stroke, viewMatrix);
if (args.fStroke->isDashed() && args.fPath->isLine(pts)) {
return GrDashingEffect::CanDrawDashLine(pts, *args.fStroke, *args.fViewMatrix);
}
return false;
}
bool GrDashLinePathRenderer::onDrawPath(GrDrawTarget* target,
GrPipelineBuilder* pipelineBuilder,
GrColor color,
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& stroke,
bool useAA) {
bool GrDashLinePathRenderer::onDrawPath(const DrawPathArgs& args) {
SkPoint pts[2];
SkAssertResult(path.isLine(pts));
return GrDashingEffect::DrawDashLine(target, *pipelineBuilder, color,
viewMatrix, pts, useAA, stroke);
SkAssertResult(args.fPath->isLine(pts));
return GrDashingEffect::DrawDashLine(args.fTarget, *args.fPipelineBuilder, args.fColor,
*args.fViewMatrix, pts, args.fAntiAlias, *args.fStroke);
}

View File

@ -12,15 +12,9 @@
#include "GrPathRenderer.h"
class GrDashLinePathRenderer : public GrPathRenderer {
public:
bool canDrawPath(const GrDrawTarget*,
const GrPipelineBuilder*,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStrokeInfo&,
bool antiAlias) const override;
private:
bool onCanDrawPath(const CanDrawPathArgs&) const override;
protected:
StencilSupport onGetStencilSupport(const GrDrawTarget*,
const GrPipelineBuilder*,
const SkPath&,
@ -28,13 +22,8 @@ protected:
return kNoSupport_StencilSupport;
}
bool onDrawPath(GrDrawTarget*,
GrPipelineBuilder*,
GrColor,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStrokeInfo&,
bool antiAlias) override;
bool onDrawPath(const DrawPathArgs&) override;
SkAutoTUnref<GrGpu> fGpu;
typedef GrPathRenderer INHERITED;
};

View File

@ -702,42 +702,28 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target,
return true;
}
bool GrDefaultPathRenderer::canDrawPath(const GrDrawTarget* target,
const GrPipelineBuilder* pipelineBuilder,
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& stroke,
bool antiAlias) const {
bool GrDefaultPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
// this class can draw any path with any fill but doesn't do any anti-aliasing.
return !antiAlias && (stroke.isFillStyle() || IsStrokeHairlineOrEquivalent(stroke,
viewMatrix,
NULL));
return !args.fAntiAlias && (args.fStroke->isFillStyle() ||
IsStrokeHairlineOrEquivalent(*args.fStroke, *args.fViewMatrix,
NULL));
}
bool GrDefaultPathRenderer::onDrawPath(GrDrawTarget* target,
GrPipelineBuilder* pipelineBuilder,
GrColor color,
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& stroke,
bool antiAlias) {
return this->internalDrawPath(target,
pipelineBuilder,
color,
viewMatrix,
path,
stroke,
bool GrDefaultPathRenderer::onDrawPath(const DrawPathArgs& args) {
return this->internalDrawPath(args.fTarget,
args.fPipelineBuilder,
args.fColor,
*args.fViewMatrix,
*args.fPath,
*args.fStroke,
false);
}
void GrDefaultPathRenderer::onStencilPath(GrDrawTarget* target,
GrPipelineBuilder* pipelineBuilder,
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& stroke) {
SkASSERT(SkPath::kInverseEvenOdd_FillType != path.getFillType());
SkASSERT(SkPath::kInverseWinding_FillType != path.getFillType());
this->internalDrawPath(target, pipelineBuilder, GrColor_WHITE, viewMatrix, path, stroke, true);
void GrDefaultPathRenderer::onStencilPath(const StencilPathArgs& args) {
SkASSERT(SkPath::kInverseEvenOdd_FillType != args.fPath->getFillType());
SkASSERT(SkPath::kInverseWinding_FillType != args.fPath->getFillType());
this->internalDrawPath(args.fTarget, args.fPipelineBuilder, GrColor_WHITE, *args.fViewMatrix,
*args.fPath, *args.fStroke, true);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -19,13 +19,6 @@ class SK_API GrDefaultPathRenderer : public GrPathRenderer {
public:
GrDefaultPathRenderer(bool separateStencilSupport, bool stencilWrapOpsSupport);
virtual bool canDrawPath(const GrDrawTarget*,
const GrPipelineBuilder*,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStrokeInfo&,
bool antiAlias) const override;
private:
virtual StencilSupport onGetStencilSupport(const GrDrawTarget*,
@ -33,19 +26,11 @@ private:
const SkPath&,
const GrStrokeInfo&) const override;
virtual bool onDrawPath(GrDrawTarget*,
GrPipelineBuilder*,
GrColor,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStrokeInfo&,
bool antiAlias) override;
bool onCanDrawPath(const CanDrawPathArgs&) const override;
virtual void onStencilPath(GrDrawTarget*,
GrPipelineBuilder*,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStrokeInfo&) override;
bool onDrawPath(const DrawPathArgs&) override;
void onStencilPath(const StencilPathArgs&) override;
bool internalDrawPath(GrDrawTarget*,
GrPipelineBuilder*,

View File

@ -1183,7 +1183,16 @@ void GrDrawContext::internalDrawPath(GrDrawTarget* target,
return;
}
pr->drawPath(target, pipelineBuilder, color, viewMatrix, *pathPtr, *strokeInfoPtr, useCoverageAA);
GrPathRenderer::DrawPathArgs args;
args.fTarget = target;
args.fResourceProvider = fContext->resourceProvider();
args.fPipelineBuilder = pipelineBuilder;
args.fColor = color;
args.fViewMatrix = &viewMatrix;
args.fPath = pathPtr;
args.fStroke = strokeInfoPtr;
args.fAntiAlias = useCoverageAA;
pr->drawPath(args);
}
bool GrDrawContext::prepareToDraw(GrRenderTarget* rt) {

View File

@ -89,68 +89,127 @@ public:
return this->onGetStencilSupport(target, pipelineBuilder, path, stroke);
}
/** Args to canDrawPath()
*
* fTarget The target that the path will be rendered to
* fPipelineBuilder The pipelineBuilder
* fViewMatrix The viewMatrix
* fPath The path to draw
* fStroke The stroke information (width, join, cap)
* fAntiAlias True if anti-aliasing is required.
*/
struct CanDrawPathArgs {
const GrDrawTarget* fTarget;
const GrPipelineBuilder* fPipelineBuilder;
const SkMatrix* fViewMatrix;
const SkPath* fPath;
const GrStrokeInfo* fStroke;
bool fAntiAlias;
};
/**
* Returns true if this path renderer is able to render the path. Returning false allows the
* caller to fallback to another path renderer This function is called when searching for a path
* renderer capable of rendering a path.
*
* @param target The target that the path will be rendered to
* @param pipelineBuilder The pipelineBuilder
* @param viewMatrix The viewMatrix
* @param path The path to draw
* @param stroke The stroke information (width, join, cap)
* @param antiAlias True if anti-aliasing is required.
*
* @return true if the path can be drawn by this object, false otherwise.
*/
virtual bool canDrawPath(const GrDrawTarget* target,
const GrPipelineBuilder* pipelineBuilder,
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& rec,
bool antiAlias) const = 0;
bool canDrawPath(const CanDrawPathArgs& args) const {
SkASSERT(args.fTarget);
SkASSERT(args.fPipelineBuilder);
SkASSERT(args.fViewMatrix);
SkASSERT(args.fPath);
SkASSERT(args.fStroke);
SkASSERT(!args.fPath->isEmpty());
return this->onCanDrawPath(args);
}
/**
* Args to drawPath()
*
* fTarget The target that the path will be rendered to
* fResourceProvider The resource provider for creating gpu resources to render the path
* fPipelineBuilder The pipelineBuilder
* fViewMatrix The viewMatrix
* fPath the path to draw.
* fStroke the stroke information (width, join, cap)
* fAntiAlias true if anti-aliasing is required.
*/
struct DrawPathArgs {
GrDrawTarget* fTarget;
GrResourceProvider* fResourceProvider;
GrPipelineBuilder* fPipelineBuilder;
GrColor fColor;
const SkMatrix* fViewMatrix;
const SkPath* fPath;
const GrStrokeInfo* fStroke;
bool fAntiAlias;
};
/**
* Draws the path into the draw target. If getStencilSupport() would return kNoRestriction then
* the subclass must respect the stencil settings of the target's draw state.
*
* @param target The target that the path will be rendered to
* @param pipelineBuilder The pipelineBuilder
* @param viewMatrix The viewMatrix
* @param path the path to draw.
* @param stroke the stroke information (width, join, cap)
* @param antiAlias true if anti-aliasing is required.
* the subclass must respect the stencil settings of the GrPipelineBuilder.
*/
bool drawPath(GrDrawTarget* target,
GrPipelineBuilder* ds,
GrColor color,
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& stroke,
bool antiAlias) {
SkASSERT(!path.isEmpty());
SkASSERT(this->canDrawPath(target, ds, viewMatrix, path, stroke, antiAlias));
SkASSERT(ds->getStencil().isDisabled() ||
kNoRestriction_StencilSupport == this->getStencilSupport(target, ds, path,
stroke));
return this->onDrawPath(target, ds, color, viewMatrix, path, stroke, antiAlias);
bool drawPath(const DrawPathArgs& args) {
SkASSERT(args.fTarget);
SkASSERT(args.fPipelineBuilder);
SkASSERT(args.fViewMatrix);
SkASSERT(args.fPath);
SkASSERT(args.fStroke);
SkASSERT(!args.fPath->isEmpty());
#ifdef SK_DEBUG
CanDrawPathArgs canArgs;
canArgs.fTarget = args.fTarget;
canArgs.fPipelineBuilder = args.fPipelineBuilder;
canArgs.fViewMatrix = args.fViewMatrix;
canArgs.fPath = args.fPath;
canArgs.fStroke = args.fStroke;
canArgs.fAntiAlias = args.fAntiAlias;
SkASSERT(this->canDrawPath(canArgs));
SkASSERT(args.fPipelineBuilder->getStencil().isDisabled() ||
kNoRestriction_StencilSupport == this->getStencilSupport(args.fTarget,
args.fPipelineBuilder,
*args.fPath,
*args.fStroke));
#endif
return this->onDrawPath(args);
}
/* Args to stencilPath().
*
* fTarget The target that the path will be rendered to.
* fPipelineBuilder The pipeline builder.
* fViewMatrix Matrix applied to the path.
* fPath The path to draw.
* fStroke The stroke information (width, join, cap)
*/
struct StencilPathArgs {
GrDrawTarget* fTarget;
GrPipelineBuilder* fPipelineBuilder;
GrResourceProvider* fResourceProvider;
const SkMatrix* fViewMatrix;
const SkPath* fPath;
const GrStrokeInfo* fStroke;
};
/**
* Draws the path to the stencil buffer. Assume the writable stencil bits are already
* initialized to zero. The pixels inside the path will have non-zero stencil values afterwards.
*
* @param path the path to draw.
* @param stroke the stroke information (width, join, cap)
* @param target target that the path will be rendered to
*/
void stencilPath(GrDrawTarget* target,
GrPipelineBuilder* ds,
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& stroke) {
SkASSERT(!path.isEmpty());
SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(target, ds, path, stroke));
this->onStencilPath(target, ds, viewMatrix, path, stroke);
void stencilPath(const StencilPathArgs& args) {
SkASSERT(args.fTarget);
SkASSERT(args.fPipelineBuilder);
SkASSERT(args.fResourceProvider);
SkASSERT(args.fViewMatrix);
SkASSERT(args.fPath);
SkASSERT(args.fStroke);
SkASSERT(!args.fPath->isEmpty());
SkASSERT(kNoSupport_StencilSupport !=
this->getStencilSupport(args.fTarget, args.fPipelineBuilder, *args.fPath,
*args.fStroke));
this->onStencilPath(args);
}
// Helper for determining if we can treat a thin stroke as a hairline w/ coverage.
@ -171,48 +230,6 @@ public:
}
protected:
/**
* Subclass overrides if it has any limitations of stenciling support.
*/
virtual StencilSupport onGetStencilSupport(const GrDrawTarget*,
const GrPipelineBuilder*,
const SkPath&,
const GrStrokeInfo&) const {
return kNoRestriction_StencilSupport;
}
/**
* Subclass implementation of drawPath()
*/
virtual bool onDrawPath(GrDrawTarget*,
GrPipelineBuilder*,
GrColor,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStrokeInfo&,
bool antiAlias) = 0;
/**
* Subclass implementation of stencilPath(). Subclass must override iff it ever returns
* kStencilOnly in onGetStencilSupport().
*/
virtual void onStencilPath(GrDrawTarget* target,
GrPipelineBuilder* pipelineBuilder,
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& stroke) {
GR_STATIC_CONST_SAME_STENCIL(kIncrementStencil,
kReplace_StencilOp,
kReplace_StencilOp,
kAlways_StencilFunc,
0xffff,
0xffff,
0xffff);
pipelineBuilder->setStencil(kIncrementStencil);
pipelineBuilder->setDisableColorXPFactory();
this->drawPath(target, pipelineBuilder, GrColor_WHITE, viewMatrix, path, stroke, false);
}
// Helper for getting the device bounds of a path. Inverse filled paths will have bounds set
// by devSize. Non-inverse path bounds will not necessarily be clipped to devSize.
static void GetPathDevBounds(const SkPath& path,
@ -230,6 +247,52 @@ protected:
}
private:
/**
* Subclass overrides if it has any limitations of stenciling support.
*/
virtual StencilSupport onGetStencilSupport(const GrDrawTarget*,
const GrPipelineBuilder*,
const SkPath&,
const GrStrokeInfo&) const {
return kNoRestriction_StencilSupport;
}
/**
* Subclass implementation of drawPath()
*/
virtual bool onDrawPath(const DrawPathArgs& args) = 0;
/**
* Subclass implementation of canDrawPath()
*/
virtual bool onCanDrawPath(const CanDrawPathArgs& args) const = 0;
/**
* Subclass implementation of stencilPath(). Subclass must override iff it ever returns
* kStencilOnly in onGetStencilSupport().
*/
virtual void onStencilPath(const StencilPathArgs& args) {
GR_STATIC_CONST_SAME_STENCIL(kIncrementStencil,
kReplace_StencilOp,
kReplace_StencilOp,
kAlways_StencilFunc,
0xffff,
0xffff,
0xffff);
args.fPipelineBuilder->setStencil(kIncrementStencil);
args.fPipelineBuilder->setDisableColorXPFactory();
DrawPathArgs drawArgs;
drawArgs.fTarget = args.fTarget;
drawArgs.fResourceProvider = args.fResourceProvider;
drawArgs.fPipelineBuilder = args.fPipelineBuilder;
drawArgs.fColor = 0xFFFFFFFF;
drawArgs.fViewMatrix = args.fViewMatrix;
drawArgs.fPath = args.fPath;
drawArgs.fStroke = args.fStroke;
drawArgs.fAntiAlias = false;
this->drawPath(drawArgs);
}
typedef SkRefCnt INHERITED;
};

View File

@ -60,7 +60,14 @@ GrPathRenderer* GrPathRendererChain::getPathRenderer(const GrDrawTarget* target,
for (int i = 0; i < fChain.count(); ++i) {
if (fChain[i]->canDrawPath(target, pipelineBuilder, viewMatrix, path, stroke, antiAlias)) {
GrPathRenderer::CanDrawPathArgs args;
args.fTarget = target;
args.fPipelineBuilder = pipelineBuilder;
args.fViewMatrix = &viewMatrix;
args.fPath = &path;
args.fStroke = &stroke;
args.fAntiAlias = antiAlias;
if (fChain[i]->canDrawPath(args)) {
if (GrPathRenderer::kNoSupport_StencilSupport != minStencilSupport) {
GrPathRenderer::StencilSupport support =
fChain[i]->getStencilSupport(target, pipelineBuilder, path, stroke);

View File

@ -12,16 +12,11 @@
#include "GrVertexBuffer.h"
////////////////////////////////////////////////////////////////////////////////
bool GrSoftwarePathRenderer::canDrawPath(const GrDrawTarget*,
const GrPipelineBuilder*,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStrokeInfo& stroke,
bool antiAlias) const {
bool GrSoftwarePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
if (NULL == fContext) {
return false;
}
if (stroke.isDashed()) {
if (args.fStroke->isDashed()) {
return false;
}
return true;
@ -117,41 +112,35 @@ void draw_around_inv_path(GrDrawTarget* target,
////////////////////////////////////////////////////////////////////////////////
// return true on success; false on failure
bool GrSoftwarePathRenderer::onDrawPath(GrDrawTarget* target,
GrPipelineBuilder* pipelineBuilder,
GrColor color,
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& stroke,
bool antiAlias) {
bool GrSoftwarePathRenderer::onDrawPath(const DrawPathArgs& args) {
if (NULL == fContext) {
return false;
}
SkIRect devPathBounds, devClipBounds;
if (!get_path_and_clip_bounds(target, pipelineBuilder, path, viewMatrix, &devPathBounds,
&devClipBounds)) {
if (path.isInverseFillType()) {
draw_around_inv_path(target, pipelineBuilder, color, viewMatrix, devClipBounds,
devPathBounds);
if (!get_path_and_clip_bounds(args.fTarget, args.fPipelineBuilder, *args.fPath,
*args.fViewMatrix, &devPathBounds, &devClipBounds)) {
if (args.fPath->isInverseFillType()) {
draw_around_inv_path(args.fTarget, args.fPipelineBuilder, args.fColor,
*args.fViewMatrix, devClipBounds, devPathBounds);
}
return true;
}
SkAutoTUnref<GrTexture> texture(
GrSWMaskHelper::DrawPathMaskToTexture(fContext, path, stroke,
GrSWMaskHelper::DrawPathMaskToTexture(fContext, *args.fPath, *args.fStroke,
devPathBounds,
antiAlias, &viewMatrix));
args.fAntiAlias, args.fViewMatrix));
if (NULL == texture) {
return false;
}
GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, pipelineBuilder, color, viewMatrix,
devPathBounds);
GrSWMaskHelper::DrawToTargetWithPathMask(texture, args.fTarget, args.fPipelineBuilder,
args.fColor, *args.fViewMatrix, devPathBounds);
if (path.isInverseFillType()) {
draw_around_inv_path(target, pipelineBuilder, color, viewMatrix, devClipBounds,
devPathBounds);
if (args.fPath->isInverseFillType()) {
draw_around_inv_path(args.fTarget, args.fPipelineBuilder, args.fColor, *args.fViewMatrix,
devClipBounds, devPathBounds);
}
return true;

View File

@ -22,26 +22,15 @@ public:
GrSoftwarePathRenderer(GrContext* context)
: fContext(context) {
}
virtual bool canDrawPath(const GrDrawTarget*,
const GrPipelineBuilder*,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStrokeInfo&,
bool antiAlias) const override;
protected:
private:
virtual StencilSupport onGetStencilSupport(const GrDrawTarget*,
const GrPipelineBuilder*,
const SkPath&,
const GrStrokeInfo&) const override;
bool onCanDrawPath(const CanDrawPathArgs&) const override;
virtual bool onDrawPath(GrDrawTarget*,
GrPipelineBuilder*,
GrColor,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStrokeInfo&,
bool antiAlias) override;
bool onDrawPath(const DrawPathArgs&) override;
private:
GrContext* fContext;

View File

@ -45,20 +45,15 @@ GrStencilAndCoverPathRenderer::GrStencilAndCoverPathRenderer(GrResourceProvider*
: fResourceProvider(resourceProvider) {
}
bool GrStencilAndCoverPathRenderer::canDrawPath(const GrDrawTarget* target,
const GrPipelineBuilder* pipelineBuilder,
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& stroke,
bool antiAlias) const {
if (stroke.isHairlineStyle()) {
bool GrStencilAndCoverPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
if (args.fStroke->isHairlineStyle()) {
return false;
}
if (!pipelineBuilder->getStencil().isDisabled()) {
if (!args.fPipelineBuilder->getStencil().isDisabled()) {
return false;
}
if (antiAlias) {
return pipelineBuilder->getRenderTarget()->isStencilBufferMultisampled();
if (args.fAntiAlias) {
return args.fPipelineBuilder->getRenderTarget()->isStencilBufferMultisampled();
} else {
return true; // doesn't do per-path AA, relies on the target having MSAA
}
@ -90,33 +85,28 @@ static GrPath* get_gr_path(GrResourceProvider* resourceProvider, const SkPath& s
return path.detach();
}
void GrStencilAndCoverPathRenderer::onStencilPath(GrDrawTarget* target,
GrPipelineBuilder* pipelineBuilder,
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& stroke) {
SkASSERT(!path.isInverseFillType());
SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(GrColor_WHITE, viewMatrix));
SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, stroke));
target->stencilPath(*pipelineBuilder, pp, p, convert_skpath_filltype(path.getFillType()));
void GrStencilAndCoverPathRenderer::onStencilPath(const StencilPathArgs& args) {
SkASSERT(!args.fPath->isInverseFillType());
SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(GrColor_WHITE, *args.fViewMatrix));
SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, *args.fPath, *args.fStroke));
args.fTarget->stencilPath(*args.fPipelineBuilder, pp, p,
convert_skpath_filltype(args.fPath->getFillType()));
}
bool GrStencilAndCoverPathRenderer::onDrawPath(GrDrawTarget* target,
GrPipelineBuilder* pipelineBuilder,
GrColor color,
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& stroke,
bool antiAlias) {
SkASSERT(!stroke.isHairlineStyle());
bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) {
SkASSERT(!args.fStroke->isHairlineStyle());
const SkPath& path = *args.fPath;
GrPipelineBuilder* pipelineBuilder = args.fPipelineBuilder;
const SkMatrix& viewMatrix = *args.fViewMatrix;
SkASSERT(pipelineBuilder->getStencil().isDisabled());
if (antiAlias) {
if (args.fAntiAlias) {
SkASSERT(pipelineBuilder->getRenderTarget()->isStencilBufferMultisampled());
pipelineBuilder->enableState(GrPipelineBuilder::kHWAntialias_Flag);
}
SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, stroke));
SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, *args.fStroke));
if (path.isInverseFillType()) {
GR_STATIC_CONST_SAME_STENCIL(kInvertedStencilPass,
@ -134,7 +124,8 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(GrDrawTarget* target,
// fake inverse with a stencil and cover
SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(GrColor_WHITE, viewMatrix));
target->stencilPath(*pipelineBuilder, pp, p, convert_skpath_filltype(path.getFillType()));
args.fTarget->stencilPath(*pipelineBuilder, pp, p,
convert_skpath_filltype(path.getFillType()));
SkMatrix invert = SkMatrix::I();
SkRect bounds =
@ -154,7 +145,7 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(GrDrawTarget* target,
}
}
const SkMatrix& viewM = viewMatrix.hasPerspective() ? SkMatrix::I() : viewMatrix;
target->drawBWRect(*pipelineBuilder, color, viewM, bounds, NULL, &invert);
args.fTarget->drawBWRect(*pipelineBuilder, args.fColor, viewM, bounds, NULL, &invert);
} else {
GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
kZero_StencilOp,
@ -165,8 +156,9 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(GrDrawTarget* target,
0xffff);
pipelineBuilder->setStencil(kStencilPass);
SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(color, viewMatrix));
target->drawPath(*pipelineBuilder, pp, p, convert_skpath_filltype(path.getFillType()));
SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(args.fColor, viewMatrix));
args.fTarget->drawPath(*pipelineBuilder, pp, p,
convert_skpath_filltype(path.getFillType()));
}
pipelineBuilder->stencil()->setDisabled();

View File

@ -23,34 +23,19 @@ public:
static GrPathRenderer* Create(GrResourceProvider*, const GrCaps&);
bool canDrawPath(const GrDrawTarget*,
const GrPipelineBuilder*,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStrokeInfo&,
bool antiAlias) const override;
protected:
private:
StencilSupport onGetStencilSupport(const GrDrawTarget*,
const GrPipelineBuilder*,
const SkPath&,
const GrStrokeInfo&) const override;
bool onDrawPath(GrDrawTarget*,
GrPipelineBuilder*,
GrColor,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStrokeInfo&,
bool antiAlias) override;
bool onCanDrawPath(const CanDrawPathArgs&) const override;
void onStencilPath(GrDrawTarget*,
GrPipelineBuilder*,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStrokeInfo&) override;
bool onDrawPath(const DrawPathArgs&) override;
void onStencilPath(const StencilPathArgs&) override;
private:
GrStencilAndCoverPathRenderer(GrResourceProvider*);
GrResourceProvider* fResourceProvider;

View File

@ -1342,15 +1342,10 @@ GrPathRenderer::StencilSupport GrTessellatingPathRenderer::onGetStencilSupport(
return GrPathRenderer::kNoSupport_StencilSupport;
}
bool GrTessellatingPathRenderer::canDrawPath(const GrDrawTarget* target,
const GrPipelineBuilder* pipelineBuilder,
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& stroke,
bool antiAlias) const {
bool GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
// This path renderer can draw all fill styles, but does not do antialiasing. It can do convex
// and concave paths, but we'll leave the convex ones to simpler algorithms.
return stroke.isFillStyle() && !antiAlias && !path.isConvex();
return args.fStroke->isFillStyle() && !args.fAntiAlias && !args.fPath->isConvex();
}
class TessellatingPathBatch : public GrBatch {
@ -1489,29 +1484,24 @@ private:
GrPipelineInfo fPipelineInfo;
};
bool GrTessellatingPathRenderer::onDrawPath(GrDrawTarget* target,
GrPipelineBuilder* pipelineBuilder,
GrColor color,
const SkMatrix& viewM,
const SkPath& path,
const GrStrokeInfo&,
bool antiAlias) {
SkASSERT(!antiAlias);
const GrRenderTarget* rt = pipelineBuilder->getRenderTarget();
bool GrTessellatingPathRenderer::onDrawPath(const DrawPathArgs& args) {
SkASSERT(!args.fAntiAlias);
const GrRenderTarget* rt = args.fPipelineBuilder->getRenderTarget();
if (NULL == rt) {
return false;
}
SkIRect clipBoundsI;
pipelineBuilder->clip().getConservativeBounds(rt, &clipBoundsI);
args.fPipelineBuilder->clip().getConservativeBounds(rt, &clipBoundsI);
SkRect clipBounds = SkRect::Make(clipBoundsI);
SkMatrix vmi;
if (!viewM.invert(&vmi)) {
if (!args.fViewMatrix->invert(&vmi)) {
return false;
}
vmi.mapRect(&clipBounds);
SkAutoTUnref<GrBatch> batch(TessellatingPathBatch::Create(color, path, viewM, clipBounds));
target->drawBatch(*pipelineBuilder, batch);
SkAutoTUnref<GrBatch> batch(TessellatingPathBatch::Create(args.fColor, *args.fPath,
*args.fViewMatrix, clipBounds));
args.fTarget->drawBatch(*args.fPipelineBuilder, batch);
return true;
}

View File

@ -18,26 +18,15 @@ class SK_API GrTessellatingPathRenderer : public GrPathRenderer {
public:
GrTessellatingPathRenderer();
bool canDrawPath(const GrDrawTarget*,
const GrPipelineBuilder*,
const SkMatrix&,
const SkPath&,
const GrStrokeInfo&,
bool antiAlias) const override;
protected:
private:
bool onCanDrawPath(const CanDrawPathArgs& ) const override;
StencilSupport onGetStencilSupport(const GrDrawTarget*,
const GrPipelineBuilder*,
const SkPath&,
const GrStrokeInfo&) const override;
bool onDrawPath(GrDrawTarget*,
GrPipelineBuilder*,
GrColor,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStrokeInfo&,
bool antiAlias) override;
bool onDrawPath(const DrawPathArgs&) override;
typedef GrPathRenderer INHERITED;
};

View File

@ -23,6 +23,7 @@ public:
void init(GrContext*, GrDrawTarget*);
GrDrawTarget* target() { return fDrawTarget.get(); }
GrResourceProvider* resourceProvider() { return fContext->resourceProvider(); }
private:
SkAutoTUnref<GrDrawTarget> fDrawTarget;

View File

@ -232,12 +232,22 @@ static SkPath create_path_15() {
return path;
}
static void test_path(GrDrawTarget* dt, GrRenderTarget* rt, const SkPath& path) {
static void test_path(GrDrawTarget* dt, GrRenderTarget* rt, GrResourceProvider* rp,
const SkPath& path) {
GrTessellatingPathRenderer tess;
GrPipelineBuilder pipelineBuilder;
pipelineBuilder.setRenderTarget(rt);
GrStrokeInfo stroke(SkStrokeRec::kFill_InitStyle);
tess.drawPath(dt, &pipelineBuilder, SK_ColorWHITE, SkMatrix::I(), path, stroke, false);
GrPathRenderer::DrawPathArgs args;
args.fTarget = dt;
args.fPipelineBuilder = &pipelineBuilder;
args.fResourceProvider = rp;
args.fColor = GrColor_WHITE;
args.fViewMatrix = &SkMatrix::I();
args.fPath = &path;
args.fStroke = &stroke;
args.fAntiAlias = false;
tess.drawPath(args);
}
DEF_GPUTEST(TessellatingPathRendererTests, reporter, factory) {
@ -257,22 +267,23 @@ DEF_GPUTEST(TessellatingPathRendererTests, reporter, factory) {
context->getTestTarget(&tt);
GrRenderTarget* rt = texture->asRenderTarget();
GrDrawTarget* dt = tt.target();
GrResourceProvider* rp = tt.resourceProvider();
test_path(dt, rt, create_path_0());
test_path(dt, rt, create_path_1());
test_path(dt, rt, create_path_2());
test_path(dt, rt, create_path_3());
test_path(dt, rt, create_path_4());
test_path(dt, rt, create_path_5());
test_path(dt, rt, create_path_6());
test_path(dt, rt, create_path_7());
test_path(dt, rt, create_path_8());
test_path(dt, rt, create_path_9());
test_path(dt, rt, create_path_10());
test_path(dt, rt, create_path_11());
test_path(dt, rt, create_path_12());
test_path(dt, rt, create_path_13());
test_path(dt, rt, create_path_14());
test_path(dt, rt, create_path_15());
test_path(dt, rt, rp, create_path_0());
test_path(dt, rt, rp, create_path_1());
test_path(dt, rt, rp, create_path_2());
test_path(dt, rt, rp, create_path_3());
test_path(dt, rt, rp, create_path_4());
test_path(dt, rt, rp, create_path_5());
test_path(dt, rt, rp, create_path_6());
test_path(dt, rt, rp, create_path_7());
test_path(dt, rt, rp, create_path_8());
test_path(dt, rt, rp, create_path_9());
test_path(dt, rt, rp, create_path_10());
test_path(dt, rt, rp, create_path_11());
test_path(dt, rt, rp, create_path_12());
test_path(dt, rt, rp, create_path_13());
test_path(dt, rt, rp, create_path_14());
test_path(dt, rt, rp, create_path_15());
}
#endif