diff options
author | piman@google.com <piman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-14 23:43:15 +0000 |
---|---|---|
committer | piman@google.com <piman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-14 23:43:15 +0000 |
commit | 7d5b8d1da5cda4a2fbd071430f7030596c3c7365 (patch) | |
tree | 99b82372e1436bcaca5dcc5ba625ad28da0460da /gpu | |
parent | 08a3cacedb78fd367b166dad5fdf7dfb01d36bfb (diff) | |
download | chromium_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.cc | 36 | ||||
-rw-r--r-- | gpu/command_buffer/client/cmd_buffer_helper.h | 8 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_implementation_unittest.cc | 8 | ||||
-rw-r--r-- | gpu/command_buffer/common/command_buffer.h | 9 | ||||
-rw-r--r-- | gpu/command_buffer/common/command_buffer_mock.h | 3 | ||||
-rw-r--r-- | gpu/command_buffer/service/command_buffer_service.cc | 6 | ||||
-rw-r--r-- | gpu/command_buffer/service/command_buffer_service.h | 3 | ||||
-rw-r--r-- | gpu/pgl/command_buffer_pepper.cc | 6 | ||||
-rw-r--r-- | gpu/pgl/command_buffer_pepper.h | 3 |
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); |