Late creation of GrPathProcessor
authorjoshualitt <joshualitt@chromium.org>
Thu, 10 Sep 2015 18:00:51 +0000 (11:00 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 10 Sep 2015 18:00:51 +0000 (11:00 -0700)
BUG=skia:

Review URL: https://codereview.chromium.org/1337513002

include/gpu/GrDrawContext.h
src/gpu/GrDrawContext.cpp
src/gpu/GrDrawTarget.cpp
src/gpu/GrDrawTarget.h
src/gpu/GrPathProcessor.cpp
src/gpu/GrPathProcessor.h
src/gpu/GrStencilAndCoverTextContext.cpp
src/gpu/batches/GrDrawPathBatch.cpp
src/gpu/batches/GrDrawPathBatch.h
src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
src/gpu/gl/GrGLPathProcessor.cpp

index aae4bf00b36aab05047d2953635d4bd35bc350ba..97cb72a7f2e530166874b8998dd132b5a95653d1 100644 (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);
 
index 8068403e4ba3d40791a737716adbc0de986343c3..3d3be749d0668b5f95dadc6a01b629c738c0f934 100644 (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);
 }
 
index 7eaa8bc76219f5ecbbec22a6747da1f651c6cdf6..84f1e92003cae2c9468c55cfdc76bc5f5d5db923 100644 (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();
 }
index 15024cd95e94194a72e085588f41a4ae0f786c33..059c1b3ed20adbbf1ee39b00cf40b7493f25b0d0 100644 (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);
 
index b6f174d8015d0cfcda762a2f36db7cc7b81786a7..ca63eac53dc6474c4e22713325ff4d3d9d8285cb 100644 (file)
 #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>();
 }
 
index 2a101107f258e22d1c7eb92577453f883644cd9b..adf00577bfc46782791616adeb2a590315358197 100644 (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;
 };
index 7325f155cf7874c2a39b64e6786b10aa5d1de121..fbd32fc8561bb11b500eec9ca9188e903ecd4848 100644 (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;
     }
index 300024ee2f3deaf41d268c0e3abf4c32080efdad..3e4c863e33abfa406a037bc1bdfac55045ab59b9 100644 (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();
index 1156dc5e201f49961c821d4f10ee04cffb7cfef5..dee4d991523150e1740e09feae70da829e188bfa 100644 (file)
 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;
 };
index 1a32e3fb75647c155f9ca97d74a9d4de4ccc7143..720c1c34f6544dc7aa7881e8806ee4a020f3cdce 100644 (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()));
     }
 
index b0ab10a4733ef4e3a50ae4467563ce552051d530..bbc3fe5d1d8c23ad6ee71dc58fb531ef8c9e213d 100644 (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();
     }
 }