summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorpiman@google.com <piman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-14 23:43:15 +0000
committerpiman@google.com <piman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-14 23:43:15 +0000
commit7d5b8d1da5cda4a2fbd071430f7030596c3c7365 (patch)
tree99b82372e1436bcaca5dcc5ba625ad28da0460da /gpu
parent08a3cacedb78fd367b166dad5fdf7dfb01d36bfb (diff)
downloadchromium_src-7d5b8d1da5cda4a2fbd071430f7030596c3c7365.zip
chromium_src-7d5b8d1da5cda4a2fbd071430f7030596c3c7365.tar.gz
chromium_src-7d5b8d1da5cda4a2fbd071430f7030596c3c7365.tar.bz2
Make CommandBuffer::Flush asynchronous, and add CommandBuffer::FlushSync with former semantics.
Also force a flush when the buffer is getting full. BUG=none TEST=gpu_unittests, some webgl content, some 3d css content, pepper flash Review URL: http://codereview.chromium.org/6316002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@71514 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r--gpu/command_buffer/client/cmd_buffer_helper.cc36
-rw-r--r--gpu/command_buffer/client/cmd_buffer_helper.h8
-rw-r--r--gpu/command_buffer/client/gles2_implementation_unittest.cc8
-rw-r--r--gpu/command_buffer/common/command_buffer.h9
-rw-r--r--gpu/command_buffer/common/command_buffer_mock.h3
-rw-r--r--gpu/command_buffer/service/command_buffer_service.cc6
-rw-r--r--gpu/command_buffer/service/command_buffer_service.h3
-rw-r--r--gpu/pgl/command_buffer_pepper.cc6
-rw-r--r--gpu/pgl/command_buffer_pepper.h3
9 files changed, 59 insertions, 23 deletions
diff --git a/gpu/command_buffer/client/cmd_buffer_helper.cc b/gpu/command_buffer/client/cmd_buffer_helper.cc
index b666e83..b525021 100644
--- a/gpu/command_buffer/client/cmd_buffer_helper.cc
+++ b/gpu/command_buffer/client/cmd_buffer_helper.cc
@@ -17,7 +17,8 @@ CommandBufferHelper::CommandBufferHelper(CommandBuffer* command_buffer)
token_(0),
last_token_read_(-1),
get_(0),
- put_(0) {
+ put_(0),
+ last_put_sent_(0) {
}
bool CommandBufferHelper::Initialize(int32 ring_buffer_size) {
@@ -45,19 +46,25 @@ bool CommandBufferHelper::Initialize(int32 ring_buffer_size) {
CommandBufferHelper::~CommandBufferHelper() {
}
-bool CommandBufferHelper::Flush() {
- CommandBuffer::State state = command_buffer_->Flush(put_);
+bool CommandBufferHelper::FlushSync() {
+ last_put_sent_ = put_;
+ CommandBuffer::State state = command_buffer_->FlushSync(put_);
SynchronizeState(state);
return state.error == error::kNoError;
}
+void CommandBufferHelper::Flush() {
+ last_put_sent_ = put_;
+ command_buffer_->Flush(put_);
+}
+
// Calls Flush() and then waits until the buffer is empty. Break early if the
// error is set.
bool CommandBufferHelper::Finish() {
do {
// Do not loop forever if the flush fails, meaning the command buffer reader
// has shutdown.
- if (!Flush())
+ if (!FlushSync())
return false;
} while (put_ != get_);
@@ -88,9 +95,7 @@ void CommandBufferHelper::WaitForToken(int32 token) {
// Return immediately if corresponding InsertToken failed.
if (token < 0)
return;
- if (last_token_read_ >= token) return; // fast path.
if (token > token_) return; // we wrapped
- Flush();
while (last_token_read_ < token) {
if (get_ == put_) {
GPU_LOG(FATAL) << "Empty command buffer while waiting on a token.";
@@ -98,7 +103,7 @@ void CommandBufferHelper::WaitForToken(int32 token) {
}
// Do not loop forever if the flush fails, meaning the command buffer reader
// has shutdown.
- if (!Flush())
+ if (!FlushSync())
return;
}
}
@@ -116,27 +121,30 @@ void CommandBufferHelper::WaitForAvailableEntries(int32 count) {
// need to make sure get wraps first, actually that get is 1 or more (since
// put will wrap to 0 after we add the jump).
GPU_DCHECK_LE(1, put_);
- Flush();
while (get_ > put_ || get_ == 0) {
// Do not loop forever if the flush fails, meaning the command buffer
// reader has shutdown.
- if (!Flush())
+ if (!FlushSync())
return;
}
// Insert a jump back to the beginning.
cmd::Jump::Set(&entries_[put_], 0);
put_ = 0;
}
- // If we have enough room, return immediatly.
- if (count <= AvailableEntries()) return;
- // Otherwise flush, and wait until we do have enough room.
- Flush();
while (AvailableEntries() < count) {
// Do not loop forever if the flush fails, meaning the command buffer reader
// has shutdown.
- if (!Flush())
+ if (!FlushSync())
return;
}
+ // Force a flush if the buffer is getting half full, or even earlier if the
+ // reader is known to be idle.
+ int32 pending =
+ (put_ + usable_entry_count_ - last_put_sent_) % usable_entry_count_;
+ int32 limit = usable_entry_count_ / ((get_ == last_put_sent_) ? 16 : 2);
+ if (pending > limit) {
+ Flush();
+ }
}
CommandBufferEntry* CommandBufferHelper::GetSpace(uint32 entries) {
diff --git a/gpu/command_buffer/client/cmd_buffer_helper.h b/gpu/command_buffer/client/cmd_buffer_helper.h
index d174831e..c28333a 100644
--- a/gpu/command_buffer/client/cmd_buffer_helper.h
+++ b/gpu/command_buffer/client/cmd_buffer_helper.h
@@ -42,13 +42,18 @@ class CommandBufferHelper {
// buffer.
bool Initialize(int32 ring_buffer_size);
+ // Asynchronously flushes the commands, setting the put pointer to let the
+ // buffer interface know that new commands have been added. After a flush
+ // returns, the command buffer service is aware of all pending commands.
+ void Flush();
+
// Flushes the commands, setting the put pointer to let the buffer interface
// know that new commands have been added. After a flush returns, the command
// buffer service is aware of all pending commands and it is guaranteed to
// have made some progress in processing them. Returns whether the flush was
// successful. The flush will fail if the command buffer service has
// disconnected.
- bool Flush();
+ bool FlushSync();
// Waits until all the commands have been executed. Returns whether it
// was successful. The function will fail if the command buffer service has
@@ -225,6 +230,7 @@ class CommandBufferHelper {
int32 last_token_read_;
int32 get_;
int32 put_;
+ int32 last_put_sent_;
friend class CommandBufferHelperTest;
DISALLOW_COPY_AND_ASSIGN(CommandBufferHelper);
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc
index d431851..dabcba3 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest.cc
+++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc
@@ -37,7 +37,11 @@ class GLES2MockCommandBufferHelper : public CommandBuffer {
return state_;
}
- virtual State Flush(int32 put_offset) {
+ virtual void Flush(int32 put_offset) {
+ state_.put_offset = put_offset;
+ }
+
+ virtual State FlushSync(int32 put_offset) {
state_.put_offset = put_offset;
state_.get_offset = put_offset;
OnFlush(transfer_buffer_buffer_.ptr);
@@ -191,7 +195,7 @@ class GLES2ImplementationTest : public testing::Test {
false));
EXPECT_CALL(*command_buffer_, OnFlush(_)).Times(1).RetiresOnSaturation();
- helper_->CommandBufferHelper::Flush();
+ helper_->CommandBufferHelper::FlushSync();
Buffer ring_buffer = command_buffer_->GetRingBuffer();
commands_ = static_cast<CommandBufferEntry*>(ring_buffer.ptr) +
command_buffer_->GetState().put_offset;
diff --git a/gpu/command_buffer/common/command_buffer.h b/gpu/command_buffer/common/command_buffer.h
index 41eda77..963b228 100644
--- a/gpu/command_buffer/common/command_buffer.h
+++ b/gpu/command_buffer/common/command_buffer.h
@@ -61,10 +61,17 @@ class CommandBuffer {
// Returns the current status.
virtual State GetState() = 0;
+ // The writer calls this to update its put offset. This ensures the reader
+ // sees the latest added commands, and will eventually process them.
+ virtual void Flush(int32 put_offset) = 0;
+
// The writer calls this to update its put offset. This function returns the
// reader's most recent get offset. Does not return until after the put offset
// change callback has been invoked. Returns -1 if the put offset is invalid.
- virtual State Flush(int32 put_offset) = 0;
+ // As opposed to Flush(), this function guarantees that the reader has
+ // processed some commands before returning (assuming the command buffer isn't
+ // empty and there is no error).
+ virtual State FlushSync(int32 put_offset) = 0;
// Sets the current get offset. This can be called from any thread.
virtual void SetGetOffset(int32 get_offset) = 0;
diff --git a/gpu/command_buffer/common/command_buffer_mock.h b/gpu/command_buffer/common/command_buffer_mock.h
index 97cd3cf..a633d24 100644
--- a/gpu/command_buffer/common/command_buffer_mock.h
+++ b/gpu/command_buffer/common/command_buffer_mock.h
@@ -20,7 +20,8 @@ class MockCommandBuffer : public CommandBuffer {
MOCK_METHOD1(Initialize, bool(int32 size));
MOCK_METHOD0(GetRingBuffer, Buffer());
MOCK_METHOD0(GetState, State());
- MOCK_METHOD1(Flush, State(int32 put_offset));
+ MOCK_METHOD1(Flush, void(int32 put_offset));
+ MOCK_METHOD1(FlushSync, State(int32 put_offset));
MOCK_METHOD1(SetGetOffset, void(int32 get_offset));
MOCK_METHOD1(CreateTransferBuffer, int32(size_t size));
MOCK_METHOD1(DestroyTransferBuffer, void(int32 handle));
diff --git a/gpu/command_buffer/service/command_buffer_service.cc b/gpu/command_buffer/service/command_buffer_service.cc
index fd443f2..c2a85af 100644
--- a/gpu/command_buffer/service/command_buffer_service.cc
+++ b/gpu/command_buffer/service/command_buffer_service.cc
@@ -77,7 +77,7 @@ CommandBufferService::State CommandBufferService::GetState() {
return state;
}
-CommandBufferService::State CommandBufferService::Flush(int32 put_offset) {
+CommandBufferService::State CommandBufferService::FlushSync(int32 put_offset) {
if (put_offset < 0 || put_offset > num_entries_) {
error_ = gpu::error::kOutOfBounds;
return GetState();
@@ -92,6 +92,10 @@ CommandBufferService::State CommandBufferService::Flush(int32 put_offset) {
return GetState();
}
+void CommandBufferService::Flush(int32 put_offset) {
+ FlushSync(put_offset);
+}
+
void CommandBufferService::SetGetOffset(int32 get_offset) {
DCHECK(get_offset >= 0 && get_offset < num_entries_);
get_offset_ = get_offset;
diff --git a/gpu/command_buffer/service/command_buffer_service.h b/gpu/command_buffer/service/command_buffer_service.h
index d9be20a..94d77c3 100644
--- a/gpu/command_buffer/service/command_buffer_service.h
+++ b/gpu/command_buffer/service/command_buffer_service.h
@@ -28,7 +28,8 @@ class CommandBufferService : public CommandBuffer {
virtual bool Initialize(int32 size);
virtual Buffer GetRingBuffer();
virtual State GetState();
- virtual State Flush(int32 put_offset);
+ virtual void Flush(int32 put_offset);
+ virtual State FlushSync(int32 put_offset);
virtual void SetGetOffset(int32 get_offset);
virtual int32 CreateTransferBuffer(size_t size);
virtual void DestroyTransferBuffer(int32 id);
diff --git a/gpu/pgl/command_buffer_pepper.cc b/gpu/pgl/command_buffer_pepper.cc
index 0025803..db72474 100644
--- a/gpu/pgl/command_buffer_pepper.cc
+++ b/gpu/pgl/command_buffer_pepper.cc
@@ -83,7 +83,11 @@ CommandBuffer::State CommandBufferPepper::GetState() {
#endif // ENABLE_NEW_NPDEVICE_API
}
-CommandBuffer::State CommandBufferPepper::Flush(int32 put_offset) {
+void CommandBufferPepper::Flush(int32 put_offset) {
+ FlushSync(put_offset);
+}
+
+CommandBuffer::State CommandBufferPepper::FlushSync(int32 put_offset) {
#if defined(ENABLE_NEW_NPDEVICE_API)
int32 input_attribs[] = {
NP3DAttrib_PutOffset, put_offset,
diff --git a/gpu/pgl/command_buffer_pepper.h b/gpu/pgl/command_buffer_pepper.h
index 5d11d98..fe80625 100644
--- a/gpu/pgl/command_buffer_pepper.h
+++ b/gpu/pgl/command_buffer_pepper.h
@@ -29,7 +29,8 @@ class CommandBufferPepper : public gpu::CommandBuffer {
virtual bool Initialize(int32 size);
virtual gpu::Buffer GetRingBuffer();
virtual State GetState();
- virtual State Flush(int32 put_offset);
+ virtual void Flush(int32 put_offset);
+ virtual State FlushSync(int32 put_offset);
virtual void SetGetOffset(int32 get_offset);
virtual int32 CreateTransferBuffer(size_t size);
virtual void DestroyTransferBuffer(int32 id);