diff options
author | jbauman@chromium.org <jbauman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-03 18:23:56 +0000 |
---|---|---|
committer | jbauman@chromium.org <jbauman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-03 18:23:56 +0000 |
commit | 627d9344c2733f6160927dac527e67a6c79d9304 (patch) | |
tree | 5ccc8ad28ae2200cb8572df59799361d187cf559 /gpu | |
parent | 88dee5e7f00ebf94465d3bf4399ef50484e9d8a2 (diff) | |
download | chromium_src-627d9344c2733f6160927dac527e67a6c79d9304.zip chromium_src-627d9344c2733f6160927dac527e67a6c79d9304.tar.gz chromium_src-627d9344c2733f6160927dac527e67a6c79d9304.tar.bz2 |
Allow gpu ringbuffer to wrap around.
The ringbuffer was unwilling to wrap around unless the last block filled it up completely - otherwise it would have to wait until it was completely empty. Fix this in the most straightforward way by filling the ringbuffer up with a padding block if necessary.
BUG=80946
TEST=
Review URL: http://codereview.chromium.org/6901138
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@83924 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/command_buffer/client/ring_buffer.cc | 27 | ||||
-rw-r--r-- | gpu/command_buffer/client/ring_buffer.h | 13 |
2 files changed, 27 insertions, 13 deletions
diff --git a/gpu/command_buffer/client/ring_buffer.cc b/gpu/command_buffer/client/ring_buffer.cc index 835f430..762f834 100644 --- a/gpu/command_buffer/client/ring_buffer.cc +++ b/gpu/command_buffer/client/ring_buffer.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -29,8 +29,11 @@ RingBuffer::~RingBuffer() { void RingBuffer::FreeOldestBlock() { GPU_DCHECK(!blocks_.empty()) << "no free blocks"; Block& block = blocks_.front(); - GPU_DCHECK(block.valid) << "attempt to allocate more than maximum memory"; - helper_->WaitForToken(block.token); + GPU_DCHECK(block.state != IN_USE) + << "attempt to allocate more than maximum memory"; + if (block.state == FREE_PENDING_TOKEN) { + helper_->WaitForToken(block.token); + } in_use_offset_ += block.size; if (in_use_offset_ == size_) { in_use_offset_ = 0; @@ -45,7 +48,7 @@ void RingBuffer::FreeOldestBlock() { RingBuffer::Offset RingBuffer::Alloc(unsigned int size) { GPU_DCHECK_LE(size, size_) << "attempt to allocate more than maximum memory"; - GPU_DCHECK(blocks_.empty() || blocks_.back().valid) + GPU_DCHECK(blocks_.empty() || blocks_.back().state != IN_USE) << "Attempt to alloc another block before freeing the previous."; // Similarly to malloc, an allocation of 0 allocates at least 1 byte, to // return different pointers every time. @@ -56,8 +59,14 @@ RingBuffer::Offset RingBuffer::Alloc(unsigned int size) { FreeOldestBlock(); } + if (size + free_offset_ > size_) { + // Add padding to fill space before wrapping around + blocks_.push_back(Block(free_offset_, size_ - free_offset_, PADDING)); + free_offset_ = 0; + } + Offset offset = free_offset_; - blocks_.push_back(Block(offset, size)); + blocks_.push_back(Block(offset, size, IN_USE)); free_offset_ += size; if (free_offset_ == size_) { free_offset_ = 0; @@ -74,10 +83,10 @@ void RingBuffer::FreePendingToken(RingBuffer::Offset offset, ++it) { Block& block = *it; if (block.offset == offset) { - GPU_DCHECK(!block.valid) + GPU_DCHECK(block.state == IN_USE) << "block that corresponds to offset already freed"; block.token = token; - block.valid = true; + block.state = FREE_PENDING_TOKEN; return; } } @@ -97,8 +106,8 @@ unsigned int RingBuffer::GetLargestFreeSizeNoWaiting() { return 0; } } else if (free_offset_ > in_use_offset_) { - // It's free from free_offset_ to size_ - return size_ - free_offset_; + // It's free from free_offset_ to size_ and from 0 to in_use_offset_ + return std::max(size_ - free_offset_, in_use_offset_); } else { // It's free from free_offset_ -> in_use_offset_; return in_use_offset_ - free_offset_; diff --git a/gpu/command_buffer/client/ring_buffer.h b/gpu/command_buffer/client/ring_buffer.h index b7194bb..b40c446 100644 --- a/gpu/command_buffer/client/ring_buffer.h +++ b/gpu/command_buffer/client/ring_buffer.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -61,18 +61,23 @@ class RingBuffer { } private: + enum State { + IN_USE, + PADDING, + FREE_PENDING_TOKEN + }; // Book-keeping sturcture that describes a block of memory. struct Block { - Block(Offset _offset, unsigned int _size) + Block(Offset _offset, unsigned int _size, State _state) : offset(_offset), size(_size), token(0), - valid(false) { + state(_state) { } Offset offset; unsigned int size; unsigned int token; // token to wait for. - bool valid; // whether or not token has been set. + State state; }; typedef std::deque<Block> Container; |