Fix cycling through buffers in buffer alloc pool

Review URL: http://codereview.appspot.com/5716050/



git-svn-id: http://skia.googlecode.com/svn/trunk@3296 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrBufferAllocPool.cpp b/src/gpu/GrBufferAllocPool.cpp
index 1d041f4..8bed75f 100644
--- a/src/gpu/GrBufferAllocPool.cpp
+++ b/src/gpu/GrBufferAllocPool.cpp
@@ -40,9 +40,9 @@
     fMinBlockSize = GrMax(GrBufferAllocPool_MIN_BLOCK_SIZE, blockSize);
 
     fBytesInUse = 0;
-            
+
     fPreallocBuffersInUse = 0;
-    fFirstPreallocBuffer = 0;
+    fPreallocBufferStartIdx = 0;
     for (int i = 0; i < preallocBufferCnt; ++i) {
         GrGeometryBuffer* buffer = this->createBuffer(fMinBlockSize);
         if (NULL != buffer) {
@@ -82,13 +82,16 @@
             buffer->unlock();
         }
     }
+    // fPreallocBuffersInUse will be decremented down to zero in the while loop
+    int preallocBuffersInUse = fPreallocBuffersInUse;
     while (!fBlocks.empty()) {
-        destroyBlock();
+        this->destroyBlock();
     }
     if (fPreallocBuffers.count()) {
         // must set this after above loop.
-        fFirstPreallocBuffer = (fFirstPreallocBuffer + fPreallocBuffersInUse) %
-                               fPreallocBuffers.count();
+        fPreallocBufferStartIdx = (fPreallocBufferStartIdx +
+                                   preallocBuffersInUse) %
+                                  fPreallocBuffers.count();
     }
     // we may have created a large cpu mirror of a large VB. Reset the size
     // to match our pre-allocated VBs.
@@ -216,6 +219,12 @@
 void GrBufferAllocPool::putBack(size_t bytes) {
     VALIDATE();
 
+    // if the putBack unwinds all the preallocated buffers then we will
+    // advance the starting index. As blocks are destroyed fPreallocBuffersInUse
+    // will be decremented. I will reach zero if all blocks using preallocated
+    // buffers are released.
+    int preallocBuffersInUse = fPreallocBuffersInUse;
+
     while (bytes) {
         // caller shouldnt try to put back more than they've taken
         GrAssert(!fBlocks.empty());
@@ -237,6 +246,11 @@
             break;
         }
     }
+    if (!fPreallocBuffersInUse && fPreallocBuffers.count()) {
+            fPreallocBufferStartIdx = (fPreallocBufferStartIdx +
+                                       preallocBuffersInUse) %
+                                      fPreallocBuffers.count();
+    }
     VALIDATE();
 }
 
@@ -252,8 +266,9 @@
     if (size == fMinBlockSize &&
         fPreallocBuffersInUse < fPreallocBuffers.count()) {
 
-        uint32_t nextBuffer = (fPreallocBuffersInUse + fFirstPreallocBuffer) %
-                               fPreallocBuffers.count();
+        uint32_t nextBuffer = (fPreallocBuffersInUse +
+                               fPreallocBufferStartIdx) %
+                              fPreallocBuffers.count();
         block.fBuffer = fPreallocBuffers[nextBuffer];
         block.fBuffer->ref();
         ++fPreallocBuffersInUse;
@@ -301,7 +316,7 @@
     BufferBlock& block = fBlocks.back();
     if (fPreallocBuffersInUse > 0) {
         uint32_t prevPreallocBuffer = (fPreallocBuffersInUse +
-                                       fFirstPreallocBuffer +
+                                       fPreallocBufferStartIdx +
                                        (fPreallocBuffers.count() - 1)) %
                                       fPreallocBuffers.count();
         if (block.fBuffer == fPreallocBuffers[prevPreallocBuffer]) {