Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4 : * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef mozilla_widget_VsyncDispatcher_h
7 : #define mozilla_widget_VsyncDispatcher_h
8 :
9 : #include "mozilla/Mutex.h"
10 : #include "mozilla/TimeStamp.h"
11 : #include "nsISupportsImpl.h"
12 : #include "nsTArray.h"
13 : #include "mozilla/RefPtr.h"
14 :
15 : namespace mozilla {
16 :
17 : class VsyncObserver
18 : {
19 273 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VsyncObserver)
20 :
21 : public:
22 : // The method called when a vsync occurs. Return true if some work was done.
23 : // In general, this vsync notification will occur on the hardware vsync
24 : // thread from VsyncSource. But it might also be called on PVsync ipc thread
25 : // if this notification is cross process. Thus all observer should check the
26 : // thread model before handling the real task.
27 : virtual bool NotifyVsync(TimeStamp aVsyncTimestamp) = 0;
28 :
29 : protected:
30 4 : VsyncObserver() {}
31 0 : virtual ~VsyncObserver() {}
32 : }; // VsyncObserver
33 :
34 : // Used to dispatch vsync events in the parent process to compositors.
35 : //
36 : // When the compositor is in-process, CompositorWidgets own a
37 : // CompositorVsyncDispatcher, and directly attach the compositor's observer
38 : // to it.
39 : //
40 : // When the compositor is out-of-process, the CompositorWidgetDelegate owns
41 : // the vsync dispatcher instead. The widget receives vsync observer/unobserve
42 : // commands via IPDL, and uses this to attach a CompositorWidgetVsyncObserver.
43 : // This observer forwards vsync notifications (on the vsync thread) to a
44 : // dedicated vsync I/O thread, which then forwards the notification to the
45 : // compositor thread in the compositor process.
46 : class CompositorVsyncDispatcher final
47 : {
48 84 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorVsyncDispatcher)
49 :
50 : public:
51 : CompositorVsyncDispatcher();
52 :
53 : // Called on the vsync thread when a hardware vsync occurs
54 : void NotifyVsync(TimeStamp aVsyncTimestamp);
55 :
56 : // Compositor vsync observers must be added/removed on the compositor thread
57 : void SetCompositorVsyncObserver(VsyncObserver* aVsyncObserver);
58 : void Shutdown();
59 :
60 : private:
61 : virtual ~CompositorVsyncDispatcher();
62 : void ObserveVsync(bool aEnable);
63 :
64 : Mutex mCompositorObserverLock;
65 : RefPtr<VsyncObserver> mCompositorVsyncObserver;
66 : bool mDidShutdown;
67 : };
68 :
69 : // Dispatch vsync event to ipc actor parent and chrome RefreshTimer.
70 : class RefreshTimerVsyncDispatcher final
71 : {
72 10 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RefreshTimerVsyncDispatcher)
73 :
74 : public:
75 : RefreshTimerVsyncDispatcher();
76 :
77 : // Please check CompositorVsyncDispatcher::NotifyVsync().
78 : void NotifyVsync(TimeStamp aVsyncTimestamp);
79 :
80 : // Set chrome process's RefreshTimer to this dispatcher.
81 : // This function can be called from any thread.
82 : void SetParentRefreshTimer(VsyncObserver* aVsyncObserver);
83 :
84 : // Add or remove the content process' RefreshTimer to this dispatcher. This
85 : // will be a no-op for AddChildRefreshTimer() if the observer is already
86 : // registered.
87 : // These functions can be called from any thread.
88 : void AddChildRefreshTimer(VsyncObserver* aVsyncObserver);
89 : void RemoveChildRefreshTimer(VsyncObserver* aVsyncObserver);
90 :
91 : private:
92 : virtual ~RefreshTimerVsyncDispatcher();
93 : void UpdateVsyncStatus();
94 : bool NeedsVsync();
95 :
96 : Mutex mRefreshTimersLock;
97 : RefPtr<VsyncObserver> mParentRefreshTimer;
98 : nsTArray<RefPtr<VsyncObserver>> mChildRefreshTimers;
99 : };
100 :
101 : } // namespace mozilla
102 :
103 : #endif // mozilla_widget_VsyncDispatcher_h
|