Make drawRect preserve vertex attrib state and push/pop the geom sources.
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 2 Apr 2013 21:00:15 +0000 (21:00 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 2 Apr 2013 21:00:15 +0000 (21:00 +0000)
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
src/gpu/GrAARectRenderer.cpp
src/gpu/GrContext.cpp
src/gpu/GrDrawState.h
src/gpu/GrDrawTarget.cpp
src/gpu/GrDrawTarget.h
src/gpu/GrInOrderDrawBuffer.cpp
src/gpu/GrInOrderDrawBuffer.h

index 08a4111..343fca0 100644 (file)
@@ -842,6 +842,7 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path,
                             kIdxsPerQuad*n);                   // iCount
         quads += n;
     }
+    target->resetIndexSource();
 
     return true;
 }
index 0093b08..6f074e6 100644 (file)
@@ -178,6 +178,7 @@ void GrAARectRenderer::fillAARect(GrGpu* gpu,
     target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1,
                                  kVertsPerAAFillRect,
                                  kIndicesPerAAFillRect);
+    target->resetIndexSource();
 }
 
 void GrAARectRenderer::strokeAARect(GrGpu* gpu,
index 85b2c83..1b62062 100644 (file)
@@ -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);
     }
index 024dfd0..0beebf7 100644 (file)
@@ -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<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.
index e9f5be5..df6965d 100644 (file)
@@ -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},
index e4394e6..fc4cd05 100644 (file)
@@ -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.
index 0f9336d..4377967 100644 (file)
@@ -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();
index cb51bc4..ed9f884 100644 (file)
@@ -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,