From 0406b9e1faee06c6ecb2732a1bcf3b0e53104e07 Mon Sep 17 00:00:00 2001 From: "bsalomon@google.com" Date: Tue, 2 Apr 2013 21:00:15 +0000 Subject: [PATCH] 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 --- src/gpu/GrAAHairLinePathRenderer.cpp | 1 + src/gpu/GrAARectRenderer.cpp | 1 + src/gpu/GrContext.cpp | 1 + src/gpu/GrDrawState.h | 21 +++++++++++ src/gpu/GrDrawTarget.cpp | 8 ++--- src/gpu/GrDrawTarget.h | 70 ++++++++++++++++++++++++++---------- src/gpu/GrInOrderDrawBuffer.cpp | 8 ++--- src/gpu/GrInOrderDrawBuffer.h | 8 ++--- 8 files changed, 87 insertions(+), 31 deletions(-) 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 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path, 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 @@ void GrAARectRenderer::fillAARect(GrGpu* gpu, 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 @@ void GrContext::drawVertices(const GrPaint& paint, 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 @@ public: 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 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::drawIndexedInstances(GrPrimitiveType type, //////////////////////////////////////////////////////////////////////////////// -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 @@ public: 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 @@ public: * 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 @@ public: //////////////////////////////////////////////////////////////////////////// + /** + * 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: + AutoGeometryPush(GrDrawTarget* target) + : fAttribRestore(target->drawState()) { + GrAssert(NULL != target); + fTarget = target; + target->pushGeometrySource(); + } + + ~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) { + : fState(target, init){ GrAssert(NULL != target); fTarget = target; target->pushGeometrySource(); + if (kPreserve_ASRInit == init) { + target->drawState()->setDefaultVertexAttribs(); + } } - ~AutoGeometryAndStatePush() { - fTarget->popGeometrySource(); - } + + ~AutoGeometryAndStatePush() { fTarget->popGeometrySource(); } + private: - GrDrawTarget* fTarget; AutoStateRestore fState; + GrDrawTarget* fTarget; }; protected: @@ -717,6 +739,16 @@ private: 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 get_vertex_bounds(const void* vertices, } } -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 @@ public: 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 @@ private: // 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, -- 2.7.4