aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-03-01 20:59:28 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-03-01 20:59:28 +0000
commitb665a6b148826eecb4f425c57e8a0df0ec63f016 (patch)
treec08b4534acf0583705a110b27b1534f221b2dca2
parent9c88bafd283421eda93d4068db003a0510883ceb (diff)
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
-rw-r--r--src/gpu/GrBufferAllocPool.cpp31
-rw-r--r--src/gpu/GrBufferAllocPool.h4
2 files changed, 26 insertions, 9 deletions
diff --git a/src/gpu/GrBufferAllocPool.cpp b/src/gpu/GrBufferAllocPool.cpp
index 1d041f461c..8bed75f5b9 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 acf0289582..3e2cd395c6 100644
--- a/src/gpu/GrBufferAllocPool.h
+++ b/src/gpu/GrBufferAllocPool.h
@@ -176,7 +176,9 @@ private:
SkTArray<BufferBlock> 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;
};