From b665a6b148826eecb4f425c57e8a0df0ec63f016 Mon Sep 17 00:00:00 2001 From: "bsalomon@google.com" Date: Thu, 1 Mar 2012 20:59:28 +0000 Subject: [PATCH] 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 --- src/gpu/GrBufferAllocPool.cpp | 31 +++++++++++++++++++++++-------- src/gpu/GrBufferAllocPool.h | 4 +++- 2 files changed, 26 insertions(+), 9 deletions(-) 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 @@ GrBufferAllocPool::GrBufferAllocPool(GrGpu* gpu, 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 @@ void GrBufferAllocPool::reset() { 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 @@ int GrBufferAllocPool::preallocatedBufferCount() const { 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 @@ void GrBufferAllocPool::putBack(size_t bytes) { break; } } + if (!fPreallocBuffersInUse && fPreallocBuffers.count()) { + fPreallocBufferStartIdx = (fPreallocBufferStartIdx + + preallocBuffersInUse) % + fPreallocBuffers.count(); + } VALIDATE(); } @@ -252,8 +266,9 @@ bool GrBufferAllocPool::createBlock(size_t requestSize) { 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 @@ void GrBufferAllocPool::destroyBlock() { BufferBlock& block = fBlocks.back(); if (fPreallocBuffersInUse > 0) { uint32_t prevPreallocBuffer = (fPreallocBuffersInUse + - fFirstPreallocBuffer + + fPreallocBufferStartIdx + (fPreallocBuffers.count() - 1)) % fPreallocBuffers.count(); if (block.fBuffer == fPreallocBuffers[prevPreallocBuffer]) { diff --git a/src/gpu/GrBufferAllocPool.h b/src/gpu/GrBufferAllocPool.h index acf0289..3e2cd39 100644 --- a/src/gpu/GrBufferAllocPool.h +++ b/src/gpu/GrBufferAllocPool.h @@ -176,7 +176,9 @@ private: SkTArray fBlocks; int fPreallocBuffersInUse; - int fFirstPreallocBuffer; + // We attempt to cycle through the preallocated buffers rather than + // always starting from the first. + int fPreallocBufferStartIdx; SkAutoMalloc fCpuData; void* fBufferPtr; }; -- 2.7.4