VsyncSource.h (3942B)
1 /* -*- Mode: C++; tab-width: 20; 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 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef GFX_VSYNCSOURCE_H 7 #define GFX_VSYNCSOURCE_H 8 9 #include "nsTArray.h" 10 #include "mozilla/DataMutex.h" 11 #include "mozilla/RefPtr.h" 12 #include "mozilla/Maybe.h" 13 #include "mozilla/Mutex.h" 14 #include "mozilla/TimeStamp.h" 15 #include "nsISupportsImpl.h" 16 #include "mozilla/layers/LayersTypes.h" 17 18 namespace mozilla { 19 class VsyncDispatcher; 20 class VsyncObserver; 21 struct VsyncEvent; 22 23 class VsyncIdType {}; 24 typedef layers::BaseTransactionId<VsyncIdType> VsyncId; 25 26 namespace gfx { 27 28 // Controls how and when to enable/disable vsync. Lives as long as the 29 // gfxPlatform does on the parent process 30 class VsyncSource { 31 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VsyncSource) 32 33 typedef mozilla::VsyncDispatcher VsyncDispatcher; 34 35 public: 36 VsyncSource(); 37 38 // Notified when this display's vsync callback occurs, on the vsync thread 39 // Different platforms give different aVsyncTimestamp values. 40 // macOS: TimeStamp::Now() or the output time of the previous vsync 41 // callback, whichever is older. 42 // Windows: It's messy, see gfxWindowsPlatform. 43 // Android: TODO 44 // 45 // @param aVsyncTimestamp The time of the Vsync that just occured. Needs to 46 // be at or before the time of the NotifyVsync call. 47 // @param aOutputTimestamp The estimated timestamp at which drawing will 48 // appear on the screen, if the drawing happens within a certain 49 // (unknown) budget. Useful for Audio/Video sync. On platforms where 50 // this timestamp is provided by the system (macOS), it is a much more 51 // stable and consistent timing source than the time at which the vsync 52 // callback is called. 53 virtual void NotifyVsync(const TimeStamp& aVsyncTimestamp, 54 const TimeStamp& aOutputTimestamp); 55 56 // Can be called on any thread. 57 // Adding the same dispatcher multiple times will increment a count. 58 // This means that the sequence "Add, Add, Remove" has the same behavior as 59 // "Add, Remove, Add". 60 void AddVsyncDispatcher(VsyncDispatcher* aDispatcher); 61 void RemoveVsyncDispatcher(VsyncDispatcher* aDispatcher); 62 63 virtual TimeDuration GetVsyncRate(); 64 65 // These should all only be called on the main thread 66 virtual void EnableVsync() = 0; 67 virtual void DisableVsync() = 0; 68 virtual bool IsVsyncEnabled() = 0; 69 virtual void Shutdown() = 0; 70 71 // Returns the rate of the fastest enabled VsyncSource or Nothing(). 72 static Maybe<TimeDuration> GetFastestVsyncRate(); 73 74 protected: 75 virtual ~VsyncSource(); 76 77 private: 78 // Can be called on any thread 79 void UpdateVsyncStatus(); 80 81 struct DispatcherRefWithCount { 82 // The dispatcher. 83 RefPtr<VsyncDispatcher> mDispatcher; 84 // The number of add calls minus the number of remove calls for this 85 // dispatcher. Should always be > 0 as long as this dispatcher is in 86 // mDispatchers. 87 size_t mCount = 0; 88 }; 89 90 struct State { 91 // The set of VsyncDispatchers which are registered with this source. 92 // At the moment, the length of this array is always zero or one. 93 // The ability to register multiple dispatchers is not used yet; it is 94 // intended for when we have one dispatcher per widget. 95 nsTArray<DispatcherRefWithCount> mDispatchers; 96 97 // The vsync ID which we used for the last vsync event. 98 VsyncId mVsyncId; 99 }; 100 101 DataMutex<State> mState; 102 }; 103 104 } // namespace gfx 105 106 struct VsyncEvent { 107 VsyncId mId; 108 TimeStamp mTime; 109 TimeStamp mOutputTime; // estimate 110 111 VsyncEvent(const VsyncId& aId, const TimeStamp& aVsyncTime, 112 const TimeStamp& aOutputTime) 113 : mId(aId), mTime(aVsyncTime), mOutputTime(aOutputTime) {} 114 VsyncEvent() = default; 115 }; 116 117 } // namespace mozilla 118 119 #endif /* GFX_VSYNCSOURCE_H */