Make drawRect preserve vertex attrib state and push/pop the geom sources.

Also, add some balancing calls for setIndexSource*()
Review URL: https://codereview.chromium.org/13468004

git-svn-id: http://skia.googlecode.com/svn/trunk@8499 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
bsalomon@google.com 2013-04-02 21:00:15 +00:00
parent 5d01bec07a
commit 0406b9e1fa
8 changed files with 89 additions and 33 deletions

View File

@ -842,6 +842,7 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path,
kIdxsPerQuad*n); // iCount kIdxsPerQuad*n); // iCount
quads += n; quads += n;
} }
target->resetIndexSource();
return true; return true;
} }

View File

@ -178,6 +178,7 @@ void GrAARectRenderer::fillAARect(GrGpu* gpu,
target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1,
kVertsPerAAFillRect, kVertsPerAAFillRect,
kIndicesPerAAFillRect); kIndicesPerAAFillRect);
target->resetIndexSource();
} }
void GrAARectRenderer::strokeAARect(GrGpu* gpu, void GrAARectRenderer::strokeAARect(GrGpu* gpu,

View File

@ -976,6 +976,7 @@ void GrContext::drawVertices(const GrPaint& paint,
if (NULL != indices) { if (NULL != indices) {
target->setIndexSourceToArray(indices, indexCount); target->setIndexSourceToArray(indices, indexCount);
target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
target->resetIndexSource();
} else { } else {
target->drawNonIndexed(primitiveType, 0, vertexCount); target->drawNonIndexed(primitiveType, 0, vertexCount);
} }

View File

@ -169,6 +169,27 @@ public:
bool validateVertexAttribs() const; bool validateVertexAttribs() const;
/**
* Helper to save/restore vertex attribs
*/
class AutoVertexAttribRestore {
public:
AutoVertexAttribRestore(GrDrawState* drawState) {
GrAssert(NULL != drawState);
fDrawState = drawState;
fVertexAttribs = drawState->fCommon.fVertexAttribs;
fDrawState->setDefaultVertexAttribs();
}
~AutoVertexAttribRestore(){
fDrawState->fCommon.fVertexAttribs = fVertexAttribs;
}
private:
GrDrawState* fDrawState;
GrVertexAttribArray<kMaxVertexAttribCnt> fVertexAttribs;
};
/** /**
* Accessing positions, local coords, or colors, of a vertex within an array is a hassle * Accessing positions, local coords, or colors, of a vertex within an array is a hassle
* involving casts and simple math. These helpers exist to keep GrDrawTarget clients' code a bit * involving casts and simple math. These helpers exist to keep GrDrawTarget clients' code a bit

View File

@ -611,10 +611,10 @@ void GrDrawTarget::drawIndexedInstances(GrPrimitiveType type,
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void GrDrawTarget::drawRect(const GrRect& rect, void GrDrawTarget::onDrawRect(const GrRect& rect,
const SkMatrix* matrix, const SkMatrix* matrix,
const GrRect* localRect, const GrRect* localRect,
const SkMatrix* localMatrix) { const SkMatrix* localMatrix) {
// position + (optional) texture coord // position + (optional) texture coord
static const GrVertexAttrib kAttribs[] = { static const GrVertexAttrib kAttribs[] = {
{kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},

View File

@ -331,16 +331,8 @@ public:
void stencilPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType fill); void stencilPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType fill);
/** /**
* Helper function for drawing rects. This does not use the current index * Helper function for drawing rects. It performs a geometry src push and pop
* and vertex sources. After returning, the vertex and index sources may * and thus will finalize any reserved geometry.
* have changed. They should be reestablished before the next draw call.
* This cannot be called between reserving and releasing
* geometry.
*
* A subclass may override this to perform more optimal rect rendering. Its
* draws should be funneled through one of the public GrDrawTarget draw methods
* (e.g. drawNonIndexed, drawIndexedInstances, ...). The base class draws a two
* triangle fan using drawNonIndexed from reserved vertex space.
* *
* @param rect the rect to draw * @param rect the rect to draw
* @param matrix optional matrix applied to rect (before viewMatrix) * @param matrix optional matrix applied to rect (before viewMatrix)
@ -351,10 +343,13 @@ public:
* then srcRect will be transformed by srcMatrix. * then srcRect will be transformed by srcMatrix.
* srcMatrix can be NULL when no srcMatrix is desired. * srcMatrix can be NULL when no srcMatrix is desired.
*/ */
virtual void drawRect(const GrRect& rect, void drawRect(const GrRect& rect,
const SkMatrix* matrix, const SkMatrix* matrix,
const GrRect* localRect, const GrRect* localRect,
const SkMatrix* localMatrix); const SkMatrix* localMatrix) {
AutoGeometryPush agp(this);
this->onDrawRect(rect, matrix, localRect, localMatrix);
}
/** /**
* Helper for drawRect when the caller doesn't need separate local rects or matrices. * Helper for drawRect when the caller doesn't need separate local rects or matrices.
@ -533,20 +528,47 @@ public:
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
class AutoGeometryAndStatePush : ::GrNoncopyable { /**
* Saves the geometry src state at construction and restores in the destructor. It also saves
* and then restores the vertex attrib state.
*/
class AutoGeometryPush : ::GrNoncopyable {
public: public:
AutoGeometryAndStatePush(GrDrawTarget* target, ASRInit init) AutoGeometryPush(GrDrawTarget* target)
: fState(target, init) { : fAttribRestore(target->drawState()) {
GrAssert(NULL != target); GrAssert(NULL != target);
fTarget = target; fTarget = target;
target->pushGeometrySource(); target->pushGeometrySource();
} }
~AutoGeometryAndStatePush() {
fTarget->popGeometrySource(); ~AutoGeometryPush() { fTarget->popGeometrySource(); }
}
private:
GrDrawTarget* fTarget;
GrDrawState::AutoVertexAttribRestore fAttribRestore;
};
/**
* Combination of AutoGeometryPush and AutoStateRestore. The vertex attribs will be in default
* state regardless of ASRInit value.
*/
class AutoGeometryAndStatePush : ::GrNoncopyable {
public:
AutoGeometryAndStatePush(GrDrawTarget* target, ASRInit init)
: fState(target, init){
GrAssert(NULL != target);
fTarget = target;
target->pushGeometrySource();
if (kPreserve_ASRInit == init) {
target->drawState()->setDefaultVertexAttribs();
}
}
~AutoGeometryAndStatePush() { fTarget->popGeometrySource(); }
private: private:
GrDrawTarget* fTarget;
AutoStateRestore fState; AutoStateRestore fState;
GrDrawTarget* fTarget;
}; };
protected: protected:
@ -717,6 +739,16 @@ private:
virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) = 0; virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) = 0;
// subclass called to perform drawing // subclass called to perform drawing
virtual void onDraw(const DrawInfo&) = 0; virtual void onDraw(const DrawInfo&) = 0;
// Implementation of drawRect. The geometry src and vertex attribs will already
// be saved before this is called and restored afterwards. A subclass may override
// this to perform more optimal rect rendering. Its draws should be funneled through
// one of the public GrDrawTarget draw methods (e.g. drawNonIndexed,
// drawIndexedInstances, ...). The base class draws a two triangle fan using
// drawNonIndexed from reserved vertex space.
virtual void onDrawRect(const GrRect& rect,
const SkMatrix* matrix,
const GrRect* localRect,
const SkMatrix* localMatrix);
virtual void onStencilPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType fill) = 0; virtual void onStencilPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType fill) = 0;
// helpers for reserving vertex and index space. // helpers for reserving vertex and index space.

