Index: gpu/command_buffer/client/ring_buffer.cc |
diff --git a/gpu/command_buffer/client/ring_buffer.cc b/gpu/command_buffer/client/ring_buffer.cc |
index 813bb348863d8810c93690896a9441c67e194c79..5a77326b2e5235ad96fee3340995906c5c595947 100644 |
--- a/gpu/command_buffer/client/ring_buffer.cc |
+++ b/gpu/command_buffer/client/ring_buffer.cc |
@@ -103,6 +103,63 @@ void RingBuffer::FreePendingToken(void* pointer, |
NOTREACHED() << "attempt to free non-existant block"; |
} |
+void RingBuffer::DiscardBlock(void* pointer) { |
+ Offset offset = GetOffset(pointer); |
+ offset -= base_offset_; |
+ DCHECK(!blocks_.empty()) << "no allocations to free"; |
+ for (Container::reverse_iterator it = blocks_.rbegin(); |
+ it != blocks_.rend(); |
+ ++it) { |
+ Block& block = *it; |
+ if (block.offset == offset) { |
+ if (&block == &blocks_.back()) { |
+ // If this block is the last one we can effectively remove it. |
+ if (free_offset_ == 0) { |
+ // Last block had looped around. |
+ free_offset_ = size_; |
+ } |
+ free_offset_ -= block.size; |
piman
2015/06/09 22:55:05
nit: I would just do free_offset_ = offset so that
David Yen
2015/06/10 18:17:09
Done.
|
+ blocks_.pop_back(); |
+ |
+ // We should also pop any PADDING at the back as well, |
+ // but be careful because free_offset_ must be 0 when at the end. |
+ while (!blocks_.empty() && blocks_.back().state == PADDING) { |
+ if (free_offset_ == 0) |
+ free_offset_ = size_; |
+ free_offset_ -= blocks_.back().size; |
piman
2015/06/09 22:55:05
Same here, if you want to pop PADDING ones, free_o
David Yen
2015/06/10 18:17:09
Done.
|
+ blocks_.pop_back(); |
+ } |
+ } else if (&block == &blocks_.front()) { |
piman
2015/06/09 22:55:05
I'm not sure the front part is that useful, becaus
David Yen
2015/06/10 18:17:09
I think it is better to handle it here so that Get
|
+ // If this block is the front, we can remove it from the front. |
+ in_use_offset_ += block.size; |
+ if (in_use_offset_ == size_) |
+ in_use_offset_ = 0; |
+ blocks_.pop_front(); |
+ |
+ // We should also pop any PADDING at the front as well, but be careful |
+ // because in_use_offset_ must be size_ when at the front. |
+ while (!blocks_.empty() && blocks_.front().state == PADDING) { |
+ in_use_offset_ += blocks_.front().size; |
+ if (in_use_offset_ == size_) |
+ in_use_offset_ = 0; |
+ blocks_.pop_front(); |
+ } |
+ } else { |
+ // Mark this as padding and let the FreeOldestBlock() handle offsets. |
+ block.state = PADDING; |
+ } |
+ |
+ // In the special case when there are no blocks, we should be reset it. |
+ if (blocks_.empty()) { |
+ in_use_offset_ = 0; |
+ free_offset_ = 0; |
+ } |
+ return; |
+ } |
+ } |
+ NOTREACHED() << "attempt to free non-existant block"; |
+} |
+ |
unsigned int RingBuffer::GetLargestFreeSizeNoWaiting() { |
unsigned int last_token_read = helper_->last_token_read(); |
while (!blocks_.empty()) { |