Chromium Code Reviews| 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; |