Index: gpu/command_buffer/client/fenced_allocator.cc |
diff --git a/gpu/command_buffer/client/fenced_allocator.cc b/gpu/command_buffer/client/fenced_allocator.cc |
index d262115d7c1f10da8d000d8ef8e48f6fe7fd7e4c..4a839bb52506cf05da6a1385c63e168c423a4088 100644 |
--- a/gpu/command_buffer/client/fenced_allocator.cc |
+++ b/gpu/command_buffer/client/fenced_allocator.cc |
@@ -16,7 +16,8 @@ const FencedAllocator::Offset FencedAllocator::kInvalidOffset; |
FencedAllocator::FencedAllocator(unsigned int size, |
CommandBufferHelper *helper) |
- : helper_(helper) { |
+ : helper_(helper), |
+ zero_offset_(size) { |
Block block = { FREE, 0, size, kUnusedToken }; |
blocks_.push_back(block); |
} |
@@ -39,9 +40,18 @@ FencedAllocator::~FencedAllocator() { |
// optimizing what to wait for, just looks inside the block in order (first-fit |
// as well). |
FencedAllocator::Offset FencedAllocator::Alloc(unsigned int size) { |
- // Similarly to malloc, an allocation of 0 allocates at least 1 byte, to |
- // return different pointers every time. |
- if (size == 0) size = 1; |
+ // Allocate zero size allocations outside the block. This is to satisfy 2 |
+ // issues. (1) that like malloc all ptrs are different (2) that |
+ // Alloc(GetLargestFreeSize()) always works. |
+ if (size == 0) { |
+ for (size_t ii = 0; ii < zero_allocs_.size(); ++ii) { |
apatrick
2012/12/03 20:45:43
How common is allocating with zero size? You can't
|
+ if (!zero_allocs_[ii]) { |
+ return zero_offset_ + ii; |
+ } |
+ } |
+ zero_allocs_.push_back(true); |
+ return zero_offset_ + zero_allocs_.size() - 1; |
+ } |
// Try first to allocate in a free block. |
for (unsigned int i = 0; i < blocks_.size(); ++i) { |
@@ -63,9 +73,18 @@ FencedAllocator::Offset FencedAllocator::Alloc(unsigned int size) { |
return kInvalidOffset; |
} |
+void FencedAllocator::FreeZeroAlloc(FencedAllocator::Offset offset) { |
+ size_t index = offset - zero_offset_; |
+ zero_allocs_[index] = false; |
apatrick
2012/12/03 20:45:43
Would DCHECK(zero_allocs_[index]) make sense here?
|
+} |
+ |
// Looks for the corresponding block, mark it FREE, and collapse it if |
// necessary. |
void FencedAllocator::Free(FencedAllocator::Offset offset) { |
+ if (offset >= zero_offset_) { |
+ FreeZeroAlloc(offset); |
+ return; |
+ } |
BlockIndex index = GetBlockByOffset(offset); |
GPU_DCHECK_NE(blocks_[index].state, FREE); |
blocks_[index].state = FREE; |
@@ -75,6 +94,10 @@ void FencedAllocator::Free(FencedAllocator::Offset offset) { |
// Looks for the corresponding block, mark it FREE_PENDING_TOKEN. |
void FencedAllocator::FreePendingToken( |
FencedAllocator::Offset offset, int32 token) { |
+ if (offset >= zero_offset_) { |
+ FreeZeroAlloc(offset); |
+ return; |
+ } |
BlockIndex index = GetBlockByOffset(offset); |
Block &block = blocks_[index]; |
block.state = FREE_PENDING_TOKEN; |