scheduler_state_machine.cc 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560
  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. #include "cc/scheduler/scheduler_state_machine.h"
  5. #include "base/check_op.h"
  6. #include "base/format_macros.h"
  7. #include "base/notreached.h"
  8. #include "base/trace_event/trace_event.h"
  9. #include "base/trace_event/traced_value.h"
  10. #include "base/values.h"
  11. namespace cc {
  12. namespace {
  13. // Surfaces and CompositorTimingHistory don't support more than 1 pending swap.
  14. const int kMaxPendingSubmitFrames = 1;
  15. } // namespace
  16. SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
  17. : settings_(settings) {}
  18. SchedulerStateMachine::~SchedulerStateMachine() = default;
  19. perfetto::protos::pbzero::ChromeCompositorStateMachine::MajorState::
  20. LayerTreeFrameSinkState
  21. SchedulerStateMachine::LayerTreeFrameSinkStateToProtozeroEnum(
  22. LayerTreeFrameSinkState state) {
  23. using pbzeroMajorState =
  24. perfetto::protos::pbzero::ChromeCompositorStateMachine::MajorState;
  25. switch (state) {
  26. case LayerTreeFrameSinkState::NONE:
  27. return pbzeroMajorState::LAYER_TREE_FRAME_NONE;
  28. case LayerTreeFrameSinkState::ACTIVE:
  29. return pbzeroMajorState::LAYER_TREE_FRAME_ACTIVE;
  30. case LayerTreeFrameSinkState::CREATING:
  31. return pbzeroMajorState::LAYER_TREE_FRAME_CREATING;
  32. case LayerTreeFrameSinkState::WAITING_FOR_FIRST_COMMIT:
  33. return pbzeroMajorState::LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT;
  34. case LayerTreeFrameSinkState::WAITING_FOR_FIRST_ACTIVATION:
  35. return pbzeroMajorState::LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION;
  36. }
  37. NOTREACHED();
  38. return pbzeroMajorState::LAYER_TREE_FRAME_UNSPECIFIED;
  39. }
  40. perfetto::protos::pbzero::ChromeCompositorStateMachine::MajorState::
  41. BeginImplFrameState
  42. SchedulerStateMachine::BeginImplFrameStateToProtozeroEnum(
  43. BeginImplFrameState state) {
  44. using pbzeroMajorState =
  45. perfetto::protos::pbzero::ChromeCompositorStateMachine::MajorState;
  46. switch (state) {
  47. case BeginImplFrameState::IDLE:
  48. return pbzeroMajorState::BEGIN_IMPL_FRAME_IDLE;
  49. case BeginImplFrameState::INSIDE_BEGIN_FRAME:
  50. return pbzeroMajorState::BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME;
  51. case BeginImplFrameState::INSIDE_DEADLINE:
  52. return pbzeroMajorState::BEGIN_IMPL_FRAME_INSIDE_DEADLINE;
  53. }
  54. NOTREACHED();
  55. return pbzeroMajorState::BEGIN_IMPL_FRAME_UNSPECIFIED;
  56. }
  57. const char* SchedulerStateMachine::BeginImplFrameDeadlineModeToString(
  58. BeginImplFrameDeadlineMode mode) {
  59. switch (mode) {
  60. case BeginImplFrameDeadlineMode::NONE:
  61. return "BeginImplFrameDeadlineMode::NONE";
  62. case BeginImplFrameDeadlineMode::IMMEDIATE:
  63. return "BeginImplFrameDeadlineMode::IMMEDIATE";
  64. case BeginImplFrameDeadlineMode::REGULAR:
  65. return "BeginImplFrameDeadlineMode::REGULAR";
  66. case BeginImplFrameDeadlineMode::LATE:
  67. return "BeginImplFrameDeadlineMode::LATE";
  68. case BeginImplFrameDeadlineMode::BLOCKED:
  69. return "BeginImplFrameDeadlineMode::BLOCKED";
  70. }
  71. NOTREACHED();
  72. return "???";
  73. }
  74. perfetto::protos::pbzero::ChromeCompositorSchedulerState::
  75. BeginImplFrameDeadlineMode
  76. SchedulerStateMachine::BeginImplFrameDeadlineModeToProtozeroEnum(
  77. BeginImplFrameDeadlineMode mode) {
  78. using pbzeroSchedulerState =
  79. perfetto::protos::pbzero::ChromeCompositorSchedulerState;
  80. switch (mode) {
  81. case BeginImplFrameDeadlineMode::NONE:
  82. return pbzeroSchedulerState::DEADLINE_MODE_NONE;
  83. case BeginImplFrameDeadlineMode::IMMEDIATE:
  84. return pbzeroSchedulerState::DEADLINE_MODE_IMMEDIATE;
  85. case BeginImplFrameDeadlineMode::REGULAR:
  86. return pbzeroSchedulerState::DEADLINE_MODE_REGULAR;
  87. case BeginImplFrameDeadlineMode::LATE:
  88. return pbzeroSchedulerState::DEADLINE_MODE_LATE;
  89. case BeginImplFrameDeadlineMode::BLOCKED:
  90. return pbzeroSchedulerState::DEADLINE_MODE_BLOCKED;
  91. }
  92. NOTREACHED();
  93. return pbzeroSchedulerState::DEADLINE_MODE_UNSPECIFIED;
  94. }
  95. perfetto::protos::pbzero::ChromeCompositorStateMachine::MajorState::
  96. BeginMainFrameState
  97. SchedulerStateMachine::BeginMainFrameStateToProtozeroEnum(
  98. BeginMainFrameState state) {
  99. using pbzeroMajorState =
  100. perfetto::protos::pbzero::ChromeCompositorStateMachine::MajorState;
  101. switch (state) {
  102. case BeginMainFrameState::IDLE:
  103. return pbzeroMajorState::BEGIN_MAIN_FRAME_IDLE;
  104. case BeginMainFrameState::SENT:
  105. return pbzeroMajorState::BEGIN_MAIN_FRAME_SENT;
  106. case BeginMainFrameState::READY_TO_COMMIT:
  107. return pbzeroMajorState::BEGIN_MAIN_FRAME_READY_TO_COMMIT;
  108. }
  109. NOTREACHED();
  110. return pbzeroMajorState::BEGIN_MAIN_FRAME_UNSPECIFIED;
  111. }
  112. perfetto::protos::pbzero::ChromeCompositorStateMachine::MajorState::
  113. ForcedRedrawOnTimeoutState
  114. SchedulerStateMachine::ForcedRedrawOnTimeoutStateToProtozeroEnum(
  115. ForcedRedrawOnTimeoutState state) {
  116. using pbzeroMajorState =
  117. perfetto::protos::pbzero::ChromeCompositorStateMachine::MajorState;
  118. switch (state) {
  119. case ForcedRedrawOnTimeoutState::IDLE:
  120. return pbzeroMajorState::FORCED_REDRAW_IDLE;
  121. case ForcedRedrawOnTimeoutState::WAITING_FOR_COMMIT:
  122. return pbzeroMajorState::FORCED_REDRAW_WAITING_FOR_COMMIT;
  123. case ForcedRedrawOnTimeoutState::WAITING_FOR_ACTIVATION:
  124. return pbzeroMajorState::FORCED_REDRAW_WAITING_FOR_ACTIVATION;
  125. case ForcedRedrawOnTimeoutState::WAITING_FOR_DRAW:
  126. return pbzeroMajorState::FORCED_REDRAW_WAITING_FOR_DRAW;
  127. }
  128. NOTREACHED();
  129. return pbzeroMajorState::FORCED_REDRAW_UNSPECIFIED;
  130. }
  131. perfetto::protos::pbzero::ChromeCompositorStateMachine::MinorState::
  132. ScrollHandlerState
  133. ScrollHandlerStateToProtozeroEnum(ScrollHandlerState state) {
  134. using pbzeroMinorState =
  135. perfetto::protos::pbzero::ChromeCompositorStateMachine::MinorState;
  136. switch (state) {
  137. case ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER:
  138. return pbzeroMinorState::SCROLL_AFFECTS_SCROLL_HANDLER;
  139. case ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER:
  140. return pbzeroMinorState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER;
  141. }
  142. NOTREACHED();
  143. return pbzeroMinorState::SCROLL_HANDLER_UNSPECIFIED;
  144. }
  145. perfetto::protos::pbzero::ChromeCompositorSchedulerAction
  146. SchedulerStateMachine::ActionToProtozeroEnum(Action action) {
  147. using pbzeroSchedulerAction =
  148. perfetto::protos::pbzero::ChromeCompositorSchedulerAction;
  149. switch (action) {
  150. case Action::NONE:
  151. return pbzeroSchedulerAction::CC_SCHEDULER_ACTION_NONE;
  152. case Action::SEND_BEGIN_MAIN_FRAME:
  153. return pbzeroSchedulerAction::CC_SCHEDULER_ACTION_SEND_BEGIN_MAIN_FRAME;
  154. case Action::COMMIT:
  155. case Action::POST_COMMIT:
  156. // TODO(szager): Add CC_SCHEDULER_ACTION_POST_COMMIT to perfetto
  157. return pbzeroSchedulerAction::CC_SCHEDULER_ACTION_COMMIT;
  158. case Action::ACTIVATE_SYNC_TREE:
  159. return pbzeroSchedulerAction::CC_SCHEDULER_ACTION_ACTIVATE_SYNC_TREE;
  160. case Action::DRAW_IF_POSSIBLE:
  161. return pbzeroSchedulerAction::CC_SCHEDULER_ACTION_DRAW_IF_POSSIBLE;
  162. case Action::DRAW_FORCED:
  163. return pbzeroSchedulerAction::CC_SCHEDULER_ACTION_DRAW_FORCED;
  164. case Action::DRAW_ABORT:
  165. return pbzeroSchedulerAction::CC_SCHEDULER_ACTION_DRAW_ABORT;
  166. case Action::BEGIN_LAYER_TREE_FRAME_SINK_CREATION:
  167. return pbzeroSchedulerAction::
  168. CC_SCHEDULER_ACTION_BEGIN_LAYER_TREE_FRAME_SINK_CREATION;
  169. case Action::PREPARE_TILES:
  170. return pbzeroSchedulerAction::CC_SCHEDULER_ACTION_PREPARE_TILES;
  171. case Action::INVALIDATE_LAYER_TREE_FRAME_SINK:
  172. return pbzeroSchedulerAction::
  173. CC_SCHEDULER_ACTION_INVALIDATE_LAYER_TREE_FRAME_SINK;
  174. case Action::PERFORM_IMPL_SIDE_INVALIDATION:
  175. return pbzeroSchedulerAction::
  176. CC_SCHEDULER_ACTION_PERFORM_IMPL_SIDE_INVALIDATION;
  177. case Action::NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL:
  178. return pbzeroSchedulerAction::
  179. CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL;
  180. case Action::NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON:
  181. return pbzeroSchedulerAction::
  182. CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON;
  183. }
  184. NOTREACHED();
  185. return pbzeroSchedulerAction::CC_SCHEDULER_ACTION_UNSPECIFIED;
  186. }
  187. void SchedulerStateMachine::AsProtozeroInto(
  188. perfetto::protos::pbzero::ChromeCompositorStateMachine* state) const {
  189. auto* major_state = state->set_major_state();
  190. major_state->set_next_action(ActionToProtozeroEnum(NextAction()));
  191. major_state->set_begin_impl_frame_state(
  192. BeginImplFrameStateToProtozeroEnum(begin_impl_frame_state_));
  193. major_state->set_begin_main_frame_state(
  194. BeginMainFrameStateToProtozeroEnum(begin_main_frame_state_));
  195. major_state->set_layer_tree_frame_sink_state(
  196. LayerTreeFrameSinkStateToProtozeroEnum(layer_tree_frame_sink_state_));
  197. major_state->set_forced_redraw_state(
  198. ForcedRedrawOnTimeoutStateToProtozeroEnum(forced_redraw_state_));
  199. auto* minor_state = state->set_minor_state();
  200. minor_state->set_commit_count(commit_count_);
  201. minor_state->set_current_frame_number(current_frame_number_);
  202. minor_state->set_last_frame_number_submit_performed(
  203. last_frame_number_submit_performed_);
  204. minor_state->set_last_frame_number_draw_performed(
  205. last_frame_number_draw_performed_);
  206. minor_state->set_last_frame_number_begin_main_frame_sent(
  207. last_frame_number_begin_main_frame_sent_);
  208. minor_state->set_did_draw(did_draw_);
  209. minor_state->set_did_send_begin_main_frame_for_current_frame(
  210. did_send_begin_main_frame_for_current_frame_);
  211. minor_state->set_did_notify_begin_main_frame_not_expected_until(
  212. did_notify_begin_main_frame_not_expected_until_);
  213. minor_state->set_did_notify_begin_main_frame_not_expected_soon(
  214. did_notify_begin_main_frame_not_expected_soon_);
  215. minor_state->set_wants_begin_main_frame_not_expected(
  216. wants_begin_main_frame_not_expected_);
  217. minor_state->set_did_commit_during_frame(did_commit_during_frame_);
  218. minor_state->set_did_invalidate_layer_tree_frame_sink(
  219. did_invalidate_layer_tree_frame_sink_);
  220. minor_state->set_did_perform_impl_side_invalidaion(
  221. did_perform_impl_side_invalidation_);
  222. minor_state->set_did_prepare_tiles(did_prepare_tiles_);
  223. minor_state->set_consecutive_checkerboard_animations(
  224. consecutive_checkerboard_animations_);
  225. minor_state->set_pending_submit_frames(pending_submit_frames_);
  226. minor_state->set_submit_frames_with_current_layer_tree_frame_sink(
  227. submit_frames_with_current_layer_tree_frame_sink_);
  228. minor_state->set_needs_redraw(needs_redraw_);
  229. minor_state->set_needs_prepare_tiles(needs_prepare_tiles_);
  230. minor_state->set_needs_begin_main_frame(needs_begin_main_frame_);
  231. minor_state->set_needs_one_begin_impl_frame(needs_one_begin_impl_frame_);
  232. minor_state->set_visible(visible_);
  233. minor_state->set_begin_frame_source_paused(begin_frame_source_paused_);
  234. minor_state->set_can_draw(can_draw_);
  235. minor_state->set_resourceless_draw(resourceless_draw_);
  236. minor_state->set_has_pending_tree(has_pending_tree_);
  237. minor_state->set_pending_tree_is_ready_for_activation(
  238. pending_tree_is_ready_for_activation_);
  239. minor_state->set_active_tree_needs_first_draw(active_tree_needs_first_draw_);
  240. minor_state->set_active_tree_is_ready_to_draw(active_tree_is_ready_to_draw_);
  241. minor_state->set_did_create_and_initialize_first_layer_tree_frame_sink(
  242. did_create_and_initialize_first_layer_tree_frame_sink_);
  243. minor_state->set_tree_priority(TreePriorityToProtozeroEnum(tree_priority_));
  244. minor_state->set_scroll_handler_state(
  245. ScrollHandlerStateToProtozeroEnum(scroll_handler_state_));
  246. minor_state->set_critical_begin_main_frame_to_activate_is_fast(
  247. critical_begin_main_frame_to_activate_is_fast_);
  248. minor_state->set_main_thread_missed_last_deadline(
  249. main_thread_missed_last_deadline_);
  250. minor_state->set_video_needs_begin_frames(video_needs_begin_frames_);
  251. minor_state->set_defer_begin_main_frame(defer_begin_main_frame_);
  252. minor_state->set_last_commit_had_no_updates(last_commit_had_no_updates_);
  253. minor_state->set_did_draw_in_last_frame(did_attempt_draw_in_last_frame_);
  254. minor_state->set_did_submit_in_last_frame(did_submit_in_last_frame_);
  255. minor_state->set_needs_impl_side_invalidation(needs_impl_side_invalidation_);
  256. minor_state->set_current_pending_tree_is_impl_side(
  257. current_pending_tree_is_impl_side_);
  258. minor_state->set_previous_pending_tree_was_impl_side(
  259. previous_pending_tree_was_impl_side_);
  260. minor_state->set_processing_animation_worklets_for_active_tree(
  261. processing_animation_worklets_for_active_tree_);
  262. minor_state->set_processing_animation_worklets_for_pending_tree(
  263. processing_animation_worklets_for_pending_tree_);
  264. minor_state->set_processing_paint_worklets_for_pending_tree(
  265. processing_paint_worklets_for_pending_tree_);
  266. }
  267. bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const {
  268. // Normally when |visible_| is false or |begin_frame_source_paused_| is true,
  269. // pending activations will be forced and draws will be aborted. However,
  270. // when the embedder is Android WebView, software draws could be scheduled by
  271. // the Android OS at any time and draws should not be aborted in this case.
  272. bool is_layer_tree_frame_sink_lost =
  273. (layer_tree_frame_sink_state_ == LayerTreeFrameSinkState::NONE);
  274. if (resourceless_draw_)
  275. return is_layer_tree_frame_sink_lost || !can_draw_;
  276. // These are all the cases where we normally cannot or do not want
  277. // to draw but, if |needs_redraw_| is true and we do not draw to
  278. // make forward progress, we might deadlock with the main
  279. // thread. This should be a superset of ShouldAbortCurrentFrame()
  280. // since activation of the pending tree is blocked by drawing of the
  281. // active tree and the main thread might be blocked on activation of
  282. // the most recent commit.
  283. return is_layer_tree_frame_sink_lost || !can_draw_ || !visible_ ||
  284. begin_frame_source_paused_;
  285. }
  286. bool SchedulerStateMachine::ShouldAbortCurrentFrame() const {
  287. // Abort the frame if there is no output surface to trigger our
  288. // activations, avoiding deadlock with the main thread.
  289. if (layer_tree_frame_sink_state_ == LayerTreeFrameSinkState::NONE)
  290. return true;
  291. // If we're not visible, we should just abort the frame. Since we
  292. // set RequiresHighResToDraw when becoming visible, we ensure that
  293. // we don't checkerboard until all visible resources are
  294. // done. Furthermore, if we do keep the pending tree around, when
  295. // becoming visible we might activate prematurely causing
  296. // RequiresHighResToDraw flag to be reset. In all cases, we can
  297. // simply activate on becoming invisible since we don't need to draw
  298. // the active tree when we're in this state.
  299. if (!visible_)
  300. return true;
  301. // Abort the frame when viz::BeginFrameSource is paused to avoid
  302. // deadlocking the main thread.
  303. if (begin_frame_source_paused_)
  304. return true;
  305. return false;
  306. }
  307. bool SchedulerStateMachine::ShouldBeginLayerTreeFrameSinkCreation() const {
  308. if (!visible_)
  309. return false;
  310. // We only want to start output surface initialization after the
  311. // previous commit is complete.
  312. if (begin_main_frame_state_ != BeginMainFrameState::IDLE) {
  313. return false;
  314. }
  315. // Make sure the BeginImplFrame from any previous LayerTreeFrameSinks
  316. // are complete before creating the new LayerTreeFrameSink.
  317. if (begin_impl_frame_state_ != BeginImplFrameState::IDLE)
  318. return false;
  319. // We want to clear the pipeline of any pending draws and activations
  320. // before starting output surface initialization. This allows us to avoid
  321. // weird corner cases where we abort draws or force activation while we
  322. // are initializing the output surface.
  323. if (active_tree_needs_first_draw_ || has_pending_tree_)
  324. return false;
  325. // We need to create the output surface if we don't have one and we haven't
  326. // started creating one yet.
  327. return layer_tree_frame_sink_state_ == LayerTreeFrameSinkState::NONE;
  328. }
  329. bool SchedulerStateMachine::ShouldDraw() const {
  330. // If we need to abort draws, we should do so ASAP since the draw could
  331. // be blocking other important actions (like output surface initialization),
  332. // from occurring. If we are waiting for the first draw, then perform the
  333. // aborted draw to keep things moving. If we are not waiting for the first
  334. // draw however, we don't want to abort for no reason.
  335. if (PendingDrawsShouldBeAborted())
  336. return active_tree_needs_first_draw_;
  337. // Do not draw more than once in the deadline. Aborted draws are ok because
  338. // those are effectively nops.
  339. if (did_draw_)
  340. return false;
  341. // Don't draw if an early check determined the frame does not have damage.
  342. if (skip_draw_)
  343. return false;
  344. // Don't draw if we are waiting on the first commit after a surface.
  345. if (layer_tree_frame_sink_state_ != LayerTreeFrameSinkState::ACTIVE)
  346. return false;
  347. // Do not queue too many draws.
  348. if (IsDrawThrottled())
  349. return false;
  350. // Except for the cases above, do not draw outside of the BeginImplFrame
  351. // deadline.
  352. if (begin_impl_frame_state_ != BeginImplFrameState::INSIDE_DEADLINE)
  353. return false;
  354. // Wait for ready to draw in full-pipeline mode or the browser compositor's
  355. // commit-to-active-tree mode.
  356. if ((settings_.wait_for_all_pipeline_stages_before_draw ||
  357. settings_.commit_to_active_tree) &&
  358. !active_tree_is_ready_to_draw_) {
  359. return false;
  360. }
  361. // Browser compositor commit steals any resources submitted in draw. Therefore
  362. // drawing while a commit is pending is wasteful.
  363. if (settings_.commit_to_active_tree && CommitPending())
  364. return false;
  365. // Only handle forced redraws due to timeouts on the regular deadline.
  366. if (forced_redraw_state_ == ForcedRedrawOnTimeoutState::WAITING_FOR_DRAW)
  367. return true;
  368. return needs_redraw_;
  369. }
  370. bool SchedulerStateMachine::ShouldActivateSyncTree() const {
  371. // There is nothing to activate.
  372. if (!has_pending_tree_)
  373. return false;
  374. // We should not activate a second tree before drawing the first one.
  375. // Even if we need to force activation of the pending tree, we should abort
  376. // drawing the active tree first. Relax this requirement for synchronous
  377. // compositor where scheduler does not control draw, and blocking commit
  378. // may lead to bad scheduling.
  379. if (!settings_.using_synchronous_renderer_compositor &&
  380. active_tree_needs_first_draw_) {
  381. return false;
  382. }
  383. // Delay pending tree activation until paint worklets have completed painting
  384. // the pending tree. This must occur before the |ShouldAbortCurrentFrame|
  385. // check as we cannot have an unpainted active tree.
  386. //
  387. // Note that paint worklets continue to paint when the page is not visible, so
  388. // any abort will eventually happen when they complete.
  389. if (processing_paint_worklets_for_pending_tree_)
  390. return false;
  391. if (ShouldAbortCurrentFrame())
  392. return true;
  393. // Delay pending tree activation until animation worklets have completed
  394. // their asynchronous updates to pick up initial values.
  395. if (processing_animation_worklets_for_pending_tree_)
  396. return false;
  397. // At this point, only activate if we are ready to activate.
  398. return pending_tree_is_ready_for_activation_;
  399. }
  400. bool SchedulerStateMachine::ShouldNotifyBeginMainFrameNotExpectedUntil() const {
  401. // This method returns true if most of the conditions for sending a
  402. // BeginMainFrame are met, but one is not actually requested. This gives the
  403. // main thread the chance to do something else.
  404. if (!wants_begin_main_frame_not_expected_)
  405. return false;
  406. // Don't notify if a BeginMainFrame has already been requested or is in
  407. // progress.
  408. if (needs_begin_main_frame_ ||
  409. begin_main_frame_state_ != BeginMainFrameState::IDLE)
  410. return false;
  411. // Only notify when we're visible.
  412. if (!visible_)
  413. return false;
  414. // There are no BeginImplFrames while viz::BeginFrameSource is paused, meaning
  415. // the scheduler should send SendBeginMainFrameNotExpectedSoon instead,
  416. // indicating a longer period of inactivity.
  417. if (begin_frame_source_paused_)
  418. return false;
  419. // If we've gone idle and have stopped getting BeginFrames, we should send
  420. // SendBeginMainFrameNotExpectedSoon instead.
  421. if (!BeginFrameNeeded() &&
  422. begin_impl_frame_state_ == BeginImplFrameState::IDLE) {
  423. return false;
  424. }
  425. // Do not notify that no BeginMainFrame was sent too many times in a single
  426. // frame.
  427. if (did_notify_begin_main_frame_not_expected_until_)
  428. return false;
  429. // Do not notify if a commit happened during this frame as the main thread
  430. // will already be active and does not need to be woken up to make further
  431. // actions. (This occurs if the main frame was scheduled but didn't complete
  432. // before the vsync deadline).
  433. if (did_commit_during_frame_)
  434. return false;
  435. return true;
  436. }
  437. bool SchedulerStateMachine::ShouldNotifyBeginMainFrameNotExpectedSoon() const {
  438. if (!wants_begin_main_frame_not_expected_)
  439. return false;
  440. // Don't notify if a BeginMainFrame has already been requested or is in
  441. // progress.
  442. if (needs_begin_main_frame_ ||
  443. begin_main_frame_state_ != BeginMainFrameState::IDLE) {
  444. return false;
  445. }
  446. // Only send this when we've stopped getting BeginFrames and have gone idle.
  447. if (BeginFrameNeeded() ||
  448. begin_impl_frame_state_ != BeginImplFrameState::IDLE) {
  449. return false;
  450. }
  451. // Do not notify that we're not expecting frames more than once per frame.
  452. if (did_notify_begin_main_frame_not_expected_soon_)
  453. return false;
  454. return true;
  455. }
  456. bool SchedulerStateMachine::CouldSendBeginMainFrame() const {
  457. if (!needs_begin_main_frame_)
  458. return false;
  459. // We can not perform commits if we are not visible.
  460. if (!visible_)
  461. return false;
  462. // There are no BeginImplFrames while viz::BeginFrameSource is paused,
  463. // so should also stop BeginMainFrames.
  464. if (begin_frame_source_paused_)
  465. return false;
  466. // Do not send begin main frame when it is deferred.
  467. if (defer_begin_main_frame_)
  468. return false;
  469. return true;
  470. }
  471. bool SchedulerStateMachine::ShouldSendBeginMainFrame() const {
  472. if (!CouldSendBeginMainFrame())
  473. return false;
  474. // Do not send more than one begin main frame in a begin frame.
  475. if (did_send_begin_main_frame_for_current_frame_)
  476. return false;
  477. // Only send BeginMainFrame when there isn't another commit pending already.
  478. // Other parts of the state machine indirectly defer the BeginMainFrame
  479. // by transitioning to WAITING commit states rather than going
  480. // immediately to IDLE.
  481. if (begin_main_frame_state_ != BeginMainFrameState::IDLE)
  482. return false;
  483. // MFBA is disabled and we are waiting for previous activation, or the current
  484. // pending tree is impl-side.
  485. bool can_send_main_frame_with_pending_tree =
  486. settings_.main_frame_before_activation_enabled ||
  487. current_pending_tree_is_impl_side_;
  488. if (has_pending_tree_ && !can_send_main_frame_with_pending_tree)
  489. return false;
  490. // We are waiting for previous frame to be drawn, submitted and acked.
  491. if (settings_.commit_to_active_tree &&
  492. (active_tree_needs_first_draw_ || IsDrawThrottled())) {
  493. return false;
  494. }
  495. // Don't send BeginMainFrame early if we are prioritizing the active tree
  496. // because of ImplLatencyTakesPriority.
  497. if (ImplLatencyTakesPriority() &&
  498. (has_pending_tree_ || active_tree_needs_first_draw_)) {
  499. return false;
  500. }
  501. // We should not send BeginMainFrame while we are in the idle state since we
  502. // might have new user input arriving soon. It's okay to send BeginMainFrame
  503. // for the synchronous compositor because the main thread is always high
  504. // latency in that case.
  505. // TODO(brianderson): Allow sending BeginMainFrame while idle when the main
  506. // thread isn't consuming user input for non-synchronous compositor.
  507. if (!settings_.using_synchronous_renderer_compositor &&
  508. begin_impl_frame_state_ == BeginImplFrameState::IDLE) {
  509. return false;
  510. }
  511. // We need a new commit for the forced redraw. This honors the
  512. // single commit per interval because the result will be swapped to screen.
  513. if (forced_redraw_state_ == ForcedRedrawOnTimeoutState::WAITING_FOR_COMMIT)
  514. return true;
  515. // We shouldn't normally accept commits if there isn't a LayerTreeFrameSink.
  516. if (!HasInitializedLayerTreeFrameSink())
  517. return false;
  518. // Throttle the BeginMainFrames on CompositorFrameAck unless we just
  519. // submitted a frame to potentially improve impl-thread latency over
  520. // main-thread throughput.
  521. // TODO(brianderson): Remove this restriction to improve throughput or
  522. // make it conditional on ImplLatencyTakesPriority.
  523. bool just_submitted_in_deadline =
  524. begin_impl_frame_state_ == BeginImplFrameState::INSIDE_DEADLINE &&
  525. did_submit_in_last_frame_;
  526. if (IsDrawThrottled() && !just_submitted_in_deadline)
  527. return false;
  528. return true;
  529. }
  530. bool SchedulerStateMachine::ShouldCommit() const {
  531. if (begin_main_frame_state_ != BeginMainFrameState::READY_TO_COMMIT)
  532. return false;
  533. // We must not finish the commit until the pending tree is free.
  534. if (has_pending_tree_) {
  535. DCHECK(settings_.main_frame_before_activation_enabled ||
  536. current_pending_tree_is_impl_side_);
  537. return false;
  538. }
  539. // If we only have an active tree, it is incorrect to replace it before we've
  540. // drawn it.
  541. DCHECK(!settings_.commit_to_active_tree || !active_tree_needs_first_draw_);
  542. // In browser compositor commit reclaims any resources submitted during draw.
  543. DCHECK(!settings_.commit_to_active_tree || !IsDrawThrottled());
  544. return true;
  545. }
  546. void SchedulerStateMachine::DidCommit() {
  547. DCHECK(!needs_post_commit_);
  548. needs_post_commit_ = true;
  549. }
  550. bool SchedulerStateMachine::ShouldRunPostCommit() const {
  551. return needs_post_commit_;
  552. }
  553. void SchedulerStateMachine::DidPostCommit() {
  554. DCHECK(needs_post_commit_);
  555. needs_post_commit_ = false;
  556. }
  557. bool SchedulerStateMachine::ShouldPrepareTiles() const {
  558. // In full-pipeline mode, we need to prepare tiles ASAP to ensure that we
  559. // don't get stuck.
  560. if (settings_.wait_for_all_pipeline_stages_before_draw)
  561. return needs_prepare_tiles_;
  562. // Do not prepare tiles if we've already done so in commit or impl side
  563. // invalidation.
  564. if (did_prepare_tiles_)
  565. return false;
  566. // Limiting to once per-frame is not enough, since we only want to prepare
  567. // tiles _after_ draws.
  568. if (begin_impl_frame_state_ != BeginImplFrameState::INSIDE_DEADLINE)
  569. return false;
  570. return needs_prepare_tiles_;
  571. }
  572. bool SchedulerStateMachine::ShouldInvalidateLayerTreeFrameSink() const {
  573. // Do not invalidate more than once per begin frame.
  574. if (did_invalidate_layer_tree_frame_sink_)
  575. return false;
  576. // Only the synchronous compositor requires invalidations.
  577. if (!settings_.using_synchronous_renderer_compositor)
  578. return false;
  579. // Invalidations are only performed inside a BeginFrame.
  580. if (begin_impl_frame_state_ != BeginImplFrameState::INSIDE_BEGIN_FRAME)
  581. return false;
  582. // Don't invalidate for draw if we cannnot draw.
  583. // TODO(sunnyps): needs_prepare_tiles_ is needed here because PrepareTiles is
  584. // called only inside the deadline / draw phase. We could remove this if we
  585. // allowed PrepareTiles to happen in OnBeginImplFrame.
  586. return (needs_redraw_ && !PendingDrawsShouldBeAborted()) ||
  587. needs_prepare_tiles_;
  588. }
  589. SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const {
  590. if (ShouldSendBeginMainFrame())
  591. return Action::SEND_BEGIN_MAIN_FRAME;
  592. if (ShouldRunPostCommit())
  593. return Action::POST_COMMIT;
  594. if (ShouldActivateSyncTree())
  595. return Action::ACTIVATE_SYNC_TREE;
  596. if (ShouldCommit())
  597. return Action::COMMIT;
  598. if (ShouldDraw()) {
  599. if (PendingDrawsShouldBeAborted())
  600. return Action::DRAW_ABORT;
  601. else if (forced_redraw_state_ ==
  602. ForcedRedrawOnTimeoutState::WAITING_FOR_DRAW)
  603. return Action::DRAW_FORCED;
  604. else
  605. return Action::DRAW_IF_POSSIBLE;
  606. }
  607. if (ShouldPerformImplSideInvalidation())
  608. return Action::PERFORM_IMPL_SIDE_INVALIDATION;
  609. if (ShouldPrepareTiles())
  610. return Action::PREPARE_TILES;
  611. if (ShouldInvalidateLayerTreeFrameSink())
  612. return Action::INVALIDATE_LAYER_TREE_FRAME_SINK;
  613. if (ShouldBeginLayerTreeFrameSinkCreation())
  614. return Action::BEGIN_LAYER_TREE_FRAME_SINK_CREATION;
  615. if (ShouldNotifyBeginMainFrameNotExpectedUntil())
  616. return Action::NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL;
  617. if (ShouldNotifyBeginMainFrameNotExpectedSoon())
  618. return Action::NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON;
  619. return Action::NONE;
  620. }
  621. bool SchedulerStateMachine::ShouldPerformImplSideInvalidation() const {
  622. if (begin_frame_is_animate_only_)
  623. return false;
  624. if (!needs_impl_side_invalidation_)
  625. return false;
  626. // Don't invalidate if we've already done so either from the scheduler or as
  627. // part of commit.
  628. if (did_perform_impl_side_invalidation_)
  629. return false;
  630. // No invalidations should be done outside the impl frame.
  631. if (begin_impl_frame_state_ == BeginImplFrameState::IDLE)
  632. return false;
  633. // We need to be able to create a pending tree to perform an invalidation.
  634. if (!CouldCreatePendingTree())
  635. return false;
  636. // Check if we should defer invalidating so we can merge these invalidations
  637. // with the main frame.
  638. if (ShouldDeferInvalidatingForMainFrame())
  639. return false;
  640. // If invalidations go to the active tree and we are waiting for the previous
  641. // frame to be drawn, submitted and acked.
  642. if (settings_.commit_to_active_tree &&
  643. (active_tree_needs_first_draw_ || IsDrawThrottled())) {
  644. return false;
  645. }
  646. return true;
  647. }
  648. bool SchedulerStateMachine::ShouldDeferInvalidatingForMainFrame() const {
  649. DCHECK_NE(begin_impl_frame_state_, BeginImplFrameState::IDLE);
  650. // If the main thread is ready to commit, the impl-side invalidations will be
  651. // merged with the incoming main frame.
  652. if (begin_main_frame_state_ == BeginMainFrameState::READY_TO_COMMIT)
  653. return true;
  654. // If commits are being aborted (which would be the common case for a
  655. // compositor scroll), don't defer the invalidation.
  656. if (last_frame_events_.commit_had_no_updates || last_commit_had_no_updates_)
  657. return false;
  658. // If we prefer to invalidate over waiting on the main frame, do the
  659. // invalidation now.
  660. if (!should_defer_invalidation_for_fast_main_frame_)
  661. return false;
  662. // If there is a request for a main frame, then this could either be a
  663. // request that we need to respond to in this impl frame or its possible the
  664. // request is for the next frame (a rAF issued at the beginning of the current
  665. // main frame). In either case, defer invalidating so we can merge it with the
  666. // main frame.
  667. if (needs_begin_main_frame_)
  668. return true;
  669. // If the main frame was already sent, wait for the main thread to respond.
  670. if (begin_main_frame_state_ == BeginMainFrameState::SENT)
  671. return true;
  672. // If the main thread committed during the last frame, i.e. it was not
  673. // aborted, then we might get another main frame request later in the impl
  674. // frame. This could be the case for a timer based animation running on the
  675. // main thread which doesn't align with our vsync. For such cases,
  676. // conservatively defer invalidating until the deadline.
  677. if (last_frame_events_.did_commit_during_frame)
  678. return true;
  679. // If the main thread is not requesting any frames, perform the invalidation
  680. // at the beginning of the impl frame.
  681. return false;
  682. }
  683. void SchedulerStateMachine::WillPerformImplSideInvalidation() {
  684. current_pending_tree_is_impl_side_ = true;
  685. WillPerformImplSideInvalidationInternal();
  686. }
  687. void SchedulerStateMachine::WillPerformImplSideInvalidationInternal() {
  688. DCHECK(needs_impl_side_invalidation_);
  689. DCHECK(!has_pending_tree_);
  690. needs_impl_side_invalidation_ = false;
  691. has_pending_tree_ = true;
  692. did_perform_impl_side_invalidation_ = true;
  693. pending_tree_needs_first_draw_on_activation_ =
  694. next_invalidation_needs_first_draw_on_activation_;
  695. next_invalidation_needs_first_draw_on_activation_ = false;
  696. // TODO(eseckler): Track impl-side invalidations for pending/active tree and
  697. // CompositorFrame freshness computation.
  698. }
  699. bool SchedulerStateMachine::CouldCreatePendingTree() const {
  700. // Can't create a new pending tree till the current one is activated.
  701. if (has_pending_tree_)
  702. return false;
  703. // Can't make frames while we're invisible.
  704. if (!visible_)
  705. return false;
  706. // If the viz::BeginFrameSource is paused, we will not be able to make any
  707. // impl frames.
  708. if (begin_frame_source_paused_)
  709. return false;
  710. // Don't create a pending tree till a frame sink is fully initialized. Check
  711. // for the ACTIVE state explicitly instead of calling
  712. // HasInitializedLayerTreeFrameSink() because that only checks if frame sink
  713. // has been recreated, but doesn't check if we're waiting for first commit or
  714. // activation.
  715. if (layer_tree_frame_sink_state_ != LayerTreeFrameSinkState::ACTIVE)
  716. return false;
  717. return true;
  718. }
  719. void SchedulerStateMachine::WillSendBeginMainFrame() {
  720. DCHECK(!has_pending_tree_ || settings_.main_frame_before_activation_enabled ||
  721. current_pending_tree_is_impl_side_);
  722. DCHECK(visible_);
  723. DCHECK(!begin_frame_source_paused_);
  724. DCHECK(!did_send_begin_main_frame_for_current_frame_);
  725. begin_main_frame_state_ = BeginMainFrameState::SENT;
  726. needs_begin_main_frame_ = false;
  727. did_send_begin_main_frame_for_current_frame_ = true;
  728. last_frame_number_begin_main_frame_sent_ = current_frame_number_;
  729. }
  730. void SchedulerStateMachine::WillNotifyBeginMainFrameNotExpectedUntil() {
  731. DCHECK(visible_);
  732. DCHECK(!begin_frame_source_paused_);
  733. DCHECK(BeginFrameNeeded() ||
  734. begin_impl_frame_state_ != BeginImplFrameState::IDLE);
  735. DCHECK(!did_notify_begin_main_frame_not_expected_until_);
  736. did_notify_begin_main_frame_not_expected_until_ = true;
  737. }
  738. void SchedulerStateMachine::WillNotifyBeginMainFrameNotExpectedSoon() {
  739. DCHECK(!BeginFrameNeeded());
  740. DCHECK(begin_impl_frame_state_ == BeginImplFrameState::IDLE);
  741. DCHECK(!did_notify_begin_main_frame_not_expected_soon_);
  742. did_notify_begin_main_frame_not_expected_soon_ = true;
  743. }
  744. void SchedulerStateMachine::WillCommit(bool commit_has_no_updates) {
  745. bool can_have_pending_tree =
  746. commit_has_no_updates &&
  747. (settings_.main_frame_before_activation_enabled ||
  748. current_pending_tree_is_impl_side_);
  749. DCHECK(!has_pending_tree_ || can_have_pending_tree);
  750. commit_count_++;
  751. last_commit_had_no_updates_ = commit_has_no_updates;
  752. begin_main_frame_state_ = BeginMainFrameState::IDLE;
  753. did_commit_during_frame_ = true;
  754. if (!commit_has_no_updates) {
  755. // If there was a commit, the impl-side invalidations will be merged with
  756. // it. We always fill the impl-side invalidation funnel here, even if no
  757. // request was currently pending, to defer creating another pending tree and
  758. // performing PrepareTiles until the next frame, in case the invalidation
  759. // request is received after the commit.
  760. if (needs_impl_side_invalidation_)
  761. WillPerformImplSideInvalidationInternal();
  762. did_perform_impl_side_invalidation_ = true;
  763. // We have a new pending tree.
  764. has_pending_tree_ = true;
  765. pending_tree_needs_first_draw_on_activation_ = true;
  766. pending_tree_is_ready_for_activation_ = false;
  767. if (!active_tree_needs_first_draw_ ||
  768. !settings_.wait_for_all_pipeline_stages_before_draw) {
  769. // Wait for the new pending tree to become ready to draw, which may happen
  770. // before or after activation (unless we're in full-pipeline mode and
  771. // need first draw to come through).
  772. active_tree_is_ready_to_draw_ = false;
  773. }
  774. aborted_begin_main_frame_count_ = 0;
  775. } else {
  776. aborted_begin_main_frame_count_++;
  777. }
  778. // Update state related to forced draws.
  779. if (forced_redraw_state_ == ForcedRedrawOnTimeoutState::WAITING_FOR_COMMIT) {
  780. forced_redraw_state_ =
  781. has_pending_tree_ ? ForcedRedrawOnTimeoutState::WAITING_FOR_ACTIVATION
  782. : ForcedRedrawOnTimeoutState::WAITING_FOR_DRAW;
  783. }
  784. // Update the output surface state.
  785. if (layer_tree_frame_sink_state_ ==
  786. LayerTreeFrameSinkState::WAITING_FOR_FIRST_COMMIT) {
  787. layer_tree_frame_sink_state_ =
  788. has_pending_tree_
  789. ? LayerTreeFrameSinkState::WAITING_FOR_FIRST_ACTIVATION
  790. : LayerTreeFrameSinkState::ACTIVE;
  791. }
  792. }
  793. void SchedulerStateMachine::WillActivate() {
  794. // We cannot activate the pending tree while paint worklets are still being
  795. // processed; the pending tree *must* be fully painted before it can ever be
  796. // activated because we cannot paint the active tree.
  797. DCHECK(!processing_paint_worklets_for_pending_tree_);
  798. if (layer_tree_frame_sink_state_ ==
  799. LayerTreeFrameSinkState::WAITING_FOR_FIRST_ACTIVATION)
  800. layer_tree_frame_sink_state_ = LayerTreeFrameSinkState::ACTIVE;
  801. if (forced_redraw_state_ ==
  802. ForcedRedrawOnTimeoutState::WAITING_FOR_ACTIVATION)
  803. forced_redraw_state_ = ForcedRedrawOnTimeoutState::WAITING_FOR_DRAW;
  804. has_pending_tree_ = false;
  805. pending_tree_is_ready_for_activation_ = false;
  806. active_tree_needs_first_draw_ = pending_tree_needs_first_draw_on_activation_;
  807. pending_tree_needs_first_draw_on_activation_ = false;
  808. needs_redraw_ = true;
  809. previous_pending_tree_was_impl_side_ = current_pending_tree_is_impl_side_;
  810. current_pending_tree_is_impl_side_ = false;
  811. }
  812. void SchedulerStateMachine::WillDrawInternal() {
  813. // If a new active tree is pending after the one we are about to draw,
  814. // the main thread is in a high latency mode.
  815. // main_thread_missed_last_deadline_ is here in addition to
  816. // OnBeginImplFrameIdle for cases where the scheduler aborts draws outside
  817. // of the deadline.
  818. main_thread_missed_last_deadline_ =
  819. CommitPending() ||
  820. (has_pending_tree_ && !current_pending_tree_is_impl_side_);
  821. // We need to reset needs_redraw_ before we draw since the
  822. // draw itself might request another draw.
  823. needs_redraw_ = false;
  824. did_draw_ = true;
  825. active_tree_needs_first_draw_ = false;
  826. last_frame_number_draw_performed_ = current_frame_number_;
  827. if (forced_redraw_state_ == ForcedRedrawOnTimeoutState::WAITING_FOR_DRAW)
  828. forced_redraw_state_ = ForcedRedrawOnTimeoutState::IDLE;
  829. }
  830. void SchedulerStateMachine::DidDrawInternal(DrawResult draw_result) {
  831. switch (draw_result) {
  832. case INVALID_RESULT:
  833. case DRAW_ABORTED_CANT_DRAW:
  834. NOTREACHED() << "Invalid return DrawResult:" << draw_result;
  835. break;
  836. case DRAW_ABORTED_DRAINING_PIPELINE:
  837. case DRAW_SUCCESS:
  838. consecutive_checkerboard_animations_ = 0;
  839. forced_redraw_state_ = ForcedRedrawOnTimeoutState::IDLE;
  840. break;
  841. case DRAW_ABORTED_CHECKERBOARD_ANIMATIONS:
  842. DCHECK(!did_submit_in_last_frame_);
  843. needs_begin_main_frame_ = true;
  844. needs_redraw_ = true;
  845. consecutive_checkerboard_animations_++;
  846. if (consecutive_checkerboard_animations_ >=
  847. settings_.maximum_number_of_failed_draws_before_draw_is_forced &&
  848. forced_redraw_state_ == ForcedRedrawOnTimeoutState::IDLE) {
  849. // We need to force a draw, but it doesn't make sense to do this until
  850. // we've committed and have new textures.
  851. forced_redraw_state_ = ForcedRedrawOnTimeoutState::WAITING_FOR_COMMIT;
  852. }
  853. break;
  854. case DRAW_ABORTED_MISSING_HIGH_RES_CONTENT:
  855. DCHECK(!did_submit_in_last_frame_);
  856. // It's not clear whether this missing content is because of missing
  857. // pictures (which requires a commit) or because of memory pressure
  858. // removing textures (which might not). To be safe, request a commit
  859. // anyway.
  860. needs_begin_main_frame_ = true;
  861. break;
  862. }
  863. }
  864. void SchedulerStateMachine::WillDraw() {
  865. DCHECK(!did_draw_);
  866. WillDrawInternal();
  867. // Set this to true to proactively request a new BeginFrame. We can't set this
  868. // in WillDrawInternal because AbortDraw calls WillDrawInternal but shouldn't
  869. // request another frame.
  870. did_attempt_draw_in_last_frame_ = true;
  871. }
  872. void SchedulerStateMachine::DidDraw(DrawResult draw_result) {
  873. draw_succeeded_in_last_frame_ = draw_result == DRAW_SUCCESS;
  874. DidDrawInternal(draw_result);
  875. }
  876. void SchedulerStateMachine::SetNeedsImplSideInvalidation(
  877. bool needs_first_draw_on_activation) {
  878. needs_impl_side_invalidation_ = true;
  879. next_invalidation_needs_first_draw_on_activation_ |=
  880. needs_first_draw_on_activation;
  881. }
  882. void SchedulerStateMachine::SetMainThreadWantsBeginMainFrameNotExpectedMessages(
  883. bool new_state) {
  884. wants_begin_main_frame_not_expected_ = new_state;
  885. }
  886. void SchedulerStateMachine::AbortDraw() {
  887. // Pretend like the draw was successful.
  888. // Note: We may abort at any time and cannot DCHECK that
  889. // we haven't drawn in or swapped in the last frame here.
  890. WillDrawInternal();
  891. DidDrawInternal(DRAW_ABORTED_DRAINING_PIPELINE);
  892. }
  893. void SchedulerStateMachine::WillPrepareTiles() {
  894. needs_prepare_tiles_ = false;
  895. }
  896. void SchedulerStateMachine::WillBeginLayerTreeFrameSinkCreation() {
  897. DCHECK_EQ(layer_tree_frame_sink_state_, LayerTreeFrameSinkState::NONE);
  898. layer_tree_frame_sink_state_ = LayerTreeFrameSinkState::CREATING;
  899. // The following DCHECKs make sure we are in the proper quiescent state.
  900. // The pipeline should be flushed entirely before we start output
  901. // surface creation to avoid complicated corner cases.
  902. DCHECK(begin_main_frame_state_ == BeginMainFrameState::IDLE);
  903. DCHECK(!has_pending_tree_);
  904. DCHECK(!active_tree_needs_first_draw_);
  905. }
  906. void SchedulerStateMachine::WillInvalidateLayerTreeFrameSink() {
  907. DCHECK(!did_invalidate_layer_tree_frame_sink_);
  908. did_invalidate_layer_tree_frame_sink_ = true;
  909. last_frame_number_invalidate_layer_tree_frame_sink_performed_ =
  910. current_frame_number_;
  911. }
  912. bool SchedulerStateMachine::BeginFrameNeededForVideo() const {
  913. return video_needs_begin_frames_;
  914. }
  915. bool SchedulerStateMachine::BeginFrameNeeded() const {
  916. // We can't handle BeginFrames when output surface isn't initialized.
  917. // TODO(brianderson): Support output surface creation inside a BeginFrame.
  918. if (!HasInitializedLayerTreeFrameSink())
  919. return false;
  920. // The propagation of the needsBeginFrame signal to viz is inherently racy
  921. // with issuing the next BeginFrame. In full-pipe mode, it is important we
  922. // don't miss a BeginFrame because our needsBeginFrames signal propagated to
  923. // viz too slowly. To avoid the race, we simply always request BeginFrames
  924. // from viz.
  925. if (settings_.wait_for_all_pipeline_stages_before_draw)
  926. return true;
  927. // If we are not visible, we don't need BeginFrame messages.
  928. if (!visible_)
  929. return false;
  930. return BeginFrameRequiredForAction() || BeginFrameNeededForVideo() ||
  931. ProactiveBeginFrameWanted();
  932. }
  933. void SchedulerStateMachine::SetVideoNeedsBeginFrames(
  934. bool video_needs_begin_frames) {
  935. video_needs_begin_frames_ = video_needs_begin_frames;
  936. }
  937. void SchedulerStateMachine::SetDeferBeginMainFrame(
  938. bool defer_begin_main_frame) {
  939. defer_begin_main_frame_ = defer_begin_main_frame;
  940. }
  941. // These are the cases where we require a BeginFrame message to make progress
  942. // on requested actions.
  943. bool SchedulerStateMachine::BeginFrameRequiredForAction() const {
  944. // The forced draw respects our normal draw scheduling, so we need to
  945. // request a BeginImplFrame for it.
  946. if (forced_redraw_state_ == ForcedRedrawOnTimeoutState::WAITING_FOR_DRAW)
  947. return true;
  948. return needs_redraw_ || needs_one_begin_impl_frame_ ||
  949. (needs_begin_main_frame_ && !defer_begin_main_frame_) ||
  950. needs_impl_side_invalidation_;
  951. }
  952. // These are cases where we are very likely want a BeginFrame message in the
  953. // near future. Proactively requesting the BeginImplFrame helps hide the round
  954. // trip latency of the SetNeedsBeginFrame request that has to go to the
  955. // Browser.
  956. // This includes things like drawing soon, but might not actually have a new
  957. // frame to draw when we receive the next BeginImplFrame.
  958. bool SchedulerStateMachine::ProactiveBeginFrameWanted() const {
  959. // Do not be proactive when invisible.
  960. if (!visible_)
  961. return false;
  962. // We should proactively request a BeginImplFrame if a commit is pending
  963. // because we will want to draw if the commit completes quickly. Do not
  964. // request frames when commits are disabled, because the frame requests will
  965. // not provide the needed commit (and will wake up the process when it could
  966. // stay idle).
  967. // TODO(schenney) crbug.com/805798 This will need to change. We do want to
  968. // issue BeginMainFrames even if commits are deferred if this is during page
  969. // load and we want to run lifecycle updates in preparation for the first
  970. // commit. We probably need another flag to indicate that we are
  971. // pre-rendering the page or in a page navigation state.
  972. if ((begin_main_frame_state_ != BeginMainFrameState::IDLE) &&
  973. !defer_begin_main_frame_)
  974. return true;
  975. // If the pending tree activates quickly, we'll want a BeginImplFrame soon
  976. // to draw the new active tree.
  977. if (has_pending_tree_)
  978. return true;
  979. // Changing priorities may allow us to activate (given the new priorities),
  980. // which may result in a new frame.
  981. if (needs_prepare_tiles_)
  982. return true;
  983. // If we just tried to draw, it's likely that we are going to produce another
  984. // frame soon. This helps avoid negative glitches in our SetNeedsBeginFrame
  985. // requests, which may propagate to the BeginImplFrame provider and get
  986. // sampled at an inopportune time, delaying the next BeginImplFrame.
  987. if (did_attempt_draw_in_last_frame_)
  988. return true;
  989. // If the last commit was aborted because of early out (no updates), we should
  990. // still want a begin frame in case there is a commit coming again.
  991. if (last_commit_had_no_updates_)
  992. return true;
  993. // If there is active interaction happening (e.g. scroll/pinch), then keep
  994. // reqeusting frames.
  995. if (tree_priority_ == SMOOTHNESS_TAKES_PRIORITY)
  996. return true;
  997. return false;
  998. }
  999. void SchedulerStateMachine::OnBeginImplFrame(const viz::BeginFrameId& frame_id,
  1000. bool animate_only) {
  1001. begin_impl_frame_state_ = BeginImplFrameState::INSIDE_BEGIN_FRAME;
  1002. current_frame_number_++;
  1003. begin_frame_is_animate_only_ = animate_only;
  1004. // Cache the values from the previous impl frame before reseting them for this
  1005. // frame.
  1006. last_frame_events_.commit_had_no_updates = last_commit_had_no_updates_;
  1007. last_frame_events_.did_commit_during_frame = did_commit_during_frame_;
  1008. last_commit_had_no_updates_ = false;
  1009. did_attempt_draw_in_last_frame_ = false;
  1010. draw_succeeded_in_last_frame_ = false;
  1011. did_submit_in_last_frame_ = false;
  1012. needs_one_begin_impl_frame_ = false;
  1013. did_notify_begin_main_frame_not_expected_until_ = false;
  1014. did_notify_begin_main_frame_not_expected_soon_ = false;
  1015. did_send_begin_main_frame_for_current_frame_ = false;
  1016. did_commit_during_frame_ = false;
  1017. did_invalidate_layer_tree_frame_sink_ = false;
  1018. did_perform_impl_side_invalidation_ = false;
  1019. }
  1020. void SchedulerStateMachine::OnBeginImplFrameDeadline() {
  1021. begin_impl_frame_state_ = BeginImplFrameState::INSIDE_DEADLINE;
  1022. // Clear funnels for any actions we perform during the deadline.
  1023. did_draw_ = false;
  1024. }
  1025. void SchedulerStateMachine::OnBeginImplFrameIdle() {
  1026. begin_impl_frame_state_ = BeginImplFrameState::IDLE;
  1027. // Count any prepare tiles that happens in commits in between frames. We want
  1028. // to prevent a prepare tiles during the next frame's deadline in that case.
  1029. // This also allows synchronous compositor to do one PrepareTiles per draw.
  1030. // This is same as the old prepare tiles funnel behavior.
  1031. did_prepare_tiles_ = false;
  1032. // If a new or undrawn active tree is pending after the deadline,
  1033. // then the main thread is in a high latency mode.
  1034. main_thread_missed_last_deadline_ =
  1035. CommitPending() || has_pending_tree_ || active_tree_needs_first_draw_;
  1036. // If we're entering a state where we won't get BeginFrames set all the
  1037. // funnels so that we don't perform any actions that we shouldn't.
  1038. if (!BeginFrameNeeded())
  1039. did_send_begin_main_frame_for_current_frame_ = true;
  1040. }
  1041. SchedulerStateMachine::BeginImplFrameDeadlineMode
  1042. SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const {
  1043. const bool outside_begin_frame =
  1044. begin_impl_frame_state_ != BeginImplFrameState::INSIDE_BEGIN_FRAME;
  1045. if (settings_.using_synchronous_renderer_compositor || outside_begin_frame) {
  1046. // No deadline for synchronous compositor, or when outside the begin frame.
  1047. return BeginImplFrameDeadlineMode::NONE;
  1048. } else if (ShouldBlockDeadlineIndefinitely()) {
  1049. // We do not want to wait for a deadline because we're waiting for full
  1050. // pipeline to be flushed for headless.
  1051. return BeginImplFrameDeadlineMode::BLOCKED;
  1052. } else if (ShouldTriggerBeginImplFrameDeadlineImmediately()) {
  1053. // We are ready to draw a new active tree immediately because there's no
  1054. // commit expected or we're prioritizing active tree latency.
  1055. return BeginImplFrameDeadlineMode::IMMEDIATE;
  1056. } else if (needs_redraw_) {
  1057. // We have an animation or fast input path on the impl thread that wants
  1058. // to draw, so don't wait too long for a new active tree.
  1059. return BeginImplFrameDeadlineMode::REGULAR;
  1060. } else {
  1061. // The impl thread doesn't have anything it wants to draw and we are just
  1062. // waiting for a new active tree.
  1063. return BeginImplFrameDeadlineMode::LATE;
  1064. }
  1065. }
  1066. bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately()
  1067. const {
  1068. // If we aborted the current frame we should end the deadline right now.
  1069. if (ShouldAbortCurrentFrame() && !has_pending_tree_)
  1070. return true;
  1071. // Throttle the deadline on CompositorFrameAck since we wont draw and submit
  1072. // anyway.
  1073. if (IsDrawThrottled())
  1074. return false;
  1075. // Delay immediate draws when we have pending animation worklet updates to
  1076. // give them time to produce output before we draw.
  1077. if (processing_animation_worklets_for_active_tree_)
  1078. return false;
  1079. // In full-pipe mode, we just gave all pipeline stages a chance to contribute.
  1080. // We shouldn't wait any longer in any case - even if there are no updates.
  1081. if (settings_.wait_for_all_pipeline_stages_before_draw)
  1082. return true;
  1083. if (active_tree_needs_first_draw_)
  1084. return true;
  1085. if (!needs_redraw_)
  1086. return false;
  1087. // This is used to prioritize impl-thread draws when the main thread isn't
  1088. // producing anything, e.g., after an aborted commit. We also check that we
  1089. // don't have a pending tree -- otherwise we should give it a chance to
  1090. // activate.
  1091. // TODO(skyostil): Revisit this when we have more accurate deadline estimates.
  1092. if (!CommitPending() && !has_pending_tree_)
  1093. return true;
  1094. // Prioritize impl-thread draws in ImplLatencyTakesPriority mode.
  1095. if (ImplLatencyTakesPriority())
  1096. return true;
  1097. return false;
  1098. }
  1099. bool SchedulerStateMachine::ShouldBlockDeadlineIndefinitely() const {
  1100. if (!settings_.wait_for_all_pipeline_stages_before_draw &&
  1101. !settings_.commit_to_active_tree) {
  1102. return false;
  1103. }
  1104. // Avoid blocking for any reason if we don't have a layer tree frame sink or
  1105. // are invisible.
  1106. if (layer_tree_frame_sink_state_ == LayerTreeFrameSinkState::NONE)
  1107. return false;
  1108. if (!visible_)
  1109. return false;
  1110. // Do not wait for main frame to be ready for commits if in full-pipe mode,
  1111. // if we're deferring commits, as the main thread may be blocked on paused
  1112. // virtual time, causing deadlock against external frame control.
  1113. if (defer_begin_main_frame_ &&
  1114. settings_.wait_for_all_pipeline_stages_before_draw) {
  1115. return false;
  1116. }
  1117. // Wait for main frame if one is in progress or about to be started.
  1118. if (ShouldSendBeginMainFrame())
  1119. return true;
  1120. // TODO(schenney): Is the right way to handle main frame without commit
  1121. // to add a new begin_main_frame_state_?
  1122. if (begin_main_frame_state_ != BeginMainFrameState::IDLE)
  1123. return true;
  1124. // Wait for tiles and activation.
  1125. if (has_pending_tree_)
  1126. return true;
  1127. // Avoid blocking for draw when we can't draw. We block in the above cases
  1128. // even if we cannot draw, because we may still be waiting for the first
  1129. // active tree.
  1130. if (!can_draw_)
  1131. return false;
  1132. // Wait for remaining tiles and draw.
  1133. if (!active_tree_is_ready_to_draw_)
  1134. return true;
  1135. return false;
  1136. }
  1137. bool SchedulerStateMachine::IsDrawThrottled() const {
  1138. return pending_submit_frames_ >= kMaxPendingSubmitFrames;
  1139. }
  1140. void SchedulerStateMachine::SetVisible(bool visible) {
  1141. if (visible_ == visible)
  1142. return;
  1143. visible_ = visible;
  1144. if (visible)
  1145. main_thread_missed_last_deadline_ = false;
  1146. did_prepare_tiles_ = false;
  1147. }
  1148. void SchedulerStateMachine::SetBeginFrameSourcePaused(bool paused) {
  1149. begin_frame_source_paused_ = paused;
  1150. }
  1151. void SchedulerStateMachine::SetResourcelessSoftwareDraw(
  1152. bool resourceless_draw) {
  1153. resourceless_draw_ = resourceless_draw;
  1154. }
  1155. void SchedulerStateMachine::SetCanDraw(bool can_draw) {
  1156. can_draw_ = can_draw;
  1157. }
  1158. void SchedulerStateMachine::SetSkipDraw(bool skip_draw) {
  1159. skip_draw_ = skip_draw;
  1160. }
  1161. void SchedulerStateMachine::SetNeedsRedraw() {
  1162. needs_redraw_ = true;
  1163. }
  1164. void SchedulerStateMachine::SetNeedsPrepareTiles() {
  1165. if (!needs_prepare_tiles_) {
  1166. TRACE_EVENT0("cc", "SchedulerStateMachine::SetNeedsPrepareTiles");
  1167. needs_prepare_tiles_ = true;
  1168. }
  1169. }
  1170. void SchedulerStateMachine::DidSubmitCompositorFrame() {
  1171. TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("cc", "Scheduler:pending_submit_frames",
  1172. TRACE_ID_LOCAL(this), "pending_frames",
  1173. pending_submit_frames_);
  1174. DCHECK_LT(pending_submit_frames_, kMaxPendingSubmitFrames);
  1175. pending_submit_frames_++;
  1176. submit_frames_with_current_layer_tree_frame_sink_++;
  1177. did_submit_in_last_frame_ = true;
  1178. last_frame_number_submit_performed_ = current_frame_number_;
  1179. }
  1180. void SchedulerStateMachine::DidReceiveCompositorFrameAck() {
  1181. TRACE_EVENT_NESTABLE_ASYNC_END1("cc", "Scheduler:pending_submit_frames",
  1182. TRACE_ID_LOCAL(this), "pending_frames",
  1183. pending_submit_frames_);
  1184. pending_submit_frames_--;
  1185. }
  1186. void SchedulerStateMachine::SetTreePrioritiesAndScrollState(
  1187. TreePriority tree_priority,
  1188. ScrollHandlerState scroll_handler_state) {
  1189. tree_priority_ = tree_priority;
  1190. scroll_handler_state_ = scroll_handler_state;
  1191. }
  1192. void SchedulerStateMachine::SetCriticalBeginMainFrameToActivateIsFast(
  1193. bool is_fast) {
  1194. critical_begin_main_frame_to_activate_is_fast_ = is_fast;
  1195. }
  1196. bool SchedulerStateMachine::ImplLatencyTakesPriority() const {
  1197. // Attempt to synchronize with the main thread if it has a scroll listener
  1198. // and is fast.
  1199. if (ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER ==
  1200. scroll_handler_state_ &&
  1201. critical_begin_main_frame_to_activate_is_fast_)
  1202. return false;
  1203. // Don't wait for the main thread if we are prioritizing smoothness.
  1204. if (SMOOTHNESS_TAKES_PRIORITY == tree_priority_)
  1205. return true;
  1206. return false;
  1207. }
  1208. void SchedulerStateMachine::SetNeedsBeginMainFrame() {
  1209. needs_begin_main_frame_ = true;
  1210. }
  1211. void SchedulerStateMachine::SetNeedsOneBeginImplFrame() {
  1212. needs_one_begin_impl_frame_ = true;
  1213. }
  1214. void SchedulerStateMachine::NotifyReadyToCommit() {
  1215. DCHECK_EQ(begin_main_frame_state_, BeginMainFrameState::SENT);
  1216. begin_main_frame_state_ = BeginMainFrameState::READY_TO_COMMIT;
  1217. // In commit_to_active_tree mode, commit should happen right after BeginFrame,
  1218. // meaning when this function is called, next action should be commit.
  1219. if (settings_.commit_to_active_tree)
  1220. DCHECK(ShouldCommit());
  1221. }
  1222. void SchedulerStateMachine::BeginMainFrameAborted(CommitEarlyOutReason reason) {
  1223. DCHECK_EQ(begin_main_frame_state_, BeginMainFrameState::SENT);
  1224. // If the main thread aborted, it doesn't matter if the main thread missed
  1225. // the last deadline since it didn't have an update anyway.
  1226. main_thread_missed_last_deadline_ = false;
  1227. switch (reason) {
  1228. case CommitEarlyOutReason::ABORTED_NOT_VISIBLE:
  1229. case CommitEarlyOutReason::ABORTED_DEFERRED_MAIN_FRAME_UPDATE:
  1230. case CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT:
  1231. // TODO(schenney) For ABORTED_DEFERRED_COMMIT we will need to do
  1232. // something different because we have updated the main frame, but
  1233. // we have not committed it. So we do not need a begin main frame
  1234. // but we might need a commit.
  1235. // We might have top split the compositor commit code from frame updates,
  1236. // or track a pending commit separately from a pending main frame update.
  1237. begin_main_frame_state_ = BeginMainFrameState::IDLE;
  1238. SetNeedsBeginMainFrame();
  1239. return;
  1240. case CommitEarlyOutReason::FINISHED_NO_UPDATES:
  1241. WillCommit(/*commit_had_no_updates=*/true);
  1242. return;
  1243. }
  1244. }
  1245. void SchedulerStateMachine::DidPrepareTiles() {
  1246. needs_prepare_tiles_ = false;
  1247. did_prepare_tiles_ = true;
  1248. }
  1249. void SchedulerStateMachine::DidLoseLayerTreeFrameSink() {
  1250. if (layer_tree_frame_sink_state_ == LayerTreeFrameSinkState::NONE ||
  1251. layer_tree_frame_sink_state_ == LayerTreeFrameSinkState::CREATING)
  1252. return;
  1253. layer_tree_frame_sink_state_ = LayerTreeFrameSinkState::NONE;
  1254. needs_redraw_ = false;
  1255. }
  1256. bool SchedulerStateMachine::NotifyReadyToActivate() {
  1257. // It is not valid for clients to try and activate the pending tree whilst
  1258. // paint worklets are still being processed; the pending tree *must* be fully
  1259. // painted before it can ever be activated (even if e.g. it is not visible),
  1260. // because we cannot paint the active tree.
  1261. DCHECK(!processing_paint_worklets_for_pending_tree_);
  1262. if (!has_pending_tree_ || pending_tree_is_ready_for_activation_)
  1263. return false;
  1264. pending_tree_is_ready_for_activation_ = true;
  1265. return true;
  1266. }
  1267. bool SchedulerStateMachine::IsReadyToActivate() {
  1268. return pending_tree_is_ready_for_activation_;
  1269. }
  1270. void SchedulerStateMachine::NotifyReadyToDraw() {
  1271. active_tree_is_ready_to_draw_ = true;
  1272. }
  1273. void SchedulerStateMachine::NotifyAnimationWorkletStateChange(
  1274. AnimationWorkletState state,
  1275. TreeType tree) {
  1276. if (tree == TreeType::ACTIVE) {
  1277. switch (state) {
  1278. case AnimationWorkletState::PROCESSING:
  1279. DCHECK_GE(processing_animation_worklets_for_active_tree_, 0);
  1280. DCHECK_LE(processing_animation_worklets_for_active_tree_, 1);
  1281. processing_animation_worklets_for_active_tree_++;
  1282. break;
  1283. case AnimationWorkletState::IDLE:
  1284. DCHECK_LE(processing_animation_worklets_for_active_tree_, 2);
  1285. DCHECK_GE(processing_animation_worklets_for_active_tree_, 1);
  1286. processing_animation_worklets_for_active_tree_--;
  1287. }
  1288. } else {
  1289. processing_animation_worklets_for_pending_tree_ =
  1290. (state == AnimationWorkletState::PROCESSING);
  1291. }
  1292. }
  1293. void SchedulerStateMachine::NotifyPaintWorkletStateChange(
  1294. PaintWorkletState state) {
  1295. bool processing_paint_worklets_for_pending_tree =
  1296. (state == PaintWorkletState::PROCESSING);
  1297. DCHECK_NE(processing_paint_worklets_for_pending_tree,
  1298. processing_paint_worklets_for_pending_tree_);
  1299. processing_paint_worklets_for_pending_tree_ =
  1300. processing_paint_worklets_for_pending_tree;
  1301. }
  1302. void SchedulerStateMachine::DidCreateAndInitializeLayerTreeFrameSink() {
  1303. DCHECK_EQ(layer_tree_frame_sink_state_, LayerTreeFrameSinkState::CREATING);
  1304. layer_tree_frame_sink_state_ =
  1305. LayerTreeFrameSinkState::WAITING_FOR_FIRST_COMMIT;
  1306. if (did_create_and_initialize_first_layer_tree_frame_sink_) {
  1307. // TODO(boliu): See if we can remove this when impl-side painting is always
  1308. // on. Does anything on the main thread need to update after recreate?
  1309. needs_begin_main_frame_ = true;
  1310. }
  1311. did_create_and_initialize_first_layer_tree_frame_sink_ = true;
  1312. pending_submit_frames_ = 0;
  1313. submit_frames_with_current_layer_tree_frame_sink_ = 0;
  1314. main_thread_missed_last_deadline_ = false;
  1315. }
  1316. bool SchedulerStateMachine::HasInitializedLayerTreeFrameSink() const {
  1317. switch (layer_tree_frame_sink_state_) {
  1318. case LayerTreeFrameSinkState::NONE:
  1319. case LayerTreeFrameSinkState::CREATING:
  1320. return false;
  1321. case LayerTreeFrameSinkState::ACTIVE:
  1322. case LayerTreeFrameSinkState::WAITING_FOR_FIRST_COMMIT:
  1323. case LayerTreeFrameSinkState::WAITING_FOR_FIRST_ACTIVATION:
  1324. return true;
  1325. }
  1326. NOTREACHED();
  1327. return false;
  1328. }
  1329. } // namespace cc