aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/gpu/GrContext.h1
-rw-r--r--src/gpu/GrAAConvexPathRenderer.cpp73
-rw-r--r--src/gpu/GrAAConvexPathRenderer.h17
-rw-r--r--src/gpu/GrAAHairLinePathRenderer.cpp144
-rw-r--r--src/gpu/GrAAHairLinePathRenderer.h40
-rw-r--r--src/gpu/GrContext.cpp12
-rw-r--r--src/gpu/GrDefaultPathRenderer.cpp215
-rw-r--r--src/gpu/GrDefaultPathRenderer.h55
-rw-r--r--src/gpu/GrGpu.cpp13
-rw-r--r--src/gpu/GrPathRenderer.cpp32
-rw-r--r--src/gpu/GrPathRenderer.h137
-rw-r--r--src/gpu/GrPathRendererChain.cpp11
-rw-r--r--src/gpu/GrPathRendererChain.h4
-rw-r--r--src/gpu/GrTesselatedPathRenderer.cpp83
-rw-r--r--src/gpu/GrTesselatedPathRenderer.h13
-rw-r--r--src/gpu/gl/GrGLVertexBuffer.cpp1
16 files changed, 381 insertions, 470 deletions
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index ffb5065925..37160b1709 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -700,6 +700,7 @@ private:
GrPathRenderer* getPathRenderer(const GrPath& path,
GrPathFill fill,
+ const GrDrawTarget* target,
bool antiAlias);
/**
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<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;
}
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<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;
}
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));