Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1059)

Unified Diff: gpu/command_buffer/client/fenced_allocator.cc

Issue 116863003: gpu: Reuse transfer buffers more aggresively (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..39720c4a199786eb5a0974058dbf25a9272849e7 100644
--- a/gpu/command_buffer/client/fenced_allocator.cc
+++ b/gpu/command_buffer/client/fenced_allocator.cc
@@ -34,8 +34,10 @@ const FencedAllocator::Offset FencedAllocator::kInvalidOffset;
#endif
FencedAllocator::FencedAllocator(unsigned int size,
+ bool aggressive_reuse,
CommandBufferHelper *helper)
: helper_(helper),
+ aggressive_reuse_(aggressive_reuse),
bytes_in_use_(0) {
Block block = { FREE, 0, RoundDown(size), kUnusedToken };
blocks_.push_back(block);
@@ -68,6 +70,10 @@ FencedAllocator::Offset FencedAllocator::Alloc(unsigned int size) {
// Round up the allocation size to ensure alignment.
size = RoundUp(size);
+ if (aggressive_reuse_) {
+ return AggressiveAlloc(size);
+ }
+
// Try first to allocate in a free block.
for (unsigned int i = 0; i < blocks_.size(); ++i) {
Block &block = blocks_[i];
@@ -88,6 +94,45 @@ FencedAllocator::Offset FencedAllocator::Alloc(unsigned int size) {
return kInvalidOffset;
}
+FencedAllocator::Offset FencedAllocator::AggressiveAlloc(unsigned int size) {
+ // Find first series of blocks that together make a large enough area.
+ unsigned int range_start = 0, range_stop = 0;
+ unsigned int current_size = 0;
+ for (unsigned int i = 0; i < blocks_.size(); ++i) {
+ Block &block = blocks_[i];
+ if (block.state == IN_USE) {
+ current_size = 0;
+ } else {
+ DCHECK(block.state == FREE || block.state == FREE_PENDING_TOKEN);
+
+ if (current_size == 0)
+ range_start = i;
+ range_stop = i;
+
+ current_size += block.size;
+ if (current_size >= size)
+ break;
+ }
+ }
+
+ if (current_size < size)
+ return kInvalidOffset;
+
+ // Collapse the blocks in the range |range_start| -> |range_stop| into
+ // one block. Override the previous state, as we don't care whether
+ // the block was FREE or FREE_PENDING_TOKEN here.
+ unsigned int new_size = blocks_[range_start].size;
+ const unsigned int second_in_range = range_start + 1;
+ for (unsigned int i = range_start; i < range_stop; ++i) {
+ new_size += blocks_[second_in_range].size;
+ blocks_.erase(blocks_.begin() + second_in_range);
+ }
+ blocks_[range_start].size = new_size;
+ blocks_[range_start].state = FREE;
+
+ return AllocInBlock(range_start, size);
+}
+
// Looks for the corresponding block, mark it FREE, and collapse it if
// necessary.
void FencedAllocator::Free(FencedAllocator::Offset offset) {
@@ -228,7 +273,12 @@ FencedAllocator::Offset FencedAllocator::AllocInBlock(BlockIndex index,
block.state = IN_USE;
return offset;
}
- Block newblock = { FREE, offset + size, block.size - size, kUnusedToken};
+ Block newblock = {
+ block.state,
+ offset + size,
+ block.size - size,
+ kUnusedToken
+ };
block.state = IN_USE;
block.size = size;
// this is the last thing being done because it may invalidate block;

Powered by Google App Engine
This is Rietveld 408576698