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
This commit is contained in:
bsalomon@google.com 2012-03-02 21:26:50 +00:00
Родитель 6a81b8a282
Коммит c2099d2707
16 изменённых файлов: 381 добавлений и 470 удалений

Просмотреть файл

@ -700,6 +700,7 @@ private:
GrPathRenderer* getPathRenderer(const GrPath& path,
GrPathFill fill,
const GrDrawTarget* target,
bool antiAlias);
/**

Просмотреть файл

@ -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;
}
GrDrawState* drawState = fTarget->drawState();
}
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 = 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;
}

Просмотреть файл

@ -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;
};

Просмотреть файл

@ -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) {
if (!this->createGeom(stageMask)) {
return;
bool GrAAHairLinePathRenderer::canDrawPath(const SkPath& path,
GrPathFill fill,
const GrDrawTarget* target,
bool antiAlias) const {
if (fill != kHairLine_PathFill || !antiAlias) {
return false;
}
GrDrawState* drawState = fTarget->drawState();
static const uint32_t gReqDerivMask = SkPath::kCubic_SegmentMask |
SkPath::kQuad_SegmentMask;
if (!target->getCaps().fShaderDerivativeSupport &&
(gReqDerivMask & path.getSegmentMasks())) {
return false;
}
return true;
}
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 = 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;
}

Просмотреть файл

@ -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;
};

Просмотреть файл

@ -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);
}
////////////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -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();
tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, path.getBounds());
GrDrawState* drawState = target->drawState();
// FIXME: It's really dumb that we recreate the verts for a new vertex
// layout. We only do that because the GrDrawTarget API doesn't allow
// us to change the vertex layout after reserveVertexSpace(). We won't
// actually change the vertex data when the layout changes since all the
// stages reference the positions (rather than having separate tex coords)
// and we don't ever have per-vert colors. In practice our call sites
// won't change the stages in use inside a setPath / removePath pair. But
// it is a silly limitation of the GrDrawTarget design that should be fixed.
if (tol != fPreviousSrcTol ||
stageMask != fPreviousStages) {
if (!this->createGeom(tol, stageMask)) {
return;
}
int vertexCnt;
int indexCnt;
GrPrimitiveType primType;
if (!this->createGeom(path,
fill,
translate,
tol,
target,
stageMask,
&primType,
&vertexCnt,
&indexCnt)) {
return false;
}
GrAssert(NULL != fTarget);
GrDrawTarget::AutoStateRestore asr(fTarget);
GrAssert(NULL != target);
GrDrawTarget::AutoStateRestore asr(target);
bool colorWritesWereDisabled = drawState->isColorWriteDisabled();
// face culling doesn't make sense here
GrAssert(GrDrawState::kBoth_DrawFace == drawState->getDrawFace());
@ -394,7 +374,7 @@ 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;
}
void GrDefaultPathRenderer::drawPath(GrDrawState::StageMask stageMask) {
this->onDrawPath(stageMask, false);
bool GrDefaultPathRenderer::canDrawPath(const SkPath& path,
GrPathFill fill,
const GrDrawTarget* target,
bool antiAlias) const {
// this class can draw any path with any fill but doesn't do any
// anti-aliasing.
return !antiAlias;
}
void GrDefaultPathRenderer::drawPathToStencil() {
GrAssert(kInverseEvenOdd_PathFill != fFill);
GrAssert(kInverseWinding_PathFill != fFill);
this->onDrawPath(0, true);
bool GrDefaultPathRenderer::onDrawPath(const SkPath& path,
GrPathFill fill,
const GrVec* translate,
GrDrawTarget* target,
GrDrawState::StageMask stageMask,
bool antiAlias) {
return this->internalDrawPath(path,
fill,
translate,
target,
stageMask,
false);
}
void GrDefaultPathRenderer::drawPathToStencil(const SkPath& path,
GrPathFill fill,
GrDrawTarget* target) {
GrAssert(kInverseEvenOdd_PathFill != fill);
GrAssert(kInverseWinding_PathFill != fill);
this->internalDrawPath(path, fill, NULL, target, 0, true);
}

Просмотреть файл

@ -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;
};

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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:

Просмотреть файл

@ -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];
}
}

Просмотреть файл

@ -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:

Просмотреть файл

@ -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");
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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));