simplify GrPathRenderer interface
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 2 Mar 2012 21:26:50 +0000 (21:26 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 2 Mar 2012 21:26:50 +0000 (21:26 +0000)
Review URL: http://codereview.appspot.com/5706053/

git-svn-id: http://skia.googlecode.com/svn/trunk@3312 2bbb7eff-a529-9590-31e7-b0007b416f81

16 files changed:
include/gpu/GrContext.h
src/gpu/GrAAConvexPathRenderer.cpp
src/gpu/GrAAConvexPathRenderer.h
src/gpu/GrAAHairLinePathRenderer.cpp
src/gpu/GrAAHairLinePathRenderer.h
src/gpu/GrContext.cpp
src/gpu/GrDefaultPathRenderer.cpp
src/gpu/GrDefaultPathRenderer.h
src/gpu/GrGpu.cpp
src/gpu/GrPathRenderer.cpp
src/gpu/GrPathRenderer.h
src/gpu/GrPathRendererChain.cpp
src/gpu/GrPathRendererChain.h
src/gpu/GrTesselatedPathRenderer.cpp
src/gpu/GrTesselatedPathRenderer.h
src/gpu/gl/GrGLVertexBuffer.cpp

index ffb5065..37160b1 100644 (file)
@@ -700,6 +700,7 @@ private:
 
     GrPathRenderer* getPathRenderer(const GrPath& path,
                                     GrPathFill fill,
+                                    const GrDrawTarget* target,
                                     bool antiAlias);
 
     /**
index d596284..60749d8 100644 (file)
 GrAAConvexPathRenderer::GrAAConvexPathRenderer() {
 }
 
-bool GrAAConvexPathRenderer::canDrawPath(const GrDrawTarget::Caps& targetCaps,
-                                         const SkPath& path,
-                                         GrPathFill fill,
-                                         bool antiAlias) const {
-    return targetCaps.fShaderDerivativeSupport && antiAlias &&
-           kHairLine_PathFill != fill && !GrIsFillInverted(fill) &&
-           path.isConvex();
-}
-
 namespace {
 
 struct Segment {
@@ -415,17 +406,38 @@ void create_vertices(const SegmentArray&  segments,
 
 }
 
-void GrAAConvexPathRenderer::drawPath(GrDrawState::StageMask stageMask) {
-    GrAssert(fPath->isConvex());
-    if (fPath->isEmpty()) {
-        return;
+bool GrAAConvexPathRenderer::canDrawPath(const SkPath& path,
+                                         GrPathFill fill,
+                                         const GrDrawTarget* target,
+                                         bool antiAlias) const {
+    if (!target->getCaps().fShaderDerivativeSupport || !antiAlias ||
+        kHairLine_PathFill == fill || GrIsFillInverted(fill) ||
+        !path.isConvex()) {
+        return false;
+    }  else {
+        return true;
+    }
+}
+
+bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath,
+                                        GrPathFill fill,
+                                        const GrVec* translate,
+                                        GrDrawTarget* target,
+                                        GrDrawState::StageMask stageMask,
+                                        bool antiAlias) {
+
+
+    if (origPath.isEmpty()) {
+        return true;
     }
-    GrDrawState* drawState = fTarget->drawState();
+    GrDrawState* drawState = target->drawState();
 
     GrDrawTarget::AutoStateRestore asr;
     GrMatrix vm = drawState->getViewMatrix();
-    vm.postTranslate(fTranslate.fX, fTranslate.fY);
-    asr.set(fTarget);
+    if (NULL != translate) {
+        vm.postTranslate(translate->fX, translate->fY);
+    }
+    asr.set(target);
     GrMatrix ivm;
     if (vm.invert(&ivm)) {
         drawState->preConcatSamplerMatrices(stageMask, ivm);
@@ -433,7 +445,7 @@ void GrAAConvexPathRenderer::drawPath(GrDrawState::StageMask stageMask) {
     drawState->setViewMatrix(GrMatrix::I());
 
     SkPath path;
-    fPath->transform(vm, &path);
+    origPath.transform(vm, &path);
 
     GrVertexLayout layout = 0;
     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
@@ -451,26 +463,27 @@ void GrAAConvexPathRenderer::drawPath(GrDrawState::StageMask stageMask) {
     SegmentArray segments;
     SkPoint fanPt;
     if (!get_segments(path, &segments, &fanPt, &vCount, &iCount)) {
-        return;
+        return false;
     }
 
-    if (!fTarget->reserveVertexSpace(layout,
-                                     vCount,
-                                     reinterpret_cast<void**>(&verts))) {
-        return;
+    if (!target->reserveVertexSpace(layout,
+                                    vCount,
+                                    reinterpret_cast<void**>(&verts))) {
+        return false;
     }
-    if (!fTarget->reserveIndexSpace(iCount, reinterpret_cast<void**>(&idxs))) {
-        fTarget->resetVertexSource();
-        return;
+    if (!target->reserveIndexSpace(iCount, reinterpret_cast<void**>(&idxs))) {
+        target->resetVertexSource();
+        return false;
     }
 
     create_vertices(segments, fanPt, verts, idxs);
 
     drawState->setVertexEdgeType(GrDrawState::kQuad_EdgeType);
-    fTarget->drawIndexed(kTriangles_PrimitiveType,
-                         0,        // start vertex
-                         0,        // start index
-                         vCount,
-                         iCount);
+    target->drawIndexed(kTriangles_PrimitiveType,
+                        0,        // start vertex
+                        0,        // start index
+                        vCount,
+                        iCount);
+    return true;
 }
 
index dff06c6..df0c001 100644 (file)
 class GrAAConvexPathRenderer : public GrPathRenderer {
 public:
     GrAAConvexPathRenderer();
-    bool canDrawPath(const GrDrawTarget::Caps& targetCaps,
-                                       const SkPath& path,
-                                       GrPathFill fill,
-                                       bool antiAlias) const;
-    void drawPath(GrDrawState::StageMask stageMask);
+
+    virtual bool canDrawPath(const SkPath& path,
+                             GrPathFill fill,
+                             const GrDrawTarget* target,
+                             bool antiAlias) const SK_OVERRIDE;
+protected:
+    virtual bool onDrawPath(const SkPath& path,
+                            GrPathFill fill,
+                            const GrVec* translate,
+                            GrDrawTarget* target,
+                            GrDrawState::StageMask stageMask,
+                            bool antiAlias) SK_OVERRIDE;
 };
index e11c12b..3ed4488 100644 (file)
@@ -99,7 +99,6 @@ GrAAHairLinePathRenderer::GrAAHairLinePathRenderer(
     linesIndexBuffer->ref();
     fQuadsIndexBuffer = quadsIndexBuffer;
     quadsIndexBuffer->ref();
-    this->resetGeom();
 }
 
 GrAAHairLinePathRenderer::~GrAAHairLinePathRenderer() {
@@ -107,33 +106,6 @@ GrAAHairLinePathRenderer::~GrAAHairLinePathRenderer() {
     fQuadsIndexBuffer->unref();
 }
 
-bool GrAAHairLinePathRenderer::canDrawPath(const GrDrawTarget::Caps& targetCaps,
-                                           const SkPath& path,
-                                           GrPathFill fill,
-                                           bool antiAlias) const {
-    static const uint32_t gReqDerivMask = SkPath::kCubic_SegmentMask |
-                                          SkPath::kQuad_SegmentMask;
-    return (kHairLine_PathFill == fill &&
-            antiAlias &&
-            (targetCaps.fShaderDerivativeSupport ||
-             !(gReqDerivMask & path.getSegmentMasks())));
-}
-
-void GrAAHairLinePathRenderer::pathWillClear() {
-    this->resetGeom();
-}
-
-void GrAAHairLinePathRenderer::resetGeom() {
-    fPreviousStages = ~0;
-    fPreviousRTHeight = ~0;
-    fPreviousViewMatrix = GrMatrix::InvalidMatrix();
-    fLineSegmentCnt = 0;
-    fQuadCnt = 0; 
-    if ((fQuadCnt || fLineSegmentCnt) && NULL != fTarget) {
-        fTarget->resetVertexSource();
-    }
-}
-
 namespace {
 
 typedef SkTArray<SkPoint, true> PtArray;
@@ -528,28 +500,23 @@ void add_line(const SkPoint p[2],
 
 }
 
-bool GrAAHairLinePathRenderer::createGeom(GrDrawState::StageMask stageMask) {
-    const GrDrawState& drawState = fTarget->getDrawState();
+bool GrAAHairLinePathRenderer::createGeom(const SkPath& path,
+                                          const GrVec* translate,
+                                          GrDrawTarget* target,
+                                          GrDrawState::StageMask stageMask,
+                                          int* lineCnt,
+                                          int* quadCnt) {
+    const GrDrawState& drawState = target->getDrawState();
     int rtHeight = drawState.getRenderTarget()->height();
 
     GrIRect clip;
-    if (fTarget->getClip().hasConservativeBounds()) {
-        GrRect clipRect =  fTarget->getClip().getConservativeBounds();
+    if (target->getClip().hasConservativeBounds()) {
+        GrRect clipRect =  target->getClip().getConservativeBounds();
         clipRect.roundOut(&clip);
     } else {
         clip.setLargest();
     }
 
-    // If none of the inputs that affect generation of path geometry have
-    // have changed since last previous path draw then we can reuse the
-    // previous geoemtry.
-    if (stageMask == fPreviousStages &&
-        fPreviousViewMatrix == drawState.getViewMatrix() &&
-        fPreviousTranslate == fTranslate &&
-        rtHeight == fPreviousRTHeight &&
-        fClipRect == clip) {
-        return true;
-    }
 
     GrVertexLayout layout = GrDrawTarget::kEdge_VertexLayoutBit;
     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
@@ -563,16 +530,20 @@ bool GrAAHairLinePathRenderer::createGeom(GrDrawState::StageMask stageMask) {
     PREALLOC_PTARRAY(128) lines;
     PREALLOC_PTARRAY(128) quads;
     IntArray qSubdivs;
-    fQuadCnt = generate_lines_and_quads(*fPath, viewM, fTranslate, clip,
+    static const GrVec gZeroVec = {0, 0};
+    if (NULL == translate) {
+        translate = &gZeroVec;
+    }
+    *quadCnt = generate_lines_and_quads(path, viewM, *translate, clip,
                                         &lines, &quads, &qSubdivs);
 
-    fLineSegmentCnt = lines.count() / 2;
-    int vertCnt = kVertsPerLineSeg * fLineSegmentCnt + kVertsPerQuad * fQuadCnt;
+    *lineCnt = lines.count() / 2;
+    int vertCnt = kVertsPerLineSeg * *lineCnt + kVertsPerQuad * *quadCnt;
 
     GrAssert(sizeof(Vertex) == GrDrawTarget::VertexSize(layout));
 
     Vertex* verts;
-    if (!fTarget->reserveVertexSpace(layout, vertCnt, (void**)&verts)) {
+    if (!target->reserveVertexSpace(layout, vertCnt, (void**)&verts)) {
         return false;
     }
 
@@ -587,7 +558,7 @@ bool GrAAHairLinePathRenderer::createGeom(GrDrawState::StageMask stageMask) {
         }
     }
 
-    for (int i = 0; i < fLineSegmentCnt; ++i) {
+    for (int i = 0; i < *lineCnt; ++i) {
         add_line(&lines[2*i], rtHeight, toSrc, &verts);
     }
 
@@ -597,25 +568,50 @@ bool GrAAHairLinePathRenderer::createGeom(GrDrawState::StageMask stageMask) {
         add_quads(&quads[3*i], qSubdivs[i], toDevice, toSrc, &verts);
     }
 
-    fPreviousStages = stageMask;
-    fPreviousViewMatrix = drawState.getViewMatrix();
-    fPreviousRTHeight = rtHeight;
-    fClipRect = clip;
-    fPreviousTranslate = fTranslate;
     return true;
 }
 
-void GrAAHairLinePathRenderer::drawPath(GrDrawState::StageMask stageMask) {
+bool GrAAHairLinePathRenderer::canDrawPath(const SkPath& path,
+                                           GrPathFill fill,
+                                           const GrDrawTarget* target,
+                                           bool antiAlias) const {
+    if (fill != kHairLine_PathFill || !antiAlias) {
+        return false;
+    }
+
+    static const uint32_t gReqDerivMask = SkPath::kCubic_SegmentMask |
+                                          SkPath::kQuad_SegmentMask;
+    if (!target->getCaps().fShaderDerivativeSupport &&
+        (gReqDerivMask & path.getSegmentMasks())) {
+        return false;
+    }
+    return true;
+}
 
-    if (!this->createGeom(stageMask)) {
-        return;
+bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path,
+                                          GrPathFill fill,
+                                          const GrVec* translate,
+                                          GrDrawTarget* target,
+                                          GrDrawState::StageMask stageMask,
+                                          bool antiAlias) {
+
+    int lineCnt;
+    int quadCnt;
+
+    if (!this->createGeom(path,
+                          translate,
+                          target,
+                          stageMask,
+                          &lineCnt,
+                          &quadCnt)) {
+        return false;
     }
 
-    GrDrawState* drawState = fTarget->drawState();
+    GrDrawState* drawState = target->drawState();
 
     GrDrawTarget::AutoStateRestore asr;
     if (!drawState->getViewMatrix().hasPerspective()) {
-        asr.set(fTarget);
+        asr.set(target);
         GrMatrix ivm;
         if (drawState->getViewInverse(&ivm)) {
             drawState->preConcatSamplerMatrices(stageMask, ivm);
@@ -625,32 +621,32 @@ void GrAAHairLinePathRenderer::drawPath(GrDrawState::StageMask stageMask) {
 
     // TODO: See whether rendering lines as degenerate quads improves perf
     // when we have a mix
-    fTarget->setIndexSourceToBuffer(fLinesIndexBuffer);
+    target->setIndexSourceToBuffer(fLinesIndexBuffer);
     int lines = 0;
     int nBufLines = fLinesIndexBuffer->maxQuads();
-    while (lines < fLineSegmentCnt) {
-        int n = GrMin(fLineSegmentCnt-lines, nBufLines);
+    while (lines < lineCnt) {
+        int n = GrMin(lineCnt - lines, nBufLines);
         drawState->setVertexEdgeType(GrDrawState::kHairLine_EdgeType);
-        fTarget->drawIndexed(kTriangles_PrimitiveType,
-                             kVertsPerLineSeg*lines,    // startV
-                             0,                         // startI
-                             kVertsPerLineSeg*n,        // vCount
-                             kIdxsPerLineSeg*n);        // iCount
+        target->drawIndexed(kTriangles_PrimitiveType,
+                            kVertsPerLineSeg*lines,    // startV
+                            0,                         // startI
+                            kVertsPerLineSeg*n,        // vCount
+                            kIdxsPerLineSeg*n);        // iCount
         lines += n;
     }
 
-    fTarget->setIndexSourceToBuffer(fQuadsIndexBuffer);
+    target->setIndexSourceToBuffer(fQuadsIndexBuffer);
     int quads = 0;
-    while (quads < fQuadCnt) {
-        int n = GrMin(fQuadCnt-quads, kNumQuadsInIdxBuffer);
+    while (quads < quadCnt) {
+        int n = GrMin(quadCnt - quads, kNumQuadsInIdxBuffer);
         drawState->setVertexEdgeType(GrDrawState::kHairQuad_EdgeType);
-        fTarget->drawIndexed(kTriangles_PrimitiveType,
-                             4*fLineSegmentCnt + kVertsPerQuad*quads, // startV
-                             0,                                       // startI
-                             kVertsPerQuad*n,                         // vCount
-                             kIdxsPerQuad*n);                         // iCount
+        target->drawIndexed(kTriangles_PrimitiveType,
+                            4 * lineCnt + kVertsPerQuad*quads, // startV
+                            0,                                 // startI
+                            kVertsPerQuad*n,                   // vCount
+                            kIdxsPerQuad*n);                   // iCount
         quads += n;
     }
-
+    return true;
 }
 
index 3b29919..33b7332 100644 (file)
@@ -16,41 +16,35 @@ public:
     virtual ~GrAAHairLinePathRenderer();
 
     static GrPathRenderer* Create(GrContext* context);
-    // GrPathRenderer overrides
-    virtual bool canDrawPath(const GrDrawTarget::Caps& targetCaps,
-                             const SkPath& path,
-                             GrPathFill fill,
-                             bool antiAlias) const  SK_OVERRIDE;
-    virtual void drawPath(GrDrawState::StageMask stages) SK_OVERRIDE;
 
+    virtual bool canDrawPath(const SkPath& path,
+                            GrPathFill fill,
+                            const GrDrawTarget* target,
+                            bool antiAlias) const SK_OVERRIDE;
 protected:
-
-    // GrPathRenderer overrides
-    virtual void pathWillClear()  SK_OVERRIDE;
-
+    virtual bool onDrawPath(const SkPath& path,
+                            GrPathFill fill,
+                            const GrVec* translate,
+                            GrDrawTarget* target,
+                            GrDrawState::StageMask stageMask,
+                            bool antiAlias) SK_OVERRIDE;
 private:
-    void resetGeom();
 
     GrAAHairLinePathRenderer(const GrContext* context,
                              const GrIndexBuffer* fLinesIndexBuffer,
                              const GrIndexBuffer* fQuadsIndexBuffer);
 
-    bool createGeom(GrDrawState::StageMask stages);
+    bool createGeom(const SkPath& path,
+                    const GrVec* translate,
+                    GrDrawTarget* target,
+                    GrDrawState::StageMask stageMask,
+                    int* lineCnt,
+                    int* quadCnt);
 
     const GrIndexBuffer*        fLinesIndexBuffer;
     const GrIndexBuffer*        fQuadsIndexBuffer;
 
-    // have to recreate geometry if stages in use changes :(
-    GrDrawState::StageMask      fPreviousStages;
-    int                         fPreviousRTHeight;
-    SkVector                    fPreviousTranslate;
-    GrIRect                     fClipRect;
-
-    // this path renderer draws everything in device coordinates
-    GrMatrix                    fPreviousViewMatrix;
-    int                         fLineSegmentCnt;
-    int                         fQuadCnt;
-
     typedef GrPathRenderer INHERITED;
 };
 
index d6ebada..2a12399 100644 (file)
@@ -1381,7 +1381,7 @@ void GrContext::drawPath(const GrPaint& paint, const GrPath& path,
 
     GrPathRenderer* pr = NULL;
     if (prAA) {
-        pr = this->getPathRenderer(path, fill, true);
+        pr = this->getPathRenderer(path, fill, target, true);
         if (NULL == pr) {
             GrAutoScratchTexture ast;
             GrIRect pathBounds, clipBounds;
@@ -1422,7 +1422,7 @@ void GrContext::drawPath(const GrPaint& paint, const GrPath& path,
             }
         }
     } else {
-        pr = this->getPathRenderer(path, fill, false);
+        pr = this->getPathRenderer(path, fill, target, false);
     }
 
     if (NULL == pr) {
@@ -1432,9 +1432,7 @@ void GrContext::drawPath(const GrPaint& paint, const GrPath& path,
         return;
     }
 
-    GrPathRenderer::AutoClearPath arp(pr, target, &path, fill, prAA, translate);
-
-    pr->drawPath(stageMask);
+    pr->drawPath(path, fill, translate, target, stageMask, prAA);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1884,13 +1882,13 @@ GrDrawTarget* GrContext::prepareToDraw(const GrPaint& paint,
 
 GrPathRenderer* GrContext::getPathRenderer(const GrPath& path,
                                            GrPathFill fill,
+                                           const GrDrawTarget* target,
                                            bool antiAlias) {
     if (NULL == fPathRendererChain) {
         fPathRendererChain = 
             new GrPathRendererChain(this, GrPathRendererChain::kNone_UsageFlag);
     }
-    return fPathRendererChain->getPathRenderer(fGpu->getCaps(), path,
-                                               fill, antiAlias);
+    return fPathRendererChain->getPathRenderer(path, fill, target, antiAlias);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
index 51cbde0..72b3c60 100644 (file)
 GrDefaultPathRenderer::GrDefaultPathRenderer(bool separateStencilSupport,
                                              bool stencilWrapOpsSupport)
     : fSeparateStencil(separateStencilSupport)
-    , fStencilWrapOps(stencilWrapOpsSupport)
-    , fSubpathCount(0)
-    , fSubpathVertCount(0)
-    , fPreviousSrcTol(-GR_Scalar1)
-    , fPreviousStages(-1) {
-    fTarget = NULL;
-}
-
-bool GrDefaultPathRenderer::canDrawPath(const GrDrawTarget::Caps& targetCaps,
-                                        const SkPath& path,
-                                        GrPathFill fill,
-                                        bool antiAlias) const {
-    // this class can draw any path with any fill but doesn't do any 
-    // anti-aliasing.
-    return !antiAlias; 
+    , fStencilWrapOps(stencilWrapOpsSupport) {
 }
 
 
@@ -175,22 +161,12 @@ static inline bool single_pass_path(const GrPath& path, GrPathFill fill) {
 #endif
 }
 
-bool GrDefaultPathRenderer::requiresStencilPass(const GrDrawTarget* target,
-                                                const GrPath& path,
-                                                GrPathFill fill) const {
+bool GrDefaultPathRenderer::requiresStencilPass(const SkPath& path,
+                                                GrPathFill fill,
+                                                const GrDrawTarget* target) const {
     return !single_pass_path(path, fill);
 }
 
-void GrDefaultPathRenderer::pathWillClear() {
-    fSubpathVertCount.reset(0);
-    fTarget->resetVertexSource();
-    if (fUseIndexedDraw) {
-        fTarget->resetIndexSource();
-    }
-    fPreviousSrcTol = -GR_Scalar1;
-    fPreviousStages = -1;
-}
-
 static inline void append_countour_edge_indices(GrPathFill fillType,
                                                 uint16_t fanCenterIdx,
                                                 uint16_t edgeV0Idx,
@@ -205,13 +181,21 @@ static inline void append_countour_edge_indices(GrPathFill fillType,
     *((*indices)++) = edgeV0Idx + 1;
 }
 
-bool GrDefaultPathRenderer::createGeom(GrScalar srcSpaceTol,
-                                       GrDrawState::StageMask stageMask) {
+bool GrDefaultPathRenderer::createGeom(const SkPath& path,
+                                       GrPathFill fill,
+                                       const GrVec* translate,
+                                       GrScalar srcSpaceTol,
+                                       GrDrawTarget* target,
+                                       GrDrawState::StageMask stageMask,
+                                       GrPrimitiveType* primType,
+                                       int* vertexCnt,
+                                       int* indexCnt) {
     {
     SK_TRACE_EVENT0("GrDefaultPathRenderer::createGeom");
 
     GrScalar srcSpaceTolSqd = GrMul(srcSpaceTol, srcSpaceTol);
-    int maxPts = GrPathUtils::worstCasePointCount(*fPath, &fSubpathCount,
+    int contourCnt;
+    int maxPts = GrPathUtils::worstCasePointCount(path, &contourCnt,
                                                   srcSpaceTol);
 
     if (maxPts <= 0) {
@@ -229,27 +213,27 @@ bool GrDefaultPathRenderer::createGeom(GrScalar srcSpaceTol,
         }
     }
 
-    fUseIndexedDraw = fSubpathCount > 1;
+    bool indexed = contourCnt > 1;
 
     int maxIdxs = 0;
-    if (kHairLine_PathFill == fFill) {
-        if (fUseIndexedDraw) {
+    if (kHairLine_PathFill == fill) {
+        if (indexed) {
             maxIdxs = 2 * maxPts;
-            fPrimitiveType = kLines_PrimitiveType;
+            *primType = kLines_PrimitiveType;
         } else {
-            fPrimitiveType = kLineStrip_PrimitiveType;
+            *primType = kLineStrip_PrimitiveType;
         }
     } else {
-        if (fUseIndexedDraw) {
+        if (indexed) {
             maxIdxs = 3 * maxPts;
-            fPrimitiveType = kTriangles_PrimitiveType;
+            *primType = kTriangles_PrimitiveType;
         } else {
-            fPrimitiveType = kTriangleFan_PrimitiveType;
+            *primType = kTriangleFan_PrimitiveType;
         }
     }
 
     GrPoint* base;
-    if (!fTarget->reserveVertexSpace(layout, maxPts, (void**)&base)) {
+    if (!target->reserveVertexSpace(layout, maxPts, (void**)&base)) {
         return false;
     }
     GrAssert(NULL != base);
@@ -258,23 +242,21 @@ bool GrDefaultPathRenderer::createGeom(GrScalar srcSpaceTol,
     uint16_t* idxBase = NULL;
     uint16_t* idx = NULL;
     uint16_t subpathIdxStart = 0;
-    if (fUseIndexedDraw) {
-        if (!fTarget->reserveIndexSpace(maxIdxs, (void**)&idxBase)) {
-            fTarget->resetVertexSource();
+    if (indexed) {
+        if (!target->reserveIndexSpace(maxIdxs, (void**)&idxBase)) {
+            target->resetVertexSource();
             return false;
         }
         GrAssert(NULL != idxBase);
         idx = idxBase;
     }
 
-    fSubpathVertCount.reset(fSubpathCount);
-
     GrPoint pts[4];
 
     bool first = true;
     int subpath = 0;
 
-    SkPath::Iter iter(*fPath, false);
+    SkPath::Iter iter(path, false);
 
     for (;;) {
         GrPathCmd cmd = (GrPathCmd)iter.next(pts);
@@ -282,7 +264,6 @@ bool GrDefaultPathRenderer::createGeom(GrScalar srcSpaceTol,
             case kMove_PathCmd:
                 if (!first) {
                     uint16_t currIdx = (uint16_t) (vert - base);
-                    fSubpathVertCount[subpath] = currIdx - subpathIdxStart;
                     subpathIdxStart = currIdx;
                     ++subpath;
                 }
@@ -290,9 +271,9 @@ bool GrDefaultPathRenderer::createGeom(GrScalar srcSpaceTol,
                 vert++;
                 break;
             case kLine_PathCmd:
-                if (fUseIndexedDraw) {
+                if (indexed) {
                     uint16_t prevIdx = (uint16_t)(vert - base) - 1;
-                    append_countour_edge_indices(fFill, subpathIdxStart,
+                    append_countour_edge_indices(fill, subpathIdxStart,
                                                  prevIdx, &idx);
                 }
                 *(vert++) = pts[1];
@@ -305,9 +286,9 @@ bool GrDefaultPathRenderer::createGeom(GrScalar srcSpaceTol,
                             pts[0], pts[1], pts[2],
                             srcSpaceTolSqd, &vert,
                             GrPathUtils::quadraticPointCount(pts, srcSpaceTol));
-                if (fUseIndexedDraw) {
+                if (indexed) {
                     for (uint16_t i = 0; i < numPts; ++i) {
-                        append_countour_edge_indices(fFill, subpathIdxStart,
+                        append_countour_edge_indices(fill, subpathIdxStart,
                                                      firstQPtIdx + i, &idx);
                     }
                 }
@@ -320,9 +301,9 @@ bool GrDefaultPathRenderer::createGeom(GrScalar srcSpaceTol,
                                 pts[0], pts[1], pts[2], pts[3],
                                 srcSpaceTolSqd, &vert,
                                 GrPathUtils::cubicPointCount(pts, srcSpaceTol));
-                if (fUseIndexedDraw) {
+                if (indexed) {
                     for (uint16_t i = 0; i < numPts; ++i) {
-                        append_countour_edge_indices(fFill, subpathIdxStart,
+                        append_countour_edge_indices(fill, subpathIdxStart,
                                                      firstCPtIdx + i, &idx);
                     }
                 }
@@ -332,7 +313,6 @@ bool GrDefaultPathRenderer::createGeom(GrScalar srcSpaceTol,
                 break;
             case kEnd_PathCmd:
                 uint16_t currIdx = (uint16_t) (vert - base);
-                fSubpathVertCount[subpath] = currIdx - subpathIdxStart;
                 goto FINISHED;
         }
         first = false;
@@ -341,49 +321,49 @@ FINISHED:
     GrAssert((vert - base) <= maxPts);
     GrAssert((idx - idxBase) <= maxIdxs);
 
-    fVertexCnt = vert - base;
-    fIndexCnt = idx - idxBase;
+    *vertexCnt = vert - base;
+    *indexCnt = idx - idxBase;
 
-    if (fTranslate.fX || fTranslate.fY) {
+    if (NULL != translate && 
+        (translate->fX || translate->fY)) {
         int count = vert - base;
         for (int i = 0; i < count; i++) {
-            base[i].offset(fTranslate.fX, fTranslate.fY);
+            base[i].offset(translate->fX, translate->fY);
         }
     }
     }
-    // set these at the end so if we failed on first drawPath inside a
-    // setPath/clearPath block we won't assume geom was created on a subsequent
-    // drawPath in the same block.
-    fPreviousSrcTol = srcSpaceTol;
-    fPreviousStages = stageMask;
     return true;
 }
 
-void GrDefaultPathRenderer::onDrawPath(GrDrawState::StageMask stageMask,
-                                       bool stencilOnly) {
+bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path,
+                                             GrPathFill fill,
+                                             const GrVec* translate,
+                                             GrDrawTarget* target,
+                                             GrDrawState::StageMask stageMask,
+                                             bool stencilOnly) {
 
-    GrMatrix viewM = fTarget->getDrawState().getViewMatrix();
+    GrMatrix viewM = target->getDrawState().getViewMatrix();
     GrScalar tol = GR_Scalar1;
-    tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, fPath->getBounds());
-    GrDrawState* drawState = fTarget->drawState();
-
-    // FIXME: It's really dumb that we recreate the verts for a new vertex
-    // layout. We only do that because the GrDrawTarget API doesn't allow
-    // us to change the vertex layout after reserveVertexSpace(). We won't
-    // actually change the vertex data when the layout changes since all the
-    // stages reference the positions (rather than having separate tex coords)
-    // and we don't ever have per-vert colors. In practice our call sites
-    // won't change the stages in use inside a setPath / removePath pair. But
-    // it is a silly limitation of the GrDrawTarget design that should be fixed.
-    if (tol != fPreviousSrcTol ||
-        stageMask != fPreviousStages) {
-        if (!this->createGeom(tol, stageMask)) {
-            return;
-        }
+    tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, path.getBounds());
+    GrDrawState* drawState = target->drawState();
+
+    int vertexCnt;
+    int indexCnt;
+    GrPrimitiveType primType;
+    if (!this->createGeom(path,
+                          fill,
+                          translate,
+                          tol,
+                          target,
+                          stageMask,
+                          &primType,
+                          &vertexCnt,
+                          &indexCnt)) {
+        return false;
     }
 
-    GrAssert(NULL != fTarget);
-    GrDrawTarget::AutoStateRestore asr(fTarget);
+    GrAssert(NULL != target);
+    GrDrawTarget::AutoStateRestore asr(target);
     bool colorWritesWereDisabled = drawState->isColorWriteDisabled();
     // face culling doesn't make sense here
     GrAssert(GrDrawState::kBoth_DrawFace == drawState->getDrawFace());
@@ -394,7 +374,7 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawState::StageMask stageMask,
     bool                        reverse = false;
     bool                        lastPassIsBounds;
 
-    if (kHairLine_PathFill == fFill) {
+    if (kHairLine_PathFill == fill) {
         passCount = 1;
         if (stencilOnly) {
             passes[0] = &gDirectToStencil;
@@ -404,7 +384,7 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawState::StageMask stageMask,
         lastPassIsBounds = false;
         drawFace[0] = GrDrawState::kBoth_DrawFace;
     } else {
-        if (single_pass_path(*fPath, fFill)) {
+        if (single_pass_path(path, fill)) {
             passCount = 1;
             if (stencilOnly) {
                 passes[0] = &gDirectToStencil;
@@ -414,7 +394,7 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawState::StageMask stageMask,
             drawFace[0] = GrDrawState::kBoth_DrawFace;
             lastPassIsBounds = false;
         } else {
-            switch (fFill) {
+            switch (fill) {
                 case kInverseEvenOdd_PathFill:
                     reverse = true;
                     // fallthrough
@@ -475,7 +455,7 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawState::StageMask stageMask,
                     break;
                 default:
                     GrAssert(!"Unknown path fFill!");
-                    return;
+                    return false;
             }
         }
     }
@@ -507,44 +487,63 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawState::StageMask stageMask,
                     if (stageMask) {
                         if (!drawState->getViewInverse(&vmi)) {
                             GrPrintf("Could not invert matrix.");
-                            return;
+                            return false;
                         }
                         drawState->preConcatSamplerMatrices(stageMask, vmi);
                     }
                     drawState->setViewMatrix(GrMatrix::I());
                 }
             } else {
-                bounds = fPath->getBounds();
-                bounds.offset(fTranslate);
+                bounds = path.getBounds();
+                if (NULL != translate) {
+                    bounds.offset(*translate);
+                }
             }
-            GrDrawTarget::AutoGeometryPush agp(fTarget);
-            fTarget->drawSimpleRect(bounds, NULL, stageMask);
+            GrDrawTarget::AutoGeometryPush agp(target);
+            target->drawSimpleRect(bounds, NULL, stageMask);
         } else {
             if (passCount > 1) {
                 drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
             }
-            if (fUseIndexedDraw) {
-                fTarget->drawIndexed(fPrimitiveType, 0, 0, 
-                                     fVertexCnt, fIndexCnt);
+            if (indexCnt) {
+                target->drawIndexed(primType, 0, 0, 
+                                    vertexCnt, indexCnt);
             } else {
-                int baseVertex = 0;
-                for (int sp = 0; sp < fSubpathCount; ++sp) {
-                    fTarget->drawNonIndexed(fPrimitiveType, baseVertex,
-                                            fSubpathVertCount[sp]);
-                    baseVertex += fSubpathVertCount[sp];
-                }
+                target->drawNonIndexed(primType, 0, vertexCnt);
             }
         }
     }
     }
+    return true;
+}
+
+bool GrDefaultPathRenderer::canDrawPath(const SkPath& path,
+                                        GrPathFill fill,
+                                        const GrDrawTarget* target,
+                                        bool antiAlias) const {
+    // this class can draw any path with any fill but doesn't do any 
+    // anti-aliasing.
+    return !antiAlias;
 }
 
-void GrDefaultPathRenderer::drawPath(GrDrawState::StageMask stageMask) {
-    this->onDrawPath(stageMask, false);
+bool GrDefaultPathRenderer::onDrawPath(const SkPath& path,
+                                       GrPathFill fill,
+                                       const GrVec* translate,
+                                       GrDrawTarget* target,
+                                       GrDrawState::StageMask stageMask,
+                                       bool antiAlias) {
+    return this->internalDrawPath(path,
+                                  fill,
+                                  translate,
+                                  target,
+                                  stageMask,
+                                  false);
 }
 
-void GrDefaultPathRenderer::drawPathToStencil() {
-    GrAssert(kInverseEvenOdd_PathFill != fFill);
-    GrAssert(kInverseWinding_PathFill != fFill);
-    this->onDrawPath(0, true);
+void GrDefaultPathRenderer::drawPathToStencil(const SkPath& path,
+                                              GrPathFill fill,
+                                              GrDrawTarget* target) {
+    GrAssert(kInverseEvenOdd_PathFill != fill);
+    GrAssert(kInverseWinding_PathFill != fill);
+    this->internalDrawPath(path, fill, NULL, target, 0, true);
 }
index adfe7d2..a6a4cda 100644 (file)
@@ -20,40 +20,49 @@ public:
     GrDefaultPathRenderer(bool separateStencilSupport,
                           bool stencilWrapOpsSupport);
 
-    virtual bool canDrawPath(const GrDrawTarget::Caps& targetCaps,
-                             const SkPath& path,
-                             GrPathFill fill,
-                             bool antiAlias) const SK_OVERRIDE;
 
-    virtual bool requiresStencilPass(const GrDrawTarget* target,
-                                     const SkPath& path,
-                                     GrPathFill fill) const SK_OVERRIDE;
+    virtual bool requiresStencilPass(const SkPath& path,
+                                     GrPathFill fill,
+                                     const GrDrawTarget* target) const SK_OVERRIDE;
 
-    virtual void drawPath(GrDrawState::StageMask stageMask) SK_OVERRIDE;
-    virtual void drawPathToStencil() SK_OVERRIDE;
+    virtual bool canDrawPath(const SkPath& path,
+                            GrPathFill fill,
+                            const GrDrawTarget* target,
+                            bool antiAlias) const SK_OVERRIDE;
 
-protected:
-    virtual void pathWillClear();
+    virtual void drawPathToStencil(const SkPath& path,
+                                   GrPathFill fill,
+                                   GrDrawTarget* target) SK_OVERRIDE;
 
 private:
 
-    void onDrawPath(GrDrawState::StageMask stages, bool stencilOnly);
+    virtual bool onDrawPath(const SkPath& path,
+                            GrPathFill fill,
+                            const GrVec* translate,
+                            GrDrawTarget* target,
+                            GrDrawState::StageMask stageMask,
+                            bool antiAlias) SK_OVERRIDE;
 
-    bool createGeom(GrScalar srcSpaceTol,
-                   GrDrawState::StageMask stages);
+    bool internalDrawPath(const SkPath& path,
+                          GrPathFill fill,
+                          const GrVec* translate,
+                          GrDrawTarget* target,
+                          GrDrawState::StageMask stageMask,
+                          bool stencilOnly);
+
+    bool createGeom(const SkPath& path,
+                    GrPathFill fill,
+                    const GrVec* translate,
+                    GrScalar srcSpaceTol,
+                    GrDrawTarget* target,
+                    GrDrawState::StageMask stages,
+                    GrPrimitiveType* primType,
+                    int* vertexCnt,
+                    int* indexCnt);
 
     bool    fSeparateStencil;
     bool    fStencilWrapOps;
 
-    int                         fSubpathCount;
-    SkAutoSTMalloc<8, uint16_t> fSubpathVertCount;
-    int                         fIndexCnt;
-    int                         fVertexCnt;
-    GrScalar                    fPreviousSrcTol;
-    GrDrawState::StageMask      fPreviousStages;
-    GrPrimitiveType             fPrimitiveType;
-    bool                        fUseIndexedDraw;
-
     typedef GrPathRenderer INHERITED;
 };
 
index a14de73..32338ca 100644 (file)
@@ -632,7 +632,6 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
 
                 GrPathRenderer* pr = NULL;
                 const GrPath* clipPath = NULL;
-                GrPathRenderer::AutoClearPath arp;
                 if (kRect_ClipType == clip.getElementType(c)) {
                     canRenderDirectToStencil = true;
                     fill = kEvenOdd_PathFill;
@@ -655,8 +654,7 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
                         return false;
                     }
                     canRenderDirectToStencil =
-                        !pr->requiresStencilPass(this, *clipPath, fill);
-                    arp.set(pr, this, clipPath, fill, false, NULL);
+                        !pr->requiresStencilPass(*clipPath, fill, this);
                 }
 
                 GrSetOp op = (c == start) ? startOp : clip.getOp(c);
@@ -690,9 +688,9 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
                     } else {
                         if (canRenderDirectToStencil) {
                             *drawState->stencil() = gDrawToStencil;
-                            pr->drawPath(0);
+                            pr->drawPath(*clipPath, fill, NULL, this, 0, false);
                         } else {
-                            pr->drawPathToStencil();
+                            pr->drawPathToStencil(*clipPath, fill, this);
                         }
                     }
                 }
@@ -708,7 +706,7 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
                             this->drawSimpleRect(clip.getRect(c), NULL, 0);
                         } else {
                             SET_RANDOM_COLOR
-                            pr->drawPath(0);
+                            pr->drawPath(*clipPath, fill, NULL, this, 0, false);
                         }
                     } else {
                         SET_RANDOM_COLOR
@@ -739,8 +737,7 @@ GrPathRenderer* GrGpu::getClipPathRenderer(const GrPath& path,
             new GrPathRendererChain(this->getContext(),
                                     GrPathRendererChain::kNonAAOnly_UsageFlag);
     }
-    return fPathRendererChain->getPathRenderer(this->getCaps(),
-                                               path, fill, false);
+    return fPathRendererChain->getPathRenderer(path, fill, this, false);
 }
 
 
index a4f7d0c..31e06a6 100644 (file)
@@ -8,36 +8,6 @@
 
 #include "GrPathRenderer.h"
 
-GrPathRenderer::GrPathRenderer()
-    : fPath(NULL)
-    , fTarget(NULL) {
+GrPathRenderer::GrPathRenderer() {
 }
 
-void GrPathRenderer::setPath(GrDrawTarget* target,
-                             const SkPath* path,
-                             GrPathFill fill,
-                             bool antiAlias,
-                             const GrPoint* translate) {
-    GrAssert(NULL == fPath);
-    GrAssert(NULL == fTarget);
-    GrAssert(NULL != target);
-
-    fTarget = target;
-    fPath = path;
-    fFill = fill;
-    fAntiAlias = antiAlias;
-    if (NULL != translate) {
-        fTranslate = *translate;
-    } else {
-        fTranslate.fX = fTranslate.fY = 0;
-    }
-    this->pathWasSet();
-}
-
-void GrPathRenderer::clearPath() {
-    this->pathWillClear();
-    fTarget->resetVertexSource();
-    fTarget->resetIndexSource();
-    fTarget = NULL;
-    fPath = NULL;
-}
index e24b982..6ffcade 100644 (file)
@@ -49,25 +49,7 @@ public:
                                  GrPathRendererChain* prChain);
 
 
-    GrPathRenderer(void);
-    /**
-     * Returns true if this path renderer is able to render the path.
-     * Returning false allows the caller to fallback to another path renderer.
-     * When searching for a path renderer capable of rendering a path this
-     * function is called.
-     *
-     * @param targetCaps The caps of the draw target that will be used to draw
-     *                   the path.
-     * @param path       The path to draw
-     * @param fill       The fill rule to use
-     * @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::Caps& targetCaps,
-                             const SkPath& path,
-                             GrPathFill fill,
-                             bool antiAlias) const = 0;
+    GrPathRenderer();
 
     /**
      * For complex clips Gr uses the stencil buffer. The path renderer must be
@@ -90,54 +72,37 @@ public:
      *         returns true the drawPathToStencil will be used when rendering
      *         clips.
      */
-    virtual bool requiresStencilPass(const GrDrawTarget* target,
-                                     const SkPath& path,
-                                     GrPathFill fill) const { return false; }
-
-    /**
-     * Sets the path to render and target to render into. All calls to drawPath
-     * and drawPathToStencil must occur between setPath and clearPath. The
-     * path cannot be modified externally between setPath and clearPath. The
-     * path may be drawn several times (e.g. tiled supersampler). The target's
-     * state may change between setPath and drawPath* calls. However, if the
-     * path renderer specified vertices/indices during setPath or drawPath*
-     * they will still be set at subsequent drawPath* calls until the next
-     * clearPath. The target's draw state may change between drawPath* calls
-     * so if the subclass does any caching of tesselation, etc. then it must
-     * validate that target parameters that guided the decisions still hold.
-     *
-     * @param target                the target to draw into.
-     * @param path                  the path to draw.
-     * @param fill                  the fill rule to apply.
-     * @param antiAlias             perform antiAliasing when drawing the path.
-     * @param translate             optional additional translation to apply to
-     *                              the path. NULL means (0,0).
-     */
-    void setPath(GrDrawTarget* target,
-                 const SkPath* path,
-                 GrPathFill fill,
-                 bool antiAlias,
-                 const GrPoint* translate);
-
-    /**
-     * Notifies path renderer that path set in setPath is no longer in use.
-     */
-    void clearPath();
+    virtual bool requiresStencilPass(const SkPath& path,
+                                     GrPathFill fill,
+                                     const GrDrawTarget* target) const {
+        return false;
+    }
 
+    virtual bool canDrawPath(const SkPath& path,
+                             GrPathFill fill,
+                             const GrDrawTarget* target,
+                             bool antiAlias) const = 0;
     /**
      * Draws the path into the draw target. If requiresStencilBuffer returned
      * false then the target may be setup for stencil rendering (since the 
      * path renderer didn't claim that it needs to use the stencil internally).
      *
-     * Only called between setPath / clearPath.
-     *
      * @param stages                bitfield that indicates which stages are
      *                              in use. All enabled stages expect positions
      *                              as texture coordinates. The path renderer
      *                              use the remaining stages for its path
      *                              filling algorithm.
      */
-    virtual void drawPath(GrDrawState::StageMask stageMask) = 0;
+    virtual bool drawPath(const SkPath& path,
+                          GrPathFill fill,
+                          const GrVec* translate,
+                          GrDrawTarget* target,
+                          GrDrawState::StageMask stageMask,
+                          bool antiAlias) {
+        GrAssert(this->canDrawPath(path, fill, target, antiAlias));
+        return this->onDrawPath(path, fill, translate,
+                                target, stageMask, antiAlias);
+    }
 
     /**
      * Draws the path to the stencil buffer. Assume the writable stencil bits
@@ -150,64 +115,20 @@ public:
      * The default implementation assumes the path filling algorithm doesn't
      * require a separate stencil pass and so crashes.
      *
-     * Only called between setPath / clearPath.
      */
-    virtual void drawPathToStencil() {
+    virtual void drawPathToStencil(const SkPath& path,
+                                   GrPathFill fill,
+                                   GrDrawTarget* target) {
         GrCrash("Unexpected call to drawPathToStencil.");
     }
 
-    /**
-     * Helper that sets a path and automatically remove it in destructor.
-     */
-    class AutoClearPath {
-    public:
-        AutoClearPath() {
-            fPathRenderer = NULL;
-        }
-        AutoClearPath(GrPathRenderer* pr,
-                      GrDrawTarget* target,
-                      const SkPath* path,
-                      GrPathFill fill,
-                      bool antiAlias,
-                      const GrPoint* translate) {
-            GrAssert(NULL != pr);
-            pr->setPath(target, path, fill, antiAlias, translate);
-            fPathRenderer = pr;
-        }
-        void set(GrPathRenderer* pr,
-                 GrDrawTarget* target,
-                 const SkPath* path,
-                 GrPathFill fill,
-                 bool antiAlias,
-                 const GrPoint* translate) {
-            if (NULL != fPathRenderer) {
-                fPathRenderer->clearPath();
-            }
-            GrAssert(NULL != pr);
-            pr->setPath(target, path, fill, antiAlias, translate);
-            fPathRenderer = pr;
-        }
-        ~AutoClearPath() {
-            if (NULL != fPathRenderer) {
-                fPathRenderer->clearPath();
-            }
-        }
-    private:
-        GrPathRenderer* fPathRenderer;
-    };
-
 protected:
-
-    // subclass can override these to be notified just after a path is set
-    // and just before the path is cleared.
-    virtual void pathWasSet() {}
-    virtual void pathWillClear() {}
-
-    const SkPath*               fPath;
-    GrDrawTarget*               fTarget;
-    GrPathFill                  fFill;
-    GrPoint                     fTranslate;
-    bool                        fAntiAlias;
+    virtual bool onDrawPath(const SkPath& path,
+                            GrPathFill fill,
+                            const GrVec* translate,
+                            GrDrawTarget* target,
+                            GrDrawState::StageMask stageMask,
+                            bool antiAlias) = 0;
 
 private:
 
index ad7f3db..00f0b81 100644 (file)
@@ -31,16 +31,15 @@ GrPathRenderer* GrPathRendererChain::addPathRenderer(GrPathRenderer* pr) {
     return pr;
 }
 
-GrPathRenderer* GrPathRendererChain::getPathRenderer(
-                                        const GrDrawTarget::Caps& targetCaps,
-                                        const GrPath& path,
-                                        GrPathFill fill,
-                                        bool antiAlias) {
+GrPathRenderer* GrPathRendererChain::getPathRenderer(const SkPath& path,
+                                                     GrPathFill fill,
+                                                     const GrDrawTarget* target,
+                                                     bool antiAlias) {
     if (!fInit) {
         this->init();
     }
     for (int i = 0; i < fChain.count(); ++i) {
-        if (fChain[i]->canDrawPath(targetCaps, path, fill, antiAlias)) {
+        if (fChain[i]->canDrawPath(path, fill, target, antiAlias)) {
             return fChain[i];
         }
     }
index 8f95ea3..54737cb 100644 (file)
@@ -40,9 +40,9 @@ public:
     // takes a ref and unrefs in destructor
     GrPathRenderer* addPathRenderer(GrPathRenderer* pr);
 
-    GrPathRenderer* getPathRenderer(const GrDrawTarget::Caps& targetCaps,
-                                    const SkPath& path,
+    GrPathRenderer* getPathRenderer(const SkPath& path,
                                     GrPathFill fill,
+                                    const GrDrawTarget* target,
                                     bool antiAlias);
 
 private:
index f6fcdef..3823bbd 100644 (file)
@@ -347,20 +347,26 @@ static size_t computeEdgesAndIntersect(const GrMatrix& matrix,
     return edges->count();
 }
 
-void GrTesselatedPathRenderer::drawPath(GrDrawState::StageMask stageMask) {
-    GrDrawTarget::AutoStateRestore asr(fTarget);
-    GrDrawState* drawState = fTarget->drawState();
+bool GrTesselatedPathRenderer::onDrawPath(const SkPath& path,
+                                          GrPathFill fill,
+                                          const GrVec* translate,
+                                          GrDrawTarget* target,
+                                          GrDrawState::StageMask stageMask,
+                                          bool antiAlias) {
+
+    GrDrawTarget::AutoStateRestore asr(target);
+    GrDrawState* drawState = target->drawState();
     // face culling doesn't make sense here
     GrAssert(GrDrawState::kBoth_DrawFace == drawState->getDrawFace());
 
     GrMatrix viewM = drawState->getViewMatrix();
 
     GrScalar tol = GR_Scalar1;
-    tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, fPath->getBounds());
+    tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, path.getBounds());
     GrScalar tolSqd = GrMul(tol, tol);
 
     int subpathCnt;
-    int maxPts = GrPathUtils::worstCasePointCount(*fPath, &subpathCnt, tol);
+    int maxPts = GrPathUtils::worstCasePointCount(path, &subpathCnt, tol);
 
     GrVertexLayout layout = 0;
     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
@@ -369,13 +375,13 @@ void GrTesselatedPathRenderer::drawPath(GrDrawState::StageMask stageMask) {
         }
     }
 
-    bool inverted = GrIsFillInverted(fFill);
+    bool inverted = GrIsFillInverted(fill);
     if (inverted) {
         maxPts += 4;
         subpathCnt++;
     }
     if (maxPts > USHRT_MAX) {
-        return;
+        return false;
     }
     SkAutoSTMalloc<8, GrPoint> baseMem(maxPts);
     GrPoint* base = baseMem;
@@ -385,7 +391,7 @@ void GrTesselatedPathRenderer::drawPath(GrDrawState::StageMask stageMask) {
     SkAutoSTMalloc<8, uint16_t> subpathVertCount(subpathCnt);
 
     GrPoint pts[4];
-    SkPath::Iter iter(*fPath, false);
+    SkPath::Iter iter(path, false);
 
     bool first = true;
     int subpath = 0;
@@ -427,9 +433,9 @@ void GrTesselatedPathRenderer::drawPath(GrDrawState::StageMask stageMask) {
         first = false;
     }
 FINISHED:
-    if (0 != fTranslate.fX || 0 != fTranslate.fY) {
+    if (NULL != translate && 0 != translate->fX && 0 != translate->fY) {
         for (int i = 0; i < vert - base; i++) {
-            base[i].offset(fTranslate.fX, fTranslate.fY);
+            base[i].offset(translate->fX, translate->fY);
         }
     }
 
@@ -456,25 +462,25 @@ FINISHED:
     size_t count = vert - base;
 
     if (count < 3) {
-        return;
+        return true;
     }
 
-    if (subpathCnt == 1 && !inverted && fPath->isConvex()) {
-        if (fAntiAlias) {
+    if (subpathCnt == 1 && !inverted && path.isConvex()) {
+        if (antiAlias) {
             GrEdgeArray edges;
             GrMatrix inverse, matrix = drawState->getViewMatrix();
             drawState->getViewInverse(&inverse);
 
             count = computeEdgesAndIntersect(matrix, inverse, base, count, &edges, 0.0f);
-            size_t maxEdges = fTarget->getMaxEdges();
+            size_t maxEdges = target->getMaxEdges();
             if (count == 0) {
-                return;
+                return true;
             }
             if (count <= maxEdges) {
                 // All edges fit; upload all edges and draw all verts as a fan
-                fTarget->setVertexSourceToArray(layout, base, count);
+                target->setVertexSourceToArray(layout, base, count);
                 drawState->setEdgeAAData(&edges[0], count);
-                fTarget->drawNonIndexed(kTriangleFan_PrimitiveType, 0, count);
+                target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, count);
             } else {
                 // Upload "maxEdges" edges and verts at a time, and draw as
                 // separate fans
@@ -482,31 +488,31 @@ FINISHED:
                     edges[i] = edges[0];
                     base[i] = base[0];
                     int size = GR_CT_MIN(count - i, maxEdges);
-                    fTarget->setVertexSourceToArray(layout, &base[i], size);
+                    target->setVertexSourceToArray(layout, &base[i], size);
                     drawState->setEdgeAAData(&edges[i], size);
-                    fTarget->drawNonIndexed(kTriangleFan_PrimitiveType, 0, size);
+                    target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, size);
                 }
             }
             drawState->setEdgeAAData(NULL, 0);
         } else {
-            fTarget->setVertexSourceToArray(layout, base, count);
-            fTarget->drawNonIndexed(kTriangleFan_PrimitiveType, 0, count);
+            target->setVertexSourceToArray(layout, base, count);
+            target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, count);
         }
-        return;
+        return true;
     }
 
-    if (fAntiAlias) {
+    if (antiAlias) {
         // Run the tesselator once to get the boundaries.
-        GrBoundaryTess btess(count, fill_type_to_glu_winding_rule(fFill));
+        GrBoundaryTess btess(count, fill_type_to_glu_winding_rule(fill));
         btess.addVertices(base, subpathVertCount, subpathCnt);
 
         GrMatrix inverse, matrix = drawState->getViewMatrix();
         if (!drawState->getViewInverse(&inverse)) {
-            return;
+            return false;
         }
 
         if (btess.vertices().count() > USHRT_MAX) {
-            return;
+            return false;
         }
 
         // Inflate the boundary, and run the tesselator again to generate
@@ -532,7 +538,7 @@ FINISHED:
         Sk_gluTessEndPolygon(ptess.tess());
 
         if (ptess.vertices().count() > USHRT_MAX) {
-            return;
+            return false;
         }
 
         // Draw the resulting polys and upload their edge data.
@@ -570,37 +576,34 @@ FINISHED:
                 tri_edges[t++] = edge5;
             }
             drawState->setEdgeAAData(&tri_edges[0], t);
-            fTarget->setVertexSourceToArray(layout, &tri_verts[0], 3);
-            fTarget->drawNonIndexed(kTriangles_PrimitiveType, 0, 3);
+            target->setVertexSourceToArray(layout, &tri_verts[0], 3);
+            target->drawNonIndexed(kTriangles_PrimitiveType, 0, 3);
         }
         drawState->setEdgeAAData(NULL, 0);
         drawState->disableState(GrDrawState::kEdgeAAConcave_StateBit);
-        return;
+        return true;
     }
 
-    GrPolygonTess ptess(count, fill_type_to_glu_winding_rule(fFill));
+    GrPolygonTess ptess(count, fill_type_to_glu_winding_rule(fill));
     ptess.addVertices(base, subpathVertCount, subpathCnt);
     const GrPointArray& vertices = ptess.vertices();
     const GrIndexArray& indices = ptess.indices();
     if (indices.count() > 0) {
-        fTarget->setVertexSourceToArray(layout, vertices.begin(), vertices.count());
-        fTarget->setIndexSourceToArray(indices.begin(), indices.count());
-        fTarget->drawIndexed(kTriangles_PrimitiveType,
+        target->setVertexSourceToArray(layout, vertices.begin(), vertices.count());
+        target->setIndexSourceToArray(indices.begin(), indices.count());
+        target->drawIndexed(kTriangles_PrimitiveType,
                             0,
                             0,
                             vertices.count(),
                             indices.count());
     }
+    return true;
 }
 
-bool GrTesselatedPathRenderer::canDrawPath(const GrDrawTarget::Caps& caps,
-                                           const SkPath& path,
+bool GrTesselatedPathRenderer::canDrawPath(const SkPath& path,
                                            GrPathFill fill,
+                                           const GrDrawTarget* target,
                                            bool antiAlias) const {
     return kHairLine_PathFill != fill;
 }
 
-void GrTesselatedPathRenderer::drawPathToStencil() {
-    GrAlwaysAssert(!"multipass stencil should not be needed");
-}
-
index e783958..3d12ae9 100644 (file)
@@ -16,12 +16,17 @@ class GrTesselatedPathRenderer : public GrPathRenderer {
 public:
     GrTesselatedPathRenderer();
 
-    virtual void drawPath(GrDrawState::StageMask stageMask);
-    virtual bool canDrawPath(const GrDrawTarget::Caps& targetCaps,
-                             const GrPath& path,
+    virtual bool canDrawPath(const SkPath& path,
                              GrPathFill fill,
+                             const GrDrawTarget* target,
                              bool antiAlias) const SK_OVERRIDE;
-    virtual void drawPathToStencil() SK_OVERRIDE;
+
+    virtual bool onDrawPath(const SkPath& path,
+                            GrPathFill fill,
+                            const GrVec* translate,
+                            GrDrawTarget* target,
+                            GrDrawState::StageMask stageMask,
+                            bool antiAlias) SK_OVERRIDE;
 };
 
 #endif
index 126a95f..48479dc 100644 (file)
@@ -102,7 +102,6 @@ bool GrGLVertexBuffer::updateData(const void* src, size_t srcSizeInBytes) {
     this->bind();
     GrGLenum usage = dynamic() ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW;
 
-    bool doNullHint = GR_GL_USE_BUFFER_DATA_NULL_HINT;
 #if GR_GL_USE_BUFFER_DATA_NULL_HINT
     if (this->sizeInBytes() == srcSizeInBytes) {
         GL_CALL(BufferData(GR_GL_ARRAY_BUFFER, srcSizeInBytes, src, usage));