CompositorVsyncScheduler.h (5999B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_layers_CompositorVsyncScheduler_h 8 #define mozilla_layers_CompositorVsyncScheduler_h 9 10 #include <stdint.h> // for uint64_t 11 12 #include "mozilla/Monitor.h" // for Monitor 13 #include "mozilla/RefPtr.h" // for RefPtr 14 #include "mozilla/TimeStamp.h" // for TimeStamp 15 #include "mozilla/gfx/Point.h" // for IntSize 16 #include "mozilla/layers/SampleTime.h" 17 #include "mozilla/webrender/webrender_ffi.h" 18 #include "mozilla/VsyncDispatcher.h" 19 #include "mozilla/widget/CompositorWidget.h" 20 #include "nsISupportsImpl.h" 21 22 namespace mozilla { 23 24 class CancelableRunnable; 25 class Runnable; 26 27 namespace gfx { 28 class DrawTarget; 29 } // namespace gfx 30 31 namespace layers { 32 33 class CompositorVsyncSchedulerOwner; 34 35 /** 36 * Manages the vsync (de)registration and tracking on behalf of the 37 * compositor when it need to paint. 38 * Turns vsync notifications into scheduled composites. 39 **/ 40 class CompositorVsyncScheduler { 41 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorVsyncScheduler) 42 43 public: 44 CompositorVsyncScheduler(CompositorVsyncSchedulerOwner* aVsyncSchedulerOwner, 45 widget::CompositorWidget* aWidget); 46 47 /** 48 * Notify this class of a vsync. This will trigger a composite if one is 49 * needed. This must be called from the vsync dispatch thread. 50 */ 51 void NotifyVsync(const VsyncEvent& aVsync); 52 53 /** 54 * Do cleanup. This must be called on the compositor thread. 55 */ 56 void Destroy(); 57 58 /** 59 * Notify this class that a composition is needed. This will trigger a 60 * composition soon (likely at the next vsync). This must be called on the 61 * compositor thread. 62 */ 63 void ScheduleComposition(wr::RenderReasons aReasons); 64 65 /** 66 * Cancel any composite task that has been scheduled but hasn't run yet. 67 * 68 * Returns the render reasons of the canceled task if any. 69 */ 70 wr::RenderReasons CancelCurrentCompositeTask(); 71 72 /** 73 * Check if a composite is pending. This is generally true between a call 74 * to ScheduleComposition() and the time the composite happens. 75 */ 76 bool NeedsComposite(); 77 78 /** 79 * Force a composite to happen right away, without waiting for the next vsync. 80 * This must be called on the compositor thread. 81 */ 82 void ForceComposeToTarget(wr::RenderReasons aReasons, 83 gfx::DrawTarget* aTarget, 84 const gfx::IntRect* aRect); 85 86 /** 87 * If a composite is pending, force it to trigger right away. This must be 88 * called on the compositor thread. Returns true if there was a composite 89 * flushed. 90 */ 91 bool FlushPendingComposite(); 92 93 /** 94 * Return the vsync timestamp of the last or ongoing composite. Must be called 95 * on the compositor thread. 96 */ 97 const SampleTime& GetLastComposeTime() const; 98 99 /** 100 * Return the vsync timestamp and id of the most recently received 101 * vsync event. Must be called on the compositor thread. 102 */ 103 const TimeStamp& GetLastVsyncTime() const; 104 const TimeStamp& GetLastVsyncOutputTime() const; 105 const VsyncId& GetLastVsyncId() const; 106 107 /** 108 * Update LastCompose TimeStamp to current timestamp. 109 * The function is typically used when composition is handled outside the 110 * CompositorVsyncScheduler. 111 */ 112 void UpdateLastComposeTime(); 113 114 private: 115 virtual ~CompositorVsyncScheduler(); 116 117 // Post a task to run Composite() on the compositor thread, if there isn't 118 // such a task already queued. Can be called from any thread. 119 void PostCompositeTask(const VsyncEvent& aVsyncEvent, 120 wr::RenderReasons aReasons); 121 122 // Post a task to run DispatchVREvents() on the VR thread, if there isn't 123 // such a task already queued. Can be called from any thread. 124 void PostVRTask(TimeStamp aTimestamp); 125 126 /** 127 * Cancel any VR task that has been scheduled but hasn't run yet. 128 */ 129 void CancelCurrentVRTask(); 130 131 // This gets run at vsync time and "does" a composite (which really means 132 // update internal state and call the owner to do the composite). 133 void Composite(const VsyncEvent& aVsyncEvent, wr::RenderReasons aReasons); 134 135 void ObserveVsync(); 136 void UnobserveVsync(); 137 138 void DispatchVREvents(TimeStamp aVsyncTimestamp); 139 140 class Observer final : public VsyncObserver { 141 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorVsyncScheduler::Observer, 142 override) 143 144 public: 145 explicit Observer(CompositorVsyncScheduler* aOwner); 146 void NotifyVsync(const VsyncEvent& aVsync) override; 147 void Destroy(); 148 149 private: 150 virtual ~Observer(); 151 152 Mutex mMutex; 153 // Hold raw pointer to avoid mutual reference. 154 CompositorVsyncScheduler* mOwner; 155 }; 156 157 CompositorVsyncSchedulerOwner* mVsyncSchedulerOwner; 158 SampleTime mLastComposeTime; 159 TimeStamp mLastVsyncTime; 160 TimeStamp mLastVsyncOutputTime; 161 VsyncId mLastVsyncId; 162 163 bool mAsapScheduling; 164 bool mIsObservingVsync; 165 // Accessed on the compositor thread. 166 wr::RenderReasons mRendersDelayedByVsyncReasons; 167 TimeStamp mCompositeRequestedAt; 168 int32_t mVsyncNotificationsSkipped; 169 widget::CompositorWidget* mWidget; 170 RefPtr<CompositorVsyncScheduler::Observer> mVsyncObserver; 171 172 mozilla::Monitor mCurrentCompositeTaskMonitor; 173 RefPtr<CancelableRunnable> mCurrentCompositeTask 174 MOZ_GUARDED_BY(mCurrentCompositeTaskMonitor); 175 // Accessed on multiple threads, guarded by mCurrentCompositeTaskMonitor. 176 wr::RenderReasons mCurrentCompositeTaskReasons 177 MOZ_GUARDED_BY(mCurrentCompositeTaskMonitor); 178 179 mozilla::Monitor mCurrentVRTaskMonitor; 180 RefPtr<CancelableRunnable> mCurrentVRTask 181 MOZ_GUARDED_BY(mCurrentVRTaskMonitor); 182 }; 183 } // namespace layers 184 } // namespace mozilla 185 186 #endif // mozilla_layers_CompositorVsyncScheduler_h