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 0e90bf385b4d0f8a9dded299cfb5a04b1aef2137..ae715320f99abaf9841a012ef5808e301c3931a6 100644 |
--- a/gpu/command_buffer/client/fenced_allocator.cc |
+++ b/gpu/command_buffer/client/fenced_allocator.cc |
@@ -42,10 +42,18 @@ FencedAllocator::FencedAllocator(unsigned int size, |
} |
FencedAllocator::~FencedAllocator() { |
- // Free blocks pending tokens. |
+ // Free blocks pending tokens and serials. |
for (unsigned int i = 0; i < blocks_.size(); ++i) { |
- if (blocks_[i].state == FREE_PENDING_TOKEN) { |
- i = WaitForTokenAndFreeBlock(i); |
+ switch (blocks_[i].state) { |
+ case FREE_PENDING_TOKEN: |
+ i = WaitForTokenAndFreeBlock(i); |
+ break; |
+ case FREE_PENDING_SERIAL: |
+ blocks_[i].state = FREE; |
+ CollapseFreeBlock(i); |
reveman
2014/01/16 17:24:49
I don't think it makes sense free this immediately
piman
2014/01/16 21:22:50
That is actually not needed to ensure things on th
jadahl
2014/01/17 08:50:25
We could just helper_->Finish() before the loop to
reveman
2014/01/17 16:56:47
If we're adding an async-token, then some command
|
+ break; |
+ default: |
+ break; |
} |
} |
// These checks are not valid if the service has crashed or lost the context. |
@@ -113,6 +121,16 @@ void FencedAllocator::FreePendingToken( |
block.token = token; |
} |
+void FencedAllocator::FreePendingSerial( |
+ FencedAllocator::Offset offset, uint32 serial) { |
+ BlockIndex index = GetBlockByOffset(offset); |
+ Block &block = blocks_[index]; |
+ if (block.state == IN_USE) |
+ bytes_in_use_ -= block.size; |
+ block.state = FREE_PENDING_SERIAL; |
+ block.serial = serial; |
+} |
+ |
// Gets the max of the size of the blocks marked as free. |
unsigned int FencedAllocator::GetLargestFreeSize() { |
FreeUnused(); |
@@ -132,12 +150,16 @@ unsigned int FencedAllocator::GetLargestFreeOrPendingSize() { |
unsigned int current_size = 0; |
for (unsigned int i = 0; i < blocks_.size(); ++i) { |
Block &block = blocks_[i]; |
- if (block.state == IN_USE) { |
- max_size = std::max(max_size, current_size); |
- current_size = 0; |
- } else { |
- DCHECK(block.state == FREE || block.state == FREE_PENDING_TOKEN); |
- current_size += block.size; |
+ switch (block.state) { |
+ case IN_USE: |
+ case FREE_PENDING_SERIAL: |
+ max_size = std::max(max_size, current_size); |
+ current_size = 0; |
+ break; |
+ default: |
+ DCHECK(block.state == FREE || block.state == FREE_PENDING_TOKEN); |
+ current_size += block.size; |
+ break; |
} |
} |
return std::max(max_size, current_size); |
@@ -203,14 +225,28 @@ FencedAllocator::BlockIndex FencedAllocator::WaitForTokenAndFreeBlock( |
// Frees any blocks pending a token for which the token has been read. |
void FencedAllocator::FreeUnused() { |
- int32 last_token_read = helper_->last_token_read(); |
for (unsigned int i = 0; i < blocks_.size();) { |
Block& block = blocks_[i]; |
- if (block.state == FREE_PENDING_TOKEN && block.token <= last_token_read) { |
- block.state = FREE; |
- i = CollapseFreeBlock(i); |
- } else { |
- ++i; |
+ switch (block.state) { |
+ case FREE_PENDING_TOKEN: |
+ if (helper_->HasTokenPassed(block.token)) { |
+ block.state = FREE; |
+ i = CollapseFreeBlock(i); |
+ } else { |
+ ++i; |
+ } |
+ break; |
+ case FREE_PENDING_SERIAL: |
+ if (helper_->HasSerialPassed(block.serial)) { |
+ block.state = FREE; |
+ i = CollapseFreeBlock(i); |
+ } else { |
+ ++i; |
+ } |
+ break; |
+ default: |
+ ++i; |
+ break; |
} |
} |
} |
@@ -228,7 +264,12 @@ FencedAllocator::Offset FencedAllocator::AllocInBlock(BlockIndex index, |
block.state = IN_USE; |
return offset; |
} |
- Block newblock = { FREE, offset + size, block.size - size, kUnusedToken}; |
+ Block newblock = { |
+ FREE, offset + size, |
+ block.size - size, |
+ kUnusedToken, |
+ kUnusedSerial |
+ }; |
block.state = IN_USE; |
block.size = size; |
// this is the last thing being done because it may invalidate block; |
@@ -238,7 +279,13 @@ FencedAllocator::Offset FencedAllocator::AllocInBlock(BlockIndex index, |
// The blocks are in offset order, so we can do a binary search. |
FencedAllocator::BlockIndex FencedAllocator::GetBlockByOffset(Offset offset) { |
- Block templ = { IN_USE, offset, 0, kUnusedToken }; |
+ Block templ = { |
+ IN_USE, |
+ offset, |
+ 0, |
+ kUnusedToken, |
+ kUnusedSerial |
+ }; |
Container::iterator it = std::lower_bound(blocks_.begin(), blocks_.end(), |
templ, OffsetCmp()); |
DCHECK(it != blocks_.end() && it->offset == offset); |