diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-07-01 14:57:55 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-07-01 14:57:55 +0000 |
commit | ee435122d7dcb9cd4be4524004b0de282c42848b (patch) | |
tree | 7e74d0c1edfe7df8a59aee965b36272d950b99c2 /gpu/src | |
parent | db2a09f2408728871ed9e26eb1197cad6585a15d (diff) |
Tesselate path once for tiled offscreen AA
Review URL: http://codereview.appspot.com/4661062/
git-svn-id: http://skia.googlecode.com/svn/trunk@1777 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'gpu/src')
-rw-r--r-- | gpu/src/GrContext.cpp | 23 | ||||
-rw-r--r-- | gpu/src/GrGpu.cpp | 32 | ||||
-rw-r--r-- | gpu/src/GrPathRenderer.cpp | 329 | ||||
-rw-r--r-- | gpu/src/GrTesselatedPathRenderer.cpp | 96 |
4 files changed, 253 insertions, 227 deletions
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp index 4982704c6d..eee73d9554 100644 --- a/gpu/src/GrContext.cpp +++ b/gpu/src/GrContext.cpp @@ -715,7 +715,7 @@ void GrContext::doOffscreenAAPass2(GrDrawTarget* target, OffscreenRecord* record) { SK_TRACE_EVENT0("GrContext::doOffscreenAAPass2"); GrAssert(NULL != record->fEntry0); - + GrDrawTarget::AutoGeometryPush agp(target); GrIRect tileRect; tileRect.fLeft = boundRect.fLeft + tileX * record->fTileSizeX; tileRect.fTop = boundRect.fTop + tileY * record->fTileSizeY, @@ -1321,7 +1321,9 @@ void GrContext::drawPath(const GrPaint& paint, const GrPath& path, GrPathFill fill, const GrPoint* translate) { GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); - GrPathRenderer* pr = this->getPathRenderer(target, path, fill); + GrPathRenderer* pr = this->getPathRenderer(path, fill); + GrPathRenderer::AutoClearPath arp(pr, target, &path, fill, translate); + GrDrawTarget::StageBitfield stageMask = paint.getActiveStageMask(); if (!pr->supportsAA(target, path, fill) && this->doOffscreenAA(target, paint, kHairLine_PathFill == fill)) { @@ -1357,13 +1359,12 @@ void GrContext::drawPath(const GrPaint& paint, const GrPath& path, for (int tx = 0; tx < record.fTileCountX; ++tx) { for (int ty = 0; ty < record.fTileCountY; ++ty) { this->setupOffscreenAAPass1(target, bound, tx, ty, &record); - pr->drawPath(target, 0, path, fill, translate); + pr->drawPath(0); this->doOffscreenAAPass2(target, paint, bound, tx, ty, &record); } } this->cleanupOffscreenAA(target, pr, &record); if (IsFillInverted(fill) && bound != clipIBounds) { - int stageMask = paint.getActiveStageMask(); GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask); GrRect rect; if (clipIBounds.fTop < bound.fTop) { @@ -1389,11 +1390,8 @@ void GrContext::drawPath(const GrPaint& paint, const GrPath& path, } return; } - } - - GrDrawTarget::StageBitfield enabledStages = paint.getActiveStageMask(); - - pr->drawPath(target, enabledStages, path, fill, translate); + } + pr->drawPath(stageMask); } //////////////////////////////////////////////////////////////////////////////// @@ -1690,14 +1688,13 @@ const GrIndexBuffer* GrContext::getQuadIndexBuffer() const { return fGpu->getQuadIndexBuffer(); } -GrPathRenderer* GrContext::getPathRenderer(const GrDrawTarget* target, - const GrPath& path, +GrPathRenderer* GrContext::getPathRenderer(const GrPath& path, GrPathFill fill) { if (NULL != fCustomPathRenderer && - fCustomPathRenderer->canDrawPath(target, path, fill)) { + fCustomPathRenderer->canDrawPath(path, fill)) { return fCustomPathRenderer; } else { - GrAssert(fDefaultPathRenderer.canDrawPath(target, path, fill)); + GrAssert(fDefaultPathRenderer.canDrawPath(path, fill)); return &fDefaultPathRenderer; } } diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp index 192d29b0d4..62c96f524a 100644 --- a/gpu/src/GrGpu.cpp +++ b/gpu/src/GrGpu.cpp @@ -24,9 +24,8 @@ #include "GrPathRenderer.h" // probably makes no sense for this to be less than a page -static const size_t VERTEX_POOL_VB_SIZE = 1 << 12; -static const int VERTEX_POOL_VB_COUNT = 1; - +static const size_t VERTEX_POOL_VB_SIZE = 1 << 18; +static const int VERTEX_POOL_VB_COUNT = 4; //////////////////////////////////////////////////////////////////////////////// @@ -454,6 +453,7 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) { // with the existing clip. for (int c = firstElement; c < count; ++c) { GrPathFill fill; + bool fillInverted; // enabled at bottom of loop this->disableState(kModifyStencilClip_StateBit); @@ -465,16 +465,20 @@ 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; + fillInverted = false; } else { fill = clip.getPathFill(c); + fillInverted = IsFillInverted(fill); + fill = NonInvertedFill(fill); clipPath = &clip.getPath(c); - pr = this->getClipPathRenderer(*clipPath, NonInvertedFill(fill)); + pr = this->getClipPathRenderer(*clipPath, fill); canRenderDirectToStencil = - !pr->requiresStencilPass(this, *clipPath, - NonInvertedFill(fill)); + !pr->requiresStencilPass(this, *clipPath, fill); + arp.set(pr, this, clipPath, fill, NULL); } GrSetOp op = firstElement == c ? kReplace_SetOp : clip.getOp(c); @@ -489,7 +493,7 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) { GrStencilSettings::GetClipPasses(op, canRenderDirectToStencil, clipBit, - IsFillInverted(fill), + fillInverted, &passes, stencilSettings); // draw the element to the client stencil bits if necessary @@ -509,12 +513,9 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) { } else { if (canRenderDirectToStencil) { this->setStencil(gDrawToStencil); - pr->drawPath(this, 0, *clipPath, NonInvertedFill(fill), - NULL); + pr->drawPath(0); } else { - pr->drawPathToStencil(this, *clipPath, - NonInvertedFill(fill), - NULL); + pr->drawPathToStencil(); } } } @@ -530,8 +531,7 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) { this->drawSimpleRect(clip.getRect(c), NULL, 0); } else { SET_RANDOM_COLOR - GrAssert(!IsFillInverted(fill)); - pr->drawPath(this, 0, *clipPath, fill, NULL); + pr->drawPath(0); } } else { SET_RANDOM_COLOR @@ -558,7 +558,7 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) { GrPathRenderer* GrGpu::getClipPathRenderer(const GrPath& path, GrPathFill fill) { if (NULL != fClientPathRenderer && - fClientPathRenderer->canDrawPath(this, path, fill)) { + fClientPathRenderer->canDrawPath(path, fill)) { return fClientPathRenderer; } else { if (NULL == fDefaultPathRenderer) { @@ -566,7 +566,7 @@ GrPathRenderer* GrGpu::getClipPathRenderer(const GrPath& path, new GrDefaultPathRenderer(this->supportsTwoSidedStencil(), this->supportsStencilWrapOps()); } - GrAssert(fDefaultPathRenderer->canDrawPath(this, path, fill)); + GrAssert(fDefaultPathRenderer->canDrawPath(path, fill)); return fDefaultPathRenderer; } } diff --git a/gpu/src/GrPathRenderer.cpp b/gpu/src/GrPathRenderer.cpp index 1e3c64518b..b103880d21 100644 --- a/gpu/src/GrPathRenderer.cpp +++ b/gpu/src/GrPathRenderer.cpp @@ -11,15 +11,49 @@ #include SK_USER_TRACE_INCLUDE_FILE GrPathRenderer::GrPathRenderer() - : fCurveTolerance (GR_Scalar1) { + : fCurveTolerance (GR_Scalar1) + , fPath(NULL) + , fTarget(NULL) { +} + + +void GrPathRenderer::setPath(GrDrawTarget* target, + const SkPath* path, + GrPathFill fill, + const GrPoint* translate) { + GrAssert(NULL == fPath); + GrAssert(NULL == fTarget); + GrAssert(NULL != target); + + fTarget = target; + fPath = path; + fFill = fill; + if (NULL != translate) { + fTranslate = *translate; + } else { + fTranslate.fX = fTranslate.fY = 0; + } + this->pathWasSet(); +} +void GrPathRenderer::clearPath() { + this->pathWillClear(); + fTarget->resetVertexSource(); + fTarget = NULL; + fPath = NULL; } - + +//////////////////////////////////////////////////////////////////////////////// + GrDefaultPathRenderer::GrDefaultPathRenderer(bool separateStencilSupport, bool stencilWrapOpsSupport) : fSeparateStencil(separateStencilSupport) - , fStencilWrapOps(stencilWrapOpsSupport) { - + , fStencilWrapOps(stencilWrapOpsSupport) + , fSubpathCount(0) + , fSubpathVertCount(0) + , fPreviousSrcTol(-GR_Scalar1) + , fPreviousStages(-1) { + fTarget = NULL; } //////////////////////////////////////////////////////////////////////////////// @@ -189,21 +223,105 @@ bool GrDefaultPathRenderer::requiresStencilPass(const GrDrawTarget* target, return !single_pass_path(*target, path, fill); } -void GrDefaultPathRenderer::onDrawPath(GrDrawTarget* target, - GrDrawTarget::StageBitfield stages, - const GrPath& path, - GrPathFill fill, - const GrPoint* translate, +void GrDefaultPathRenderer::pathWillClear() { + fSubpathVertCount.realloc(0); + fTarget->resetVertexSource(); + fPreviousSrcTol = -GR_Scalar1; + fPreviousStages = -1; +} + +void GrDefaultPathRenderer::createGeom(GrScalar srcSpaceTol, + GrDrawTarget::StageBitfield stages) { + { + SK_TRACE_EVENT0("GrDefaultPathRenderer::createGeom"); + + fPreviousSrcTol = srcSpaceTol; + fPreviousStages = stages; + + GrScalar srcSpaceTolSqd = GrMul(srcSpaceTol, srcSpaceTol); + int maxPts = GrPathUtils::worstCasePointCount(*fPath, &fSubpathCount, + srcSpaceTol); + + GrVertexLayout layout = 0; + for (int s = 0; s < GrDrawTarget::kNumStages; ++s) { + if ((1 << s) & stages) { + layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s); + } + } + + // add 4 to hold the bounding rect + GrPoint* base; + fTarget->reserveVertexSpace(layout, maxPts + 4, (void**)&base); + + GrPoint* vert = base; + GrPoint* subpathBase = base; + + fSubpathVertCount.realloc(fSubpathCount); + + GrPoint pts[4]; + + bool first = true; + int subpath = 0; + + SkPath::Iter iter(*fPath, false); + + for (;;) { + GrPathCmd cmd = (GrPathCmd)iter.next(pts); + switch (cmd) { + case kMove_PathCmd: + if (!first) { + fSubpathVertCount[subpath] = vert-subpathBase; + subpathBase = vert; + ++subpath; + } + *vert = pts[0]; + vert++; + break; + case kLine_PathCmd: + *vert = pts[1]; + vert++; + break; + case kQuadratic_PathCmd: { + GrPathUtils::generateQuadraticPoints(pts[0], pts[1], pts[2], + srcSpaceTolSqd, &vert, + GrPathUtils::quadraticPointCount(pts, srcSpaceTol)); + break; + } + case kCubic_PathCmd: { + GrPathUtils::generateCubicPoints(pts[0], pts[1], pts[2], pts[3], + srcSpaceTolSqd, &vert, + GrPathUtils::cubicPointCount(pts, srcSpaceTol)); + break; + } + case kClose_PathCmd: + break; + case kEnd_PathCmd: + fSubpathVertCount[subpath] = vert-subpathBase; + ++subpath; // this could be only in debug + goto FINISHED; + } + first = false; + } +FINISHED: + GrAssert(subpath == fSubpathCount); + GrAssert((vert - base) <= maxPts); + + if (fTranslate.fX || fTranslate.fY) { + int count = vert - base; + for (int i = 0; i < count; i++) { + base[i].offset(fTranslate.fX, fTranslate.fY); + } + } + } +} + +void GrDefaultPathRenderer::onDrawPath(GrDrawTarget::StageBitfield stages, bool stencilOnly) { + SK_TRACE_EVENT1("GrDefaultPathRenderer::onDrawPath", "points", SkStringPrintf("%i", path.countPoints()).c_str()); - GrDrawTarget::AutoStateRestore asr(target); - bool colorWritesWereDisabled = target->isColorWriteDisabled(); - // face culling doesn't make sense here - GrAssert(GrDrawTarget::kBoth_DrawFace == target->getDrawFace()); - - GrMatrix viewM = target->getViewMatrix(); + GrMatrix viewM = fTarget->getViewMatrix(); // In order to tesselate the path we get a bound on how much the matrix can // stretch when mapping to screen coordinates. GrScalar stretch = viewM.getMaxStretch(); @@ -216,28 +334,25 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawTarget* target, } else { tol = GrScalarDiv(tol, stretch); } - GrScalar tolSqd = GrMul(tol, tol); - - int subpathCnt; - int maxPts = GrPathUtils::worstCasePointCount(path, &subpathCnt, tol); - - GrVertexLayout layout = 0; - for (int s = 0; s < GrDrawTarget::kNumStages; ++s) { - if ((1 << s) & stages) { - layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s); - } + // 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 || + stages != fPreviousStages) { + this->createGeom(tol, stages); } - // add 4 to hold the bounding rect - GrDrawTarget::AutoReleaseGeometry arg(target, layout, maxPts + 4, 0); - - GrPoint* base = (GrPoint*) arg.vertices(); - GrPoint* vert = base; - GrPoint* subpathBase = base; - - SkAutoSTMalloc<8, uint16_t> subpathVertCount(subpathCnt); + GrAssert(NULL != fTarget); + GrDrawTarget::AutoStateRestore asr(fTarget); + bool colorWritesWereDisabled = fTarget->isColorWriteDisabled(); + // face culling doesn't make sense here + GrAssert(GrDrawTarget::kBoth_DrawFace == fTarget->getDrawFace()); - // TODO: use primitve restart if available rather than multiple draws GrPrimitiveType type; int passCount = 0; const GrStencilSettings* passes[3]; @@ -245,7 +360,7 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawTarget* target, bool reverse = false; bool lastPassIsBounds; - if (kHairLine_PathFill == fill) { + if (kHairLine_PathFill == fFill) { type = kLineStrip_PrimitiveType; passCount = 1; if (stencilOnly) { @@ -257,7 +372,7 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawTarget* target, drawFace[0] = GrDrawTarget::kBoth_DrawFace; } else { type = kTriangleFan_PrimitiveType; - if (single_pass_path(*target, path, fill)) { + if (single_pass_path(*fTarget, *fPath, fFill)) { passCount = 1; if (stencilOnly) { passes[0] = &gDirectToStencil; @@ -267,7 +382,7 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawTarget* target, drawFace[0] = GrDrawTarget::kBoth_DrawFace; lastPassIsBounds = false; } else { - switch (fill) { + switch (fFill) { case kInverseEvenOdd_PathFill: reverse = true; // fallthrough @@ -327,140 +442,62 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawTarget* target, } break; default: - GrAssert(!"Unknown path fill!"); + GrAssert(!"Unknown path fFill!"); return; } } } - GrPoint pts[4]; - - bool first = true; - int subpath = 0; - - SkPath::Iter iter(path, false); - - { - SK_TRACE_EVENT0("GrDefaultPathRenderer::onDrawPath::assembleVerts"); - for (;;) { - - GrPathCmd cmd = (GrPathCmd)iter.next(pts); - switch (cmd) { - case kMove_PathCmd: - if (!first) { - subpathVertCount[subpath] = vert-subpathBase; - subpathBase = vert; - ++subpath; - } - *vert = pts[0]; - vert++; - break; - case kLine_PathCmd: - *vert = pts[1]; - vert++; - break; - case kQuadratic_PathCmd: { - GrPathUtils::generateQuadraticPoints(pts[0], pts[1], pts[2], - tolSqd, &vert, - GrPathUtils::quadraticPointCount(pts, tol)); - break; - } - case kCubic_PathCmd: { - GrPathUtils::generateCubicPoints(pts[0], pts[1], pts[2], pts[3], - tolSqd, &vert, - GrPathUtils::cubicPointCount(pts, tol)); - break; - } - case kClose_PathCmd: - break; - case kEnd_PathCmd: - subpathVertCount[subpath] = vert-subpathBase; - ++subpath; // this could be only in debug - goto FINISHED; - } - first = false; - } - } -FINISHED: - GrAssert(subpath == subpathCnt); - GrAssert((vert - base) <= maxPts); - - if (translate) { - int count = vert - base; - for (int i = 0; i < count; i++) { - base[i].offset(translate->fX, translate->fY); - } - } - - // if we're stenciling we will follow with a pass that draws - // a bounding rect to set the color. We're stenciling when - // passCount > 1. - const int& boundVertexStart = maxPts; - GrPoint* boundsVerts = base + boundVertexStart; - if (lastPassIsBounds) { - GrRect bounds; - if (reverse) { - GrAssert(NULL != target->getRenderTarget()); - // draw over the whole world. - bounds.setLTRB(0, 0, - GrIntToScalar(target->getRenderTarget()->width()), - GrIntToScalar(target->getRenderTarget()->height())); - GrMatrix vmi; - if (target->getViewInverse(&vmi)) { - vmi.mapRect(&bounds); - } - } else { - bounds.setBounds((GrPoint*)base, vert - base); - } - boundsVerts[0].setRectFan(bounds.fLeft, bounds.fTop, bounds.fRight, - bounds.fBottom); - } - { SK_TRACE_EVENT1("GrDefaultPathRenderer::onDrawPath::renderPasses", "verts", SkStringPrintf("%i", vert - base).c_str()); for (int p = 0; p < passCount; ++p) { - target->setDrawFace(drawFace[p]); + fTarget->setDrawFace(drawFace[p]); if (NULL != passes[p]) { - target->setStencil(*passes[p]); + fTarget->setStencil(*passes[p]); } if (lastPassIsBounds && (p == passCount-1)) { if (!colorWritesWereDisabled) { - target->disableState(GrDrawTarget::kNoColorWrites_StateBit); + fTarget->disableState(GrDrawTarget::kNoColorWrites_StateBit); } - target->drawNonIndexed(kTriangleFan_PrimitiveType, - boundVertexStart, 4); - + GrRect bounds; + if (reverse) { + GrAssert(NULL != fTarget->getRenderTarget()); + // draw over the whole world. + bounds.setLTRB(0, 0, + GrIntToScalar(fTarget->getRenderTarget()->width()), + GrIntToScalar(fTarget->getRenderTarget()->height())); + GrMatrix vmi; + if (fTarget->getViewInverse(&vmi)) { + vmi.mapRect(&bounds); + } + } else { + bounds = fPath->getBounds(); + } + GrDrawTarget::AutoGeometryPush agp(fTarget); + fTarget->drawSimpleRect(bounds, NULL, stages); } else { if (passCount > 1) { - target->enableState(GrDrawTarget::kNoColorWrites_StateBit); + fTarget->enableState(GrDrawTarget::kNoColorWrites_StateBit); } int baseVertex = 0; - for (int sp = 0; sp < subpathCnt; ++sp) { - target->drawNonIndexed(type, - baseVertex, - subpathVertCount[sp]); - baseVertex += subpathVertCount[sp]; + for (int sp = 0; sp < fSubpathCount; ++sp) { + fTarget->drawNonIndexed(type, baseVertex, + fSubpathVertCount[sp]); + baseVertex += fSubpathVertCount[sp]; } } } } } -void GrDefaultPathRenderer::drawPath(GrDrawTarget* target, - GrDrawTarget::StageBitfield stages, - const GrPath& path, - GrPathFill fill, - const GrPoint* translate) { - this->onDrawPath(target, stages, path, fill, translate, false); +void GrDefaultPathRenderer::drawPath(GrDrawTarget::StageBitfield stages) { + this->onDrawPath(stages, false); } -void GrDefaultPathRenderer::drawPathToStencil(GrDrawTarget* target, - const GrPath& path, - GrPathFill fill, - const GrPoint* translate) { - GrAssert(kInverseEvenOdd_PathFill != fill); - GrAssert(kInverseWinding_PathFill != fill); - this->onDrawPath(target, 0, path, fill, translate, true); +void GrDefaultPathRenderer::drawPathToStencil() { + GrAssert(kInverseEvenOdd_PathFill != fFill); + GrAssert(kInverseWinding_PathFill != fFill); + this->onDrawPath(0, true); } diff --git a/gpu/src/GrTesselatedPathRenderer.cpp b/gpu/src/GrTesselatedPathRenderer.cpp index 5ddba99e38..c85040a941 100644 --- a/gpu/src/GrTesselatedPathRenderer.cpp +++ b/gpu/src/GrTesselatedPathRenderer.cpp @@ -33,7 +33,7 @@ typedef void (*TESSCB)(); // limit the allowable vertex range to approximately half of the representable // IEEE exponent in order to avoid overflow when doing multiplies between // vertex components, -const float kMaxVertexValue = 1e18; +const float kMaxVertexValue = 1e18f; static inline GrDrawTarget::Edge computeEdge(const GrPoint& p, const GrPoint& q, @@ -352,16 +352,12 @@ static size_t computeEdgesAndIntersect(const GrMatrix& matrix, return edges->count(); } -void GrTesselatedPathRenderer::drawPath(GrDrawTarget* target, - GrDrawTarget::StageBitfield stages, - const GrPath& path, - GrPathFill fill, - const GrPoint* translate) { - GrDrawTarget::AutoStateRestore asr(target); +void GrTesselatedPathRenderer::drawPath(GrDrawTarget::StageBitfield stages) { + GrDrawTarget::AutoStateRestore asr(fTarget); // face culling doesn't make sense here - GrAssert(GrDrawTarget::kBoth_DrawFace == target->getDrawFace()); + GrAssert(GrDrawTarget::kBoth_DrawFace == fTarget->getDrawFace()); - GrMatrix viewM = target->getViewMatrix(); + GrMatrix viewM = fTarget->getViewMatrix(); // In order to tesselate the path we get a bound on how much the matrix can // stretch when mapping to screen coordinates. GrScalar stretch = viewM.getMaxStretch(); @@ -377,7 +373,7 @@ void GrTesselatedPathRenderer::drawPath(GrDrawTarget* target, GrScalar tolSqd = GrMul(tol, tol); int subpathCnt; - int maxPts = GrPathUtils::worstCasePointCount(path, &subpathCnt, tol); + int maxPts = GrPathUtils::worstCasePointCount(*fPath, &subpathCnt, tol); GrVertexLayout layout = 0; for (int s = 0; s < GrDrawTarget::kNumStages; ++s) { @@ -386,7 +382,7 @@ void GrTesselatedPathRenderer::drawPath(GrDrawTarget* target, } } - bool inverted = IsFillInverted(fill); + bool inverted = IsFillInverted(fFill); if (inverted) { maxPts += 4; subpathCnt++; @@ -402,7 +398,7 @@ void GrTesselatedPathRenderer::drawPath(GrDrawTarget* target, SkAutoSTMalloc<8, uint16_t> subpathVertCount(subpathCnt); GrPoint pts[4]; - SkPath::Iter iter(path, false); + SkPath::Iter iter(*fPath, false); bool first = true; int subpath = 0; @@ -444,20 +440,20 @@ void GrTesselatedPathRenderer::drawPath(GrDrawTarget* target, first = false; } FINISHED: - if (translate) { + if (0 != fTranslate.fX || 0 != fTranslate.fY) { for (int i = 0; i < vert - base; i++) { - base[i].offset(translate->fX, translate->fY); + base[i].offset(fTranslate.fX, fTranslate.fY); } } if (inverted) { GrRect bounds; - GrAssert(NULL != target->getRenderTarget()); + GrAssert(NULL != fTarget->getRenderTarget()); bounds.setLTRB(0, 0, - GrIntToScalar(target->getRenderTarget()->width()), - GrIntToScalar(target->getRenderTarget()->height())); + GrIntToScalar(fTarget->getRenderTarget()->width()), + GrIntToScalar(fTarget->getRenderTarget()->height())); GrMatrix vmi; - if (target->getViewInverse(&vmi)) { + if (fTarget->getViewInverse(&vmi)) { vmi.mapRect(&bounds); } *vert++ = GrPoint::Make(bounds.fLeft, bounds.fTop); @@ -476,22 +472,22 @@ FINISHED: return; } - if (subpathCnt == 1 && !inverted && path.isConvex()) { - if (target->isAntialiasState()) { + if (subpathCnt == 1 && !inverted && fPath->isConvex()) { + if (fTarget->isAntialiasState()) { GrEdgeArray edges; - GrMatrix inverse, matrix = target->getViewMatrix(); - target->getViewInverse(&inverse); + GrMatrix inverse, matrix = fTarget->getViewMatrix(); + fTarget->getViewInverse(&inverse); count = computeEdgesAndIntersect(matrix, inverse, base, count, &edges, 0.0f); - size_t maxEdges = target->getMaxEdges(); + size_t maxEdges = fTarget->getMaxEdges(); if (count == 0) { return; } if (count <= maxEdges) { // All edges fit; upload all edges and draw all verts as a fan - target->setVertexSourceToArray(layout, base, count); - target->setEdgeAAData(&edges[0], count); - target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, count); + fTarget->setVertexSourceToArray(layout, base, count); + fTarget->setEdgeAAData(&edges[0], count); + fTarget->drawNonIndexed(kTriangleFan_PrimitiveType, 0, count); } else { // Upload "maxEdges" edges and verts at a time, and draw as // separate fans @@ -499,26 +495,26 @@ FINISHED: edges[i] = edges[0]; base[i] = base[0]; int size = GR_CT_MIN(count - i, maxEdges); - target->setVertexSourceToArray(layout, &base[i], size); - target->setEdgeAAData(&edges[i], size); - target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, size); + fTarget->setVertexSourceToArray(layout, &base[i], size); + fTarget->setEdgeAAData(&edges[i], size); + fTarget->drawNonIndexed(kTriangleFan_PrimitiveType, 0, size); } } - target->setEdgeAAData(NULL, 0); + fTarget->setEdgeAAData(NULL, 0); } else { - target->setVertexSourceToArray(layout, base, count); - target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, count); + fTarget->setVertexSourceToArray(layout, base, count); + fTarget->drawNonIndexed(kTriangleFan_PrimitiveType, 0, count); } return; } - if (target->isAntialiasState()) { + if (fTarget->isAntialiasState()) { // Run the tesselator once to get the boundaries. - GrBoundaryTess btess(count, fill_type_to_glu_winding_rule(fill)); + GrBoundaryTess btess(count, fill_type_to_glu_winding_rule(fFill)); btess.addVertices(base, subpathVertCount, subpathCnt); - GrMatrix inverse, matrix = target->getViewMatrix(); - if (!target->getViewInverse(&inverse)) { + GrMatrix inverse, matrix = fTarget->getViewMatrix(); + if (!fTarget->getViewInverse(&inverse)) { return; } @@ -553,7 +549,7 @@ FINISHED: } // Draw the resulting polys and upload their edge data. - target->enableState(GrDrawTarget::kEdgeAAConcave_StateBit); + fTarget->enableState(GrDrawTarget::kEdgeAAConcave_StateBit); const GrPointArray& vertices = ptess.vertices(); const GrIndexArray& indices = ptess.indices(); const GrDrawTarget::Edge* edges = ptess.edges(); @@ -586,23 +582,23 @@ FINISHED: tri_edges[t++] = edge4; tri_edges[t++] = edge5; } - target->setEdgeAAData(&tri_edges[0], t); - target->setVertexSourceToArray(layout, &tri_verts[0], 3); - target->drawNonIndexed(kTriangles_PrimitiveType, 0, 3); + fTarget->setEdgeAAData(&tri_edges[0], t); + fTarget->setVertexSourceToArray(layout, &tri_verts[0], 3); + fTarget->drawNonIndexed(kTriangles_PrimitiveType, 0, 3); } - target->setEdgeAAData(NULL, 0); - target->disableState(GrDrawTarget::kEdgeAAConcave_StateBit); + fTarget->setEdgeAAData(NULL, 0); + fTarget->disableState(GrDrawTarget::kEdgeAAConcave_StateBit); return; } - GrPolygonTess ptess(count, fill_type_to_glu_winding_rule(fill)); + GrPolygonTess ptess(count, fill_type_to_glu_winding_rule(fFill)); ptess.addVertices(base, subpathVertCount, subpathCnt); const GrPointArray& vertices = ptess.vertices(); const GrIndexArray& indices = ptess.indices(); if (indices.count() > 0) { - target->setVertexSourceToArray(layout, vertices.begin(), vertices.count()); - target->setIndexSourceToArray(indices.begin(), indices.count()); - target->drawIndexed(kTriangles_PrimitiveType, + fTarget->setVertexSourceToArray(layout, vertices.begin(), vertices.count()); + fTarget->setIndexSourceToArray(indices.begin(), indices.count()); + fTarget->drawIndexed(kTriangles_PrimitiveType, 0, 0, vertices.count(), @@ -610,16 +606,12 @@ FINISHED: } } -bool GrTesselatedPathRenderer::canDrawPath(const GrDrawTarget* target, - const SkPath& path, +bool GrTesselatedPathRenderer::canDrawPath(const SkPath& path, GrPathFill fill) const { return kHairLine_PathFill != fill; } -void GrTesselatedPathRenderer::drawPathToStencil(GrDrawTarget* target, - const SkPath& path, - GrPathFill fill, - const GrPoint* translate) { +void GrTesselatedPathRenderer::drawPathToStencil() { GrAlwaysAssert(!"multipass stencil should not be needed"); } |