simplify GrPathRenderer interface

Review URL: http://codereview.appspot.com/5706053/



git-svn-id: http://skia.googlecode.com/svn/trunk@3312 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp
index 51cbde0..72b3c60 100644
--- a/src/gpu/GrDefaultPathRenderer.cpp
+++ b/src/gpu/GrDefaultPathRenderer.cpp
@@ -18,21 +18,7 @@
 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 @@
 #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 @@
     *((*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 @@
         }
     }
 
-    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 @@
     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 @@
             case kMove_PathCmd:
                 if (!first) {
                     uint16_t currIdx = (uint16_t) (vert - base);
-                    fSubpathVertCount[subpath] = currIdx - subpathIdxStart;
                     subpathIdxStart = currIdx;
                     ++subpath;
                 }
@@ -290,9 +271,9 @@
                 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 @@
                             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 @@
                                 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 @@
                 break;
             case kEnd_PathCmd:
                 uint16_t currIdx = (uint16_t) (vert - base);
-                fSubpathVertCount[subpath] = currIdx - subpathIdxStart;
                 goto FINISHED;
         }
         first = false;
@@ -341,49 +321,49 @@
     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();
+    tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, path.getBounds());
+    GrDrawState* drawState = target->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;
-        }
+    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 @@
     bool                        reverse = false;
     bool                        lastPassIsBounds;
 
-    if (kHairLine_PathFill == fFill) {
+    if (kHairLine_PathFill == fill) {
         passCount = 1;
         if (stencilOnly) {
             passes[0] = &gDirectToStencil;
@@ -404,7 +384,7 @@
         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 @@
             drawFace[0] = GrDrawState::kBoth_DrawFace;
             lastPassIsBounds = false;
         } else {
-            switch (fFill) {
+            switch (fill) {
                 case kInverseEvenOdd_PathFill:
                     reverse = true;
                     // fallthrough
@@ -475,7 +455,7 @@
                     break;
                 default:
                     GrAssert(!"Unknown path fFill!");
-                    return;
+                    return false;
             }
         }
     }
@@ -507,44 +487,63 @@
                     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;
 }
 
-void GrDefaultPathRenderer::drawPath(GrDrawState::StageMask stageMask) {
-    this->onDrawPath(stageMask, false);
+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::drawPathToStencil() {
-    GrAssert(kInverseEvenOdd_PathFill != fFill);
-    GrAssert(kInverseWinding_PathFill != fFill);
-    this->onDrawPath(0, true);
+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(const SkPath& path,
+                                              GrPathFill fill,
+                                              GrDrawTarget* target) {
+    GrAssert(kInverseEvenOdd_PathFill != fill);
+    GrAssert(kInverseWinding_PathFill != fill);
+    this->internalDrawPath(path, fill, NULL, target, 0, true);
 }