View File

@ -73,10 +73,10 @@ void get_vertex_bounds(const void* vertices,
} }
} }
void GrInOrderDrawBuffer::drawRect(const GrRect& rect, void GrInOrderDrawBuffer::onDrawRect(const GrRect& rect,
const SkMatrix* matrix, const SkMatrix* matrix,
const GrRect* localRect, const GrRect* localRect,
const SkMatrix* localMatrix) { const SkMatrix* localMatrix) {
GrDrawState::AutoColorRestore acr; GrDrawState::AutoColorRestore acr;
GrDrawState* drawState = this->drawState(); GrDrawState* drawState = this->drawState();

View File

@ -76,10 +76,6 @@ public:
virtual void clear(const GrIRect* rect, virtual void clear(const GrIRect* rect,
GrColor color, GrColor color,
GrRenderTarget* renderTarget = NULL) SK_OVERRIDE; GrRenderTarget* renderTarget = NULL) SK_OVERRIDE;
virtual void drawRect(const GrRect& rect,
const SkMatrix* matrix,
const GrRect* localRect,
const SkMatrix* localMatrix) SK_OVERRIDE;
protected: protected:
virtual void clipWillBeSet(const GrClipData* newClip) SK_OVERRIDE; virtual void clipWillBeSet(const GrClipData* newClip) SK_OVERRIDE;
@ -119,6 +115,10 @@ private:
// overrides from GrDrawTarget // overrides from GrDrawTarget
virtual void onDraw(const DrawInfo&) SK_OVERRIDE; virtual void onDraw(const DrawInfo&) SK_OVERRIDE;
virtual void onDrawRect(const GrRect& rect,
const SkMatrix* matrix,
const GrRect* localRect,
const SkMatrix* localMatrix) SK_OVERRIDE;
virtual void onStencilPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType) SK_OVERRIDE; virtual void onStencilPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType) SK_OVERRIDE;
virtual bool onReserveVertexSpace(size_t vertexSize, virtual bool onReserveVertexSpace(size_t vertexSize,
int vertexCount, int vertexCount,