Add IndexType parameter to GrDrawTarget::drawPaths

Allows the caller to decide whether they sent 8, 16, or 32 bit path
indices.

BUG=skia:

Review URL: https://codereview.chromium.org/746253003
This commit is contained in:
cdalton 2014-11-25 11:00:56 -08:00 committed by Commit bot
parent b116619028
commit 55b24afc17
13 changed files with 152 additions and 88 deletions

View File

@ -617,15 +617,17 @@ void GrDrawTarget::drawPath(GrDrawState* ds,
void GrDrawTarget::drawPaths(GrDrawState* ds, void GrDrawTarget::drawPaths(GrDrawState* ds,
const GrPathRange* pathRange, const GrPathRange* pathRange,
const uint32_t indices[], const void* indices,
PathIndexType indexType,
const float transformValues[],
PathTransformType transformType,
int count, int count,
const float transforms[],
PathTransformType transformsType,
GrPathRendering::FillType fill) { GrPathRendering::FillType fill) {
SkASSERT(this->caps()->pathRenderingSupport()); SkASSERT(this->caps()->pathRenderingSupport());
SkASSERT(pathRange); SkASSERT(pathRange);
SkASSERT(indices); SkASSERT(indices);
SkASSERT(transforms); SkASSERT(0 == reinterpret_cast<long>(indices) % GrPathRange::PathIndexSizeInBytes(indexType));
SkASSERT(transformValues);
SkASSERT(ds); SkASSERT(ds);
// Setup clip // Setup clip
@ -652,8 +654,8 @@ void GrDrawTarget::drawPaths(GrDrawState* ds,
return; return;
} }
this->onDrawPaths(*ds, pathRange, indices, count, transforms, transformsType, scissorState, this->onDrawPaths(*ds, pathRange, indices, indexType, transformValues, transformType, count,
stencilSettings, dstCopy.texture() ? &dstCopy : NULL); scissorState, stencilSettings, dstCopy.texture() ? &dstCopy : NULL);
} }
void GrDrawTarget::clear(const SkIRect* rect, void GrDrawTarget::clear(const SkIRect* rect,

View File

@ -35,7 +35,8 @@ class GrDrawTarget : public SkRefCnt {
public: public:
SK_DECLARE_INST_COUNT(GrDrawTarget) SK_DECLARE_INST_COUNT(GrDrawTarget)
typedef GrPathRendering::PathTransformType PathTransformType ; typedef GrPathRange::PathIndexType PathIndexType;
typedef GrPathRendering::PathTransformType PathTransformType;
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -279,22 +280,24 @@ public:
void drawPath(GrDrawState*, const GrPath*, GrPathRendering::FillType fill); void drawPath(GrDrawState*, const GrPath*, GrPathRendering::FillType fill);
/** /**
* Draws many paths. It will respect the HW * Draws the aggregate path from combining multiple. Note that this will not
* antialias flag on the draw state (if possible in the 3D API). * always be equivalent to back-to-back calls to drawPath(). It will respect
* the HW antialias flag on the draw state (if possible in the 3D API).
* *
* @param pathRange Source of paths to draw from * @param pathRange Source paths to draw from
* @param indices Array of indices into the the pathRange * @param indices Array of path indices to draw
* @param count Number of paths to draw (length of indices array) * @param indexType Data type of the array elements in indexBuffer
* @param transforms Array of individual transforms, one for each path * @param transformValues Array of transforms for the individual paths
* @param transformsType Type of transformations in the array. Array contains * @param transformType Type of transforms in transformBuffer
PathTransformSize(transformsType) * count elements * @param count Number of paths to draw
* @param fill Fill type for drawing all the paths * @param fill Fill type for drawing all the paths
*/ */
void drawPaths(GrDrawState*, const GrPathRange* pathRange, void drawPaths(GrDrawState*, const GrPathRange* pathRange,
const uint32_t indices[], const void* indices,
PathIndexType indexType,
const float transformValues[],
PathTransformType transformType,
int count, int count,
const float transforms[],
PathTransformType transformsType,
GrPathRendering::FillType fill); GrPathRendering::FillType fill);
/** /**
@ -704,10 +707,11 @@ private:
const GrDeviceCoordTexture* dstCopy) = 0; const GrDeviceCoordTexture* dstCopy) = 0;
virtual void onDrawPaths(const GrDrawState&, virtual void onDrawPaths(const GrDrawState&,
const GrPathRange*, const GrPathRange*,
const uint32_t indices[], const void* indices,
int count, PathIndexType,
const float transforms[], const float transformValues[],
PathTransformType, PathTransformType,
int count,
const GrClipMaskManager::ScissorState&, const GrClipMaskManager::ScissorState&,
const GrStencilSettings&, const GrStencilSettings&,
const GrDeviceCoordTexture*) = 0; const GrDeviceCoordTexture*) = 0;

View File

@ -317,10 +317,11 @@ void GrGpu::drawPath(const GrOptDrawState& ds,
void GrGpu::drawPaths(const GrOptDrawState& ds, void GrGpu::drawPaths(const GrOptDrawState& ds,
const GrPathRange* pathRange, const GrPathRange* pathRange,
const uint32_t indices[], const void* indices,
GrDrawTarget::PathIndexType indexType,
const float transformValues[],
GrDrawTarget::PathTransformType transformType,
int count, int count,
const float transforms[],
GrDrawTarget::PathTransformType transformsType,
const GrStencilSettings& stencilSettings) { const GrStencilSettings& stencilSettings) {
this->handleDirtyContext(); this->handleDirtyContext();
@ -328,7 +329,7 @@ void GrGpu::drawPaths(const GrOptDrawState& ds,
return; return;
} }
pathRange->willDrawPaths(indices, count); pathRange->willDrawPaths(indices, indexType, count);
this->pathRendering()->drawPaths(pathRange, indices, count, transforms, transformsType, this->pathRendering()->drawPaths(pathRange, indices, indexType, transformValues,
stencilSettings); transformType, count, stencilSettings);
} }

View File

@ -365,10 +365,11 @@ public:
const GrStencilSettings&); const GrStencilSettings&);
virtual void drawPaths(const GrOptDrawState&, virtual void drawPaths(const GrOptDrawState&,
const GrPathRange*, const GrPathRange*,
const uint32_t indices[], const void* indices,
int count, GrDrawTarget::PathIndexType,
const float transforms[], const float transformValues[],
GrDrawTarget::PathTransformType, GrDrawTarget::PathTransformType,
int count,
const GrStencilSettings&); const GrStencilSettings&);
static DrawType PrimTypeToDrawType(GrPrimitiveType type) { static DrawType PrimTypeToDrawType(GrPrimitiveType type) {

View File

@ -324,24 +324,33 @@ void GrInOrderDrawBuffer::onDrawPath(const GrDrawState& ds,
void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds, void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds,
const GrPathRange* pathRange, const GrPathRange* pathRange,
const uint32_t indices[], const void* indices,
PathIndexType indexType,
const float transformValues[],
PathTransformType transformType,
int count, int count,
const float transforms[],
PathTransformType transformsType,
const GrClipMaskManager::ScissorState& scissorState, const GrClipMaskManager::ScissorState& scissorState,
const GrStencilSettings& stencilSettings, const GrStencilSettings& stencilSettings,
const GrDeviceCoordTexture* dstCopy) { const GrDeviceCoordTexture* dstCopy) {
SkASSERT(pathRange); SkASSERT(pathRange);
SkASSERT(indices); SkASSERT(indices);
SkASSERT(transforms); SkASSERT(transformValues);
if (!this->recordStateAndShouldDraw(ds, GrGpu::kDrawPath_DrawType, scissorState, dstCopy)) { if (!this->recordStateAndShouldDraw(ds, GrGpu::kDrawPath_DrawType, scissorState, dstCopy)) {
return; return;
} }
uint32_t* savedIndices = fPathIndexBuffer.append(count, indices); int indexBytes = GrPathRange::PathIndexSizeInBytes(indexType);
float* savedTransforms = fPathTransformBuffer.append(count * if (int misalign = fPathIndexBuffer.count() % indexBytes) {
GrPathRendering::PathTransformSize(transformsType), transforms); // Add padding to the index buffer so the indices are aligned properly.
fPathIndexBuffer.append(indexBytes - misalign);
}
char* savedIndices = fPathIndexBuffer.append(count * indexBytes,
reinterpret_cast<const char*>(indices));
float* savedTransforms = fPathTransformBuffer.append(
count * GrPathRendering::PathTransformSize(transformType),
transformValues);
if (kDrawPaths_Cmd == strip_trace_bit(fCmdBuffer.back().fType)) { if (kDrawPaths_Cmd == strip_trace_bit(fCmdBuffer.back().fType)) {
// The previous command was also DrawPaths. Try to collapse this call into the one // The previous command was also DrawPaths. Try to collapse this call into the one
@ -353,7 +362,8 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds,
// font tend to all wind in the same direction. // font tend to all wind in the same direction.
DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back()); DrawPaths* previous = static_cast<DrawPaths*>(&fCmdBuffer.back());
if (pathRange == previous->pathRange() && if (pathRange == previous->pathRange() &&
transformsType == previous->fTransformsType && indexType == previous->fIndexType &&
transformType == previous->fTransformType &&
stencilSettings == previous->fStencilSettings && stencilSettings == previous->fStencilSettings &&
path_fill_type_is_winding(stencilSettings) && path_fill_type_is_winding(stencilSettings) &&
!ds.willBlendWithDst()) { !ds.willBlendWithDst()) {
@ -365,9 +375,10 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds,
DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange)); DrawPaths* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPaths, (pathRange));
dp->fIndicesLocation = savedIndices - fPathIndexBuffer.begin(); dp->fIndicesLocation = savedIndices - fPathIndexBuffer.begin();
dp->fCount = count; dp->fIndexType = indexType;
dp->fTransformsLocation = savedTransforms - fPathTransformBuffer.begin(); dp->fTransformsLocation = savedTransforms - fPathTransformBuffer.begin();
dp->fTransformsType = transformsType; dp->fTransformType = transformType;
dp->fCount = count;
dp->fStencilSettings = stencilSettings; dp->fStencilSettings = stencilSettings;
this->recordTraceMarkersIfNecessary(); this->recordTraceMarkersIfNecessary();
@ -522,9 +533,9 @@ void GrInOrderDrawBuffer::DrawPaths::execute(GrInOrderDrawBuffer* buf,
const GrOptDrawState* optState) { const GrOptDrawState* optState) {
SkASSERT(optState); SkASSERT(optState);
buf->fDstGpu->drawPaths(*optState, this->pathRange(), buf->fDstGpu->drawPaths(*optState, this->pathRange(),
&buf->fPathIndexBuffer[fIndicesLocation], fCount, &buf->fPathIndexBuffer[fIndicesLocation], fIndexType,
&buf->fPathTransformBuffer[fTransformsLocation], fTransformsType, &buf->fPathTransformBuffer[fTransformsLocation], fTransformType,
fStencilSettings); fCount, fStencilSettings);
} }
void GrInOrderDrawBuffer::SetState::execute(GrInOrderDrawBuffer*, const GrOptDrawState*) {} void GrInOrderDrawBuffer::SetState::execute(GrInOrderDrawBuffer*, const GrOptDrawState*) {}

View File

@ -157,9 +157,10 @@ private:
void execute(GrInOrderDrawBuffer*, const GrOptDrawState*) SK_OVERRIDE; void execute(GrInOrderDrawBuffer*, const GrOptDrawState*) SK_OVERRIDE;
int fIndicesLocation; int fIndicesLocation;
size_t fCount; PathIndexType fIndexType;
int fTransformsLocation; int fTransformsLocation;
PathTransformType fTransformsType; PathTransformType fTransformType;
int fCount;
GrStencilSettings fStencilSettings; GrStencilSettings fStencilSettings;
private: private:
@ -249,10 +250,11 @@ private:
const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE; const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
void onDrawPaths(const GrDrawState&, void onDrawPaths(const GrDrawState&,
const GrPathRange*, const GrPathRange*,
const uint32_t indices[], const void* indices,
int count, PathIndexType,
const float transforms[], const float transformValues[],
PathTransformType, PathTransformType,
int count,
const ScissorState&, const ScissorState&,
const GrStencilSettings&, const GrStencilSettings&,
const GrDeviceCoordTexture*) SK_OVERRIDE; const GrDeviceCoordTexture*) SK_OVERRIDE;
@ -293,8 +295,8 @@ private:
// TODO: Use a single allocator for commands and records // TODO: Use a single allocator for commands and records
enum { enum {
kCmdBufferInitialSizeInBytes = 8 * 1024, kCmdBufferInitialSizeInBytes = 8 * 1024,
kPathIdxBufferMinReserve = 64, kPathIdxBufferMinReserve = 2 * 64, // 64 uint16_t's
kPathXformBufferMinReserve = 2 * kPathIdxBufferMinReserve, kPathXformBufferMinReserve = 2 * 64, // 64 two-float transforms
kGeoPoolStatePreAllocCnt = 4, kGeoPoolStatePreAllocCnt = 4,
}; };
@ -318,7 +320,7 @@ private:
GrGpu* fDstGpu; GrGpu* fDstGpu;
GrVertexBufferAllocPool& fVertexPool; GrVertexBufferAllocPool& fVertexPool;
GrIndexBufferAllocPool& fIndexPool; GrIndexBufferAllocPool& fIndexPool;
SkTDArray<uint32_t> fPathIndexBuffer; SkTDArray<char> fPathIndexBuffer;
SkTDArray<float> fPathTransformBuffer; SkTDArray<float> fPathTransformBuffer;
GeoPoolStateStack fGeoPoolStateStack; GeoPoolStateStack fGeoPoolStateStack;
bool fFlushing; bool fFlushing;

View File

@ -32,17 +32,29 @@ GrPathRange::GrPathRange(GrGpu* gpu,
fStroke(stroke) { fStroke(stroke) {
} }
void GrPathRange::willDrawPaths(const uint32_t indices[], int count) const { void GrPathRange::willDrawPaths(const void* indices, PathIndexType indexType, int count) const {
if (NULL == fPathGenerator.get()) { if (!fPathGenerator) {
return; return;
} }
switch (indexType) {
case kU8_PathIndexType: return this->willDrawPaths<uint8_t>(indices, count);
case kU16_PathIndexType: return this->willDrawPaths<uint16_t>(indices, count);
case kU32_PathIndexType: return this->willDrawPaths<uint32_t>(indices, count);
default: SkFAIL("Unknown path index type");
}
}
template<typename IndexType> void GrPathRange::willDrawPaths(const void* indices, int count) const {
SkASSERT(fPathGenerator);
const IndexType* indexArray = reinterpret_cast<const IndexType*>(indices);
bool didLoadPaths = false; bool didLoadPaths = false;
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
SkASSERT(indices[i] < static_cast<uint32_t>(fNumPaths)); SkASSERT(indexArray[i] < static_cast<uint32_t>(fNumPaths));
const int groupIndex = indices[i] / kPathsPerGroup; const int groupIndex = indexArray[i] / kPathsPerGroup;
const int groupByte = groupIndex / 8; const int groupByte = groupIndex / 8;
const uint8_t groupBit = 1 << (groupIndex % 8); const uint8_t groupBit = 1 << (groupIndex % 8);

View File

@ -36,8 +36,25 @@ public:
return type; return type;
} }
enum PathIndexType {
kU8_PathIndexType, //!< uint8_t
kU16_PathIndexType, //!< uint16_t
kU32_PathIndexType, //!< uint32_t
kLast_PathIndexType = kU32_PathIndexType
};
static inline int PathIndexSizeInBytes(PathIndexType type) {
GR_STATIC_ASSERT(0 == kU8_PathIndexType);
GR_STATIC_ASSERT(1 == kU16_PathIndexType);
GR_STATIC_ASSERT(2 == kU32_PathIndexType);
GR_STATIC_ASSERT(kU32_PathIndexType == kLast_PathIndexType);
return 1 << type;
}
/** /**
* Class that generates the paths for a specific range. * Class that generates the paths for a specific range.
*/ */
class PathGenerator : public SkRefCnt { class PathGenerator : public SkRefCnt {
public: public:
@ -76,7 +93,8 @@ protected:
private: private:
// Notify when paths will be drawn in case this is a lazy-loaded path range. // Notify when paths will be drawn in case this is a lazy-loaded path range.
friend class GrGpu; friend class GrGpu;
void willDrawPaths(const uint32_t indices[], int count) const; void willDrawPaths(const void* indices, PathIndexType, int count) const;
template<typename IndexType> void willDrawPaths(const void* indices, int count) const;
mutable SkAutoTUnref<PathGenerator> fPathGenerator; mutable SkAutoTUnref<PathGenerator> fPathGenerator;
mutable SkTArray<uint8_t, true /*MEM_COPY*/> fGeneratedPaths; mutable SkTArray<uint8_t, true /*MEM_COPY*/> fGeneratedPaths;

View File

@ -34,17 +34,7 @@ class GrPathRendering {
public: public:
virtual ~GrPathRendering() { } virtual ~GrPathRendering() { }
// No native support for inverse at this time typedef GrPathRange::PathIndexType PathIndexType;
enum FillType {
/** Specifies that "inside" is computed by a non-zero sum of signed
edge crossings
*/
kWinding_FillType,
/** Specifies that "inside" is computed by an odd number of edge
crossings
*/
kEvenOdd_FillType,
};
enum PathTransformType { enum PathTransformType {
kNone_PathTransformType, //!< [] kNone_PathTransformType, //!< []
@ -74,6 +64,18 @@ public:
} }
} }
// No native support for inverse at this time
enum FillType {
/** Specifies that "inside" is computed by a non-zero sum of signed
edge crossings
*/
kWinding_FillType,
/** Specifies that "inside" is computed by an odd number of edge
crossings
*/
kEvenOdd_FillType,
};
/** /**
* Creates a new gpu path, based on the specified path and stroke and returns it. * Creates a new gpu path, based on the specified path and stroke and returns it.
* The caller owns a ref on the returned path which must be balanced by a call to unref. * The caller owns a ref on the returned path which must be balanced by a call to unref.
@ -126,8 +128,8 @@ public:
virtual void stencilPath(const GrPath*, const GrStencilSettings&) = 0; virtual void stencilPath(const GrPath*, const GrStencilSettings&) = 0;
virtual void drawPath(const GrPath*, const GrStencilSettings&) = 0; virtual void drawPath(const GrPath*, const GrStencilSettings&) = 0;
virtual void drawPaths(const GrPathRange*, const uint32_t indices[], int count, virtual void drawPaths(const GrPathRange*, const void* indices, PathIndexType,
const float transforms[], PathTransformType, const float transformValues[], PathTransformType, int count,
const GrStencilSettings&) = 0; const GrStencilSettings&) = 0;
protected: protected:
GrPathRendering() { } GrPathRendering() { }

View File

@ -367,9 +367,9 @@ void GrStencilAndCoverTextContext::flush() {
return; return;
} }
fDrawTarget->drawPaths(&fDrawState, fGlyphs, fIndexBuffer, fPendingGlyphCount, fTransformBuffer, fDrawTarget->drawPaths(&fDrawState, fGlyphs, fIndexBuffer, GrPathRange::kU16_PathIndexType,
GrPathRendering::kTranslate_PathTransformType, fTransformBuffer, GrPathRendering::kTranslate_PathTransformType,
GrPathRendering::kWinding_FillType); fPendingGlyphCount, GrPathRendering::kWinding_FillType);
fPendingGlyphCount = 0; fPendingGlyphCount = 0;
} }

View File

@ -57,7 +57,7 @@ private:
float fTextInverseRatio; float fTextInverseRatio;
SkGlyphCache* fGlyphCache; SkGlyphCache* fGlyphCache;
GrPathRange* fGlyphs; GrPathRange* fGlyphs;
uint32_t fIndexBuffer[kGlyphBufferSize]; uint16_t fIndexBuffer[kGlyphBufferSize];
float fTransformBuffer[2 * kGlyphBufferSize]; float fTransformBuffer[2 * kGlyphBufferSize];
int fPendingGlyphCount; int fPendingGlyphCount;
SkMatrix fContextInitialMatrix; SkMatrix fContextInitialMatrix;

View File

@ -21,6 +21,17 @@
#define GL_CALL_RET(RET, X) GR_GL_CALL_RET(fGpu->glInterface(), RET, X) #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(fGpu->glInterface(), RET, X)
static const GrGLenum gIndexType2GLType[] = {
GR_GL_UNSIGNED_BYTE,
GR_GL_UNSIGNED_SHORT,
GR_GL_UNSIGNED_INT
};
GR_STATIC_ASSERT(0 == GrPathRange::kU8_PathIndexType);
GR_STATIC_ASSERT(1 == GrPathRange::kU16_PathIndexType);
GR_STATIC_ASSERT(2 == GrPathRange::kU32_PathIndexType);
GR_STATIC_ASSERT(GrPathRange::kU32_PathIndexType == GrPathRange::kLast_PathIndexType);
static const GrGLenum gXformType2GLType[] = { static const GrGLenum gXformType2GLType[] = {
GR_GL_NONE, GR_GL_NONE,
GR_GL_TRANSLATE_X, GR_GL_TRANSLATE_X,
@ -194,9 +205,10 @@ void GrGLPathRendering::drawPath(const GrPath* path, const GrStencilSettings& st
} }
} }
void GrGLPathRendering::drawPaths(const GrPathRange* pathRange, const uint32_t indices[], int count, void GrGLPathRendering::drawPaths(const GrPathRange* pathRange,
const float transforms[], PathTransformType transformsType, const void* indices, PathIndexType indexType,
const GrStencilSettings& stencilSettings) { const float transformValues[], PathTransformType transformType,
int count, const GrStencilSettings& stencilSettings) {
SkASSERT(fGpu->caps()->pathRenderingSupport()); SkASSERT(fGpu->caps()->pathRenderingSupport());
GrGLuint baseID = static_cast<const GrGLPathRange*>(pathRange)->basePathID(); GrGLuint baseID = static_cast<const GrGLPathRange*>(pathRange)->basePathID();
@ -215,19 +227,18 @@ void GrGLPathRendering::drawPaths(const GrPathRange* pathRange, const uint32_t i
if (stroke.needToApply()) { if (stroke.needToApply()) {
if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
GL_CALL(StencilFillPathInstanced( GL_CALL(StencilFillPathInstanced(
count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, count, gIndexType2GLType[indexType], indices, baseID, fillMode,
writeMask, gXformType2GLType[transformsType], writeMask, gXformType2GLType[transformType], transformValues));
transforms));
} }
this->stencilThenCoverStrokePathInstanced( this->stencilThenCoverStrokePathInstanced(
count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff, writeMask, count, gIndexType2GLType[indexType], indices, baseID,
GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, 0xffff, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
gXformType2GLType[transformsType], transforms); gXformType2GLType[transformType], transformValues);
} else { } else {
this->stencilThenCoverFillPathInstanced( this->stencilThenCoverFillPathInstanced(
count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, writeMask, count, gIndexType2GLType[indexType], indices, baseID,
GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, fillMode, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
gXformType2GLType[transformsType], transforms); gXformType2GLType[transformType], transformValues);
} }
} }

View File

@ -41,8 +41,8 @@ public:
const SkStrokeRec&) SK_OVERRIDE; const SkStrokeRec&) SK_OVERRIDE;
virtual void stencilPath(const GrPath*, const GrStencilSettings&) SK_OVERRIDE; virtual void stencilPath(const GrPath*, const GrStencilSettings&) SK_OVERRIDE;
virtual void drawPath(const GrPath*, const GrStencilSettings&) SK_OVERRIDE; virtual void drawPath(const GrPath*, const GrStencilSettings&) SK_OVERRIDE;
virtual void drawPaths(const GrPathRange*, const uint32_t indices[], int count, virtual void drawPaths(const GrPathRange*, const void* indices, PathIndexType,
const float transforms[], PathTransformType, const float transformValues[], PathTransformType, int count,
const GrStencilSettings&) SK_OVERRIDE; const GrStencilSettings&) SK_OVERRIDE;
/* Called when the 3D context state is unknown. */ /* Called when the 3D context state is unknown. */