Late creation of GrPathProcessor

BUG=skia:

Review URL: https://codereview.chromium.org/1337513002
This commit is contained in:
joshualitt 2015-09-10 11:00:51 -07:00 committed by Commit bot
parent 512be5340c
commit f238469b05
11 changed files with 96 additions and 65 deletions

View File

@ -64,7 +64,9 @@ public:
// drawPathsFromRange is thanks to GrStencilAndCoverTextContext
// TODO: remove once path batches can be created external to GrDrawTarget.
void drawPathsFromRange(const GrPipelineBuilder*,
const GrPathProcessor*,
const SkMatrix& viewMatrix,
const SkMatrix& localMatrix,
GrColor color,
GrPathRangeDraw* draw,
int /*GrPathRendering::FillType*/ fill);

View File

@ -112,10 +112,12 @@ void GrDrawContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, const S
}
void GrDrawContext::drawPathsFromRange(const GrPipelineBuilder* pipelineBuilder,
const GrPathProcessor* pathProc,
const SkMatrix& viewMatrix,
const SkMatrix& localMatrix,
GrColor color,
GrPathRangeDraw* draw,
int /*GrPathRendering::FillType*/ fill) {
fDrawTarget->drawPathsFromRange(*pipelineBuilder, pathProc, draw,
fDrawTarget->drawPathsFromRange(*pipelineBuilder, viewMatrix, localMatrix, color, draw,
(GrPathRendering::FillType) fill);
}

View File

@ -207,7 +207,7 @@ void GrDrawTarget::getPathStencilSettingsForFilltype(GrPathRendering::FillType f
}
void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder,
const GrPathProcessor* pathProc,
const SkMatrix& viewMatrix,
const GrPath* path,
GrPathRendering::FillType fill) {
// TODO: extract portions of checkDraw that are relevant to path stenciling.
@ -228,7 +228,7 @@ void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder,
GrStencilAttachment* sb = rt->renderTargetPriv().attachStencilAttachment();
this->getPathStencilSettingsForFilltype(fill, sb, &stencilSettings);
GrBatch* batch = GrStencilPathBatch::Create(pathProc->viewMatrix(),
GrBatch* batch = GrStencilPathBatch::Create(viewMatrix,
pipelineBuilder.isHWAntialias(),
stencilSettings, scissorState,
pipelineBuilder.getRenderTarget(),
@ -238,22 +238,25 @@ void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder,
}
void GrDrawTarget::drawPath(const GrPipelineBuilder& pipelineBuilder,
const GrPathProcessor* pathProc,
const SkMatrix& viewMatrix,
GrColor color,
const GrPath* path,
GrPathRendering::FillType fill) {
SkASSERT(path);
SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport());
GrDrawPathBatchBase* batch = GrDrawPathBatch::Create(pathProc, path);
GrDrawPathBatchBase* batch = GrDrawPathBatch::Create(viewMatrix, color, path);
this->drawPathBatch(pipelineBuilder, batch, fill);
batch->unref();
}
void GrDrawTarget::drawPathsFromRange(const GrPipelineBuilder& pipelineBuilder,
const GrPathProcessor* pathProc,
const SkMatrix& viewMatrix,
const SkMatrix& localMatrix,
GrColor color,
GrPathRangeDraw* draw,
GrPathRendering::FillType fill) {
GrDrawPathBatchBase* batch = GrDrawPathRangeBatch::Create(pathProc, draw);
GrDrawPathBatchBase* batch = GrDrawPathRangeBatch::Create(viewMatrix, localMatrix, color, draw);
this->drawPathBatch(pipelineBuilder, batch, fill);
batch->unref();
}

View File

@ -69,7 +69,7 @@ public:
* on the GrPipelineBuilder (if possible in the 3D API). Note, we will never have an inverse
* fill with stencil path
*/
void stencilPath(const GrPipelineBuilder&, const GrPathProcessor*, const GrPath*,
void stencilPath(const GrPipelineBuilder&, const SkMatrix& viewMatrix, const GrPath*,
GrPathRendering::FillType);
/**
@ -78,8 +78,8 @@ public:
*
* TODO: Remove this function and construct the batch outside GrDrawTarget.
*/
void drawPath(const GrPipelineBuilder&, const GrPathProcessor*, const GrPath*,
GrPathRendering::FillType);
void drawPath(const GrPipelineBuilder&, const SkMatrix& viewMatrix, GrColor color,
const GrPath*, GrPathRendering::FillType);
/**
* Draws the aggregate path from combining multiple. Note that this will not
@ -94,7 +94,9 @@ public:
* @param fill Fill type for drawing all the paths
*/
void drawPathsFromRange(const GrPipelineBuilder&,
const GrPathProcessor*,
const SkMatrix& viewMatrix,
const SkMatrix& localMatrix,
GrColor color,
GrPathRangeDraw* draw,
GrPathRendering::FillType fill);

View File

@ -13,12 +13,14 @@
#include "glsl/GrGLSLCaps.h"
GrPathProcessor::GrPathProcessor(GrColor color,
const GrPipelineOptimizations& opts,
const SkMatrix& viewMatrix,
const SkMatrix& localMatrix)
: INHERITED(true)
, fColor(color)
, fViewMatrix(viewMatrix)
, fLocalMatrix(localMatrix) {
, fLocalMatrix(localMatrix)
, fOpts(opts) {
this->initClassID<GrPathProcessor>();
}

View File

@ -24,9 +24,10 @@ struct PathBatchTracker {
class GrPathProcessor : public GrPrimitiveProcessor {
public:
static GrPathProcessor* Create(GrColor color,
const GrPipelineOptimizations& opts,
const SkMatrix& viewMatrix = SkMatrix::I(),
const SkMatrix& localMatrix = SkMatrix::I()) {
return new GrPathProcessor(color, viewMatrix, localMatrix);
return new GrPathProcessor(color, opts, viewMatrix, localMatrix);
}
void initBatchTracker(GrBatchTracker*, const GrPipelineOptimizations&) const override;
@ -41,7 +42,6 @@ public:
const SkMatrix& viewMatrix() const { return fViewMatrix; }
const SkMatrix& localMatrix() const { return fLocalMatrix; }
void getInvariantOutputColor(GrInitInvariantOutput* out) const override;
void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override;
@ -56,14 +56,18 @@ public:
bool hasTransformedLocalCoords() const override { return false; }
const GrPipelineOptimizations& opts() const { return fOpts; }
private:
GrPathProcessor(GrColor color, const SkMatrix& viewMatrix, const SkMatrix& localMatrix);
GrPathProcessor(GrColor color, const GrPipelineOptimizations& opts,
const SkMatrix& viewMatrix, const SkMatrix& localMatrix);
bool hasExplicitLocalCoords() const override { return false; }
GrColor fColor;
const SkMatrix fViewMatrix;
const SkMatrix fLocalMatrix;
GrPipelineOptimizations fOpts;
typedef GrPrimitiveProcessor INHERITED;
};

View File

@ -427,9 +427,6 @@ static const SkScalar* get_xy_scalar_array(const SkPoint* pointArray) {
void GrStencilAndCoverTextContext::flush(GrDrawContext* dc) {
if (fDraw) {
SkASSERT(fDraw->count());
SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(fPaint.getColor(),
fViewMatrix,
fLocalMatrix));
// We should only be flushing about once every run. However, if this impacts performance
// we could move the creation of the GrPipelineBuilder earlier.
@ -447,7 +444,8 @@ void GrStencilAndCoverTextContext::flush(GrDrawContext* dc) {
*pipelineBuilder.stencil() = kStencilPass;
dc->drawPathsFromRange(&pipelineBuilder, pp, fDraw, GrPathRendering::kWinding_FillType);
dc->drawPathsFromRange(&pipelineBuilder, fViewMatrix, fLocalMatrix, fPaint.getColor(),
fDraw, GrPathRendering::kWinding_FillType);
fDraw->unref();
fDraw = nullptr;
}

View File

@ -15,9 +15,13 @@ SkString GrDrawPathBatch::dumpInfo() const {
void GrDrawPathBatch::onDraw(GrBatchFlushState* state) {
GrProgramDesc desc;
state->gpu()->buildProgramDesc(&desc, *this->pathProcessor(),
SkAutoTUnref<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color(),
this->opts(),
this->viewMatrix()));
state->gpu()->buildProgramDesc(&desc, *pathProc,
*this->pipeline(), *this->tracker());
GrPathRendering::DrawPathArgs args(this->pathProcessor(), this->pipeline(),
GrPathRendering::DrawPathArgs args(pathProc, this->pipeline(),
&desc, this->tracker(), &this->stencilSettings());
state->gpu()->pathRendering()->drawPath(args, fPath.get());
}
@ -52,10 +56,11 @@ bool GrDrawPathRangeBatch::isWinding() const {
return isWinding;
}
GrDrawPathRangeBatch::GrDrawPathRangeBatch(const GrPathProcessor* pathProc,
GrPathRangeDraw* pathRangeDraw)
: INHERITED(pathProc)
, fDraws(4) {
GrDrawPathRangeBatch::GrDrawPathRangeBatch(const SkMatrix& viewMatrix, const SkMatrix& localMatrix,
GrColor color, GrPathRangeDraw* pathRangeDraw)
: INHERITED(viewMatrix, color)
, fDraws(4)
, fLocalMatrix(localMatrix) {
SkDEBUGCODE(pathRangeDraw->fUsedInBatch = true;)
this->initClassID<GrDrawPathRangeBatch>();
fDraws.addToHead(SkRef(pathRangeDraw));
@ -75,8 +80,9 @@ bool GrDrawPathRangeBatch::onCombineIfPossible(GrBatch* t, const GrCaps& caps) {
if (!GrPipeline::AreEqual(*this->pipeline(), *that->pipeline(), false)) {
return false;
}
if (!this->pathProcessor()->isEqual(*this->tracker(), *that->pathProcessor(),
*that->tracker())) {
if (this->color() != that->color() ||
!this->viewMatrix().cheapEqualTo(that->viewMatrix()) ||
!fLocalMatrix.cheapEqualTo(that->fLocalMatrix)) {
return false;
}
// TODO: Check some other things here. (winding, opaque, pathProc color, vm, ...)
@ -103,9 +109,13 @@ bool GrDrawPathRangeBatch::onCombineIfPossible(GrBatch* t, const GrCaps& caps) {
void GrDrawPathRangeBatch::onDraw(GrBatchFlushState* state) {
GrProgramDesc desc;
state->gpu()->buildProgramDesc(&desc, *this->pathProcessor(), *this->pipeline(),
*this->tracker());
GrPathRendering::DrawPathArgs args(this->pathProcessor(), this->pipeline(),
SkAutoTUnref<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color(),
this->opts(),
this->viewMatrix(),
fLocalMatrix));
state->gpu()->buildProgramDesc(&desc, *pathProc, *this->pipeline(),
*this->tracker());
GrPathRendering::DrawPathArgs args(pathProc, this->pipeline(),
&desc, this->tracker(), &this->stencilSettings());
if (fDraws.count() == 1) {
const GrPathRangeDraw& draw = **fDraws.head();

View File

@ -20,42 +20,51 @@
class GrDrawPathBatchBase : public GrDrawBatch {
public:
void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
this->pathProcessor()->getInvariantOutputColor(out);
out->setKnownFourComponents(fColor);
}
void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
this->pathProcessor()->getInvariantOutputCoverage(out);
out->setKnownSingleComponent(0xff);
}
void setStencilSettings(const GrStencilSettings& stencil) { fStencilSettings = stencil; }
protected:
GrDrawPathBatchBase(const GrPathProcessor* pathProc) : fPrimitiveProcessor(pathProc) {}
GrDrawPathBatchBase(const SkMatrix& viewMatrix, GrColor initialColor)
: fViewMatrix(viewMatrix)
, fColor(initialColor) {}
GrBatchTracker* tracker() { return reinterpret_cast<GrBatchTracker*>(&fWhatchamacallit); }
const GrPathProcessor* pathProcessor() const { return fPrimitiveProcessor.get(); }
const GrStencilSettings& stencilSettings() const { return fStencilSettings; }
const GrPipelineOptimizations& opts() const { return fOpts; }
const SkMatrix& viewMatrix() const { return fViewMatrix; }
GrColor color() const { return fColor; }
// TODO delete
const GrBatchTracker* tracker() const { return &fBatchTracker; }
private:
void initBatchTracker(const GrPipelineOptimizations& opts) override {
this->pathProcessor()->initBatchTracker(this->tracker(), opts);
opts.getOverrideColorIfSet(&fColor);
fOpts = opts;
}
GrPendingProgramElement<const GrPathProcessor> fPrimitiveProcessor;
PathBatchTracker fWhatchamacallit; // TODO: delete this
SkMatrix fViewMatrix;
GrColor fColor;
GrStencilSettings fStencilSettings;
GrPipelineOptimizations fOpts;
// TODO delete
GrBatchTracker fBatchTracker;
typedef GrDrawBatch INHERITED;
};
class GrDrawPathBatch final : public GrDrawPathBatchBase {
public:
// This can't return a more abstract type because we install the stencil settings late :(
static GrDrawPathBatchBase* Create(const GrPathProcessor* primProc, const GrPath* path) {
return new GrDrawPathBatch(primProc, path);
static GrDrawPathBatchBase* Create(const SkMatrix& viewMatrix, GrColor color,
const GrPath* path) {
return new GrDrawPathBatch(viewMatrix, color, path);
}
const char* name() const override { return "DrawPath"; }
@ -63,11 +72,11 @@ public:
SkString dumpInfo() const override;
private:
GrDrawPathBatch(const GrPathProcessor* pathProc, const GrPath* path)
: INHERITED(pathProc)
GrDrawPathBatch(const SkMatrix& viewMatrix, GrColor color, const GrPath* path)
: INHERITED(viewMatrix, color)
, fPath(path) {
fBounds = path->getBounds();
this->pathProcessor()->viewMatrix().mapRect(&fBounds);
viewMatrix.mapRect(&fBounds);
this->initClassID<GrDrawPathBatch>();
}
@ -145,9 +154,9 @@ private:
class GrDrawPathRangeBatch final : public GrDrawPathBatchBase {
public:
// This can't return a more abstracet type because we install the stencil settings late :(
static GrDrawPathBatchBase* Create(const GrPathProcessor* pathProc,
GrPathRangeDraw* pathRangeDraw) {
return SkNEW_ARGS(GrDrawPathRangeBatch, (pathProc, pathRangeDraw));
static GrDrawPathBatchBase* Create(const SkMatrix& viewMatrix, const SkMatrix& localMatrix,
GrColor color, GrPathRangeDraw* pathRangeDraw) {
return SkNEW_ARGS(GrDrawPathRangeBatch, (viewMatrix, localMatrix, color, pathRangeDraw));
}
~GrDrawPathRangeBatch() override;
@ -159,7 +168,8 @@ public:
private:
inline bool isWinding() const;
GrDrawPathRangeBatch(const GrPathProcessor* pathProc, GrPathRangeDraw* pathRangeDraw);
GrDrawPathRangeBatch(const SkMatrix& viewMatrix, const SkMatrix& localMatrix, GrColor color,
GrPathRangeDraw* pathRangeDraw);
bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override;
@ -170,6 +180,7 @@ private:
typedef SkTLList<GrPathRangeDraw*> DrawList;
DrawList fDraws;
int fTotalPathCount;
SkMatrix fLocalMatrix;
typedef GrDrawPathBatchBase INHERITED;
};

View File

@ -79,9 +79,8 @@ static GrPath* get_gr_path(GrResourceProvider* resourceProvider, const SkPath& s
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,
args.fTarget->stencilPath(*args.fPipelineBuilder, *args.fViewMatrix, p,
convert_skpath_filltype(args.fPath->getFillType()));
}
@ -115,8 +114,7 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) {
pipelineBuilder->setStencil(kInvertedStencilPass);
// fake inverse with a stencil and cover
SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(GrColor_WHITE, viewMatrix));
args.fTarget->stencilPath(*pipelineBuilder, pp, p,
args.fTarget->stencilPath(*pipelineBuilder, viewMatrix, p,
convert_skpath_filltype(path.getFillType()));
SkMatrix invert = SkMatrix::I();
@ -148,8 +146,7 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) {
0xffff);
pipelineBuilder->setStencil(kStencilPass);
SkAutoTUnref<GrPathProcessor> pp(GrPathProcessor::Create(args.fColor, viewMatrix));
args.fTarget->drawPath(*pipelineBuilder, pp, p,
args.fTarget->drawPath(*pipelineBuilder, viewMatrix, args.fColor, p,
convert_skpath_filltype(path.getFillType()));
}

View File

@ -17,13 +17,13 @@ GrGLPathProcessor::GrGLPathProcessor(const GrPathProcessor&, const GrBatchTracke
void GrGLPathProcessor::emitCode(EmitArgs& args) {
GrGLGPBuilder* pb = args.fPB;
GrGLFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder();
const PathBatchTracker& local = args.fBT.cast<PathBatchTracker>();
const GrPathProcessor& pathProc = args.fGP.cast<GrPathProcessor>();
// emit transforms
this->emitTransforms(args.fPB, args.fTransformsIn, args.fTransformsOut);
// Setup uniform color
if (kUniform_GrGPInput == local.fInputColorType) {
if (pathProc.opts().readsColor()) {
const char* stagedLocalVarName;
fColorUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kVec4f_GrSLType,
@ -34,28 +34,28 @@ void GrGLPathProcessor::emitCode(EmitArgs& args) {
}
// setup constant solid coverage
if (kAllOnes_GrGPInput == local.fInputCoverageType) {
if (pathProc.opts().readsCoverage()) {
fs->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
}
}
void GrGLPathProcessor::GenKey(const GrPathProcessor&,
void GrGLPathProcessor::GenKey(const GrPathProcessor& pathProc,
const GrBatchTracker& bt,
const GrGLSLCaps&,
GrProcessorKeyBuilder* b) {
const PathBatchTracker& local = bt.cast<PathBatchTracker>();
b->add32(local.fInputColorType | local.fInputCoverageType << 16);
b->add32(SkToInt(pathProc.opts().readsColor()) |
SkToInt(pathProc.opts().readsCoverage()) << 16);
}
void GrGLPathProcessor::setData(const GrGLProgramDataManager& pdman,
const GrPrimitiveProcessor& primProc,
const GrBatchTracker& bt) {
const PathBatchTracker& local = bt.cast<PathBatchTracker>();
if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
if (pathProc.opts().readsColor() && pathProc.color() != fColor) {
GrGLfloat c[4];
GrColorToRGBAFloat(local.fColor, c);
GrColorToRGBAFloat(pathProc.color(), c);
pdman.set4fv(fColorUniform, 1, c);
fColor = local.fColor;
fColor = pathProc.color();
}
}