diff options
author | jbates@chromium.org <jbates@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-18 23:55:10 +0000 |
---|---|---|
committer | jbates@chromium.org <jbates@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-18 23:55:10 +0000 |
commit | 80c49759f6489e638e7777256aa4700e38dbdcfc (patch) | |
tree | d61f4b4d4cc25cab5068fe73b016fcd24e06b4ba /gpu | |
parent | 5f9f681a330988123e0e01d00da2888789e9b476 (diff) | |
download | chromium_src-80c49759f6489e638e7777256aa4700e38dbdcfc.zip chromium_src-80c49759f6489e638e7777256aa4700e38dbdcfc.tar.gz chromium_src-80c49759f6489e638e7777256aa4700e38dbdcfc.tar.bz2 |
GpuScheduler no longer spins when it is waiting on a latch.
BUG=79632
TEST=run trace in about:gpu; observe the number of times the GPU process sequentially calls WaitLatch; verify it is not spinning.
Review URL: http://codereview.chromium.org/6874029
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@82033 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/command_buffer/common/constants.h | 6 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 19 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.h | 5 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_mock.h | 1 | ||||
-rw-r--r-- | gpu/command_buffer/service/gpu_scheduler.cc | 5 | ||||
-rw-r--r-- | gpu/command_buffer/service/gpu_scheduler.h | 7 |
6 files changed, 36 insertions, 7 deletions
diff --git a/gpu/command_buffer/common/constants.h b/gpu/command_buffer/common/constants.h index bebc046..6ef22aa 100644 --- a/gpu/command_buffer/common/constants.h +++ b/gpu/command_buffer/common/constants.h @@ -23,9 +23,9 @@ namespace error { kLostContext, kGenericError, - // This is not an error. It is returned by commands that want to - // be called again until they return a different error. For - // example: WaitLatch. + // This is not an error. It is returned by WaitLatch when it is blocked. + // When blocked, the context will not reschedule itself until another + // context executes a SetLatch command. kWaiting, // This is not an error. It is returned by commands to mark a position diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 2c0de18..9e14183 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -686,6 +686,7 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, virtual void SetResizeCallback(Callback1<gfx::Size>::Type* callback); virtual void SetSwapBuffersCallback(Callback0::Type* callback); + virtual void SetLatchCallback(const base::Callback<void(bool)>& callback);; virtual bool GetServiceTextureId(uint32 client_texture_id, uint32* service_texture_id); @@ -1447,6 +1448,7 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, scoped_ptr<Callback1<gfx::Size>::Type> resize_callback_; scoped_ptr<Callback0::Type> swap_buffers_callback_; + base::Callback<void(bool)> latch_callback_; // The format of the back buffer_ GLenum back_buffer_color_format_; @@ -2458,6 +2460,11 @@ void GLES2DecoderImpl::SetSwapBuffersCallback(Callback0::Type* callback) { swap_buffers_callback_.reset(callback); } +void GLES2DecoderImpl::SetLatchCallback( + const base::Callback<void(bool)>& callback) { + latch_callback_ = callback; +} + bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id, uint32* service_texture_id) { TextureManager::TextureInfo* texture = @@ -6398,7 +6405,9 @@ error::Error GLES2DecoderImpl::HandleSetLatchCHROMIUM( if (!latch) { return error::kOutOfBounds; } - *latch = 1; + base::subtle::NoBarrier_Store(latch, 1); + if (!latch_callback_.is_null()) + latch_callback_.Run(true); return error::kNoError; } @@ -6419,7 +6428,13 @@ error::Error GLES2DecoderImpl::HandleWaitLatchCHROMIUM( base::subtle::Atomic32 old = base::subtle::NoBarrier_CompareAndSwap(latch, 1, 0); - return (old == 0) ? error::kWaiting : error::kNoError; + if (old == 0) { + if (!latch_callback_.is_null()) + latch_callback_.Run(false); + return error::kWaiting; + } else { + return error::kNoError; + } } error::Error GLES2DecoderImpl::HandleCommandBufferEnableCHROMIUM( diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h index 1646c90..cb28d21 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder.h @@ -103,6 +103,11 @@ class GLES2Decoder : public CommonDecoder { // Sets a callback which is called when a SwapBuffers command is processed. virtual void SetSwapBuffersCallback(Callback0::Type* callback) = 0; + // Sets a callback which is called after a Set/WaitLatch command is processed. + // The bool parameter will be true for SetLatch, and false for a WaitLatch + // that is blocked. An unblocked WaitLatch will not trigger a callback. + virtual void SetLatchCallback(const base::Callback<void(bool)>& callback) = 0; + // Get the service texture ID corresponding to a client texture ID. // If no such record is found then return false. virtual bool GetServiceTextureId(uint32 client_texture_id, diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h index 37a7e72..3ab6f06 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h @@ -43,6 +43,7 @@ class MockGLES2Decoder : public GLES2Decoder { MOCK_METHOD0(GetContextGroup, ContextGroup*()); MOCK_METHOD1(SetResizeCallback, void(Callback1<gfx::Size>::Type*)); MOCK_METHOD1(SetSwapBuffersCallback, void(Callback0::Type*)); + MOCK_METHOD1(SetLatchCallback, void(const base::Callback<void(bool)>&)); MOCK_METHOD3(DoCommand, error::Error(unsigned int command, unsigned int arg_count, const void* cmd_data)); diff --git a/gpu/command_buffer/service/gpu_scheduler.cc b/gpu/command_buffer/service/gpu_scheduler.cc index 933b468..1ae36c4 100644 --- a/gpu/command_buffer/service/gpu_scheduler.cc +++ b/gpu/command_buffer/service/gpu_scheduler.cc @@ -166,9 +166,10 @@ void GpuScheduler::ProcessCommands() { throttle_fences_.pop(); } + error::Error error = error::kNoError; int commands_processed = 0; while (commands_processed < commands_per_update_ && !parser_->IsEmpty()) { - error::Error error = parser_->ProcessCommand(); + error = parser_->ProcessCommand(); if (error == error::kWaiting) { break; } @@ -201,7 +202,7 @@ void GpuScheduler::ProcessCommands() { command_buffer_->SetGetOffset(static_cast<int32>(parser_->get())); - if (!parser_->IsEmpty()) { + if (error != error::kWaiting && !parser_->IsEmpty()) { ScheduleProcessCommands(); } } diff --git a/gpu/command_buffer/service/gpu_scheduler.h b/gpu/command_buffer/service/gpu_scheduler.h index 5ed808c..36cc009 100644 --- a/gpu/command_buffer/service/gpu_scheduler.h +++ b/gpu/command_buffer/service/gpu_scheduler.h @@ -114,6 +114,13 @@ class GpuScheduler : public CommandBufferEngine { virtual void SetCommandProcessedCallback(Callback0::Type* callback); + // Sets a callback which is called after a Set/WaitLatch command is processed. + // The bool parameter will be true for SetLatch, and false for a WaitLatch + // that is blocked. An unblocked WaitLatch will not trigger a callback. + void SetLatchCallback(const base::Callback<void(bool)>& callback) { + decoder_->SetLatchCallback(callback); + } + // Get the GLES2Decoder associated with this scheduler. gles2::GLES2Decoder* decoder() const { return decoder_.get(); } |