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
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp
index 08a4111..343fca0 100644
--- a/src/gpu/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/GrAAHairLinePathRenderer.cpp
@@ -842,6 +842,7 @@
kIdxsPerQuad*n); // iCount
quads += n;
}
+ target->resetIndexSource();
return true;
}
diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp
index 0093b08..6f074e6 100644
--- a/src/gpu/GrAARectRenderer.cpp
+++ b/src/gpu/GrAARectRenderer.cpp
@@ -178,6 +178,7 @@
target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1,
kVertsPerAAFillRect,
kIndicesPerAAFillRect);
+ target->resetIndexSource();
}
void GrAARectRenderer::strokeAARect(GrGpu* gpu,
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 85b2c83..1b62062 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -976,6 +976,7 @@
if (NULL != indices) {
target->setIndexSourceToArray(indices, indexCount);
target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
+ target->resetIndexSource();
} else {
target->drawNonIndexed(primitiveType, 0, vertexCount);
}
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index 024dfd0..0beebf7 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -170,6 +170,27 @@
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
* involving casts and simple math. These helpers exist to keep GrDrawTarget clients' code a bit
* nicer looking.
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index e9f5be5..df6965d 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -611,10 +611,10 @@
////////////////////////////////////////////////////////////////////////////////
-void GrDrawTarget::drawRect(const GrRect& rect,
- const SkMatrix* matrix,
- const GrRect* localRect,
- const SkMatrix* localMatrix) {
+void GrDrawTarget::onDrawRect(const GrRect& rect,
+ const SkMatrix* matrix,
+ const GrRect* localRect,
+ const SkMatrix* localMatrix) {
// position + (optional) texture coord
static const GrVertexAttrib kAttribs[] = {
{kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding},
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index e4394e6..fc4cd05 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -331,16 +331,8 @@
void stencilPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType fill);
/**
- * Helper function for drawing rects. This does not use the current index
- * and vertex sources. After returning, the vertex and index sources may
- * 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.
+ * Helper function for drawing rects. It performs a geometry src push and pop
+ * and thus will finalize any reserved geometry.
*
* @param rect the rect to draw
* @param matrix optional matrix applied to rect (before viewMatrix)
@@ -351,10 +343,13 @@
* then srcRect will be transformed by srcMatrix.
* srcMatrix can be NULL when no srcMatrix is desired.
*/
- virtual void drawRect(const GrRect& rect,
- const SkMatrix* matrix,
- const GrRect* localRect,
- const SkMatrix* localMatrix);
+ void drawRect(const GrRect& rect,
+ const SkMatrix* matrix,
+ const GrRect* localRect,
+ 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.
@@ -533,20 +528,47 @@
////////////////////////////////////////////////////////////////////////////
- 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:
- AutoGeometryAndStatePush(GrDrawTarget* target, ASRInit init)
- : fState(target, init) {
+ AutoGeometryPush(GrDrawTarget* target)
+ : fAttribRestore(target->drawState()) {
GrAssert(NULL != target);
fTarget = target;
target->pushGeometrySource();
}
- ~AutoGeometryAndStatePush() {
- fTarget->popGeometrySource();
- }
+
+ ~AutoGeometryPush() { fTarget->popGeometrySource(); }
+
private:
- GrDrawTarget* fTarget;
+ 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:
AutoStateRestore fState;
+ GrDrawTarget* fTarget;
};
protected:
@@ -717,6 +739,16 @@
virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) = 0;
// subclass called to perform drawing
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;
// helpers for reserving vertex and index space.
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index 0f9336d..4377967 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -73,10 +73,10 @@
}
}
-void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
- const SkMatrix* matrix,
- const GrRect* localRect,
- const SkMatrix* localMatrix) {
+void GrInOrderDrawBuffer::onDrawRect(const GrRect& rect,
+ const SkMatrix* matrix,
+ const GrRect* localRect,
+ const SkMatrix* localMatrix) {
GrDrawState::AutoColorRestore acr;
GrDrawState* drawState = this->drawState();
diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h
index cb51bc4..ed9f884 100644
--- a/src/gpu/GrInOrderDrawBuffer.h
+++ b/src/gpu/GrInOrderDrawBuffer.h
@@ -76,10 +76,6 @@
virtual void clear(const GrIRect* rect,
GrColor color,
GrRenderTarget* renderTarget = NULL) SK_OVERRIDE;
- virtual void drawRect(const GrRect& rect,
- const SkMatrix* matrix,
- const GrRect* localRect,
- const SkMatrix* localMatrix) SK_OVERRIDE;
protected:
virtual void clipWillBeSet(const GrClipData* newClip) SK_OVERRIDE;
@@ -119,6 +115,10 @@
// overrides from GrDrawTarget
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 bool onReserveVertexSpace(size_t vertexSize,
int vertexCount,