diff --git a/include/gpu/GrDrawContext.h b/include/gpu/GrDrawContext.h index aae4bf00b3..97cb72a7f2 100644 --- a/include/gpu/GrDrawContext.h +++ b/include/gpu/GrDrawContext.h @@ -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); diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp index 8068403e4b..3d3be749d0 100644 --- a/src/gpu/GrDrawContext.cpp +++ b/src/gpu/GrDrawContext.cpp @@ -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); } diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index 7eaa8bc762..84f1e92003 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -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(); } diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index 15024cd95e..059c1b3ed2 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -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); diff --git a/src/gpu/GrPathProcessor.cpp b/src/gpu/GrPathProcessor.cpp index b6f174d801..ca63eac53d 100644 --- a/src/gpu/GrPathProcessor.cpp +++ b/src/gpu/GrPathProcessor.cpp @@ -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(); } diff --git a/src/gpu/GrPathProcessor.h b/src/gpu/GrPathProcessor.h index 2a101107f2..adf00577bf 100644 --- a/src/gpu/GrPathProcessor.h +++ b/src/gpu/GrPathProcessor.h @@ -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; }; diff --git a/src/gpu/GrStencilAndCoverTextContext.cpp b/src/gpu/GrStencilAndCoverTextContext.cpp index 7325f155cf..fbd32fc856 100644 --- a/src/gpu/GrStencilAndCoverTextContext.cpp +++ b/src/gpu/GrStencilAndCoverTextContext.cpp @@ -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 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; } diff --git a/src/gpu/batches/GrDrawPathBatch.cpp b/src/gpu/batches/GrDrawPathBatch.cpp index 300024ee2f..3e4c863e33 100644 --- a/src/gpu/batches/GrDrawPathBatch.cpp +++ b/src/gpu/batches/GrDrawPathBatch.cpp @@ -15,9 +15,13 @@ SkString GrDrawPathBatch::dumpInfo() const { void GrDrawPathBatch::onDraw(GrBatchFlushState* state) { GrProgramDesc desc; - state->gpu()->buildProgramDesc(&desc, *this->pathProcessor(), + + SkAutoTUnref 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(); 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 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(); diff --git a/src/gpu/batches/GrDrawPathBatch.h b/src/gpu/batches/GrDrawPathBatch.h index 1156dc5e20..dee4d99152 100644 --- a/src/gpu/batches/GrDrawPathBatch.h +++ b/src/gpu/batches/GrDrawPathBatch.h @@ -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(&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 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(); } @@ -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 DrawList; DrawList fDraws; int fTotalPathCount; + SkMatrix fLocalMatrix; typedef GrDrawPathBatchBase INHERITED; }; diff --git a/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp b/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp index 1a32e3fb75..720c1c34f6 100644 --- a/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp +++ b/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp @@ -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 pp(GrPathProcessor::Create(GrColor_WHITE, *args.fViewMatrix)); SkAutoTUnref 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 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 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())); } diff --git a/src/gpu/gl/GrGLPathProcessor.cpp b/src/gpu/gl/GrGLPathProcessor.cpp index b0ab10a473..bbc3fe5d1d 100644 --- a/src/gpu/gl/GrGLPathProcessor.cpp +++ b/src/gpu/gl/GrGLPathProcessor.cpp @@ -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(); + const GrPathProcessor& pathProc = args.fGP.cast(); // 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(); - 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(); - if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { + const GrPathProcessor& pathProc = primProc.cast(); + 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(); } }