summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorbacker@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-06 22:32:44 +0000
committerbacker@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-06 22:32:44 +0000
commit6802e3c649238b7b799b2140b3b6bc5db3a336fb (patch)
treefe856dc427af1a659b5434e1d26a30d0d042f540 /gpu
parente230a44f882894d7172881951a8783c40ca9f74f (diff)
downloadchromium_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.cc14
-rw-r--r--gpu/command_buffer/service/gpu_scheduler.h29
-rw-r--r--gpu/command_buffer_service.gypi1
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',