Refactor GrDrawTarget vertex/index api
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 21 Jun 2011 18:17:25 +0000 (18:17 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 21 Jun 2011 18:17:25 +0000 (18:17 +0000)
Review URL: http://codereview.appspot.com/4631056/

git-svn-id: http://skia.googlecode.com/svn/trunk@1662 2bbb7eff-a529-9590-31e7-b0007b416f81

13 files changed:
gpu/include/GrDrawTarget.h
gpu/include/GrGpu.h
gpu/include/GrInOrderDrawBuffer.h
gpu/src/GrBufferAllocPool.cpp
gpu/src/GrBufferAllocPool.h
gpu/src/GrDrawTarget.cpp
gpu/src/GrGpu.cpp
gpu/src/GrGpuGL.cpp
gpu/src/GrGpuGL.h
gpu/src/GrGpuGLFixed.cpp
gpu/src/GrGpuGLShaders.cpp
gpu/src/GrInOrderDrawBuffer.cpp
gpu/src/GrTextContext.cpp

index d576d80..e0b66a4 100644 (file)
@@ -202,6 +202,7 @@ public:
     ///////////////////////////////////////////////////////////////////////////
 
     GrDrawTarget();
+    virtual ~GrDrawTarget();
 
     /**
      * Sets the current clip to the region specified by clip. All draws will be
@@ -607,9 +608,14 @@ public:
     GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
 
     /**
-     * There are three paths for specifying geometry (vertices and optionally
+     * There are three methods for specifying geometry (vertices and optionally
      * indices) to the draw target. When indexed drawing the indices and vertices
-     * can be each use a different path.
+     * can use a different method. Once geometry is specified it can be used for
+     * multiple drawIndexed and drawNonIndexed calls.
+     *
+     * Sometimes it is necessary to perform a draw while upstack code has
+     * already specified geometry that it isn't finished with. There are push
+     * pop methods
      *
      * 1. Provide a cpu array (set*SourceToArray). This is useful when the
      *    caller's client has already provided vertex data in a format
@@ -618,69 +624,76 @@ public:
      *    drawIndexed & drawNonIndexed calls until set*SourceToArray is called
      *    again or one of the other two paths is chosen.
      *
-     * 2. Reserve and Lock. This is most useful when the caller has data it must
-     *    transform before drawing and will not likely render it again. The
-     *    caller requests that the draw target make room for some amount of
-     *    vertex and/or index data. The target provides ptrs to hold the data
-     *    data. The caller can write the data into the pts up until the first
-     *    drawIndexed or drawNonIndexed call. At this point the data is frozen
-     *    and the ptrs are no longer guaranteed to be valid. All subsequent
-     *    drawIndexed & drawNonIndexed calls will use this data until
-     *    releaseReserved geometry is called. This must be called before another
-     *    source is set.
+     * 2. Reserve. This is most useful when the caller has data it must
+     *    transform before drawing and is not long-lived. The caller requests
+     *    that the draw target make room for some amount of vertex and/or index
+     *    data. The target provides ptrs to hold the vertex and/or index data.
+     *
+     *    The data is writable up until the next drawIndexed, drawNonIndexed, 
+     *    or pushGeometrySource At this point the data is frozen and the ptrs
+     *    are no longer valid.
      *
      * 3. Vertex and Index Buffers. This is most useful for geometry that will
-     *    be rendered multiple times. SetVertexSourceToBuffer &
-     *    SetIndexSourceToBuffer are used to set the buffer and subsequent
-     *    drawIndexed and drawNonIndexed calls use this source until another
-     *    source is set.
+     *    is long-lived. SetVertexSourceToBuffer and SetIndexSourceToBuffer are
+     *    used to set the buffer and subsequent drawIndexed and drawNonIndexed 
+     *    calls use this source until another source is set.
      */
 
     /**
-     * Reserves space for vertices and/or indices. Draw target will use
-     * reserved vertices / indices at next draw.
+     * Reserves space for vertices. Draw target will use reserved vertices at
+     * at the next draw.
      *
      * If succeeds:
-     *          if vertexCount is nonzero, *vertices will be the array
+     *          if vertexCount > 0, *vertices will be the array
      *          of vertices to be filled by caller. The next draw will read
      *          these vertices.
      *
-     *          if indexCount is nonzero, *indices will be the array of indices
-     *          to be filled by caller. The next indexed draw will read from
-     *          these indices.
-     *
      * If a client does not already have a vertex buffer then this is the
-     * preferred way to allocate vertex/index array. It allows the subclass of
+     * preferred way to allocate vertex data. It allows the subclass of
      * GrDrawTarget to decide whether to put data in buffers, to group vertex
      * data that uses the same state (e.g. for deferred rendering), etc.
      *
-     * Following the first draw after reserveAndLockGeometry the ptrs returned
-     * by releaseReservedGeometry are no longer valid and the geometry data
-     * cannot be further modified. The contents that were put in the reserved
-     * space can be drawn by multiple draws, however.
+     * After the next draw or pushGeometrySource the vertices ptr is no longer
+     * valid and the geometry data cannot be further modified. The contents
+     * that were put in the reserved space can be drawn by multiple draws,
+     * however.
      *
-     * reserveAndLockGeometry must be matched with a releaseReservedGeometry
-     * call after all draws that reference the reserved geometry data have
-     * been called.
-     *
-     * AutoGeometryRelease can be used to automatically call the release.
-     *
-     * @param vertexCount  the number of vertices to reserve space for. Can be 0.
-     * @param indexCount   the number of indices to reserve space for. Can be 0.
      * @param vertexLayout the format of vertices (ignored if vertexCount == 0).
+     * @param vertexCount  the number of vertices to reserve space for. Can be 0.
      * @param vertices     will point to reserved vertex space if vertexCount is
      *                     non-zero. Illegal to pass NULL if vertexCount > 0.
-     * @param indices      will point to reserved index space if indexCount is
-     *                     non-zero. Illegal to pass NULL if indexCount > 0.
      *
      * @return  true if succeeded in allocating space for the vertices and false
      *               if not.
      */
-    bool reserveAndLockGeometry(GrVertexLayout    vertexLayout,
-                                uint32_t          vertexCount,
-                                uint32_t          indexCount,
-                                void**            vertices,
-                                void**            indices);
+    bool reserveVertexSpace(GrVertexLayout vertexLayout,
+                            int vertexCount,
+                            void** vertices);
+    /**
+     * Reserves space for indices. Draw target will use the reserved indices at
+     * the next indexed draw.
+     *
+     * If succeeds:
+     *          if indexCount > 0, *indices will be the array
+     *          of indices to be filled by caller. The next draw will read
+     *          these indices.
+     *
+     * If a client does not already have a index buffer then this is the
+     * preferred way to allocate index data. It allows the subclass of
+     * GrDrawTarget to decide whether to put data in buffers, to group index
+     * data that uses the same state (e.g. for deferred rendering), etc.
+     *
+     * After the next indexed draw or pushGeometrySource the indices ptr is no
+     * longer valid and the geometry data cannot be further modified. The
+     * contents that were put in the reserved space can be drawn by multiple
+     * draws, however.
+     *
+     * @param indexCount   the number of indices to reserve space for. Can be 0.
+     * @param indices      will point to reserved index space if indexCount is
+     *                     non-zero. Illegal to pass NULL if indexCount > 0.
+     */
+
+    bool reserveIndexSpace(int indexCount, void** indices);
     /**
      * Provides hints to caller about the number of vertices and indices
      * that can be allocated cheaply. This can be useful if caller is reserving
@@ -708,11 +721,6 @@ public:
                                int* indexCount) const;
 
     /**
-     * Releases reserved vertex/index data from reserveAndLockGeometry().
-     */
-    void releaseReservedGeometry();
-
-    /**
      * Sets source of vertex data for the next draw. Array must contain
      * the vertex data when this is called.
      *
@@ -752,8 +760,36 @@ public:
      *               before indexed draw call.
      */
     void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
+    
+    /**
+     * Resets vertex source. Drawing from reset vertices is illegal. Set vertex
+     * source to reserved, array, or buffer before next draw. May be able to free
+     * up temporary storage allocated by setVertexSourceToArray or
+     * reserveVertexSpace.
+     */
+    void resetVertexSource();
+    
+    /**
+     * Resets index source. Indexed Drawing from reset indices is illegal. Set
+     * index source to reserved, array, or buffer before next indexed draw. May
+     * be able to free up temporary storage allocated by setIndexSourceToArray
+     * or reserveIndexSpace.
+     */
+    void resetIndexSource(); 
 
     /**
+     * Pushes and resets the vertex/index sources. Any reserved vertex / index
+     * data is finalized (i.e. cannot be updated after the matching pop but can
+     * be drawn from). Must be balanced by a pop.
+     */
+    void pushGeometrySource();
+
+    /**
+     * Pops the vertex / index sources from the matching push.
+     */
+    void popGeometrySource();
+    
+    /**
      * Draws indexed geometry using the current state and current vertex / index
      * sources.
      *
@@ -766,11 +802,11 @@ public:
      *                     is effectively trimmed to the last completely
      *                     specified primitive.
      */
-    virtual void drawIndexed(GrPrimitiveType type,
-                             int startVertex,
-                             int startIndex,
-                             int vertexCount,
-                             int indexCount) = 0;
+    void drawIndexed(GrPrimitiveType type,
+                     int startVertex,
+                     int startIndex,
+                     int vertexCount,
+                     int indexCount);
 
     /**
      * Draws non-indexed geometry using the current state and current vertex
@@ -781,9 +817,9 @@ public:
      *                     to index 0
      * @param vertexCount  one greater than the max index.
      */
-    virtual void drawNonIndexed(GrPrimitiveType type,
-                                int startVertex,
-                                int vertexCount)  = 0;
+    void drawNonIndexed(GrPrimitiveType type,
+                        int startVertex,
+                        int vertexCount);
 
     /**
      * Helper function for drawing rects. This does not use the current index
@@ -840,7 +876,7 @@ public:
      */
     virtual int getMaxEdges() const { return 6; }
 
-    ///////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
 
     class AutoStateRestore : ::GrNoncopyable {
     public:
@@ -860,7 +896,7 @@ public:
         SavedDrawState      fDrawState;
     };
 
-    ///////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
 
     class AutoViewMatrixRestore : ::GrNoncopyable {
     public:
@@ -893,7 +929,7 @@ public:
         GrMatrix            fMatrix;
     };
 
-    ///////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
 
     /** 
      * Sets the view matrix to I and preconcats all stage matrices enabled in
@@ -910,63 +946,36 @@ public:
         int                 fStageMask;
     };
 
-    ///////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
 
     class AutoReleaseGeometry : ::GrNoncopyable {
     public:
         AutoReleaseGeometry(GrDrawTarget*  target,
                             GrVertexLayout vertexLayout,
-                            uint32_t       vertexCount,
-                            uint32_t       indexCount) {
-            fTarget = NULL;
-            this->set(target, vertexLayout, vertexCount, indexCount);
-        }
-
-        AutoReleaseGeometry() {
-            fTarget = NULL;
-        }
-
-        ~AutoReleaseGeometry() {
-            if (NULL != fTarget) {
-                fTarget->releaseReservedGeometry();
-            }
-        }
-
+                            int            vertexCount,
+                            int            indexCount);
+        AutoReleaseGeometry();
+        ~AutoReleaseGeometry();
         bool set(GrDrawTarget*  target,
                  GrVertexLayout vertexLayout,
-                 uint32_t       vertexCount,
-                 uint32_t       indexCount) {
-            if (NULL != fTarget) {
-                fTarget->releaseReservedGeometry();
-            }
-            fTarget = target;
-            if (NULL != fTarget) {
-                if (!fTarget->reserveAndLockGeometry(vertexLayout,
-                                                     vertexCount,
-                                                     indexCount,
-                                                     &fVertices,
-                                                     &fIndices)) {
-                    fTarget = NULL;
-                }
-            }
-            return NULL != fTarget;
-        }
-
+                 int            vertexCount,
+                 int            indexCount);
         bool succeeded() const { return NULL != fTarget; }
         void* vertices() const { return fVertices; }
         void* indices() const { return fIndices; }
-
         GrPoint* positions() const {
             return static_cast<GrPoint*>(fVertices);
         }
 
     private:
+        void reset();
+        
         GrDrawTarget* fTarget;
         void*         fVertices;
         void*         fIndices;
     };
 
-    ///////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////
 
     class AutoClipRestore : ::GrNoncopyable {
     public:
@@ -982,6 +991,22 @@ public:
         GrDrawTarget* fTarget;
         GrClip        fClip;
     };
+    
+    ////////////////////////////////////////////////////////////////////////////
+    
+    class AutoGeometryPush : ::GrNoncopyable {
+    public:
+        AutoGeometryPush(GrDrawTarget* target) {
+            GrAssert(NULL != target);
+            fTarget = target;
+            target->pushGeometrySource();
+        }
+        ~AutoGeometryPush() {
+            fTarget->popGeometrySource();
+        }
+    private:
+        GrDrawTarget* fTarget;
+    };
 
     ////////////////////////////////////////////////////////////////////////////
     // Helpers for picking apart vertex layouts
@@ -1140,6 +1165,34 @@ public:
     static void VertexLayoutUnitTest();
 
 protected:
+    
+    enum GeometrySrcType {
+        kNone_GeometrySrcType,     //<! src has not been specified
+        kReserved_GeometrySrcType, //<! src was set using reserve*Space
+        kArray_GeometrySrcType,    //<! src was set using set*SourceToArray
+        kBuffer_GeometrySrcType    //<! src was set using set*SourceToBuffer
+    };
+    
+    struct GeometrySrcState {
+        GeometrySrcType         fVertexSrc;
+        union {
+            // valid if src type is buffer
+            const GrVertexBuffer*   fVertexBuffer;
+            // valid if src type is reserved or array
+            int                     fVertexCount;
+        };
+        
+        GeometrySrcType         fIndexSrc;
+        union {
+            // valid if src type is buffer
+            const GrIndexBuffer*    fIndexBuffer;
+            // valid if src type is reserved or array
+            int                     fIndexCount;
+        };
+        
+        GrVertexLayout          fVertexLayout;
+    };
+    
     // given a vertex layout and a draw state, will a stage be used?
     static bool StageWillBeUsed(int stage, GrVertexLayout layout, 
                          const DrState& state) {
@@ -1147,7 +1200,8 @@ protected:
     }
 
     bool isStageEnabled(int stage) const {
-        return StageWillBeUsed(stage, fGeometrySrc.fVertexLayout, fCurrDrawState);
+        return StageWillBeUsed(stage, this->getGeomSrc().fVertexLayout, 
+                               fCurrDrawState);
     }
 
     // Helpers for GrDrawTarget subclasses that won't have private access to
@@ -1157,21 +1211,38 @@ protected:
     static const DrState& accessSavedDrawState(const SavedDrawState& sds)
                                                         { return sds.fState; }
 
-    // implemented by subclass
-    virtual bool onAcquireGeometry(GrVertexLayout vertexLayout,
-                                   void** vertices,
-                                   void** indices) = 0;
-
-    virtual void onReleaseGeometry() = 0;
-
-    // subclass overrides to be notified when clip is set.
-    virtual void clipWillBeSet(const GrClip& clip) = 0;
-
+    // implemented by subclass to allocate space for reserved geom
+    virtual bool onReserveVertexSpace(GrVertexLayout vertexLayout,
+                                      int vertexCount,
+                                      void** vertices) = 0;
+    virtual bool onReserveIndexSpace(int indexCount, void** indices) = 0;
+    // implemented by subclass to handle release of reserved geom space
+    virtual void releaseReservedVertexSpace() = 0;
+    virtual void releaseReservedIndexSpace() = 0;
+    // subclass must consume array contents when set
     virtual void onSetVertexSourceToArray(const void* vertexArray,
                                           int vertexCount) = 0;
-
     virtual void onSetIndexSourceToArray(const void* indexArray,
                                          int indexCount) = 0;
+    // subclass is notified that geom source will be set away from an array
+    virtual void releaseVertexArray() = 0;
+    virtual void releaseIndexArray() = 0;
+    // subclass overrides to be notified just before geo src state
+    // is pushed/popped.
+    virtual void geometrySourceWillPush() = 0;
+    virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) = 0;
+    // subclass called to perform drawing
+    virtual void onDrawIndexed(GrPrimitiveType type,
+                               int startVertex,
+                               int startIndex,
+                               int vertexCount,
+                               int indexCount) = 0;
+    virtual void onDrawNonIndexed(GrPrimitiveType type,
+                                  int startVertex,
+                                  int vertexCount) = 0;
+    // subclass overrides to be notified when clip is set.
+    virtual void clipWillBeSet(const GrClip& clip) = 0;
+
 
     // Helpers for drawRect, protected so subclasses that override drawRect
     // can use them.
@@ -1185,51 +1256,28 @@ protected:
                                 GrVertexLayout layout,
                                 void* vertices);
 
-    enum GeometrySrcType {
-        kReserved_GeometrySrcType,  // src was set using reserveAndLockGeometry
-        kArray_GeometrySrcType,     // src was set using set*SourceToArray
-        kBuffer_GeometrySrcType     // src was set using set*SourceToBuffer
-    };
-
-    struct ReservedGeometry {
-        bool            fLocked;
-        uint32_t        fVertexCount;
-        uint32_t        fIndexCount;
-    } fReservedGeometry;
-
-    struct GeometrySrc {
-        GeometrySrcType         fVertexSrc;
-        const GrVertexBuffer*   fVertexBuffer; // valid if src type is buffer
-        GeometrySrcType         fIndexSrc;
-        const GrIndexBuffer*    fIndexBuffer; // valid if src type is buffer
-        GrVertexLayout          fVertexLayout;
-    } fGeometrySrc;
+    // accessor for derived classes
+    const GeometrySrcState& getGeomSrc() const {
+        return fGeoSrcStateStack.back();
+    }
 
     GrClip fClip;
 
     DrState fCurrDrawState;
 
-    // Not meant for external use. Only setVertexSourceToBuffer and
-    // setIndexSourceToBuffer will work since GrDrawTarget subclasses don't
-    // support nested reserveAndLockGeometry (and cpu arrays internally use the
-    // same path).
-    class AutoGeometrySrcRestore {
-    public:
-        AutoGeometrySrcRestore(GrDrawTarget* target) {
-            fTarget = target;
-            fGeometrySrc = fTarget->fGeometrySrc;
-        }
-        ~AutoGeometrySrcRestore() {
-            fTarget->fGeometrySrc = fGeometrySrc;
-        }
-    private:
-        GrDrawTarget *fTarget;
-        GeometrySrc  fGeometrySrc;
-
-        AutoGeometrySrcRestore();
-        AutoGeometrySrcRestore(const AutoGeometrySrcRestore&);
-        AutoGeometrySrcRestore& operator =(AutoGeometrySrcRestore&);
+private:
+    // called when setting a new vert/idx source to unref prev vb/ib
+    void releasePreviousVertexSource();
+    void releasePreviousIndexSource();
+    
+    enum {
+        kPreallocGeoSrcStateStackCnt = 4,
     };
+    GrAlignedSTStorage<kPreallocGeoSrcStateStackCnt, 
+                        GeometrySrcState> 
+                                     fGeoSrcStateStackStorage;
+    GrTArray<GeometrySrcState, true> fGeoSrcStateStack;
+    
 };
 
 #endif
index 34ddccf..d3629b5 100644 (file)
@@ -262,16 +262,6 @@ public:
      */
     int maxRenderTargetSize() const { return fMaxRenderTargetSize; }
 
-    // GrDrawTarget overrides
-    virtual void drawIndexed(GrPrimitiveType type,
-                             int startVertex,
-                             int startIndex,
-                             int vertexCount,
-                             int indexCount);
-
-    virtual void drawNonIndexed(GrPrimitiveType type,
-                                int startVertex,
-                                int vertexCount);
     virtual void clear(const GrIRect* rect, GrColor color);
 
     /**
@@ -416,23 +406,33 @@ protected:
 
     GrGpuStats fStats;
 
-    const GrVertexBuffer*           fCurrPoolVertexBuffer;
-    int                             fCurrPoolStartVertex;
-
-    const GrIndexBuffer*            fCurrPoolIndexBuffer;
-    int                             fCurrPoolStartIndex;
+    struct GeometryPoolState {
+        const GrVertexBuffer* fPoolVertexBuffer;
+        int                   fPoolStartVertex;
+        
+        const GrIndexBuffer*  fPoolIndexBuffer;
+        int                   fPoolStartIndex;
+    };
+    const GeometryPoolState& getGeomPoolState() { 
+        return fGeomPoolStateStack.back(); 
+    }
 
     // GrDrawTarget overrides
-    virtual bool onAcquireGeometry(GrVertexLayout vertexLayout,
-                                   void**         vertices,
-                                   void**         indices);
-    virtual void onReleaseGeometry();
-
+    virtual bool onReserveVertexSpace(GrVertexLayout vertexLayout,
+                                      int vertexCount,
+                                      void** vertices);
+    virtual bool onReserveIndexSpace(int indexCount, void** indices);
+    virtual void releaseReservedVertexSpace();
+    virtual void releaseReservedIndexSpace();    
     virtual void onSetVertexSourceToArray(const void* vertexArray,
                                           int vertexCount);
-
     virtual void onSetIndexSourceToArray(const void* indexArray,
                                          int indexCount);
+    virtual void releaseVertexArray();
+    virtual void releaseIndexArray();
+    virtual void geometrySourceWillPush();
+    virtual void geometrySourceWillPop(const GeometrySrcState& restoredState);
+
     // Helpers for setting up geometry state
     void finalizeReservedVertices();
     void finalizeReservedIndices();
@@ -457,15 +457,15 @@ protected:
     virtual void onClear(const GrIRect* rect, GrColor color) = 0;
 
     // overridden by API-specific derived class to perform the draw call.
-    virtual void onDrawIndexed(GrPrimitiveType type,
-                               uint32_t startVertex,
-                               uint32_t startIndex,
-                               uint32_t vertexCount,
-                               uint32_t indexCount) = 0;
-
-    virtual void onDrawNonIndexed(GrPrimitiveType type,
+    virtual void onGpuDrawIndexed(GrPrimitiveType type,
+                                  uint32_t startVertex,
+                                  uint32_t startIndex,
                                   uint32_t vertexCount,
-                                  uint32_t numVertices) = 0;
+                                  uint32_t indexCount) = 0;
+
+    virtual void onGpuDrawNonIndexed(GrPrimitiveType type,
+                                     uint32_t vertexCount,
+                                     uint32_t numVertices) = 0;
 
     // overridden by API-specific derived class to perform flush
     virtual void onForceRenderTargetFlush() = 0;
@@ -502,7 +502,18 @@ private:
     GrVertexBufferAllocPool*    fVertexPool;
 
     GrIndexBufferAllocPool*     fIndexPool;
-
+    
+    // counts number of uses of vertex/index pool in the geometry stack
+    int                         fVertexPoolUseCnt;
+    int                         fIndexPoolUseCnt;
+    
+    enum {
+        kPreallocGeomPoolStateStackCnt = 4,
+    };
+    GrAlignedSTStorage<kPreallocGeomPoolStateStackCnt, 
+                       GeometryPoolState>           fGeoSrcStateStackStorage;
+    GrTArray<GeometryPoolState, true>               fGeomPoolStateStack;
+    
     mutable GrIndexBuffer*      fQuadIndexBuffer; // mutable so it can be
                                                   // created on-demand
 
@@ -514,14 +525,18 @@ private:
 
     bool                        fContextIsDirty;
 
-    // when in an internal draw these indicate whether the pools are in use
-    // by one of the outer draws. If false then it is safe to reset the
-    // pool.
-    bool                        fVertexPoolInUse;
-    bool                        fIndexPoolInUse;
-
     GrResource*                 fResourceHead;
 
+    // GrDrawTarget overrides
+    virtual void onDrawIndexed(GrPrimitiveType type,
+                               int startVertex,
+                               int startIndex,
+                               int vertexCount,
+                               int indexCount);
+    virtual void onDrawNonIndexed(GrPrimitiveType type,
+                                  int startVertex,
+                                  int vertexCount);
+
     // readies the pools to provide vertex/index data.
     void prepareVertexPool();
     void prepareIndexPool();
@@ -536,52 +551,6 @@ private:
         }
     }
 
-    // used to save and restore state when the GrGpu needs
-    // to make its geometry pools available internally
-    class AutoInternalDrawGeomRestore {
-    public:
-        AutoInternalDrawGeomRestore(GrGpu* gpu) : fAgsr(gpu) {
-            fGpu = gpu;
-
-            fVertexPoolWasInUse = gpu->fVertexPoolInUse;
-            fIndexPoolWasInUse  = gpu->fIndexPoolInUse;
-
-            gpu->fVertexPoolInUse = fVertexPoolWasInUse ||
-                                   (kBuffer_GeometrySrcType !=
-                                    gpu->fGeometrySrc.fVertexSrc);
-            gpu->fIndexPoolInUse  = fIndexPoolWasInUse ||
-                                   (kBuffer_GeometrySrcType !=
-                                    gpu->fGeometrySrc.fIndexSrc);;
-
-            fSavedPoolVertexBuffer = gpu->fCurrPoolVertexBuffer;
-            fSavedPoolStartVertex  = gpu->fCurrPoolStartVertex;
-            fSavedPoolIndexBuffer  = gpu->fCurrPoolIndexBuffer;
-            fSavedPoolStartIndex   = gpu->fCurrPoolStartIndex;
-
-            fSavedReservedGeometry = gpu->fReservedGeometry;
-            gpu->fReservedGeometry.fLocked = false;
-        }
-        ~AutoInternalDrawGeomRestore() {
-            fGpu->fCurrPoolVertexBuffer = fSavedPoolVertexBuffer;
-            fGpu->fCurrPoolStartVertex  = fSavedPoolStartVertex;
-            fGpu->fCurrPoolIndexBuffer  = fSavedPoolIndexBuffer;
-            fGpu->fCurrPoolStartIndex   = fSavedPoolStartIndex;
-            fGpu->fVertexPoolInUse = fVertexPoolWasInUse;
-            fGpu->fIndexPoolInUse  = fIndexPoolWasInUse;
-            fGpu->fReservedGeometry = fSavedReservedGeometry;
-        }
-    private:
-        AutoGeometrySrcRestore  fAgsr;
-        GrGpu*                  fGpu;
-        const GrVertexBuffer*   fSavedPoolVertexBuffer;
-        int                     fSavedPoolStartVertex;
-        const GrIndexBuffer*    fSavedPoolIndexBuffer;
-        int                     fSavedPoolStartIndex;
-        bool                    fVertexPoolWasInUse;
-        bool                    fIndexPoolWasInUse;
-        ReservedGeometry        fSavedReservedGeometry;
-    };
-
     typedef GrDrawTarget INHERITED;
 };
 
index b26cd72..6a8db21 100644 (file)
@@ -81,15 +81,6 @@ public:
     void playback(GrDrawTarget* target);
     
     // overrides from GrDrawTarget
-    virtual void drawIndexed(GrPrimitiveType primitiveType,
-                             int startVertex,
-                             int startIndex,
-                             int vertexCount,
-                             int indexCount);
-    virtual void drawNonIndexed(GrPrimitiveType primitiveType,
-                                int startVertex,
-                                int vertexCount);
-
     virtual void drawRect(const GrRect& rect, 
                           const GrMatrix* matrix = NULL,
                           int stageEnableMask = 0,
@@ -123,17 +114,30 @@ private:
         GrColor fColor;
     };
 
-    virtual bool onAcquireGeometry(GrVertexLayout vertexLayout,
-                                   void**         vertices,
-                                   void**         indices);
-    virtual void onReleaseGeometry();
-    virtual void clipWillBeSet(const GrClip& newClip);
-
+    // overrides from GrDrawTarget
+    virtual void onDrawIndexed(GrPrimitiveType primitiveType,
+                               int startVertex,
+                               int startIndex,
+                               int vertexCount,
+                               int indexCount);
+    virtual void onDrawNonIndexed(GrPrimitiveType primitiveType,
+                                  int startVertex,
+                                  int vertexCount);
+    virtual bool onReserveVertexSpace(GrVertexLayout layout, 
+                                      int vertexCount,
+                                      void** vertices);
+    virtual bool onReserveIndexSpace(int indexCount, void** indices);
+    virtual void releaseReservedVertexSpace();
+    virtual void releaseReservedIndexSpace();
     virtual void onSetVertexSourceToArray(const void* vertexArray,
-                                         int vertexCount);
-
+                                          int vertexCount);
     virtual void onSetIndexSourceToArray(const void* indexArray,
                                          int indexCount);
+    virtual void releaseVertexArray();
+    virtual void releaseIndexArray();
+    virtual void geometrySourceWillPush();
+    virtual void geometrySourceWillPop(const GeometrySrcState& restoredState);
+    virtual void clipWillBeSet(const GrClip& newClip);
 
     bool needsNewState() const;
     bool needsNewClip() const;
@@ -154,31 +158,36 @@ private:
     int                             fCurrQuad;
 
     GrVertexBufferAllocPool&        fVertexPool;
-    const GrVertexBuffer*           fCurrPoolVertexBuffer;
-    int                             fCurrPoolStartVertex;
 
     GrIndexBufferAllocPool&         fIndexPool;
-    const GrIndexBuffer*            fCurrPoolIndexBuffer;
-    int                             fCurrPoolStartIndex;
-
-    // caller may conservatively over reserve vertices / indices.
-    // we release unused space back to allocator if possible
-    size_t                          fReservedVertexBytes;
-    size_t                          fReservedIndexBytes;
-    size_t                          fUsedReservedVertexBytes;
-    size_t                          fUsedReservedIndexBytes;
+    struct GeometryPoolState {
+        const GrVertexBuffer*           fPoolVertexBuffer;
+        int                             fPoolStartVertex;
+        const GrIndexBuffer*            fPoolIndexBuffer;
+        int                             fPoolStartIndex;
+        // caller may conservatively over reserve vertices / indices.
+        // we release unused space back to allocator if possible
+        // can only do this if there isn't an intervening pushGeometrySource()
+        size_t                          fUsedPoolVertexBytes;
+        size_t                          fUsedPoolIndexBytes;
+    };
+    GrTArray<GeometryPoolState> fGeoPoolStateStack;
+
     
     enum {
-        kDrawPreallocCnt   = 8,
-        kStatePreallocCnt  = 8,
-        kClipPreallocCnt   = 8,
-        kClearPreallocCnt  = 4,
+        kDrawPreallocCnt         = 8,
+        kStatePreallocCnt        = 8,
+        kClipPreallocCnt         = 8,
+        kClearPreallocCnt        = 4,
+        kGeoPoolStatePreAllocCnt = 4,
     };
 
     GrAlignedSTStorage<kDrawPreallocCnt, Draw>              fDrawStorage;
     GrAlignedSTStorage<kStatePreallocCnt, SavedDrawState>   fStateStorage;
     GrAlignedSTStorage<kClipPreallocCnt, GrClip>            fClipStorage;
     GrAlignedSTStorage<kClearPreallocCnt, Clear>            fClearStorage;
+    GrAlignedSTStorage<kGeoPoolStatePreAllocCnt, 
+                        GeometryPoolState>                  fGeoStackStorage;
 
     typedef GrDrawTarget INHERITED;
 };
index d786b02..73d707f 100644 (file)
 #if GR_DEBUG
     #define VALIDATE validate
 #else
-    #define VALIDATE()
+    static void VALIDATE(bool x = false) {}
 #endif
 
+// page size
 #define GrBufferAllocPool_MIN_BLOCK_SIZE ((size_t)1 << 12)
 
 GrBufferAllocPool::GrBufferAllocPool(GrGpu* gpu,
@@ -45,6 +46,8 @@ GrBufferAllocPool::GrBufferAllocPool(GrGpu* gpu,
     fBufferPtr = NULL;
     fMinBlockSize = GrMax(GrBufferAllocPool_MIN_BLOCK_SIZE, blockSize);
 
+    fBytesInUse = 0;
+            
     fPreallocBuffersInUse = 0;
     fFirstPreallocBuffer = 0;
     for (int i = 0; i < preallocBufferCnt; ++i) {
@@ -80,6 +83,7 @@ void GrBufferAllocPool::releaseGpuRef() {
 
 void GrBufferAllocPool::reset() {
     VALIDATE();
+    fBytesInUse = 0;
     if (fBlocks.count()) {
         GrGeometryBuffer* buffer = fBlocks.back().fBuffer;
         if (buffer->isLocked()) {
@@ -116,7 +120,7 @@ void GrBufferAllocPool::unlock() {
 }
 
 #if GR_DEBUG
-void GrBufferAllocPool::validate() const {
+void GrBufferAllocPool::validate(bool unusedBlockAllowed) const {
     if (NULL != fBufferPtr) {
         GrAssert(!fBlocks.empty());
         if (fBlocks.back().fBuffer->isLocked()) {
@@ -129,9 +133,23 @@ void GrBufferAllocPool::validate() const {
     } else {
         GrAssert(fBlocks.empty() || !fBlocks.back().fBuffer->isLocked());
     }
+    size_t bytesInUse = 0;
     for (int i = 0; i < fBlocks.count() - 1; ++i) {
         GrAssert(!fBlocks[i].fBuffer->isLocked());
     }
+    for (int i = 0; i < fBlocks.count(); ++i) {
+        size_t bytes = fBlocks[i].fBuffer->size() - fBlocks[i].fBytesFree; 
+        bytesInUse += bytes;
+        GrAssert(bytes || unusedBlockAllowed);
+    }
+    
+    GrAssert(bytesInUse == fBytesInUse);
+    if (unusedBlockAllowed) {
+        GrAssert((fBytesInUse && !fBlocks.empty()) ||
+                 (!fBytesInUse && (fBlocks.count() < 2)));
+    } else {
+        GrAssert((0 == fBytesInUse) == fBlocks.empty());
+    }
 }
 #endif
 
@@ -154,20 +172,27 @@ void* GrBufferAllocPool::makeSpace(size_t size,
             *offset = usedBytes;
             *buffer = back.fBuffer;
             back.fBytesFree -= size + pad;
+            fBytesInUse += size;
             return (void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes);
         }
     }
 
+    // We could honor the space request using updateSubData on the current VB
+    // (if there is room). But we don't currently use draw calls to GL that
+    // allow the driver to know that previously issued draws won't read from
+    // the part of the buffer we update.
+    
     if (!createBlock(size)) {
         return NULL;
     }
-    VALIDATE();
     GrAssert(NULL != fBufferPtr);
 
     *offset = 0;
     BufferBlock& back = fBlocks.back();
     *buffer = back.fBuffer;
     back.fBytesFree -= size;
+    fBytesInUse += size;
+    VALIDATE();
     return fBufferPtr;
 }
 
@@ -194,29 +219,24 @@ int GrBufferAllocPool::preallocatedBufferCount() const {
 
 void GrBufferAllocPool::putBack(size_t bytes) {
     VALIDATE();
-    if (NULL != fBufferPtr) {
-        BufferBlock& back = fBlocks.back();
-        size_t bytesUsed = back.fBuffer->size() - back.fBytesFree;
+
+    while (bytes) {
+        // caller shouldnt try to put back more than they've taken
+        GrAssert(!fBlocks.empty());
+        BufferBlock& block = fBlocks.back();
+        size_t bytesUsed = block.fBuffer->size() - block.fBytesFree;
         if (bytes >= bytesUsed) {
-            destroyBlock();
             bytes -= bytesUsed;
+            fBytesInUse -= bytesUsed;
+            destroyBlock();
         } else {
-            back.fBytesFree += bytes;
-            return;
+            block.fBytesFree += bytes;
+            fBytesInUse -= bytes;
+            bytes = 0;
+            break;
         }
     }
     VALIDATE();
-    GrAssert(NULL == fBufferPtr);
-    // we don't partially roll-back buffers because our VB semantics say locking
-    // a VB discards its previous content.
-    // We could honor it by being sure we use updateSubData and not lock
-    // we will roll-back fully released buffers, though.
-    while (!fBlocks.empty() &&
-           bytes >= fBlocks.back().fBuffer->size()) {
-        bytes -= fBlocks.back().fBuffer->size();
-        destroyBlock();
-    }
-    VALIDATE();
 }
 
 bool GrBufferAllocPool::createBlock(size_t requestSize) {
@@ -269,7 +289,7 @@ bool GrBufferAllocPool::createBlock(size_t requestSize) {
         fBufferPtr = fCpuData.realloc(size);
     }
 
-    VALIDATE();
+    VALIDATE(true);
 
     return true;
 }
index 7d70ebb..c18e36b 100644 (file)
@@ -169,8 +169,10 @@ private:
     void destroyBlock();
     void flushCpuData(GrGeometryBuffer* buffer, size_t flushSize);
 #if GR_DEBUG
-    void validate() const;
+    void validate(bool unusedBlockAllowed = false) const;
 #endif
+    
+    size_t                          fBytesInUse;
 
     GrGpu*                          fGpu;
     bool                            fGpuIsReffed;
index b5f9259..cc64058 100644 (file)
@@ -18,6 +18,8 @@
 #include "GrDrawTarget.h"
 #include "GrGpuVertex.h"
 #include "GrTexture.h"
+#include "GrVertexBuffer.h"
+#include "GrIndexBuffer.h"
 
 namespace {
 
@@ -282,17 +284,33 @@ void GrDrawTarget::VertexLayoutUnitTest() {
 
 ////////////////////////////////////////////////////////////////////////////////
 
-GrDrawTarget::GrDrawTarget() {
+#define DEBUG_INVAL_BUFFER 0xdeadcafe
+#define DEBUG_INVAL_START_IDX -1
+
+GrDrawTarget::GrDrawTarget() 
+: fGeoSrcStateStack(&fGeoSrcStateStackStorage) {
 #if GR_DEBUG
     VertexLayoutUnitTest();
 #endif
-    fReservedGeometry.fLocked = false;
+    GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
 #if GR_DEBUG
-    fReservedGeometry.fVertexCount  = ~0;
-    fReservedGeometry.fIndexCount   = ~0;
+    geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
+    geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
+    geoSrc.fIndexCount = DEBUG_INVAL_START_IDX;
+    geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
 #endif
-    fGeometrySrc.fVertexSrc = kReserved_GeometrySrcType;
-    fGeometrySrc.fIndexSrc  = kReserved_GeometrySrcType;
+    geoSrc.fVertexSrc = kNone_GeometrySrcType;
+    geoSrc.fIndexSrc  = kNone_GeometrySrcType;
+}
+
+GrDrawTarget::~GrDrawTarget() {
+    int popCnt = fGeoSrcStateStack.count() - 1;
+    while (popCnt) {
+        this->popGeometrySource();
+        --popCnt;
+    }
+    this->releasePreviousVertexSource();
+    this->releasePreviousIndexSource();
 }
 
 void GrDrawTarget::setClip(const GrClip& clip) {
@@ -429,39 +447,54 @@ void GrDrawTarget::copyDrawState(const GrDrawTarget& srcTarget) {
     fCurrDrawState = srcTarget.fCurrDrawState;
 }
 
+bool GrDrawTarget::reserveVertexSpace(GrVertexLayout vertexLayout,
+                                      int vertexCount,
+                                      void** vertices) {
+    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+    bool acquired = false;
+    if (vertexCount > 0) {
+        GrAssert(NULL != vertices);
+        this->releasePreviousVertexSource();
+        geoSrc.fVertexSrc = kNone_GeometrySrcType;
 
-bool GrDrawTarget::reserveAndLockGeometry(GrVertexLayout    vertexLayout,
-                                          uint32_t          vertexCount,
-                                          uint32_t          indexCount,
-                                          void**            vertices,
-                                          void**            indices) {
-    GrAssert(!fReservedGeometry.fLocked);
-    fReservedGeometry.fVertexCount  = vertexCount;
-    fReservedGeometry.fIndexCount   = indexCount;
-
-    fReservedGeometry.fLocked = this->onAcquireGeometry(vertexLayout,
-                                                        vertices,
-                                                        indices);
-    if (fReservedGeometry.fLocked) {
-        if (vertexCount) {
-            fGeometrySrc.fVertexSrc = kReserved_GeometrySrcType;
-            fGeometrySrc.fVertexLayout = vertexLayout;
-        } else if (NULL != vertices) {
-            *vertices = NULL;
-        }
-        if (indexCount) {
-            fGeometrySrc.fIndexSrc = kReserved_GeometrySrcType;
-        } else if (NULL != indices) {
-            *indices = NULL;
-        }
+        acquired = this->onReserveVertexSpace(vertexLayout,
+                                              vertexCount,
+                                              vertices);
+    }
+    if (acquired) {
+        geoSrc.fVertexSrc = kReserved_GeometrySrcType;
+        geoSrc.fVertexCount = vertexCount;
+        geoSrc.fVertexLayout = vertexLayout;
+    } else if (NULL != vertices) {
+        *vertices = NULL;
+    }
+    return acquired;
+}
+
+bool GrDrawTarget::reserveIndexSpace(int indexCount,
+                                     void** indices) {
+    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+    bool acquired = false;
+    if (indexCount > 0) {
+        GrAssert(NULL != indices);
+        this->releasePreviousIndexSource();
+        geoSrc.fIndexSrc = kNone_GeometrySrcType;
+        
+        acquired = this->onReserveIndexSpace(indexCount, indices);
     }
-    return fReservedGeometry.fLocked;
+    if (acquired) {
+        geoSrc.fIndexSrc = kReserved_GeometrySrcType;
+        geoSrc.fIndexCount = indexCount;
+    } else if (NULL != indices) {
+        *indices = NULL;
+    }
+    return acquired;
+    
 }
 
 bool GrDrawTarget::geometryHints(GrVertexLayout vertexLayout,
                                  int32_t* vertexCount,
                                  int32_t* indexCount) const {
-    GrAssert(!fReservedGeometry.fLocked);
     if (NULL != vertexCount) {
         *vertexCount = -1;
     }
@@ -471,39 +504,199 @@ bool GrDrawTarget::geometryHints(GrVertexLayout vertexLayout,
     return false;
 }
 
-void GrDrawTarget::releaseReservedGeometry() {
-    GrAssert(fReservedGeometry.fLocked);
-    this->onReleaseGeometry();
-    fReservedGeometry.fLocked = false;
+void GrDrawTarget::releasePreviousVertexSource() {
+    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+    switch (geoSrc.fVertexSrc) {
+        case kNone_GeometrySrcType:
+            break;
+        case kArray_GeometrySrcType:
+            this->releaseVertexArray();
+            break;
+        case kReserved_GeometrySrcType:
+            this->releaseReservedVertexSpace();
+            break;
+        case kBuffer_GeometrySrcType:
+            geoSrc.fVertexBuffer->unref();
+#if GR_DEBUG
+            geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
+#endif
+            break;
+        default:
+            GrCrash("Unknown Vertex Source Type.");
+            break;
+    }
+}
+
+void GrDrawTarget::releasePreviousIndexSource() {
+    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+    switch (geoSrc.fIndexSrc) {
+        case kNone_GeometrySrcType:   // these two don't require
+            break;
+        case kArray_GeometrySrcType:
+            this->releaseIndexArray();
+            break;
+        case kReserved_GeometrySrcType:
+            this->releaseReservedIndexSpace();
+            break;
+        case kBuffer_GeometrySrcType:
+            geoSrc.fIndexBuffer->unref();
+#if GR_DEBUG
+            geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
+#endif
+            break;
+        default:
+            GrCrash("Unknown Index Source Type.");
+            break;
+    }
 }
 
 void GrDrawTarget::setVertexSourceToArray(GrVertexLayout vertexLayout,
                                           const void* vertexArray,
                                           int vertexCount) {
-    fGeometrySrc.fVertexSrc = kArray_GeometrySrcType;
-    fGeometrySrc.fVertexLayout = vertexLayout;
+    this->releasePreviousVertexSource();
+    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+    geoSrc.fVertexSrc = kArray_GeometrySrcType;
+    geoSrc.fVertexLayout = vertexLayout;
+    geoSrc.fVertexCount = vertexCount;
     this->onSetVertexSourceToArray(vertexArray, vertexCount);
 }
 
 void GrDrawTarget::setIndexSourceToArray(const void* indexArray,
                                          int indexCount) {
-    fGeometrySrc.fIndexSrc = kArray_GeometrySrcType;
+    this->releasePreviousIndexSource();
+    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+    geoSrc.fIndexSrc = kArray_GeometrySrcType;
+    geoSrc.fIndexCount = indexCount;
     this->onSetIndexSourceToArray(indexArray, indexCount);
 }
 
 void GrDrawTarget::setVertexSourceToBuffer(GrVertexLayout vertexLayout,
                                            const GrVertexBuffer* buffer) {
-    fGeometrySrc.fVertexSrc    = kBuffer_GeometrySrcType;
-    fGeometrySrc.fVertexBuffer = buffer;
-    fGeometrySrc.fVertexLayout = vertexLayout;
+    this->releasePreviousVertexSource();
+    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+    geoSrc.fVertexSrc    = kBuffer_GeometrySrcType;
+    geoSrc.fVertexBuffer = buffer;
+    buffer->ref();
+    geoSrc.fVertexLayout = vertexLayout;
 }
 
 void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
-    fGeometrySrc.fIndexSrc     = kBuffer_GeometrySrcType;
-    fGeometrySrc.fIndexBuffer  = buffer;
+    this->releasePreviousIndexSource();
+    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+    geoSrc.fIndexSrc     = kBuffer_GeometrySrcType;
+    geoSrc.fIndexBuffer  = buffer;
+    buffer->ref();
 }
 
-///////////////////////////////////////////////////////////////////////////////
+void GrDrawTarget::resetVertexSource() {
+    this->releasePreviousVertexSource();
+    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+    geoSrc.fVertexSrc = kNone_GeometrySrcType;
+}
+
+void GrDrawTarget::resetIndexSource() {
+    this->releasePreviousIndexSource();
+    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+    geoSrc.fIndexSrc = kNone_GeometrySrcType;
+}
+
+void GrDrawTarget::pushGeometrySource() {
+    this->geometrySourceWillPush();
+    GeometrySrcState& newState = fGeoSrcStateStack.push_back();
+    newState.fIndexSrc = kNone_GeometrySrcType;
+    newState.fVertexSrc = kNone_GeometrySrcType;
+#if GR_DEBUG
+    newState.fVertexCount  = ~0;
+    newState.fVertexBuffer = (GrVertexBuffer*)~0;
+    newState.fIndexCount   = ~0;
+    newState.fIndexBuffer = (GrIndexBuffer*)~0;
+#endif
+}
+
+void GrDrawTarget::popGeometrySource() {
+    const GeometrySrcState& geoSrc = this->getGeomSrc();
+    // if popping last element then pops are unbalanced with pushes
+    GrAssert(fGeoSrcStateStack.count() > 1);
+    
+    this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1));
+    this->releasePreviousVertexSource();
+    this->releasePreviousIndexSource();
+    fGeoSrcStateStack.pop_back();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void GrDrawTarget::drawIndexed(GrPrimitiveType type, int startVertex,
+                               int startIndex, int vertexCount,
+                               int indexCount) {
+#if GR_DEBUG
+    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+    int maxVertex = startVertex + vertexCount;
+    int maxValidVertex;
+    switch (geoSrc.fVertexSrc) {
+        case kNone_GeometrySrcType:
+            GrCrash("Attempting to draw indexed geom without vertex src.");
+        case kReserved_GeometrySrcType: // fallthrough
+        case kArray_GeometrySrcType:
+            maxValidVertex = geoSrc.fVertexCount;
+            break;
+        case kBuffer_GeometrySrcType:
+            maxValidVertex = geoSrc.fVertexBuffer->size() / 
+                             VertexSize(geoSrc.fVertexLayout);
+            break;
+    }
+    if (maxVertex > maxValidVertex) {
+        GrCrash("Indexed drawing outside valid vertex range.");
+    }
+    int maxIndex = startIndex + indexCount;
+    int maxValidIndex;
+    switch (geoSrc.fIndexSrc) {
+        case kNone_GeometrySrcType:
+            GrCrash("Attempting to draw indexed geom without index src.");
+        case kReserved_GeometrySrcType: // fallthrough
+        case kArray_GeometrySrcType:
+            maxValidIndex = geoSrc.fIndexCount;
+            break;
+        case kBuffer_GeometrySrcType:
+            maxValidIndex = geoSrc.fIndexBuffer->size() / sizeof(uint16_t);
+            break;
+    }
+    if (maxIndex > maxValidIndex) {
+        GrCrash("Indexed drawing outside valid index range.");
+    }
+#endif
+    this->onDrawIndexed(type, startVertex, startIndex,
+                        vertexCount, indexCount);
+}
+
+
+void GrDrawTarget::drawNonIndexed(GrPrimitiveType type,
+                                  int startVertex,
+                                  int vertexCount) {
+#if GR_DEBUG
+    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
+    int maxVertex = startVertex + vertexCount;
+    int maxValidVertex;
+    switch (geoSrc.fVertexSrc) {
+        case kNone_GeometrySrcType:
+            GrCrash("Attempting to draw non-indexed geom without vertex src.");
+        case kReserved_GeometrySrcType: // fallthrough
+        case kArray_GeometrySrcType:
+            maxValidVertex = geoSrc.fVertexCount;
+            break;
+        case kBuffer_GeometrySrcType:
+            maxValidVertex = geoSrc.fVertexBuffer->size() / 
+            VertexSize(geoSrc.fVertexLayout);
+            break;
+    }
+    if (maxVertex > maxValidVertex) {
+        GrCrash("Non-indexed drawing outside valid vertex range.");
+    }
+#endif
+    this->onDrawNonIndexed(type, startVertex, vertexCount);
+}
+
+////////////////////////////////////////////////////////////////////////////////
 
 bool GrDrawTarget::canDisableBlend() const {
     // If we compute a coverage value (using edge AA or a coverage stage) then
@@ -523,7 +716,7 @@ bool GrDrawTarget::canDisableBlend() const {
     }
 
     // If we have vertex color without alpha then we can't force blend off
-    if ((fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) ||
+    if ((this->getGeomSrc().fVertexLayout & kColor_VertexLayoutBit) ||
          0xff != GrColorUnpackA(fCurrDrawState.fColor)) {
         return false;
     }
@@ -572,7 +765,8 @@ void GrDrawTarget::setEdgeAAData(const Edge* edges, int numEdges) {
 }
 
 
-///////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
 void GrDrawTarget::drawRect(const GrRect& rect, 
                             const GrMatrix* matrix,
                             StageBitfield stageEnableBitfield,
@@ -648,7 +842,7 @@ void GrDrawTarget::SetRectVertices(const GrRect& rect,
     }
 }
 
-///////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 
 GrDrawTarget::AutoStateRestore::AutoStateRestore() {
     fDrawTarget = NULL;
@@ -679,7 +873,7 @@ void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target) {
     }
 }
 
-///////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 
 GrDrawTarget::AutoDeviceCoordDraw::AutoDeviceCoordDraw(GrDrawTarget* target, 
                                                        int stageMask) {
@@ -714,3 +908,62 @@ GrDrawTarget::AutoDeviceCoordDraw::~AutoDeviceCoordDraw() {
     }
 }
 
+////////////////////////////////////////////////////////////////////////////////
+
+GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry(
+                                         GrDrawTarget*  target,
+                                         GrVertexLayout vertexLayout,
+                                         int vertexCount,
+                                         int indexCount) {
+    fTarget = NULL;
+    this->set(target, vertexLayout, vertexCount, indexCount);
+}
+    
+GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() {
+    fTarget = NULL;
+}
+
+GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() {
+    this->reset();
+}
+
+bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget*  target,
+                                            GrVertexLayout vertexLayout,
+                                            int vertexCount,
+                                            int indexCount) {
+    this->reset();
+    fTarget = target;
+    bool success = true;
+    if (NULL != fTarget) {
+        fTarget = target;
+        if (vertexCount > 0) {
+            success = target->reserveVertexSpace(vertexLayout, 
+                                                 vertexCount,
+                                                 &fVertices);
+            if (!success) {
+                this->reset();
+            }
+        }
+        if (success && indexCount > 0) {
+            success = target->reserveIndexSpace(indexCount, &fIndices);
+            if (!success) {
+                this->reset();
+            }
+        }
+    }
+    GrAssert(success == (NULL != fTarget));
+    return success;
+}
+
+void GrDrawTarget::AutoReleaseGeometry::reset() {
+    if (NULL != fTarget) {
+        if (NULL != fVertices) {
+            fTarget->resetVertexSource();
+        }
+        if (NULL != fIndices) {
+            fTarget->resetIndexSource();
+        }
+        fTarget = NULL;
+    }
+}
+
index 4f260c7..db7de2c 100644 (file)
@@ -33,27 +33,36 @@ static const int VERTEX_POOL_VB_COUNT = 1;
 
 extern void gr_run_unittests();
 
+#define DEBUG_INVAL_BUFFER    0xdeadcafe
+#define DEBUG_INVAL_START_IDX -1
+
 GrGpu::GrGpu()
     : f8bitPaletteSupport(false)
-    , fCurrPoolVertexBuffer(NULL)
-    , fCurrPoolStartVertex(0)
-    , fCurrPoolIndexBuffer(NULL)
-    , fCurrPoolStartIndex(0)
     , fContext(NULL)
     , fVertexPool(NULL)
     , fIndexPool(NULL)
+    , fVertexPoolUseCnt(0)
+    , fIndexPoolUseCnt(0)
+    , fGeomPoolStateStack(&fGeoSrcStateStackStorage)
     , fQuadIndexBuffer(NULL)
     , fUnitSquareVertexBuffer(NULL)
     , fDefaultPathRenderer(NULL)
     , fClientPathRenderer(NULL)
     , fContextIsDirty(true)
-    , fVertexPoolInUse(false)
-    , fIndexPoolInUse(false)
     , fResourceHead(NULL) {
 
 #if GR_DEBUG
     //gr_run_unittests();
 #endif
+        
+    fGeomPoolStateStack.push_back();
+#if GR_DEBUG
+    GeometryPoolState& poolState = fGeomPoolStateStack.back();
+    poolState.fPoolVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
+    poolState.fPoolStartVertex = DEBUG_INVAL_START_IDX;
+    poolState.fPoolIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
+    poolState.fPoolStartIndex = DEBUG_INVAL_START_IDX;
+#endif
     resetStats();
 }
 
@@ -417,7 +426,7 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
             fClip.setFromRect(bounds);
 
             AutoStateRestore asr(this);
-            AutoInternalDrawGeomRestore aidgr(this);
+            AutoGeometryPush agp(this);
 
             this->setViewMatrix(GrMatrix::I());
             this->clearStencilClip(clipRect);
@@ -566,15 +575,36 @@ GrPathRenderer* GrGpu::getClipPathRenderer(const GrPath& path,
 
 ////////////////////////////////////////////////////////////////////////////////
 
-void GrGpu::drawIndexed(GrPrimitiveType type,
-                        int startVertex,
-                        int startIndex,
-                        int vertexCount,
-                        int indexCount) {
-    GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fVertexSrc ||
-             fReservedGeometry.fLocked);
-    GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fIndexSrc ||
-             fReservedGeometry.fLocked);
+void GrGpu::geometrySourceWillPush() {
+    const GeometrySrcState& geoSrc = this->getGeomSrc();
+    if (kArray_GeometrySrcType == geoSrc.fVertexSrc ||
+        kReserved_GeometrySrcType == geoSrc.fVertexSrc) {
+        this->finalizeReservedVertices();
+    }
+    if (kArray_GeometrySrcType == geoSrc.fIndexSrc ||
+        kReserved_GeometrySrcType == geoSrc.fIndexSrc) {
+        this->finalizeReservedIndices();
+    }
+    GeometryPoolState& newState = fGeomPoolStateStack.push_back();
+#if GR_DEBUG
+    newState.fPoolVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
+    newState.fPoolStartVertex = DEBUG_INVAL_START_IDX;
+    newState.fPoolIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
+    newState.fPoolStartIndex = DEBUG_INVAL_START_IDX;
+#endif
+}
+
+void GrGpu::geometrySourceWillPop(const GeometrySrcState& restoredState) {
+    // if popping last entry then pops are unbalanced with pushes
+    GrAssert(fGeomPoolStateStack.count() > 1);
+    fGeomPoolStateStack.pop_back();
+}
+
+void GrGpu::onDrawIndexed(GrPrimitiveType type,
+                          int startVertex,
+                          int startIndex,
+                          int vertexCount,
+                          int indexCount) {
 
     this->handleDirtyContext();
 
@@ -592,16 +622,13 @@ void GrGpu::drawIndexed(GrPrimitiveType type,
     int sIndex = startIndex;
     setupGeometry(&sVertex, &sIndex, vertexCount, indexCount);
 
-    this->onDrawIndexed(type, sVertex, sIndex,
-                        vertexCount, indexCount);
+    this->onGpuDrawIndexed(type, sVertex, sIndex,
+                           vertexCount, indexCount);
 }
 
-void GrGpu::drawNonIndexed(GrPrimitiveType type,
+void GrGpu::onDrawNonIndexed(GrPrimitiveType type,
                            int startVertex,
                            int vertexCount) {
-    GrAssert(kReserved_GeometrySrcType != fGeometrySrc.fVertexSrc ||
-             fReservedGeometry.fLocked);
-
     this->handleDirtyContext();
 
     if (!this->setupClipAndFlushState(type)) {
@@ -615,7 +642,7 @@ void GrGpu::drawNonIndexed(GrPrimitiveType type,
     int sVertex = startVertex;
     setupGeometry(&sVertex, NULL, vertexCount, 0);
 
-    this->onDrawNonIndexed(type, sVertex, vertexCount);
+    this->onGpuDrawNonIndexed(type, sVertex, vertexCount);
 }
 
 void GrGpu::finalizeReservedVertices() {
@@ -630,11 +657,12 @@ void GrGpu::finalizeReservedIndices() {
 
 void GrGpu::prepareVertexPool() {
     if (NULL == fVertexPool) {
+        GrAssert(0 == fVertexPoolUseCnt);
         fVertexPool = new GrVertexBufferAllocPool(this, true,
                                                   VERTEX_POOL_VB_SIZE,
                                                   VERTEX_POOL_VB_COUNT);
         fVertexPool->releaseGpuRef();
-    } else if (!fVertexPoolInUse) {
+    } else if (!fVertexPoolUseCnt) {
         // the client doesn't have valid data in the pool
         fVertexPool->reset();
     }
@@ -642,81 +670,117 @@ void GrGpu::prepareVertexPool() {
 
 void GrGpu::prepareIndexPool() {
     if (NULL == fIndexPool) {
+        GrAssert(0 == fIndexPoolUseCnt);
         fIndexPool = new GrIndexBufferAllocPool(this, true, 0, 1);
         fIndexPool->releaseGpuRef();
-    } else if (!fIndexPoolInUse) {
+    } else if (!fIndexPoolUseCnt) {
         // the client doesn't have valid data in the pool
         fIndexPool->reset();
     }
 }
 
-bool GrGpu::onAcquireGeometry(GrVertexLayout vertexLayout,
-                              void**         vertices,
-                              void**         indices) {
-    GrAssert(!fReservedGeometry.fLocked);
-    size_t reservedVertexSpace = 0;
+bool GrGpu::onReserveVertexSpace(GrVertexLayout vertexLayout,
+                                 int vertexCount,
+                                 void** vertices) {
+    GeometryPoolState& geomPoolState = fGeomPoolStateStack.back();
+    
+    GrAssert(vertexCount > 0);
+    GrAssert(NULL != vertices);
+    
+    this->prepareVertexPool();
+    
+    *vertices = fVertexPool->makeSpace(vertexLayout,
+                                       vertexCount,
+                                       &geomPoolState.fPoolVertexBuffer,
+                                       &geomPoolState.fPoolStartVertex);
+    if (NULL == *vertices) {
+        return false;
+    }
+    ++fVertexPoolUseCnt;
+    return true;
+}
 
-    if (fReservedGeometry.fVertexCount) {
-        GrAssert(NULL != vertices);
+bool GrGpu::onReserveIndexSpace(int indexCount, void** indices) {
+    GeometryPoolState& geomPoolState = fGeomPoolStateStack.back();
+    
+    GrAssert(indexCount > 0);
+    GrAssert(NULL != indices);
 
-        this->prepareVertexPool();
+    this->prepareIndexPool();
 
-        *vertices = fVertexPool->makeSpace(vertexLayout,
-                                           fReservedGeometry.fVertexCount,
-                                           &fCurrPoolVertexBuffer,
-                                           &fCurrPoolStartVertex);
-        if (NULL == *vertices) {
-            return false;
-        }
-        reservedVertexSpace = VertexSize(vertexLayout) *
-                              fReservedGeometry.fVertexCount;
-    }
-    if (fReservedGeometry.fIndexCount) {
-        GrAssert(NULL != indices);
-
-        this->prepareIndexPool();
-
-        *indices = fIndexPool->makeSpace(fReservedGeometry.fIndexCount,
-                                         &fCurrPoolIndexBuffer,
-                                         &fCurrPoolStartIndex);
-        if (NULL == *indices) {
-            fVertexPool->putBack(reservedVertexSpace);
-            fCurrPoolVertexBuffer = NULL;
-            return false;
-        }
+    *indices = fIndexPool->makeSpace(indexCount,
+                                     &geomPoolState.fPoolIndexBuffer,
+                                     &geomPoolState.fPoolStartIndex);
+    if (NULL == *indices) {
+        return false;
     }
+    ++fIndexPoolUseCnt;
     return true;
 }
 
-void GrGpu::onReleaseGeometry() {}
+void GrGpu::releaseReservedVertexSpace() {
+    const GeometrySrcState& geoSrc = this->getGeomSrc();
+    GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
+    size_t bytes = geoSrc.fVertexCount * VertexSize(geoSrc.fVertexLayout);
+    fVertexPool->putBack(bytes);
+    --fVertexPoolUseCnt;
+}
+
+void GrGpu::releaseReservedIndexSpace() {
+    const GeometrySrcState& geoSrc = this->getGeomSrc();
+    GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
+    size_t bytes = geoSrc.fIndexCount * sizeof(uint16_t);
+    fIndexPool->putBack(bytes);
+    --fIndexPoolUseCnt;
+}
 
 void GrGpu::onSetVertexSourceToArray(const void* vertexArray, int vertexCount) {
-    GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fVertexCount);
     this->prepareVertexPool();
+    GeometryPoolState& geomPoolState = fGeomPoolStateStack.back();
 #if GR_DEBUG
     bool success =
 #endif
-    fVertexPool->appendVertices(fGeometrySrc.fVertexLayout,
+    fVertexPool->appendVertices(this->getGeomSrc().fVertexLayout,
                                 vertexCount,
                                 vertexArray,
-                                &fCurrPoolVertexBuffer,
-                                &fCurrPoolStartVertex);
+                                &geomPoolState.fPoolVertexBuffer,
+                                &geomPoolState.fPoolStartVertex);
+    ++fVertexPoolUseCnt;
     GR_DEBUGASSERT(success);
 }
 
 void GrGpu::onSetIndexSourceToArray(const void* indexArray, int indexCount) {
-    GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fIndexCount);
     this->prepareIndexPool();
+    GeometryPoolState& geomPoolState = fGeomPoolStateStack.back();
 #if GR_DEBUG
     bool success =
 #endif
     fIndexPool->appendIndices(indexCount,
                               indexArray,
-                              &fCurrPoolIndexBuffer,
-                              &fCurrPoolStartIndex);
+                              &geomPoolState.fPoolIndexBuffer,
+                              &geomPoolState.fPoolStartIndex);
+    ++fIndexPoolUseCnt;
     GR_DEBUGASSERT(success);
 }
 
+void GrGpu::releaseVertexArray() {
+    // if vertex source was array, we stowed data in the pool
+    const GeometrySrcState& geoSrc = this->getGeomSrc();
+    GrAssert(kArray_GeometrySrcType == geoSrc.fVertexSrc);
+    size_t bytes = geoSrc.fVertexCount * VertexSize(geoSrc.fVertexLayout);
+    fVertexPool->putBack(bytes);
+    --fVertexPoolUseCnt;
+}
+
+void GrGpu::releaseIndexArray() {
+    // if index source was array, we stowed data in the pool
+    const GeometrySrcState& geoSrc = this->getGeomSrc();
+    GrAssert(kArray_GeometrySrcType == geoSrc.fIndexSrc);
+    size_t bytes = geoSrc.fIndexCount * sizeof(uint16_t);
+    fIndexPool->putBack(bytes);
+    --fIndexPoolUseCnt;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 
 const GrGpuStats& GrGpu::getStats() const {
index c73f60f..ffdf496 100644 (file)
@@ -1401,11 +1401,11 @@ GrGLenum gPrimitiveType2GLMode[] = {
     #endif
 #endif
 
-void GrGpuGL::onDrawIndexed(GrPrimitiveType type,
-                            uint32_t startVertex,
-                            uint32_t startIndex,
-                            uint32_t vertexCount,
-                            uint32_t indexCount) {
+void GrGpuGL::onGpuDrawIndexed(GrPrimitiveType type,
+                               uint32_t startVertex,
+                               uint32_t startIndex,
+                               uint32_t vertexCount,
+                               uint32_t indexCount) {
     GrAssert((size_t)type < GR_ARRAY_COUNT(gPrimitiveType2GLMode));
 
     GrGLvoid* indices = (GrGLvoid*)(sizeof(uint16_t) * startIndex);
@@ -1433,9 +1433,9 @@ void GrGpuGL::onDrawIndexed(GrPrimitiveType type,
 #endif
 }
 
-void GrGpuGL::onDrawNonIndexed(GrPrimitiveType type,
-                               uint32_t startVertex,
-                               uint32_t vertexCount) {
+void GrGpuGL::onGpuDrawNonIndexed(GrPrimitiveType type,
+                                  uint32_t startVertex,
+                                  uint32_t vertexCount) {
     GrAssert((size_t)type < GR_ARRAY_COUNT(gPrimitiveType2GLMode));
 
     GrAssert(NULL != fHWGeometryState.fVertexBuffer);
@@ -1924,7 +1924,7 @@ void GrGpuGL::notifyVertexBufferDelete(const GrGLVertexBuffer* buffer) {
 }
 
 void GrGpuGL::notifyIndexBufferBind(const GrGLIndexBuffer* buffer) {
-    fGeometrySrc.fIndexBuffer = buffer;
+    fHWGeometryState.fIndexBuffer = buffer;
 }
 
 void GrGpuGL::notifyIndexBufferDelete(const GrGLIndexBuffer* buffer) {
@@ -2058,17 +2058,19 @@ void GrGpuGL::setBuffers(bool indexed,
 
     GrAssert(NULL != extraVertexOffset);
 
+    const GeometryPoolState& geoPoolState = this->getGeomPoolState();
+
     GrGLVertexBuffer* vbuf;
-    switch (fGeometrySrc.fVertexSrc) {
+    switch (this->getGeomSrc().fVertexSrc) {
     case kBuffer_GeometrySrcType:
         *extraVertexOffset = 0;
-        vbuf = (GrGLVertexBuffer*) fGeometrySrc.fVertexBuffer;
+        vbuf = (GrGLVertexBuffer*) this->getGeomSrc().fVertexBuffer;
         break;
     case kArray_GeometrySrcType:
     case kReserved_GeometrySrcType:
-        finalizeReservedVertices();
-        *extraVertexOffset = fCurrPoolStartVertex;
-        vbuf = (GrGLVertexBuffer*) fCurrPoolVertexBuffer;
+        this->finalizeReservedVertices();
+        *extraVertexOffset = geoPoolState.fPoolStartVertex;
+        vbuf = (GrGLVertexBuffer*) geoPoolState.fPoolVertexBuffer;
         break;
     default:
         vbuf = NULL; // suppress warning
@@ -2087,16 +2089,16 @@ void GrGpuGL::setBuffers(bool indexed,
         GrAssert(NULL != extraIndexOffset);
 
         GrGLIndexBuffer* ibuf;
-        switch (fGeometrySrc.fIndexSrc) {
+        switch (this->getGeomSrc().fIndexSrc) {
         case kBuffer_GeometrySrcType:
             *extraIndexOffset = 0;
-            ibuf = (GrGLIndexBuffer*)fGeometrySrc.fIndexBuffer;
+            ibuf = (GrGLIndexBuffer*)this->getGeomSrc().fIndexBuffer;
             break;
         case kArray_GeometrySrcType:
         case kReserved_GeometrySrcType:
-            finalizeReservedIndices();
-            *extraIndexOffset = fCurrPoolStartIndex;
-            ibuf = (GrGLIndexBuffer*) fCurrPoolIndexBuffer;
+            this->finalizeReservedIndices();
+            *extraIndexOffset = geoPoolState.fPoolStartIndex;
+            ibuf = (GrGLIndexBuffer*) geoPoolState.fPoolIndexBuffer;
             break;
         default:
             ibuf = NULL; // suppress warning
index f7f62ab..aec55d8 100644 (file)
@@ -91,14 +91,14 @@ protected:
                               int left, int top, int width, int height,
                               GrPixelConfig, void* buffer);
 
-    virtual void onDrawIndexed(GrPrimitiveType type,
-                                   uint32_t startVertex,
-                                   uint32_t startIndex,
-                                   uint32_t vertexCount,
-                                   uint32_t indexCount);
-    virtual void onDrawNonIndexed(GrPrimitiveType type,
-                                      uint32_t vertexCount,
-                                      uint32_t numVertices);
+    virtual void onGpuDrawIndexed(GrPrimitiveType type,
+                                  uint32_t startVertex,
+                                  uint32_t startIndex,
+                                  uint32_t vertexCount,
+                                  uint32_t indexCount);
+    virtual void onGpuDrawNonIndexed(GrPrimitiveType type,
+                                     uint32_t vertexCount,
+                                     uint32_t numVertices);
     virtual void flushScissor(const GrIRect* rect);
     void clearStencil(uint32_t value, uint32_t mask);
     virtual void clearStencilClip(const GrIRect& rect);
index 65229dc..baa220b 100644 (file)
@@ -166,7 +166,7 @@ bool GrGpuGLFixed::flushGraphicsState(GrPrimitiveType type) {
         }
     }
 
-    uint32_t vertColor = (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit);
+    uint32_t vertColor = (this->getGeomSrc().fVertexLayout & kColor_VertexLayoutBit);
     uint32_t prevVertColor = (fHWGeometryState.fVertexLayout &
                               kColor_VertexLayoutBit);
 
@@ -250,7 +250,7 @@ void GrGpuGLFixed::setupGeometry(int* startVertex,
     int newColorOffset;
     int newTexCoordOffsets[kNumStages];
 
-    GrGLsizei newStride = VertexSizeAndOffsetsByStage(fGeometrySrc.fVertexLayout,
+    GrGLsizei newStride = VertexSizeAndOffsetsByStage(this->getGeomSrc().fVertexLayout,
                                                       newTexCoordOffsets,
                                                       &newColorOffset);
     int oldColorOffset;
@@ -266,7 +266,7 @@ void GrGpuGLFixed::setupGeometry(int* startVertex,
     setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);
 
     GrGLenum scalarType;
-    if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) {
+    if (this->getGeomSrc().fVertexLayout & kTextFormat_VertexLayoutBit) {
         scalarType = GrGLTextType;
     } else {
         scalarType = GrGLType;
@@ -289,7 +289,7 @@ void GrGpuGLFixed::setupGeometry(int* startVertex,
                            ((GrGLTextType != GrGLType) &&
                                 (kTextFormat_VertexLayoutBit &
                                   (fHWGeometryState.fVertexLayout ^
-                                   fGeometrySrc.fVertexLayout)));
+                                   this->getGeomSrc().fVertexLayout)));
 
     if (posAndTexChange) {
         GR_GL(VertexPointer(2, scalarType, newStride, (GrGLvoid*)vertexOffset));
@@ -328,6 +328,6 @@ void GrGpuGLFixed::setupGeometry(int* startVertex,
         GR_GL(DisableClientState(GR_GL_COLOR_ARRAY));
     }
 
-    fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
+    fHWGeometryState.fVertexLayout = this->getGeomSrc().fVertexLayout;
     fHWGeometryState.fArrayPtrsDirty = false;
 }
index 689c1fc..0b8aad7 100644 (file)
@@ -501,7 +501,7 @@ static const float ONE_OVER_255 = 1.f / 255.f;
 
 void GrGpuGLShaders::flushColor() {
     const GrGLProgram::ProgramDesc& desc = fCurrentProgram.getDesc();
-    if (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) {
+    if (this->getGeomSrc().fVertexLayout & kColor_VertexLayoutBit) {
         // color will be specified per-vertex as an attribute
         // invalidate the const vertex attrib color
         fHWDrawState.fColor = GrColor_ILLEGAL;
@@ -613,23 +613,25 @@ void GrGpuGLShaders::setupGeometry(int* startVertex,
     int newColorOffset;
     int newTexCoordOffsets[kMaxTexCoords];
 
-    GrGLsizei newStride = VertexSizeAndOffsetsByIdx(fGeometrySrc.fVertexLayout,
-                                                  newTexCoordOffsets,
-                                                  &newColorOffset);
+    GrGLsizei newStride = VertexSizeAndOffsetsByIdx(
+                                            this->getGeomSrc().fVertexLayout,
+                                            newTexCoordOffsets,
+                                            &newColorOffset);
     int oldColorOffset;
     int oldTexCoordOffsets[kMaxTexCoords];
-    GrGLsizei oldStride = VertexSizeAndOffsetsByIdx(fHWGeometryState.fVertexLayout,
-                                                  oldTexCoordOffsets,
-                                                  &oldColorOffset);
+    GrGLsizei oldStride = VertexSizeAndOffsetsByIdx(
+                                            fHWGeometryState.fVertexLayout,
+                                            oldTexCoordOffsets,
+                                            &oldColorOffset);
     bool indexed = NULL != startIndex;
 
     int extraVertexOffset;
     int extraIndexOffset;
-    setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);
+    this->setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);
 
     GrGLenum scalarType;
     bool texCoordNorm;
-    if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) {
+    if (this->getGeomSrc().fVertexLayout & kTextFormat_VertexLayoutBit) {
         scalarType = GrGLTextType;
         texCoordNorm = GR_GL_TEXT_TEXTURE_NORMALIZED;
     } else {
@@ -654,7 +656,7 @@ void GrGpuGLShaders::setupGeometry(int* startVertex,
                            (((GrGLTextType != GrGLType) || GR_GL_TEXT_TEXTURE_NORMALIZED) &&
                                 (kTextFormat_VertexLayoutBit &
                                   (fHWGeometryState.fVertexLayout ^
-                                   fGeometrySrc.fVertexLayout)));
+                                   this->getGeomSrc().fVertexLayout)));
 
     if (posAndTexChange) {
         int idx = GrGLProgram::PositionAttributeIdx();
@@ -696,7 +698,7 @@ void GrGpuGLShaders::setupGeometry(int* startVertex,
         GR_GL(DisableVertexAttribArray(GrGLProgram::ColorAttributeIdx()));
     }
 
-    fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
+    fHWGeometryState.fVertexLayout = this->getGeomSrc().fVertexLayout;
     fHWGeometryState.fArrayPtrsDirty = false;
 }
 
@@ -704,7 +706,7 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type) {
     GrGLProgram::ProgramDesc& desc = fCurrentProgram.fProgramDesc;
 
     // Must initialize all fields or cache will have false negatives!
-    desc.fVertexLayout = fGeometrySrc.fVertexLayout;
+    desc.fVertexLayout = this->getGeomSrc().fVertexLayout;
 
     desc.fEmitsPointSize = kPoints_PrimitiveType == type;
 
index 7df1f23..a685620 100644 (file)
 #include "GrGpu.h"
 
 GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrVertexBufferAllocPool* vertexPool,
-                                         GrIndexBufferAllocPool* indexPool) :
-        fDraws(&fDrawStorage),
-        fStates(&fStateStorage),
-        fClears(&fClearStorage),
-        fClips(&fClipStorage),
-        fClipSet(true),
-
-        fLastRectVertexLayout(0),
-        fQuadIndexBuffer(NULL),
-        fMaxQuads(0),
-        fCurrQuad(0),
-
-        fVertexPool(*vertexPool),
-        fCurrPoolVertexBuffer(NULL),
-        fCurrPoolStartVertex(0),
-        fIndexPool(*indexPool),
-        fCurrPoolIndexBuffer(NULL),
-        fCurrPoolStartIndex(0),
-        fReservedVertexBytes(0),
-        fReservedIndexBytes(0),
-        fUsedReservedVertexBytes(0),
-        fUsedReservedIndexBytes(0) {
+                                         GrIndexBufferAllocPool* indexPool)
+    : fDraws(&fDrawStorage)
+    , fStates(&fStateStorage)
+    , fClears(&fClearStorage)
+    , fClips(&fClipStorage)
+    , fClipSet(true)
+
+    , fLastRectVertexLayout(0)
+    , fQuadIndexBuffer(NULL)
+    , fMaxQuads(0)
+    , fCurrQuad(0)
+
+    , fVertexPool(*vertexPool)
+    , fIndexPool(*indexPool)
+    , fGeoPoolStateStack(&fGeoStackStorage) {
+    
     GrAssert(NULL != vertexPool);
     GrAssert(NULL != indexPool);
+
+    GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
+    poolState.fUsedPoolVertexBytes = 0;
+    poolState.fUsedPoolIndexBytes = 0;
+#if GR_DEBUG
+    poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
+    poolState.fPoolStartVertex = ~0;
+    poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
+    poolState.fPoolStartIndex = ~0;
+#endif
 }
 
 GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
@@ -150,19 +154,24 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
             GrAssert(0 == lastDraw.fIndexCount % 6);
             GrAssert(0 == lastDraw.fStartIndex);
 
+            GeometryPoolState& poolState = fGeoPoolStateStack.back();
             bool clearSinceLastDraw =
                             fClears.count() && 
                             fClears.back().fBeforeDrawIdx == fDraws.count();
 
-            appendToPreviousDraw =  !clearSinceLastDraw &&
-                                    lastDraw.fVertexBuffer == fCurrPoolVertexBuffer &&
-                                   (fCurrQuad * 4 + lastDraw.fStartVertex) == fCurrPoolStartVertex;
+            appendToPreviousDraw =  
+                !clearSinceLastDraw &&
+                lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer &&
+                (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex;
+
             if (appendToPreviousDraw) {
                 lastDraw.fVertexCount += 4;
                 lastDraw.fIndexCount += 6;
                 fCurrQuad += 1;
-                GrAssert(0 == fUsedReservedVertexBytes);
-                fUsedReservedVertexBytes = 4 * vsize;
+                // we reserved above, so we should be the first
+                // use of this vertex reserveation.
+                GrAssert(0 == poolState.fUsedPoolVertexBytes);
+                poolState.fUsedPoolVertexBytes = 4 * vsize;
             }
         }
         if (!appendToPreviousDraw) {
@@ -179,11 +188,11 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
     }
 }
 
-void GrInOrderDrawBuffer::drawIndexed(GrPrimitiveType primitiveType,
-                                      int startVertex,
-                                      int startIndex,
-                                      int vertexCount,
-                                      int indexCount) {
+void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType,
+                                        int startVertex,
+                                        int startIndex,
+                                        int vertexCount,
+                                        int indexCount) {
 
     if (!vertexCount || !indexCount) {
         return;
@@ -191,6 +200,8 @@ void GrInOrderDrawBuffer::drawIndexed(GrPrimitiveType primitiveType,
 
     fCurrQuad = 0;
 
+    GeometryPoolState& poolState = fGeoPoolStateStack.back();
+
     Draw& draw = fDraws.push_back();
     draw.fPrimitiveType = primitiveType;
     draw.fStartVertex   = startVertex;
@@ -208,52 +219,56 @@ void GrInOrderDrawBuffer::drawIndexed(GrPrimitiveType primitiveType,
         this->pushState();
     }
 
-    draw.fVertexLayout = fGeometrySrc.fVertexLayout;
-    switch (fGeometrySrc.fVertexSrc) {
+    draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
+    switch (this->getGeomSrc().fVertexSrc) {
     case kBuffer_GeometrySrcType:
-        draw.fVertexBuffer = fGeometrySrc.fVertexBuffer;
+        draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
         break;
-    case kReserved_GeometrySrcType: {
+    case kReserved_GeometrySrcType: // fallthrough
+    case kArray_GeometrySrcType: {
         size_t vertexBytes = (vertexCount + startVertex) *
-        VertexSize(fGeometrySrc.fVertexLayout);
-        fUsedReservedVertexBytes = GrMax(fUsedReservedVertexBytes, vertexBytes);
-    } // fallthrough
-    case kArray_GeometrySrcType:
-        draw.fVertexBuffer = fCurrPoolVertexBuffer;
-        draw.fStartVertex += fCurrPoolStartVertex;
+                             VertexSize(this->getGeomSrc().fVertexLayout);
+        poolState.fUsedPoolVertexBytes = 
+                            GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
+        draw.fVertexBuffer = poolState.fPoolVertexBuffer;
+        draw.fStartVertex += poolState.fPoolStartVertex;
         break;
+    }
     default:
         GrCrash("unknown geom src type");
     }
     draw.fVertexBuffer->ref();
 
-    switch (fGeometrySrc.fIndexSrc) {
+    switch (this->getGeomSrc().fIndexSrc) {
     case kBuffer_GeometrySrcType:
-        draw.fIndexBuffer = fGeometrySrc.fIndexBuffer;
+        draw.fIndexBuffer = this->getGeomSrc().fIndexBuffer;
         break;
-    case kReserved_GeometrySrcType: {
+    case kReserved_GeometrySrcType: // fallthrough 
+    case kArray_GeometrySrcType: {
         size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t);
-        fUsedReservedIndexBytes = GrMax(fUsedReservedIndexBytes, indexBytes);
-    } // fallthrough
-    case kArray_GeometrySrcType:
-        draw.fIndexBuffer = fCurrPoolIndexBuffer;
-        draw.fStartIndex += fCurrPoolStartVertex;
+        poolState.fUsedPoolIndexBytes = 
+                            GrMax(poolState.fUsedPoolIndexBytes, indexBytes);
+        draw.fIndexBuffer = poolState.fPoolIndexBuffer;
+        draw.fStartIndex += poolState.fPoolStartVertex;
         break;
+    }
     default:
         GrCrash("unknown geom src type");
     }
     draw.fIndexBuffer->ref();
 }
 
-void GrInOrderDrawBuffer::drawNonIndexed(GrPrimitiveType primitiveType,
-                                         int startVertex,
-                                         int vertexCount) {
+void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType,
+                                           int startVertex,
+                                           int vertexCount) {
     if (!vertexCount) {
         return;
     }
 
     fCurrQuad = 0;
 
+    GeometryPoolState& poolState = fGeoPoolStateStack.back();
+
     Draw& draw = fDraws.push_back();
     draw.fPrimitiveType = primitiveType;
     draw.fStartVertex   = startVertex;
@@ -271,21 +286,21 @@ void GrInOrderDrawBuffer::drawNonIndexed(GrPrimitiveType primitiveType,
         this->pushState();
     }
 
-    draw.fVertexLayout = fGeometrySrc.fVertexLayout;
-    switch (fGeometrySrc.fVertexSrc) {
+    draw.fVertexLayout = this->getGeomSrc().fVertexLayout;
+    switch (this->getGeomSrc().fVertexSrc) {
     case kBuffer_GeometrySrcType:
-        draw.fVertexBuffer = fGeometrySrc.fVertexBuffer;
+        draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer;
         break;
-    case kReserved_GeometrySrcType: {
+    case kReserved_GeometrySrcType: // fallthrough
+    case kArray_GeometrySrcType: {
         size_t vertexBytes = (vertexCount + startVertex) *
-        VertexSize(fGeometrySrc.fVertexLayout);
-        fUsedReservedVertexBytes = GrMax(fUsedReservedVertexBytes,
-                                         vertexBytes);
-    } // fallthrough
-    case kArray_GeometrySrcType:
-        draw.fVertexBuffer = fCurrPoolVertexBuffer;
-        draw.fStartVertex += fCurrPoolStartVertex;
+                             VertexSize(this->getGeomSrc().fVertexLayout);
+        poolState.fUsedPoolVertexBytes = 
+                            GrMax(poolState.fUsedPoolVertexBytes, vertexBytes);
+        draw.fVertexBuffer = poolState.fPoolVertexBuffer;
+        draw.fStartVertex += poolState.fPoolStartVertex;
         break;
+    }
     default:
         GrCrash("unknown geom src type");
     }
@@ -311,7 +326,9 @@ void GrInOrderDrawBuffer::clear(const GrIRect* rect, GrColor color) {
 }
 
 void GrInOrderDrawBuffer::reset() {
-    GrAssert(!fReservedGeometry.fLocked);
+    GrAssert(1 == fGeoPoolStateStack.count());
+    this->resetVertexSource();
+    this->resetIndexSource();
     uint32_t numStates = fStates.count();
     for (uint32_t i = 0; i < numStates; ++i) {
         const DrState& dstate = this->accessSavedDrawState(fStates[i]);
@@ -341,7 +358,8 @@ void GrInOrderDrawBuffer::reset() {
 }
 
 void GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
-    GrAssert(!fReservedGeometry.fLocked);
+    GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc);
+    GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc);
     GrAssert(NULL != target);
     GrAssert(target != this); // not considered and why?
 
@@ -355,9 +373,7 @@ void GrInOrderDrawBuffer::playback(GrDrawTarget* target) {
 
     GrDrawTarget::AutoStateRestore asr(target);
     GrDrawTarget::AutoClipRestore acr(target);
-    // important to not mess with reserve/lock geometry in the target with this
-    // on the stack.
-    GrDrawTarget::AutoGeometrySrcRestore agsr(target);
+    AutoGeometryPush agp(target);
 
     int currState = ~0;
     int currClip  = ~0;
@@ -435,89 +451,143 @@ bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout,
     return flush;
 }
 
-bool GrInOrderDrawBuffer::onAcquireGeometry(GrVertexLayout vertexLayout,
-                                            void**         vertices,
-                                            void**         indices) {
-    GrAssert(!fReservedGeometry.fLocked);
-    if (fReservedGeometry.fVertexCount) {
-        GrAssert(NULL != vertices);
-        GrAssert(0 == fReservedVertexBytes);
-        GrAssert(0 == fUsedReservedVertexBytes);
-
-        fReservedVertexBytes = VertexSize(vertexLayout) *
-                               fReservedGeometry.fVertexCount;
-        *vertices = fVertexPool.makeSpace(vertexLayout,
-                                          fReservedGeometry.fVertexCount,
-                                          &fCurrPoolVertexBuffer,
-                                          &fCurrPoolStartVertex);
-        if (NULL == *vertices) {
-            return false;
-        }
-    }
-    if (fReservedGeometry.fIndexCount) {
-        GrAssert(NULL != indices);
-        GrAssert(0 == fReservedIndexBytes);
-        GrAssert(0 == fUsedReservedIndexBytes);
-
-        *indices = fIndexPool.makeSpace(fReservedGeometry.fIndexCount,
-                                        &fCurrPoolIndexBuffer,
-                                        &fCurrPoolStartIndex);
-        if (NULL == *indices) {
-            fVertexPool.putBack(fReservedVertexBytes);
-            fReservedVertexBytes = 0;
-            fCurrPoolVertexBuffer = NULL;
-            return false;
-        }
-    }
-    return true;
+bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout,
+                                               int vertexCount,
+                                               void** vertices) {
+    GeometryPoolState& poolState = fGeoPoolStateStack.back();
+    GrAssert(vertexCount > 0);
+    GrAssert(NULL != vertices);
+    GrAssert(0 == poolState.fUsedPoolVertexBytes);
+    
+    *vertices = fVertexPool.makeSpace(vertexLayout,
+                                      vertexCount,
+                                      &poolState.fPoolVertexBuffer,
+                                      &poolState.fPoolStartVertex);
+    return NULL != *vertices;
+}
+    
+bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) {
+    GeometryPoolState& poolState = fGeoPoolStateStack.back();
+    GrAssert(indexCount > 0);
+    GrAssert(NULL != indices);
+    GrAssert(0 == poolState.fUsedPoolIndexBytes);
+
+    *indices = fIndexPool.makeSpace(indexCount,
+                                    &poolState.fPoolIndexBuffer,
+                                    &poolState.fPoolStartIndex);
+    return NULL != *indices;
 }
 
-void GrInOrderDrawBuffer::onReleaseGeometry() {
-    GrAssert(fUsedReservedVertexBytes <= fReservedVertexBytes);
-    GrAssert(fUsedReservedIndexBytes <= fReservedIndexBytes);
-
-    size_t vertexSlack = fReservedVertexBytes - fUsedReservedVertexBytes;
-    fVertexPool.putBack(vertexSlack);
-
-    size_t indexSlack = fReservedIndexBytes - fUsedReservedIndexBytes;
-    fIndexPool.putBack(indexSlack);
+void GrInOrderDrawBuffer::releaseReservedVertexSpace() {
+    GeometryPoolState& poolState = fGeoPoolStateStack.back();
+    const GeometrySrcState& geoSrc = this->getGeomSrc(); 
+    
+    GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
+    
+    size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) * 
+                                 geoSrc.fVertexCount;
+    fVertexPool.putBack(reservedVertexBytes - 
+                        poolState.fUsedPoolVertexBytes);
+    poolState.fUsedPoolVertexBytes = 0;
+    poolState.fPoolVertexBuffer = 0;
+}
 
-    fReservedVertexBytes = 0;
-    fReservedIndexBytes  = 0;
-    fUsedReservedVertexBytes = 0;
-    fUsedReservedIndexBytes  = 0;
-    fCurrPoolVertexBuffer = 0;
-    fCurrPoolStartVertex = 0;
+void GrInOrderDrawBuffer::releaseReservedIndexSpace() {
+    GeometryPoolState& poolState = fGeoPoolStateStack.back();
+    const GeometrySrcState& geoSrc = this->getGeomSrc(); 
 
+    GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
+    
+    size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
+    fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
+    poolState.fUsedPoolIndexBytes = 0;
+    poolState.fPoolStartVertex = 0;
 }
-
+    
 void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray,
                                                    int vertexCount) {
-    GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fVertexCount);
+
+    GeometryPoolState& poolState = fGeoPoolStateStack.back();
+    GrAssert(0 == poolState.fUsedPoolVertexBytes);
 #if GR_DEBUG
     bool success =
 #endif
-    fVertexPool.appendVertices(fGeometrySrc.fVertexLayout,
+    fVertexPool.appendVertices(this->getGeomSrc().fVertexLayout,
                                vertexCount,
                                vertexArray,
-                               &fCurrPoolVertexBuffer,
-                               &fCurrPoolStartVertex);
+                               &poolState.fPoolVertexBuffer,
+                               &poolState.fPoolStartVertex);
     GR_DEBUGASSERT(success);
 }
 
 void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray,
                                                   int indexCount) {
-    GrAssert(!fReservedGeometry.fLocked || !fReservedGeometry.fIndexCount);
+    GeometryPoolState& poolState = fGeoPoolStateStack.back();
+    GrAssert(0 == poolState.fUsedPoolIndexBytes);
 #if GR_DEBUG
     bool success =
 #endif
     fIndexPool.appendIndices(indexCount,
                              indexArray,
-                             &fCurrPoolIndexBuffer,
-                             &fCurrPoolStartIndex);
+                             &poolState.fPoolIndexBuffer,
+                             &poolState.fPoolStartIndex);
     GR_DEBUGASSERT(success);
 }
 
+void GrInOrderDrawBuffer::geometrySourceWillPush() {
+    GeometryPoolState& poolState = fGeoPoolStateStack.push_back();
+    poolState.fUsedPoolVertexBytes = 0;
+    poolState.fUsedPoolIndexBytes = 0;
+#if GR_DEBUG
+    poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0;
+    poolState.fPoolStartVertex = ~0;
+    poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0;
+    poolState.fPoolStartIndex = ~0;
+#endif
+}
+
+void GrInOrderDrawBuffer::releaseVertexArray() {
+    GeometryPoolState& poolState = fGeoPoolStateStack.back();
+    const GeometrySrcState& geoSrc = this->getGeomSrc(); 
+    
+    size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) * 
+    geoSrc.fVertexCount;
+    fVertexPool.putBack(reservedVertexBytes - poolState.fUsedPoolVertexBytes);
+    
+    poolState.fUsedPoolVertexBytes = 0;
+}
+
+void GrInOrderDrawBuffer::releaseIndexArray() {
+    GeometryPoolState& poolState = fGeoPoolStateStack.back();
+    const GeometrySrcState& geoSrc = this->getGeomSrc(); 
+    
+    size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount;
+    fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes);
+    
+    poolState.fUsedPoolIndexBytes = 0;
+}
+
+void GrInOrderDrawBuffer::geometrySourceWillPop(
+                                        const GeometrySrcState& restoredState) {
+    GrAssert(fGeoPoolStateStack.count() > 1);
+    fGeoPoolStateStack.pop_back();
+    GeometryPoolState& poolState = fGeoPoolStateStack.back();
+    // we have to assume that any slack we had in our vertex/index data
+    // is now unreleasable because data may have been appended later in the
+    // pool.
+    if (kReserved_GeometrySrcType == restoredState.fVertexSrc ||
+        kArray_GeometrySrcType == restoredState.fVertexSrc) {
+        poolState.fUsedPoolVertexBytes = 
+            VertexSize(restoredState.fVertexLayout) * 
+            restoredState.fVertexCount;
+    }
+    if (kReserved_GeometrySrcType == restoredState.fIndexSrc ||
+        kArray_GeometrySrcType == restoredState.fIndexSrc) {
+        poolState.fUsedPoolVertexBytes = sizeof(uint16_t) * 
+                                         restoredState.fIndexCount;
+    }
+}
+
 bool GrInOrderDrawBuffer::needsNewState() const {
      if (fStates.empty()) {
         return true;
index 41e4a85..5d0f9f7 100644 (file)
@@ -72,7 +72,7 @@ void GrTextContext::flushGlyphs() {
 
         fDrawTarget->drawIndexed(kTriangles_PrimitiveType,
                                  0, 0, fCurrVertex, nIndices);
-        fDrawTarget->releaseReservedGeometry();
+        fDrawTarget->resetVertexSource();
         fVertices = NULL;
         fMaxVertices = 0;
         fCurrVertex = 0;
@@ -284,10 +284,9 @@ HAS_ATLAS:
             // don't exceed the limit of the index buffer
             fMaxVertices = maxQuadVertices;
         }
-        bool success = fDrawTarget->reserveAndLockGeometry(fVertexLayout,
-                                                           fMaxVertices, 0,
-                                                   GrTCast<void**>(&fVertices),
-                                                           NULL);
+        bool success = fDrawTarget->reserveVertexSpace(fVertexLayout, 
+                                                   fMaxVertices,
+                                                   GrTCast<void**>(&fVertices));
         GrAlwaysAssert(success);
     }