diff options
author | backer@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-06 22:32:44 +0000 |
---|---|---|
committer | backer@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-06 22:32:44 +0000 |
commit | 6802e3c649238b7b799b2140b3b6bc5db3a336fb (patch) | |
tree | fe856dc427af1a659b5434e1d26a30d0d042f540 /gpu | |
parent | e230a44f882894d7172881951a8783c40ca9f74f (diff) | |
download | chromium_src-6802e3c649238b7b799b2140b3b6bc5db3a336fb.zip chromium_src-6802e3c649238b7b799b2140b3b6bc5db3a336fb.tar.gz chromium_src-6802e3c649238b7b799b2140b3b6bc5db3a336fb.tar.bz2 |
Preempt renderers by browser UI in GpuScheduler.
Adds a message filter in GpuChannel to detect if the UI has commands to execute. This is polled in GpuScheduler so that renderers will defer to the UI.
BUG=none
TEST=smoothly drag a window of https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/sdk/demos/google/san-angeles/index.html on alex
Review URL: https://chromiumcodereview.appspot.com/10186002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@140866 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/command_buffer/service/gpu_scheduler.cc | 14 | ||||
-rw-r--r-- | gpu/command_buffer/service/gpu_scheduler.h | 29 | ||||
-rw-r--r-- | gpu/command_buffer_service.gypi | 1 |
3 files changed, 42 insertions, 2 deletions
diff --git a/gpu/command_buffer/service/gpu_scheduler.cc b/gpu/command_buffer/service/gpu_scheduler.cc index af34f76..85d4f75 100644 --- a/gpu/command_buffer/service/gpu_scheduler.cc +++ b/gpu/command_buffer/service/gpu_scheduler.cc @@ -32,7 +32,8 @@ GpuScheduler::GpuScheduler( parser_(NULL), unscheduled_count_(0), rescheduled_count_(0), - reschedule_task_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { + reschedule_task_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), + was_preempted_(false) { } GpuScheduler::~GpuScheduler() { @@ -63,6 +64,17 @@ void GpuScheduler::PutChanged() { error::Error error = error::kNoError; while (!parser_->IsEmpty()) { + if (preempt_by_counter_.get() && + !was_preempted_ && + !preempt_by_counter_->IsZero()) { + TRACE_COUNTER_ID1("gpu","GpuScheduler::Preempted", this, 1); + was_preempted_ = true; + return; + } else if (was_preempted_) { + TRACE_COUNTER_ID1("gpu","GpuScheduler::Preempted", this, 0); + was_preempted_ = false; + } + DCHECK(IsScheduled()); DCHECK(unschedule_fences_.empty()); diff --git a/gpu/command_buffer/service/gpu_scheduler.h b/gpu/command_buffer/service/gpu_scheduler.h index 2ae048b..9aa7d9e 100644 --- a/gpu/command_buffer/service/gpu_scheduler.h +++ b/gpu/command_buffer/service/gpu_scheduler.h @@ -7,9 +7,12 @@ #include <queue> +#include "base/atomicops.h" +#include "base/atomic_ref_count.h" #include "base/callback.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/linked_ptr.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/shared_memory.h" #include "gpu/command_buffer/common/command_buffer.h" @@ -24,6 +27,21 @@ class GLFence; namespace gpu { +struct RefCountedCounter + : public base::RefCountedThreadSafe<RefCountedCounter> { + base::AtomicRefCount count; + RefCountedCounter() : count(0) {} + + bool IsZero() { return base::AtomicRefCountIsZero(&count); } + void IncCount() { base::AtomicRefCountInc(&count); } + void DecCount() { base::AtomicRefCountDec(&count); } + void Reset() { base::subtle::NoBarrier_Store(&count, 0); } + private: + ~RefCountedCounter() {} + + friend class base::RefCountedThreadSafe<RefCountedCounter>; +}; + // This class schedules commands that have been flushed. They are received via // a command buffer and forwarded to a command parser. TODO(apatrick): This // class should not know about the decoder. Do not add additional dependencies @@ -40,6 +58,10 @@ class GPU_EXPORT GpuScheduler void PutChanged(); + void SetPreemptByCounter(scoped_refptr<RefCountedCounter> counter) { + preempt_by_counter_ = counter; + } + // Sets whether commands should be processed by this scheduler. Setting to // false unschedules. Setting to true reschedules. Whether or not the // scheduler is currently scheduled is "reference counted". Every call with @@ -123,6 +145,11 @@ class GPU_EXPORT GpuScheduler base::Closure scheduled_callback_; base::Closure command_processed_callback_; + // If non-NULL and preempt_by_counter_->count is non-zero, + // exit PutChanged early. + scoped_refptr<RefCountedCounter> preempt_by_counter_; + bool was_preempted_; + DISALLOW_COPY_AND_ASSIGN(GpuScheduler); }; diff --git a/gpu/command_buffer_service.gypi b/gpu/command_buffer_service.gypi index 5e7d6a6..02bfaf6 100644 --- a/gpu/command_buffer_service.gypi +++ b/gpu/command_buffer_service.gypi @@ -15,6 +15,7 @@ }, 'dependencies': [ '../base/base.gyp:base', + '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', '../crypto/crypto.gyp:crypto', '../ui/gl/gl.gyp:gl', '../ui/surface/surface.gyp:surface', |