Refactor GrDrawTarget vertex/index api
Review URL: http://codereview.appspot.com/4631056/
git-svn-id: http://skia.googlecode.com/svn/trunk@1662 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrBufferAllocPool.cpp b/gpu/src/GrBufferAllocPool.cpp
index d786b02..73d707f 100644
--- a/gpu/src/GrBufferAllocPool.cpp
+++ b/gpu/src/GrBufferAllocPool.cpp
@@ -23,9 +23,10 @@
#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 @@
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::reset() {
VALIDATE();
+ fBytesInUse = 0;
if (fBlocks.count()) {
GrGeometryBuffer* buffer = fBlocks.back().fBuffer;
if (buffer->isLocked()) {
@@ -116,7 +120,7 @@
}
#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 @@
} 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 @@
*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 @@
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 @@
fBufferPtr = fCpuData.realloc(size);
}
- VALIDATE();
+ VALIDATE(true);
return true;
}