From c2099d2707abcc94e139627399aed4b8894b69bb Mon Sep 17 00:00:00 2001 From: "bsalomon@google.com" Date: Fri, 2 Mar 2012 21:26:50 +0000 Subject: 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 --- src/gpu/GrAAConvexPathRenderer.cpp | 73 +++++++----- src/gpu/GrAAConvexPathRenderer.h | 17 ++- src/gpu/GrAAHairLinePathRenderer.cpp | 144 ++++++++++++----------- src/gpu/GrAAHairLinePathRenderer.h | 40 +++---- src/gpu/GrContext.cpp | 12 +- src/gpu/GrDefaultPathRenderer.cpp | 215 +++++++++++++++++------------------ src/gpu/GrDefaultPathRenderer.h | 55 +++++---- src/gpu/GrGpu.cpp | 13 +-- src/gpu/GrPathRenderer.cpp | 32 +----- src/gpu/GrPathRenderer.h | 137 +++++----------------- src/gpu/GrPathRendererChain.cpp | 11 +- src/gpu/GrPathRendererChain.h | 4 +- src/gpu/GrTesselatedPathRenderer.cpp | 83 +++++++------- src/gpu/GrTesselatedPathRenderer.h | 13 ++- src/gpu/gl/GrGLVertexBuffer.cpp | 1 - 15 files changed, 380 insertions(+), 470 deletions(-) (limited to 'src') diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp index d5962849f0..60749d81c0 100644 --- a/src/gpu/GrAAConvexPathRenderer.cpp +++ b/src/gpu/GrAAConvexPathRenderer.cpp @@ -18,15 +18,6 @@ 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(&verts))) { - return; + if (!target->reserveVertexSpace(layout, + vCount, + reinterpret_cast(&verts))) { + return false; } - if (!fTarget->reserveIndexSpace(iCount, reinterpret_cast(&idxs))) { - fTarget->resetVertexSource(); - return; + if (!target->reserveIndexSpace(iCount, reinterpret_cast(&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; } diff --git a/src/gpu/GrAAConvexPathRenderer.h b/src/gpu/GrAAConvexPathRenderer.h index dff06c6204..df0c00126a 100644 --- a/src/gpu/GrAAConvexPathRenderer.h +++ b/src/gpu/GrAAConvexPathRenderer.h @@ -12,9 +12,16 @@ 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; }; diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp index e11c12b34f..3ed4488f2b 100644 --- a/src/gpu/GrAAHairLinePathRenderer.cpp +++ b/src/gpu/GrAAHairLinePathRenderer.cpp @@ -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 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; } diff --git a/src/gpu/GrAAHairLinePathRenderer.h b/src/gpu/GrAAHairLinePathRenderer.h index 3b29919f9e..33b73320aa 100644 --- a/src/gpu/GrAAHairLinePathRenderer.h +++ b/src/gpu/GrAAHairLinePathRenderer.h @@ -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; }; diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index d6ebada82a..2a12399555 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -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); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp index 51cbde02cf..72b3c60c2a 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 @@ 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); } diff --git a/src/gpu/GrDefaultPathRenderer.h b/src/gpu/GrDefaultPathRenderer.h index adfe7d2de1..a6a4cda84d 100644 --- a/src/gpu/GrDefaultPathRenderer.h +++ b/src/gpu/GrDefaultPathRenderer.h @@ -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; }; diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index a14de7361d..32338ca368 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -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); } diff --git a/src/gpu/GrPathRenderer.cpp b/src/gpu/GrPathRenderer.cpp index a4f7d0cdd9..31e06a6b02 100644 --- a/src/gpu/GrPathRenderer.cpp +++ b/src/gpu/GrPathRenderer.cpp @@ -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; -} diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h index e24b98224c..6ffcadece1 100644 --- a/src/gpu/GrPathRenderer.h +++ b/src/gpu/GrPathRenderer.h @@ -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: diff --git a/src/gpu/GrPathRendererChain.cpp b/src/gpu/GrPathRendererChain.cpp index ad7f3db3c3..00f0b81d85 100644 --- a/src/gpu/GrPathRendererChain.cpp +++ b/src/gpu/GrPathRendererChain.cpp @@ -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]; } } diff --git a/src/gpu/GrPathRendererChain.h b/src/gpu/GrPathRendererChain.h index 8f95ea3059..54737cbe3e 100644 --- a/src/gpu/GrPathRendererChain.h +++ b/src/gpu/GrPathRendererChain.h @@ -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: diff --git a/src/gpu/GrTesselatedPathRenderer.cpp b/src/gpu/GrTesselatedPathRenderer.cpp index f6fcdef587..3823bbd1c8 100644 --- a/src/gpu/GrTesselatedPathRenderer.cpp +++ b/src/gpu/GrTesselatedPathRenderer.cpp @@ -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"); -} - diff --git a/src/gpu/GrTesselatedPathRenderer.h b/src/gpu/GrTesselatedPathRenderer.h index e783958ca7..3d12ae970c 100644 --- a/src/gpu/GrTesselatedPathRenderer.h +++ b/src/gpu/GrTesselatedPathRenderer.h @@ -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 diff --git a/src/gpu/gl/GrGLVertexBuffer.cpp b/src/gpu/gl/GrGLVertexBuffer.cpp index 126a95f035..48479dcf44 100644 --- a/src/gpu/gl/GrGLVertexBuffer.cpp +++ b/src/gpu/gl/GrGLVertexBuffer.cpp @@ -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)); -- cgit v1.2.3