scheduler.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. // Copyright 2011 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef CC_SCHEDULER_SCHEDULER_H_
  5. #define CC_SCHEDULER_SCHEDULER_H_
  6. #include <memory>
  7. #include <string>
  8. #include <vector>
  9. #include "base/cancelable_callback.h"
  10. #include "base/memory/raw_ptr.h"
  11. #include "base/time/time.h"
  12. #include "base/timer/timer.h"
  13. #include "cc/cc_export.h"
  14. #include "cc/metrics/event_metrics.h"
  15. #include "cc/scheduler/begin_frame_tracker.h"
  16. #include "cc/scheduler/draw_result.h"
  17. #include "cc/scheduler/scheduler_settings.h"
  18. #include "cc/scheduler/scheduler_state_machine.h"
  19. #include "cc/tiles/tile_priority.h"
  20. #include "components/power_scheduler/power_mode_voter.h"
  21. #include "components/viz/common/frame_sinks/begin_frame_args.h"
  22. #include "components/viz/common/frame_sinks/begin_frame_source.h"
  23. #include "components/viz/common/frame_sinks/delay_based_time_source.h"
  24. namespace perfetto {
  25. namespace protos {
  26. namespace pbzero {
  27. class ChromeCompositorSchedulerState;
  28. }
  29. } // namespace protos
  30. } // namespace perfetto
  31. namespace base {
  32. class SingleThreadTaskRunner;
  33. }
  34. namespace viz {
  35. struct FrameTimingDetails;
  36. }
  37. namespace cc {
  38. struct BeginMainFrameMetrics;
  39. class CompositorTimingHistory;
  40. class CompositorFrameReportingController;
  41. enum class FrameSkippedReason {
  42. kRecoverLatency,
  43. kNoDamage,
  44. kWaitingOnMain,
  45. kDrawThrottled,
  46. };
  47. class SchedulerClient {
  48. public:
  49. // Returns whether the frame has damage.
  50. virtual bool WillBeginImplFrame(const viz::BeginFrameArgs& args) = 0;
  51. virtual void ScheduledActionSendBeginMainFrame(
  52. const viz::BeginFrameArgs& args) = 0;
  53. virtual DrawResult ScheduledActionDrawIfPossible() = 0;
  54. virtual DrawResult ScheduledActionDrawForced() = 0;
  55. // The Commit step occurs when the client received the BeginFrame from the
  56. // source and we perform at most one commit per BeginFrame. In this step the
  57. // main thread collects all updates then blocks and gives control to the
  58. // compositor thread, which allows Compositor thread to update its layer tree
  59. // to match the state of the layer tree on the main thread.
  60. virtual void ScheduledActionCommit() = 0;
  61. virtual void ScheduledActionPostCommit() = 0;
  62. virtual void ScheduledActionActivateSyncTree() = 0;
  63. virtual void ScheduledActionBeginLayerTreeFrameSinkCreation() = 0;
  64. virtual void ScheduledActionPrepareTiles() = 0;
  65. virtual void ScheduledActionInvalidateLayerTreeFrameSink(
  66. bool needs_redraw) = 0;
  67. virtual void ScheduledActionPerformImplSideInvalidation() = 0;
  68. // Called when the scheduler is done processing a frame. Note that the
  69. // BeginFrameArgs instance passed may not necessarily be the same instance
  70. // that was passed to WillBeginImplFrame(). Rather, |last_activated_args|
  71. // represents the latest BeginFrameArgs instance that caused an activation to
  72. // happen.
  73. virtual void DidFinishImplFrame(
  74. const viz::BeginFrameArgs& last_activated_args) = 0;
  75. virtual void DidNotProduceFrame(const viz::BeginFrameAck& ack,
  76. FrameSkippedReason reason) = 0;
  77. virtual void WillNotReceiveBeginFrame() = 0;
  78. virtual void SendBeginMainFrameNotExpectedSoon() = 0;
  79. virtual void ScheduledActionBeginMainFrameNotExpectedUntil(
  80. base::TimeTicks time) = 0;
  81. virtual void FrameIntervalUpdated(base::TimeDelta interval) = 0;
  82. // Functions used for reporting animation targeting UMA, crbug.com/758439.
  83. virtual bool HasInvalidationAnimation() const = 0;
  84. protected:
  85. virtual ~SchedulerClient() {}
  86. };
  87. class CC_EXPORT Scheduler : public viz::BeginFrameObserverBase {
  88. public:
  89. Scheduler(
  90. SchedulerClient* client,
  91. const SchedulerSettings& scheduler_settings,
  92. int layer_tree_host_id,
  93. base::SingleThreadTaskRunner* task_runner,
  94. std::unique_ptr<CompositorTimingHistory> compositor_timing_history,
  95. CompositorFrameReportingController* compositor_frame_reporting_controller,
  96. power_scheduler::PowerModeArbiter* power_mode_arbiter);
  97. Scheduler(const Scheduler&) = delete;
  98. ~Scheduler() override;
  99. Scheduler& operator=(const Scheduler&) = delete;
  100. // This is needed so that the scheduler doesn't perform spurious actions while
  101. // the compositor is being torn down.
  102. void Stop();
  103. // BeginFrameObserverBase
  104. void OnBeginFrameSourcePausedChanged(bool paused) override;
  105. bool OnBeginFrameDerivedImpl(const viz::BeginFrameArgs& args) override;
  106. void OnDrawForLayerTreeFrameSink(bool resourceless_software_draw,
  107. bool skip_draw);
  108. const SchedulerSettings& settings() const { return settings_; }
  109. void SetVisible(bool visible);
  110. bool visible() { return state_machine_.visible(); }
  111. void SetCanDraw(bool can_draw);
  112. // We have 2 copies of the layer trees on the compositor thread: pending_tree
  113. // and active_tree. When we finish asynchronously rastering all tiles on
  114. // pending_tree, call this method to notify that this pending tree is ready to
  115. // be activated, that is to be copied to the active tree.
  116. void NotifyReadyToActivate();
  117. bool IsReadyToActivate();
  118. void NotifyReadyToDraw();
  119. void SetBeginFrameSource(viz::BeginFrameSource* source);
  120. using AnimationWorkletState = SchedulerStateMachine::AnimationWorkletState;
  121. using PaintWorkletState = SchedulerStateMachine::PaintWorkletState;
  122. using TreeType = SchedulerStateMachine::TreeType;
  123. // Sets whether asynchronous animation worklet mutations are running.
  124. // Mutations on the pending tree should block activiation. Mutations on the
  125. // active tree should delay draw to allow time for the mutations to complete.
  126. void NotifyAnimationWorkletStateChange(AnimationWorkletState state,
  127. TreeType tree);
  128. // Sets whether asynchronous paint worklets are running. Paint worklets
  129. // running should block activation of the pending tree, as it isn't fully
  130. // painted until they are done.
  131. void NotifyPaintWorkletStateChange(PaintWorkletState state);
  132. // Set |needs_begin_main_frame_| to true, which will cause the BeginFrame
  133. // source to be told to send BeginFrames to this client so that this client
  134. // can send a CompositorFrame to the display compositor with appropriate
  135. // timing.
  136. void SetNeedsBeginMainFrame();
  137. // Requests a single impl frame (after the current frame if there is one
  138. // active).
  139. void SetNeedsOneBeginImplFrame();
  140. void SetNeedsRedraw();
  141. void SetNeedsPrepareTiles();
  142. // Requests a pending tree should be created to invalidate content on the impl
  143. // thread, after the current tree is activated, if any. If the request
  144. // necessitates creating a pending tree only for impl-side invalidations, the
  145. // |client_| is informed to perform this action using
  146. // ScheduledActionRunImplSideInvalidation.
  147. // If ScheduledActionCommit is performed, the impl-side invalidations should
  148. // be merged with the main frame and the request is assumed to be completed.
  149. // If |needs_first_draw_on_activation| is set to true, an impl-side pending
  150. // tree creates for this invalidation must be drawn at least once before a
  151. // new tree can be activated.
  152. void SetNeedsImplSideInvalidation(bool needs_first_draw_on_activation);
  153. bool pending_tree_is_ready_for_activation() const {
  154. return state_machine_.pending_tree_is_ready_for_activation();
  155. }
  156. // Drawing should result in submitting a CompositorFrame to the
  157. // LayerTreeFrameSink and then calling this.
  158. void DidSubmitCompositorFrame(uint32_t frame_token,
  159. base::TimeTicks submit_time,
  160. EventMetricsSet events_metrics,
  161. bool has_missing_content);
  162. // The LayerTreeFrameSink acks when it is ready for a new frame which
  163. // should result in this getting called to unblock the next draw.
  164. void DidReceiveCompositorFrameAck();
  165. void SetTreePrioritiesAndScrollState(TreePriority tree_priority,
  166. ScrollHandlerState scroll_handler_state);
  167. // Commit step happens after the main thread has completed updating for a
  168. // BeginMainFrame request from the compositor, and blocks the main thread
  169. // to copy the layer tree to the compositor thread. Call this method when the
  170. // main thread updates are completed to signal it is ready for the commmit.
  171. void NotifyReadyToCommit(std::unique_ptr<BeginMainFrameMetrics> details);
  172. void BeginMainFrameAborted(CommitEarlyOutReason reason);
  173. // In the PrepareTiles step, compositor thread divides the layers into tiles
  174. // to reduce cost of raster large layers. Then, each tile is rastered by a
  175. // dedicated thread.
  176. // |WillPrepareTiles| is called before PrepareTiles step to have the scheduler
  177. // track when PrepareTiles starts.
  178. void WillPrepareTiles();
  179. // |DidPrepareTiles| is called after PrepareTiles step to have the scheduler
  180. // track how long PrepareTiles takes.
  181. void DidPrepareTiles();
  182. // |DidPresentCompositorFrame| is called when the renderer receives
  183. // presentation feedback.
  184. void DidPresentCompositorFrame(uint32_t frame_token,
  185. const viz::FrameTimingDetails& details);
  186. void DidLoseLayerTreeFrameSink();
  187. void DidCreateAndInitializeLayerTreeFrameSink();
  188. // Tests do not want to shut down until all possible BeginMainFrames have
  189. // occured to prevent flakiness.
  190. bool MainFrameForTestingWillHappen() const {
  191. return state_machine_.CommitPending() ||
  192. state_machine_.CouldSendBeginMainFrame();
  193. }
  194. bool CommitPending() const { return state_machine_.CommitPending(); }
  195. bool RedrawPending() const { return state_machine_.RedrawPending(); }
  196. bool PrepareTilesPending() const {
  197. return state_machine_.PrepareTilesPending();
  198. }
  199. bool ImplLatencyTakesPriority() const {
  200. return state_machine_.ImplLatencyTakesPriority();
  201. }
  202. // Pass in a main_thread_start_time of base::TimeTicks() if it is not
  203. // known or not trustworthy (e.g. blink is running on a remote channel)
  204. // to signal that the start time isn't known and should not be used for
  205. // scheduling or statistics purposes.
  206. void NotifyBeginMainFrameStarted(base::TimeTicks main_thread_start_time);
  207. base::TimeTicks LastBeginImplFrameTime();
  208. // Deferring begin main frame prevents all document lkifecycle updates and
  209. // updates of new layer tree state.
  210. void SetDeferBeginMainFrame(bool defer_begin_main_frame);
  211. // Controls whether the BeginMainFrameNotExpected messages should be sent to
  212. // the main thread by the cc scheduler.
  213. void SetMainThreadWantsBeginMainFrameNotExpected(bool new_state);
  214. void AsProtozeroInto(
  215. perfetto::EventContext& ctx,
  216. perfetto::protos::pbzero::ChromeCompositorSchedulerState* state) const;
  217. void SetVideoNeedsBeginFrames(bool video_needs_begin_frames);
  218. const viz::BeginFrameSource* begin_frame_source() const {
  219. return begin_frame_source_;
  220. }
  221. viz::BeginFrameAck CurrentBeginFrameAckForActiveTree() const;
  222. const viz::BeginFrameArgs& last_dispatched_begin_main_frame_args() const {
  223. return last_dispatched_begin_main_frame_args_;
  224. }
  225. const viz::BeginFrameArgs& last_commit_origin_frame_args() const {
  226. return last_commit_origin_frame_args_;
  227. }
  228. const viz::BeginFrameArgs& last_activate_origin_frame_args() const {
  229. return last_activate_origin_frame_args_;
  230. }
  231. void ClearHistory();
  232. size_t CommitDurationSampleCountForTesting() const;
  233. protected:
  234. // Virtual for testing.
  235. virtual base::TimeTicks Now() const;
  236. const SchedulerSettings settings_;
  237. const raw_ptr<SchedulerClient> client_;
  238. const int layer_tree_host_id_;
  239. raw_ptr<base::SingleThreadTaskRunner> task_runner_;
  240. raw_ptr<viz::BeginFrameSource> begin_frame_source_ = nullptr;
  241. bool observing_begin_frame_source_ = false;
  242. bool skipped_last_frame_missed_exceeded_deadline_ = false;
  243. std::unique_ptr<CompositorTimingHistory> compositor_timing_history_;
  244. // Owned by LayerTreeHostImpl and is destroyed when LayerTreeHostImpl is
  245. // destroyed.
  246. raw_ptr<CompositorFrameReportingController, DanglingUntriaged>
  247. compositor_frame_reporting_controller_;
  248. // What the latest deadline was, and when it was scheduled.
  249. base::TimeTicks deadline_;
  250. base::TimeTicks deadline_scheduled_at_;
  251. SchedulerStateMachine::BeginImplFrameDeadlineMode deadline_mode_ =
  252. SchedulerStateMachine::BeginImplFrameDeadlineMode::NONE;
  253. BeginFrameTracker begin_impl_frame_tracker_;
  254. viz::BeginFrameAck last_begin_frame_ack_;
  255. viz::BeginFrameArgs begin_main_frame_args_;
  256. // For keeping track of the original BeginFrameArgs from the Main Thread
  257. // that led to the corresponding action, i.e.:
  258. // BeginMainFrame => Commit => Activate => Submit
  259. // So, |last_commit_origin_frame_args_| is the BeginFrameArgs that was
  260. // dispatched to the main-thread, and lead to the commit to happen.
  261. // |last_activate_origin_frame_args_| is then set to that BeginFrameArgs when
  262. // the committed change is activated.
  263. viz::BeginFrameArgs last_dispatched_begin_main_frame_args_;
  264. viz::BeginFrameArgs last_commit_origin_frame_args_;
  265. viz::BeginFrameArgs last_activate_origin_frame_args_;
  266. // Task posted for the deadline or drawing phase of the scheduler. This task
  267. // can be rescheduled e.g. when the condition for the deadline is met, it is
  268. // scheduled to run immediately.
  269. // NOTE: Scheduler weak ptrs are not necessary if CancelableOnceCallback is
  270. // used.
  271. base::DeadlineTimer begin_impl_frame_deadline_timer_;
  272. // This is used for queueing begin frames while scheduler is waiting for
  273. // previous frame's deadline, or if it's inside ProcessScheduledActions().
  274. // Only one such task is posted at any time, but the args are updated as we
  275. // get new begin frames.
  276. viz::BeginFrameArgs pending_begin_frame_args_;
  277. base::CancelableOnceClosure pending_begin_frame_task_;
  278. SchedulerStateMachine state_machine_;
  279. bool inside_process_scheduled_actions_ = false;
  280. bool inside_scheduled_action_ = false;
  281. SchedulerStateMachine::Action inside_action_ =
  282. SchedulerStateMachine::Action::NONE;
  283. bool stopped_ = false;
  284. bool needs_finish_frame_for_synchronous_compositor_ = false;
  285. // Keeps track of the begin frame interval from the last BeginFrameArgs to
  286. // arrive so that |client_| can be informed about changes.
  287. base::TimeDelta last_frame_interval_;
  288. std::unique_ptr<power_scheduler::PowerModeVoter> power_mode_voter_;
  289. power_scheduler::PowerMode last_power_mode_vote_ =
  290. power_scheduler::PowerMode::kIdle;
  291. private:
  292. // Posts the deadline task if needed by checking
  293. // SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode(). This only
  294. // happens when the scheduler is processing a begin frame
  295. // (BeginImplFrameState::INSIDE_BEGIN_FRAME).
  296. void ScheduleBeginImplFrameDeadline();
  297. // Starts or stops begin frames as needed by checking
  298. // SchedulerStateMachine::BeginFrameNeeded(). This only happens when the
  299. // scheduler is not processing a begin frame (BeginImplFrameState::IDLE).
  300. void StartOrStopBeginFrames();
  301. // This will only post a task if the args are valid and there's no existing
  302. // task. That implies that we're still expecting begin frames. If begin frames
  303. // aren't needed this will be a nop. This only happens when the scheduler is
  304. // not processing a begin frame (BeginImplFrameState::IDLE).
  305. void PostPendingBeginFrameTask();
  306. // Use |pending_begin_frame_args_| to begin a new frame like it was received
  307. // in OnBeginFrameDerivedImpl().
  308. void HandlePendingBeginFrame();
  309. // Used to drop the pending begin frame before we go idle.
  310. void CancelPendingBeginFrameTask();
  311. void BeginMainFrameNotExpectedUntil(base::TimeTicks time);
  312. void BeginMainFrameNotExpectedSoon();
  313. void DrawIfPossible();
  314. void DrawForced();
  315. void ProcessScheduledActions();
  316. void UpdateCompositorTimingHistoryRecordingEnabled();
  317. void AdvanceCommitStateIfPossible();
  318. void BeginImplFrameWithDeadline(const viz::BeginFrameArgs& args);
  319. void BeginImplFrameSynchronous(const viz::BeginFrameArgs& args);
  320. void FinishImplFrameSynchronous();
  321. void BeginImplFrame(const viz::BeginFrameArgs& args, base::TimeTicks now);
  322. void FinishImplFrame();
  323. void SendDidNotProduceFrame(const viz::BeginFrameArgs& args,
  324. FrameSkippedReason reason);
  325. void OnBeginImplFrameDeadline();
  326. void PollToAdvanceCommitState();
  327. void BeginMainFrameAnimateAndLayoutOnly(const viz::BeginFrameArgs& args);
  328. bool IsInsideAction(SchedulerStateMachine::Action action) {
  329. return inside_action_ == action;
  330. }
  331. void UpdatePowerModeVote();
  332. // Used only for UMa metric calculations.
  333. base::TimeDelta cc_frame_time_available_;
  334. base::TimeTicks cc_frame_start_; // Begin impl frame time.
  335. };
  336. } // namespace cc
  337. #endif // CC_SCHEDULER_SCHEDULER_H_