summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorjbates@chromium.org <jbates@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-18 23:55:10 +0000
committerjbates@chromium.org <jbates@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-18 23:55:10 +0000
commit80c49759f6489e638e7777256aa4700e38dbdcfc (patch)
treed61f4b4d4cc25cab5068fe73b016fcd24e06b4ba /gpu
parent5f9f681a330988123e0e01d00da2888789e9b476 (diff)
downloadchromium_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.h6
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc19
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.h5
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_mock.h1
-rw-r--r--gpu/command_buffer/service/gpu_scheduler.cc5
-rw-r--r--gpu/command_buffer/service/gpu_scheduler.h7
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(); }