diff options
Diffstat (limited to 'ui')
-rw-r--r-- | ui/aura/bench/bench_main.cc | 5 | ||||
-rw-r--r-- | ui/compositor/compositor.cc | 13 | ||||
-rw-r--r-- | ui/compositor/compositor.gyp | 2 | ||||
-rw-r--r-- | ui/compositor/compositor.h | 13 | ||||
-rw-r--r-- | ui/compositor/compositor_observer.h | 5 | ||||
-rw-r--r-- | ui/compositor/compositor_vsync_manager.cc | 63 | ||||
-rw-r--r-- | ui/compositor/compositor_vsync_manager.h | 71 | ||||
-rw-r--r-- | ui/compositor/layer_unittest.cc | 5 | ||||
-rw-r--r-- | ui/compositor/test/draw_waiter_for_test.cc | 4 | ||||
-rw-r--r-- | ui/compositor/test/draw_waiter_for_test.h | 3 | ||||
-rw-r--r-- | ui/gl/sync_control_vsync_provider.cc | 27 |
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; } |