summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorjbauman@chromium.org <jbauman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-03 18:23:56 +0000
committerjbauman@chromium.org <jbauman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-03 18:23:56 +0000
commit627d9344c2733f6160927dac527e67a6c79d9304 (patch)
tree5ccc8ad28ae2200cb8572df59799361d187cf559 /gpu
parent88dee5e7f00ebf94465d3bf4399ef50484e9d8a2 (diff)
downloadchromium_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.cc27
-rw-r--r--gpu/command_buffer/client/ring_buffer.h13
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;