summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
Diffstat (limited to 'ui')
-rw-r--r--ui/aura/bench/bench_main.cc5
-rw-r--r--ui/compositor/compositor.cc13
-rw-r--r--ui/compositor/compositor.gyp2
-rw-r--r--ui/compositor/compositor.h13
-rw-r--r--ui/compositor/compositor_observer.h5
-rw-r--r--ui/compositor/compositor_vsync_manager.cc63
-rw-r--r--ui/compositor/compositor_vsync_manager.h71
-rw-r--r--ui/compositor/layer_unittest.cc5
-rw-r--r--ui/compositor/test/draw_waiter_for_test.cc4
-rw-r--r--ui/compositor/test/draw_waiter_for_test.h3
-rw-r--r--ui/gl/sync_control_vsync_provider.cc27
11 files changed, 167 insertions, 44 deletions
diff --git a/ui/aura/bench/bench_main.cc b/ui/aura/bench/bench_main.cc
index 94a8f6f..4f59dd36 100644
--- a/ui/aura/bench/bench_main.cc
+++ b/ui/aura/bench/bench_main.cc
@@ -122,11 +122,6 @@ class BenchCompositorObserver : public ui::CompositorObserver {
virtual void OnCompositingLockStateChanged(
Compositor* compositor) OVERRIDE {}
- virtual void OnUpdateVSyncParameters(ui::Compositor* compositor,
- base::TimeTicks timebase,
- base::TimeDelta interval) OVERRIDE {
- }
-
virtual void Draw() {}
int frames() const { return frames_; }
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc
index e662533..7061599 100644
--- a/ui/compositor/compositor.cc
+++ b/ui/compositor/compositor.cc
@@ -27,6 +27,7 @@
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/compositor/compositor_observer.h"
#include "ui/compositor/compositor_switches.h"
+#include "ui/compositor/compositor_vsync_manager.h"
#include "ui/compositor/dip_util.h"
#include "ui/compositor/layer.h"
#include "ui/gfx/frame_time.h"
@@ -183,6 +184,7 @@ namespace ui {
Compositor::Compositor(gfx::AcceleratedWidget widget)
: root_layer_(NULL),
widget_(widget),
+ vsync_manager_(new CompositorVSyncManager()),
posted_swaps_(new PostedSwapQueue()),
device_scale_factor_(0.0f),
last_started_frame_(0),
@@ -420,6 +422,10 @@ void Compositor::SetBackgroundColor(SkColor color) {
ScheduleDraw();
}
+scoped_refptr<CompositorVSyncManager> Compositor::vsync_manager() const {
+ return vsync_manager_;
+}
+
void Compositor::AddObserver(CompositorObserver* observer) {
observer_list_.AddObserver(observer);
}
@@ -432,13 +438,6 @@ bool Compositor::HasObserver(CompositorObserver* observer) {
return observer_list_.HasObserver(observer);
}
-void Compositor::OnUpdateVSyncParameters(base::TimeTicks timebase,
- base::TimeDelta interval) {
- FOR_EACH_OBSERVER(CompositorObserver,
- observer_list_,
- OnUpdateVSyncParameters(this, timebase, interval));
-}
-
void Compositor::Layout() {
// We're sending damage that will be addressed during this composite
// cycle, so we don't need to schedule another composite to address it.
diff --git a/ui/compositor/compositor.gyp b/ui/compositor/compositor.gyp
index 33f01ee..e1bd763 100644
--- a/ui/compositor/compositor.gyp
+++ b/ui/compositor/compositor.gyp
@@ -27,6 +27,8 @@
'compositor.h',
'compositor_export.h',
'compositor_observer.h',
+ 'compositor_vsync_manager.cc',
+ 'compositor_vsync_manager.h',
'compositor_switches.cc',
'compositor_switches.h',
'debug_utils.cc',
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h
index 81363ba..84ed365 100644
--- a/ui/compositor/compositor.h
+++ b/ui/compositor/compositor.h
@@ -43,6 +43,7 @@ class Size;
namespace ui {
class Compositor;
+class CompositorVSyncManager;
class Layer;
class PostedSwapQueue;
class Reflector;
@@ -163,8 +164,7 @@ class COMPOSITOR_EXPORT CompositorLock
// view hierarchy.
class COMPOSITOR_EXPORT Compositor
: NON_EXPORTED_BASE(public cc::LayerTreeHostClient),
- NON_EXPORTED_BASE(public cc::LayerTreeHostSingleThreadClient),
- public base::SupportsWeakPtr<Compositor> {
+ NON_EXPORTED_BASE(public cc::LayerTreeHostSingleThreadClient) {
public:
explicit Compositor(gfx::AcceleratedWidget widget);
virtual ~Compositor();
@@ -222,6 +222,9 @@ class COMPOSITOR_EXPORT Compositor
// Returns the widget for this compositor.
gfx::AcceleratedWidget widget() const { return widget_; }
+ // Returns the vsync manager for this compositor.
+ scoped_refptr<CompositorVSyncManager> vsync_manager() const;
+
// Compositor does not own observers. It is the responsibility of the
// observer to remove itself when it is done observing.
void AddObserver(CompositorObserver* observer);
@@ -244,9 +247,6 @@ class COMPOSITOR_EXPORT Compositor
// Signals swap has aborted (e.g. lost context).
void OnSwapBuffersAborted();
- void OnUpdateVSyncParameters(base::TimeTicks timebase,
- base::TimeDelta interval);
-
// LayerTreeHostClient implementation.
virtual void WillBeginMainFrame(int frame_id) OVERRIDE {}
virtual void DidBeginMainFrame() OVERRIDE {}
@@ -302,6 +302,9 @@ class COMPOSITOR_EXPORT Compositor
scoped_refptr<cc::Layer> root_web_layer_;
scoped_ptr<cc::LayerTreeHost> host_;
+ // The manager of vsync parameters for this compositor.
+ scoped_refptr<CompositorVSyncManager> vsync_manager_;
+
// Used to verify that we have at most one draw swap in flight.
scoped_ptr<PostedSwapQueue> posted_swaps_;
diff --git a/ui/compositor/compositor_observer.h b/ui/compositor/compositor_observer.h
index aced251..badc5b4 100644
--- a/ui/compositor/compositor_observer.h
+++ b/ui/compositor/compositor_observer.h
@@ -38,11 +38,6 @@ class COMPOSITOR_EXPORT CompositorObserver {
// Called when the compositor lock state changes.
virtual void OnCompositingLockStateChanged(Compositor* compositor) = 0;
- // Called when the compositor has received updated VSync parameters.
- virtual void OnUpdateVSyncParameters(Compositor* compositor,
- base::TimeTicks timebase,
- base::TimeDelta interval) = 0;
-
protected:
virtual ~CompositorObserver() {}
};
diff --git a/ui/compositor/compositor_vsync_manager.cc b/ui/compositor/compositor_vsync_manager.cc
new file mode 100644
index 0000000..1a10d4a
--- /dev/null
+++ b/ui/compositor/compositor_vsync_manager.cc
@@ -0,0 +1,63 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/compositor/compositor_vsync_manager.h"
+
+namespace ui {
+
+CompositorVSyncManager::CompositorVSyncManager()
+ : observer_list_(new ObserverListThreadSafe<Observer>()),
+ authoritative_vsync_interval_(base::TimeDelta::FromSeconds(0)) {}
+
+CompositorVSyncManager::~CompositorVSyncManager() {}
+
+void CompositorVSyncManager::SetAuthoritativeVSyncInterval(
+ base::TimeDelta interval) {
+ base::TimeTicks timebase;
+ {
+ base::AutoLock lock(vsync_parameters_lock_);
+ timebase = last_timebase_;
+ authoritative_vsync_interval_ = interval;
+ last_interval_ = interval;
+ }
+ NotifyObservers(timebase, interval);
+}
+
+void CompositorVSyncManager::UpdateVSyncParameters(base::TimeTicks timebase,
+ base::TimeDelta interval) {
+ {
+ base::AutoLock lock(vsync_parameters_lock_);
+ if (authoritative_vsync_interval_ != base::TimeDelta::FromSeconds(0))
+ interval = authoritative_vsync_interval_;
+ last_timebase_ = timebase;
+ last_interval_ = interval;
+ }
+ NotifyObservers(timebase, interval);
+}
+
+void CompositorVSyncManager::AddObserver(Observer* observer) {
+ base::TimeTicks timebase;
+ base::TimeDelta interval;
+ {
+ base::AutoLock lock(vsync_parameters_lock_);
+ timebase = last_timebase_;
+ interval = last_interval_;
+ }
+ observer_list_->AddObserver(observer);
+ observer->OnUpdateVSyncParameters(timebase, interval);
+}
+
+void CompositorVSyncManager::RemoveObserver(Observer* observer) {
+ observer_list_->RemoveObserver(observer);
+}
+
+void CompositorVSyncManager::NotifyObservers(base::TimeTicks timebase,
+ base::TimeDelta interval) {
+ observer_list_->Notify(
+ &CompositorVSyncManager::Observer::OnUpdateVSyncParameters,
+ timebase,
+ interval);
+}
+
+} // namespace ui
diff --git a/ui/compositor/compositor_vsync_manager.h b/ui/compositor/compositor_vsync_manager.h
new file mode 100644
index 0000000..abfbad6
--- /dev/null
+++ b/ui/compositor/compositor_vsync_manager.h
@@ -0,0 +1,71 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_COMPOSITOR_COMPOSITOR_VSYNC_MANAGER_H_
+#define UI_COMPOSITOR_COMPOSITOR_VSYNC_MANAGER_H_
+
+#include "base/memory/ref_counted.h"
+#include "base/observer_list_threadsafe.h"
+#include "base/synchronization/lock.h"
+#include "base/time/time.h"
+#include "ui/compositor/compositor_export.h"
+
+namespace ui {
+
+// This class manages vsync parameters for a compositor. It merges updates of
+// the parameters from different sources and sends the merged updates to
+// observers which register to it. This class is explicitly synchronized and is
+// safe to use and update from any thread. Observers of the manager will be
+// notified on the thread they have registered from, and should be removed from
+// the same thread.
+class COMPOSITOR_EXPORT CompositorVSyncManager
+ : public base::RefCountedThreadSafe<CompositorVSyncManager> {
+ public:
+ class Observer {
+ public:
+ virtual void OnUpdateVSyncParameters(base::TimeTicks timebase,
+ base::TimeDelta interval) = 0;
+ };
+
+ CompositorVSyncManager();
+
+ // The "authoritative" vsync interval, if provided, will override |interval|
+ // as reported by UpdateVSyncParameters() whenever it is called. This is
+ // typically the value reported by a more reliable source, e.g. the platform
+ // display configuration. In the particular case of ChromeOS -- this is the
+ // value queried through XRandR, which is more reliable than the value
+ // queried through the 3D context.
+ void SetAuthoritativeVSyncInterval(base::TimeDelta interval);
+
+ // The vsync parameters consist of |timebase|, which is the platform timestamp
+ // of the last vsync, and |interval|, which is the interval between vsyncs.
+ // |interval| may be overriden by SetAuthoritativeVSyncInterval() above.
+ void UpdateVSyncParameters(base::TimeTicks timebase,
+ base::TimeDelta interval);
+
+ void AddObserver(Observer* observer);
+ void RemoveObserver(Observer* observer);
+
+ private:
+ friend class base::RefCountedThreadSafe<CompositorVSyncManager>;
+
+ ~CompositorVSyncManager();
+
+ void NotifyObservers(base::TimeTicks timebase, base::TimeDelta interval);
+
+ // List of observers.
+ scoped_refptr<ObserverListThreadSafe<Observer> > observer_list_;
+
+ // Protects the cached vsync parameters below.
+ base::Lock vsync_parameters_lock_;
+ base::TimeTicks last_timebase_;
+ base::TimeDelta last_interval_;
+ base::TimeDelta authoritative_vsync_interval_;
+
+ DISALLOW_COPY_AND_ASSIGN(CompositorVSyncManager);
+};
+
+} // namespace ui
+
+#endif // UI_COMPOSITOR_COMPOSITOR_VSYNC_MANAGER_H_
diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc
index 736f92a..a384f32 100644
--- a/ui/compositor/layer_unittest.cc
+++ b/ui/compositor/layer_unittest.cc
@@ -354,11 +354,6 @@ class TestCompositorObserver : public CompositorObserver {
virtual void OnCompositingLockStateChanged(Compositor* compositor) OVERRIDE {
}
- virtual void OnUpdateVSyncParameters(Compositor* compositor,
- base::TimeTicks timebase,
- base::TimeDelta interval) OVERRIDE {
- }
-
bool committed_;
bool started_;
bool ended_;
diff --git a/ui/compositor/test/draw_waiter_for_test.cc b/ui/compositor/test/draw_waiter_for_test.cc
index 8429675..c471a6f 100644
--- a/ui/compositor/test/draw_waiter_for_test.cc
+++ b/ui/compositor/test/draw_waiter_for_test.cc
@@ -50,8 +50,4 @@ void DrawWaiterForTest::OnCompositingAborted(Compositor* compositor) {}
void DrawWaiterForTest::OnCompositingLockStateChanged(Compositor* compositor) {}
-void DrawWaiterForTest::OnUpdateVSyncParameters(Compositor* compositor,
- base::TimeTicks timebase,
- base::TimeDelta interval) {}
-
} // namespace ui
diff --git a/ui/compositor/test/draw_waiter_for_test.h b/ui/compositor/test/draw_waiter_for_test.h
index d191ec4..051c58f 100644
--- a/ui/compositor/test/draw_waiter_for_test.h
+++ b/ui/compositor/test/draw_waiter_for_test.h
@@ -38,9 +38,6 @@ class DrawWaiterForTest : public CompositorObserver {
virtual void OnCompositingEnded(Compositor* compositor) OVERRIDE;
virtual void OnCompositingAborted(Compositor* compositor) OVERRIDE;
virtual void OnCompositingLockStateChanged(Compositor* compositor) OVERRIDE;
- virtual void OnUpdateVSyncParameters(Compositor* compositor,
- base::TimeTicks timebase,
- base::TimeDelta interval) OVERRIDE;
scoped_ptr<base::RunLoop> wait_run_loop_;
diff --git a/ui/gl/sync_control_vsync_provider.cc b/ui/gl/sync_control_vsync_provider.cc
index 16b1e8a..66d3734 100644
--- a/ui/gl/sync_control_vsync_provider.cc
+++ b/ui/gl/sync_control_vsync_provider.cc
@@ -125,16 +125,23 @@ void SyncControlVSyncProvider::GetVSyncParameters(
if (relative_change < kRelativeIntervalDifferenceThreshold) {
if (new_interval.InMicroseconds() < kMinVsyncIntervalUs ||
new_interval.InMicroseconds() > kMaxVsyncIntervalUs) {
- LOG(FATAL) << "Calculated bogus refresh interval of "
- << new_interval.InMicroseconds() << " us. "
- << "Last time base of " << last_timebase_.ToInternalValue()
- << " us. "
- << "Current time base of " << timebase.ToInternalValue()
- << " us. "
- << "Last media stream count of "
- << last_media_stream_counter_ << ". "
- << "Current media stream count of " << media_stream_counter
- << ".";
+#if defined(USE_ASH)
+ // On ash platforms (ChromeOS essentially), the real refresh interval is
+ // queried from XRandR, regardless of the value calculated here, and
+ // this value is overriden by ui::CompositorVSyncManager. The log
+ // should not be fatal in this case. Reconsider all this when XRandR
+ // support is added to non-ash platforms.
+ // http://crbug.com/340851
+ LOG(ERROR)
+#else
+ LOG(FATAL)
+#endif // USE_ASH
+ << "Calculated bogus refresh interval="
+ << new_interval.InMicroseconds()
+ << " us., last_timebase_=" << last_timebase_.ToInternalValue()
+ << " us., timebase=" << timebase.ToInternalValue()
+ << " us., last_media_stream_counter_=" << last_media_stream_counter_
+ << ", media_stream_counter=" << media_stream_counter;
} else {
last_good_interval_ = new_interval;
}