Revert 264226 "Reduce dependency of TiclInvalidationService on P..."
[chromium-blink-merge.git] / cc / scheduler / scheduler_state_machine_unittest.cc
blob060269d11e63d1cab9ac13b5c9fceb4c980e08e4
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.
5 #include "cc/scheduler/scheduler_state_machine.h"
7 #include "cc/scheduler/scheduler.h"
8 #include "testing/gtest/include/gtest/gtest.h"
10 #define EXPECT_ACTION_UPDATE_STATE(action) \
11 EXPECT_EQ(action, state.NextAction()) << *state.AsValue(); \
12 if (action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE || \
13 action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED) { \
14 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE, \
15 state.begin_impl_frame_state()) \
16 << *state.AsValue(); \
17 } \
18 state.UpdateState(action); \
19 if (action == SchedulerStateMachine::ACTION_NONE) { \
20 if (state.begin_impl_frame_state() == \
21 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) \
22 state.OnBeginImplFrameDeadlinePending(); \
23 if (state.begin_impl_frame_state() == \
24 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) \
25 state.OnBeginImplFrameIdle(); \
28 namespace cc {
30 namespace {
32 const SchedulerStateMachine::BeginImplFrameState all_begin_impl_frame_states[] =
33 {SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE,
34 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
35 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
36 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE, };
38 const SchedulerStateMachine::CommitState all_commit_states[] = {
39 SchedulerStateMachine::COMMIT_STATE_IDLE,
40 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
41 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED,
42 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
43 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION,
44 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW};
46 // Exposes the protected state fields of the SchedulerStateMachine for testing
47 class StateMachine : public SchedulerStateMachine {
48 public:
49 explicit StateMachine(const SchedulerSettings& scheduler_settings)
50 : SchedulerStateMachine(scheduler_settings) {}
52 void CreateAndInitializeOutputSurfaceWithActivatedCommit() {
53 DidCreateAndInitializeOutputSurface();
54 output_surface_state_ = OUTPUT_SURFACE_ACTIVE;
57 void SetCommitState(CommitState cs) { commit_state_ = cs; }
58 CommitState CommitState() const { return commit_state_; }
60 ForcedRedrawOnTimeoutState ForcedRedrawState() const {
61 return forced_redraw_state_;
64 void SetBeginImplFrameState(BeginImplFrameState bifs) {
65 begin_impl_frame_state_ = bifs;
68 BeginImplFrameState begin_impl_frame_state() const {
69 return begin_impl_frame_state_;
72 OutputSurfaceState output_surface_state() const {
73 return output_surface_state_;
76 void SetReadbackState(SynchronousReadbackState rs) { readback_state_ = rs; }
77 SynchronousReadbackState readback_state() const { return readback_state_; }
79 bool NeedsCommit() const { return needs_commit_; }
81 void SetNeedsRedraw(bool b) { needs_redraw_ = b; }
83 void SetNeedsForcedRedrawForTimeout(bool b) {
84 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_COMMIT;
85 active_tree_needs_first_draw_ = true;
87 bool NeedsForcedRedrawForTimeout() const {
88 return forced_redraw_state_ != FORCED_REDRAW_STATE_IDLE;
91 void SetNeedsForcedRedrawForReadback() {
92 readback_state_ = READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK;
93 active_tree_needs_first_draw_ = true;
96 bool NeedsForcedRedrawForReadback() const {
97 return readback_state_ != READBACK_STATE_IDLE;
100 void SetActiveTreeNeedsFirstDraw(bool needs_first_draw) {
101 active_tree_needs_first_draw_ = needs_first_draw;
104 bool CanDraw() const { return can_draw_; }
105 bool Visible() const { return visible_; }
107 bool PendingActivationsShouldBeForced() const {
108 return SchedulerStateMachine::PendingActivationsShouldBeForced();
111 void SetHasPendingTree(bool has_pending_tree) {
112 has_pending_tree_ = has_pending_tree;
116 TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) {
117 SchedulerSettings default_scheduler_settings;
119 // If no commit needed, do nothing.
121 StateMachine state(default_scheduler_settings);
122 state.SetCanStart();
123 EXPECT_ACTION_UPDATE_STATE(
124 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION)
125 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
126 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
127 state.SetNeedsRedraw(false);
128 state.SetVisible(true);
130 EXPECT_FALSE(state.BeginFrameNeeded());
132 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
133 EXPECT_FALSE(state.BeginFrameNeeded());
134 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
136 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
137 state.OnBeginImplFrameDeadline();
140 // If commit requested but can_start is still false, do nothing.
142 StateMachine state(default_scheduler_settings);
143 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
144 state.SetNeedsRedraw(false);
145 state.SetVisible(true);
146 state.SetNeedsCommit();
148 EXPECT_FALSE(state.BeginFrameNeeded());
150 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
151 EXPECT_FALSE(state.BeginFrameNeeded());
152 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
153 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
154 state.OnBeginImplFrameDeadline();
157 // If commit requested, begin a main frame.
159 StateMachine state(default_scheduler_settings);
160 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
161 state.SetCanStart();
162 state.UpdateState(state.NextAction());
163 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
164 state.SetNeedsRedraw(false);
165 state.SetVisible(true);
166 state.SetNeedsCommit();
168 EXPECT_TRUE(state.BeginFrameNeeded());
170 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
171 EXPECT_ACTION_UPDATE_STATE(
172 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
175 // Begin the frame, make sure needs_commit and commit_state update correctly.
177 StateMachine state(default_scheduler_settings);
178 state.SetCanStart();
179 state.UpdateState(state.NextAction());
180 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
181 state.SetVisible(true);
182 state.UpdateState(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
183 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
184 state.CommitState());
185 EXPECT_FALSE(state.NeedsCommit());
189 // Explicitly test main_frame_before_draw_enabled = false
190 TEST(SchedulerStateMachineTest, MainFrameBeforeDrawDisabled) {
191 SchedulerSettings scheduler_settings;
192 scheduler_settings.impl_side_painting = true;
193 scheduler_settings.main_frame_before_draw_enabled = false;
194 StateMachine state(scheduler_settings);
195 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
196 state.SetCanStart();
197 state.UpdateState(state.NextAction());
198 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
199 state.SetNeedsRedraw(false);
200 state.SetVisible(true);
201 state.SetCanDraw(true);
202 state.SetNeedsCommit();
204 EXPECT_TRUE(state.BeginFrameNeeded());
206 // Commit to the pending tree.
207 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
208 EXPECT_ACTION_UPDATE_STATE(
209 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
210 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
211 state.NotifyBeginMainFrameStarted();
212 state.NotifyReadyToCommit();
213 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
214 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
215 EXPECT_EQ(state.CommitState(),
216 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
218 state.OnBeginImplFrameDeadline();
219 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
220 EXPECT_EQ(state.CommitState(),
221 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
223 // Verify that the next commit doesn't start until the previous
224 // commit has been drawn.
225 state.SetNeedsCommit();
226 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
227 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
229 // Verify NotifyReadyToActivate unblocks activation, draw, and
230 // commit in that order.
231 state.NotifyReadyToActivate();
232 EXPECT_ACTION_UPDATE_STATE(
233 SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE);
234 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
235 EXPECT_EQ(state.CommitState(),
236 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
238 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
239 state.OnBeginImplFrameDeadline();
240 EXPECT_ACTION_UPDATE_STATE(
241 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
242 EXPECT_EQ(state.CommitState(), SchedulerStateMachine::COMMIT_STATE_IDLE);
243 EXPECT_ACTION_UPDATE_STATE(
244 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
245 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
246 EXPECT_EQ(state.CommitState(),
247 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
249 state.NotifyBeginMainFrameStarted();
250 state.NotifyReadyToCommit();
251 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
252 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
253 EXPECT_EQ(state.CommitState(),
254 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
257 // Explicitly test main_frame_before_activation_enabled = true
258 TEST(SchedulerStateMachineTest, MainFrameBeforeActivationEnabled) {
259 SchedulerSettings scheduler_settings;
260 scheduler_settings.impl_side_painting = true;
261 scheduler_settings.main_frame_before_activation_enabled = true;
262 StateMachine state(scheduler_settings);
263 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
264 state.SetCanStart();
265 state.UpdateState(state.NextAction());
266 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
267 state.SetNeedsRedraw(false);
268 state.SetVisible(true);
269 state.SetCanDraw(true);
270 state.SetNeedsCommit();
272 EXPECT_TRUE(state.BeginFrameNeeded());
274 // Commit to the pending tree.
275 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
276 EXPECT_ACTION_UPDATE_STATE(
277 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
278 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
280 state.NotifyBeginMainFrameStarted();
281 state.NotifyReadyToCommit();
282 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
283 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
284 EXPECT_EQ(state.CommitState(), SchedulerStateMachine::COMMIT_STATE_IDLE);
286 state.OnBeginImplFrameDeadline();
287 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
289 // Verify that the next commit starts while there is still a pending tree.
290 state.SetNeedsCommit();
291 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
292 EXPECT_ACTION_UPDATE_STATE(
293 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
294 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
296 // Verify the pending commit doesn't overwrite the pending
297 // tree until the pending tree has been activated.
298 state.NotifyBeginMainFrameStarted();
299 state.NotifyReadyToCommit();
300 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
302 // Verify NotifyReadyToActivate unblocks activation, draw, and
303 // commit in that order.
304 state.NotifyReadyToActivate();
305 EXPECT_ACTION_UPDATE_STATE(
306 SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE);
307 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
309 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
310 state.OnBeginImplFrameDeadline();
311 EXPECT_ACTION_UPDATE_STATE(
312 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
313 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
314 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
315 EXPECT_EQ(state.CommitState(), SchedulerStateMachine::COMMIT_STATE_IDLE);
318 TEST(SchedulerStateMachineTest,
319 TestFailedDrawForAnimationCheckerboardSetsNeedsCommitAndDoesNotDrawAgain) {
320 SchedulerSettings default_scheduler_settings;
321 StateMachine state(default_scheduler_settings);
322 state.SetCanStart();
323 state.UpdateState(state.NextAction());
324 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
325 state.SetVisible(true);
326 state.SetCanDraw(true);
327 state.SetNeedsRedraw(true);
328 EXPECT_TRUE(state.RedrawPending());
329 EXPECT_TRUE(state.BeginFrameNeeded());
330 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
331 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
332 state.OnBeginImplFrameDeadline();
334 // We're drawing now.
335 EXPECT_ACTION_UPDATE_STATE(
336 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
337 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
339 EXPECT_FALSE(state.RedrawPending());
340 EXPECT_FALSE(state.CommitPending());
342 // Failing the draw makes us require a commit.
343 state.DidDrawIfPossibleCompleted(
344 DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
345 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
346 EXPECT_ACTION_UPDATE_STATE(
347 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
348 EXPECT_TRUE(state.RedrawPending());
349 EXPECT_TRUE(state.CommitPending());
352 TEST(SchedulerStateMachineTest, TestFailedDrawForMissingHighResNeedsCommit) {
353 SchedulerSettings default_scheduler_settings;
354 StateMachine state(default_scheduler_settings);
355 state.SetCanStart();
356 state.UpdateState(state.NextAction());
357 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
358 state.SetVisible(true);
359 state.SetCanDraw(true);
360 state.SetNeedsRedraw(true);
361 EXPECT_TRUE(state.RedrawPending());
362 EXPECT_TRUE(state.BeginFrameNeeded());
364 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
365 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
366 state.OnBeginImplFrameDeadline();
367 EXPECT_ACTION_UPDATE_STATE(
368 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
369 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
370 EXPECT_FALSE(state.RedrawPending());
371 EXPECT_FALSE(state.CommitPending());
373 // Missing high res content requires a commit (but not a redraw)
374 state.DidDrawIfPossibleCompleted(
375 DrawSwapReadbackResult::DRAW_ABORTED_MISSING_HIGH_RES_CONTENT);
376 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
377 EXPECT_ACTION_UPDATE_STATE(
378 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
379 EXPECT_FALSE(state.RedrawPending());
380 EXPECT_TRUE(state.CommitPending());
383 TEST(SchedulerStateMachineTest,
384 TestsetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw) {
385 SchedulerSettings default_scheduler_settings;
386 StateMachine state(default_scheduler_settings);
387 state.SetCanStart();
388 state.UpdateState(state.NextAction());
389 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
391 state.SetVisible(true);
392 state.SetCanDraw(true);
393 state.SetNeedsRedraw(true);
394 EXPECT_TRUE(state.RedrawPending());
395 EXPECT_TRUE(state.BeginFrameNeeded());
396 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
397 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
398 state.OnBeginImplFrameDeadline();
400 // We're drawing now.
401 EXPECT_ACTION_UPDATE_STATE(
402 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
403 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
404 EXPECT_FALSE(state.RedrawPending());
405 EXPECT_FALSE(state.CommitPending());
407 // While still in the same BeginMainFrame callback on the main thread,
408 // set needs redraw again. This should not redraw.
409 state.SetNeedsRedraw(true);
410 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
412 // Failing the draw for animation checkerboards makes us require a commit.
413 state.DidDrawIfPossibleCompleted(
414 DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
415 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
416 EXPECT_ACTION_UPDATE_STATE(
417 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
418 EXPECT_TRUE(state.RedrawPending());
421 void TestFailedDrawsEventuallyForceDrawAfterNextCommit(
422 bool main_frame_before_draw_enabled) {
423 SchedulerSettings scheduler_settings;
424 scheduler_settings.main_frame_before_draw_enabled =
425 main_frame_before_draw_enabled;
426 scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ = 1;
427 StateMachine state(scheduler_settings);
428 state.SetCanStart();
429 state.UpdateState(state.NextAction());
430 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
431 state.SetVisible(true);
432 state.SetCanDraw(true);
434 // Start a commit.
435 state.SetNeedsCommit();
436 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
437 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
438 EXPECT_ACTION_UPDATE_STATE(
439 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
440 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
441 EXPECT_TRUE(state.CommitPending());
443 // Then initiate a draw.
444 state.SetNeedsRedraw(true);
445 state.OnBeginImplFrameDeadline();
446 EXPECT_ACTION_UPDATE_STATE(
447 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
449 // Fail the draw.
450 state.DidDrawIfPossibleCompleted(
451 DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
452 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
453 EXPECT_TRUE(state.BeginFrameNeeded());
454 EXPECT_TRUE(state.RedrawPending());
455 // But the commit is ongoing.
456 EXPECT_TRUE(state.CommitPending());
458 // Finish the commit. Note, we should not yet be forcing a draw, but should
459 // continue the commit as usual.
460 state.NotifyBeginMainFrameStarted();
461 state.NotifyReadyToCommit();
462 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
463 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
464 EXPECT_TRUE(state.RedrawPending());
466 // The redraw should be forced at the end of the next BeginImplFrame.
467 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
468 if (main_frame_before_draw_enabled) {
469 EXPECT_ACTION_UPDATE_STATE(
470 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
472 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
473 state.OnBeginImplFrameDeadline();
474 EXPECT_ACTION_UPDATE_STATE(
475 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED);
478 TEST(SchedulerStateMachineTest,
479 TestFailedDrawsEventuallyForceDrawAfterNextCommit) {
480 bool main_frame_before_draw_enabled = false;
481 TestFailedDrawsEventuallyForceDrawAfterNextCommit(
482 main_frame_before_draw_enabled);
485 TEST(SchedulerStateMachineTest,
486 TestFailedDrawsEventuallyForceDrawAfterNextCommit_CommitBeforeDraw) {
487 bool main_frame_before_draw_enabled = true;
488 TestFailedDrawsEventuallyForceDrawAfterNextCommit(
489 main_frame_before_draw_enabled);
492 TEST(SchedulerStateMachineTest, TestFailedDrawsDoNotRestartForcedDraw) {
493 SchedulerSettings scheduler_settings;
494 int draw_limit = 1;
495 scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ =
496 draw_limit;
497 scheduler_settings.impl_side_painting = true;
498 StateMachine state(scheduler_settings);
499 state.SetCanStart();
500 state.UpdateState(state.NextAction());
501 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
502 state.SetVisible(true);
503 state.SetCanDraw(true);
505 // Start a commit.
506 state.SetNeedsCommit();
507 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
508 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
509 EXPECT_ACTION_UPDATE_STATE(
510 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
511 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
512 EXPECT_TRUE(state.CommitPending());
514 // Then initiate a draw.
515 state.SetNeedsRedraw(true);
516 state.OnBeginImplFrameDeadline();
517 EXPECT_ACTION_UPDATE_STATE(
518 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
520 // Fail the draw enough times to force a redraw,
521 // then once more for good measure.
522 for (int i = 0; i < draw_limit + 1; ++i) {
523 state.DidDrawIfPossibleCompleted(
524 DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
526 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
527 EXPECT_TRUE(state.BeginFrameNeeded());
528 EXPECT_TRUE(state.RedrawPending());
529 // But the commit is ongoing.
530 EXPECT_TRUE(state.CommitPending());
531 EXPECT_TRUE(state.ForcedRedrawState() ==
532 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_COMMIT);
534 state.NotifyBeginMainFrameStarted();
535 state.NotifyReadyToCommit();
536 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
537 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
538 EXPECT_TRUE(state.RedrawPending());
539 EXPECT_FALSE(state.CommitPending());
541 // Now force redraw should be in waiting for activation
542 EXPECT_TRUE(state.ForcedRedrawState() ==
543 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION);
545 // After failing additional draws, we should still be in a forced
546 // redraw, but not back in WAITING_FOR_COMMIT.
547 for (int i = 0; i < draw_limit + 1; ++i) {
548 state.DidDrawIfPossibleCompleted(
549 DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
551 EXPECT_TRUE(state.RedrawPending());
552 EXPECT_TRUE(state.ForcedRedrawState() ==
553 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION);
556 TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedInNextBeginImplFrame) {
557 SchedulerSettings default_scheduler_settings;
558 StateMachine state(default_scheduler_settings);
559 state.SetCanStart();
560 state.UpdateState(state.NextAction());
561 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
562 state.SetVisible(true);
563 state.SetCanDraw(true);
565 // Start a draw.
566 state.SetNeedsRedraw(true);
567 EXPECT_TRUE(state.BeginFrameNeeded());
568 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
569 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
570 state.OnBeginImplFrameDeadline();
571 EXPECT_TRUE(state.RedrawPending());
572 EXPECT_ACTION_UPDATE_STATE(
573 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
575 // Failing the draw for animation checkerboards makes us require a commit.
576 state.DidDrawIfPossibleCompleted(
577 DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
578 EXPECT_ACTION_UPDATE_STATE(
579 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
580 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
581 EXPECT_TRUE(state.RedrawPending());
583 // We should not be trying to draw again now, but we have a commit pending.
584 EXPECT_TRUE(state.BeginFrameNeeded());
585 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
586 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
588 // We should try to draw again at the end of the next BeginImplFrame on
589 // the impl thread.
590 state.OnBeginImplFrameDeadline();
591 EXPECT_ACTION_UPDATE_STATE(
592 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
593 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
596 TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) {
597 SchedulerSettings default_scheduler_settings;
598 StateMachine state(default_scheduler_settings);
599 state.SetCanStart();
600 state.UpdateState(state.NextAction());
601 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
602 state.SetVisible(true);
603 state.SetCanDraw(true);
604 state.SetNeedsRedraw(true);
606 // Draw the first frame.
607 EXPECT_TRUE(state.BeginFrameNeeded());
608 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
609 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
611 state.OnBeginImplFrameDeadline();
612 EXPECT_ACTION_UPDATE_STATE(
613 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
614 state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS);
615 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
617 // Before the next BeginImplFrame, set needs redraw again.
618 // This should not redraw until the next BeginImplFrame.
619 state.SetNeedsRedraw(true);
620 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
622 // Move to another frame. This should now draw.
623 EXPECT_TRUE(state.BeginFrameNeeded());
624 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
626 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
628 state.OnBeginImplFrameDeadline();
629 EXPECT_ACTION_UPDATE_STATE(
630 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
631 state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS);
632 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
634 // We just swapped, so we should proactively request another BeginImplFrame.
635 EXPECT_TRUE(state.BeginFrameNeeded());
638 TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) {
639 SchedulerSettings default_scheduler_settings;
641 // When not in BeginImplFrame deadline, or in BeginImplFrame deadline
642 // but not visible, don't draw.
643 size_t num_commit_states =
644 sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState);
645 size_t num_begin_impl_frame_states =
646 sizeof(all_begin_impl_frame_states) /
647 sizeof(SchedulerStateMachine::BeginImplFrameState);
648 for (size_t i = 0; i < num_commit_states; ++i) {
649 for (size_t j = 0; j < num_begin_impl_frame_states; ++j) {
650 StateMachine state(default_scheduler_settings);
651 state.SetCanStart();
652 state.UpdateState(state.NextAction());
653 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
654 state.SetCommitState(all_commit_states[i]);
655 state.SetBeginImplFrameState(all_begin_impl_frame_states[j]);
656 bool visible =
657 (all_begin_impl_frame_states[j] !=
658 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
659 state.SetVisible(visible);
661 // Case 1: needs_commit=false
662 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
663 state.NextAction());
665 // Case 2: needs_commit=true
666 state.SetNeedsCommit();
667 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
668 state.NextAction())
669 << *state.AsValue();
673 // When in BeginImplFrame deadline we should always draw for SetNeedsRedraw
674 // except if we're ready to commit, in which case we expect a commit first.
675 // SetNeedsForcedRedrawForReadback should take precedence over all and
676 // issue a readback.
677 for (size_t i = 0; i < num_commit_states; ++i) {
678 for (size_t j = 0; j < 2; ++j) {
679 bool request_readback = j;
681 StateMachine state(default_scheduler_settings);
682 state.SetCanStart();
683 state.UpdateState(state.NextAction());
684 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
685 state.SetCanDraw(true);
686 state.SetCommitState(all_commit_states[i]);
687 state.SetBeginImplFrameState(
688 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
689 if (request_readback) {
690 state.SetNeedsForcedRedrawForReadback();
691 } else {
692 state.SetNeedsRedraw(true);
693 state.SetVisible(true);
696 SchedulerStateMachine::Action expected_action;
697 if (request_readback) {
698 expected_action = SchedulerStateMachine::ACTION_DRAW_AND_READBACK;
699 } else if (all_commit_states[i] ==
700 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT) {
701 expected_action = SchedulerStateMachine::ACTION_COMMIT;
702 } else {
703 expected_action =
704 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
707 // Case 1: needs_commit=false.
708 EXPECT_NE(state.BeginFrameNeeded(), request_readback) << *state.AsValue();
709 EXPECT_EQ(state.NextAction(), expected_action) << *state.AsValue();
711 // Case 2: needs_commit=true.
712 state.SetNeedsCommit();
713 EXPECT_NE(state.BeginFrameNeeded(), request_readback) << *state.AsValue();
714 EXPECT_EQ(state.NextAction(), expected_action) << *state.AsValue();
719 TEST(SchedulerStateMachineTest, TestNoCommitStatesRedrawWhenInvisible) {
720 SchedulerSettings default_scheduler_settings;
722 size_t num_commit_states =
723 sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState);
724 for (size_t i = 0; i < num_commit_states; ++i) {
725 // There shouldn't be any drawing regardless of BeginImplFrame.
726 for (size_t j = 0; j < 2; ++j) {
727 StateMachine state(default_scheduler_settings);
728 state.SetCanStart();
729 state.UpdateState(state.NextAction());
730 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
731 state.SetCommitState(all_commit_states[i]);
732 state.SetVisible(false);
733 state.SetNeedsRedraw(true);
734 if (j == 1) {
735 state.SetBeginImplFrameState(
736 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
739 // Case 1: needs_commit=false.
740 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
741 state.NextAction());
743 // Case 2: needs_commit=true.
744 state.SetNeedsCommit();
745 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
746 state.NextAction())
747 << *state.AsValue();
752 TEST(SchedulerStateMachineTest, TestCanRedraw_StopsDraw) {
753 SchedulerSettings default_scheduler_settings;
755 size_t num_commit_states =
756 sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState);
757 for (size_t i = 0; i < num_commit_states; ++i) {
758 // There shouldn't be any drawing regardless of BeginImplFrame.
759 for (size_t j = 0; j < 2; ++j) {
760 StateMachine state(default_scheduler_settings);
761 state.SetCanStart();
762 state.UpdateState(state.NextAction());
763 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
764 state.SetCommitState(all_commit_states[i]);
765 state.SetVisible(false);
766 state.SetNeedsRedraw(true);
767 if (j == 1)
768 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
770 state.SetCanDraw(false);
771 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
772 state.NextAction());
777 TEST(SchedulerStateMachineTest,
778 TestCanRedrawWithWaitingForFirstDrawMakesProgress) {
779 SchedulerSettings default_scheduler_settings;
780 StateMachine state(default_scheduler_settings);
781 state.SetCanStart();
782 state.UpdateState(state.NextAction());
783 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
785 state.SetActiveTreeNeedsFirstDraw(true);
786 state.SetNeedsCommit();
787 state.SetNeedsRedraw(true);
788 state.SetVisible(true);
789 state.SetCanDraw(false);
790 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
791 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
792 EXPECT_ACTION_UPDATE_STATE(
793 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
794 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
795 state.NotifyBeginMainFrameStarted();
796 state.NotifyReadyToCommit();
797 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
798 state.OnBeginImplFrameDeadline();
799 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
800 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
803 void TestSetNeedsCommitIsNotLost(bool main_frame_before_draw_enabled) {
804 SchedulerSettings scheduler_settings;
805 scheduler_settings.main_frame_before_draw_enabled =
806 main_frame_before_draw_enabled;
807 StateMachine state(scheduler_settings);
808 state.SetCanStart();
809 state.UpdateState(state.NextAction());
810 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
811 state.SetNeedsCommit();
812 state.SetVisible(true);
813 state.SetCanDraw(true);
815 EXPECT_TRUE(state.BeginFrameNeeded());
817 // Begin the frame.
818 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
819 EXPECT_ACTION_UPDATE_STATE(
820 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
821 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
822 state.CommitState());
824 // Now, while the frame is in progress, set another commit.
825 state.SetNeedsCommit();
826 EXPECT_TRUE(state.NeedsCommit());
828 // Let the frame finish.
829 state.NotifyBeginMainFrameStarted();
830 state.NotifyReadyToCommit();
831 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
832 state.CommitState());
834 // Expect to commit regardless of BeginImplFrame state.
835 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
836 state.begin_impl_frame_state());
837 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
839 state.OnBeginImplFrameDeadlinePending();
840 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
841 state.begin_impl_frame_state());
842 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
844 state.OnBeginImplFrameDeadline();
845 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE,
846 state.begin_impl_frame_state());
847 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
849 state.OnBeginImplFrameIdle();
850 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE,
851 state.begin_impl_frame_state());
852 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
854 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
855 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
856 state.begin_impl_frame_state());
857 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
859 // Finish the commit, then make sure we start the next commit immediately
860 // and draw on the next BeginImplFrame.
861 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
862 if (main_frame_before_draw_enabled) {
863 EXPECT_ACTION_UPDATE_STATE(
864 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
866 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
868 state.OnBeginImplFrameDeadline();
870 EXPECT_TRUE(state.active_tree_needs_first_draw());
871 EXPECT_ACTION_UPDATE_STATE(
872 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
873 state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS);
874 if (!main_frame_before_draw_enabled) {
875 EXPECT_ACTION_UPDATE_STATE(
876 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
878 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
881 TEST(SchedulerStateMachineTest, TestSetNeedsCommitIsNotLost) {
882 bool main_frame_before_draw_enabled = false;
883 TestSetNeedsCommitIsNotLost(main_frame_before_draw_enabled);
886 TEST(SchedulerStateMachineTest, TestSetNeedsCommitIsNotLost_CommitBeforeDraw) {
887 bool main_frame_before_draw_enabled = true;
888 TestSetNeedsCommitIsNotLost(main_frame_before_draw_enabled);
891 TEST(SchedulerStateMachineTest, TestFullCycle) {
892 SchedulerSettings default_scheduler_settings;
893 StateMachine state(default_scheduler_settings);
894 state.SetCanStart();
895 state.UpdateState(state.NextAction());
896 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
897 state.SetVisible(true);
898 state.SetCanDraw(true);
900 // Start clean and set commit.
901 state.SetNeedsCommit();
903 // Begin the frame.
904 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
905 EXPECT_ACTION_UPDATE_STATE(
906 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
907 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
908 state.CommitState());
909 EXPECT_FALSE(state.NeedsCommit());
910 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
912 // Tell the scheduler the frame finished.
913 state.NotifyBeginMainFrameStarted();
914 state.NotifyReadyToCommit();
915 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
916 state.CommitState());
918 // Commit.
919 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
920 EXPECT_TRUE(state.active_tree_needs_first_draw());
921 EXPECT_TRUE(state.needs_redraw());
923 // Expect to do nothing until BeginImplFrame deadline
924 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
926 // At BeginImplFrame deadline, draw.
927 state.OnBeginImplFrameDeadline();
928 EXPECT_ACTION_UPDATE_STATE(
929 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
930 state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS);
932 // Should be synchronized, no draw needed, no action needed.
933 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
934 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
935 EXPECT_FALSE(state.needs_redraw());
938 TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween) {
939 SchedulerSettings default_scheduler_settings;
940 StateMachine state(default_scheduler_settings);
941 state.SetCanStart();
942 state.UpdateState(state.NextAction());
943 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
944 state.SetVisible(true);
945 state.SetCanDraw(true);
947 // Start clean and set commit.
948 state.SetNeedsCommit();
950 // Begin the frame.
951 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
952 EXPECT_ACTION_UPDATE_STATE(
953 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
954 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
955 state.CommitState());
956 EXPECT_FALSE(state.NeedsCommit());
957 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
959 // Request another commit while the commit is in flight.
960 state.SetNeedsCommit();
961 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
963 // Tell the scheduler the frame finished.
964 state.NotifyBeginMainFrameStarted();
965 state.NotifyReadyToCommit();
966 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
967 state.CommitState());
969 // First commit.
970 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
971 EXPECT_TRUE(state.active_tree_needs_first_draw());
972 EXPECT_TRUE(state.needs_redraw());
974 // Expect to do nothing until BeginImplFrame deadline.
975 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
977 // At BeginImplFrame deadline, draw.
978 state.OnBeginImplFrameDeadline();
979 EXPECT_ACTION_UPDATE_STATE(
980 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
981 state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS);
983 // Should be synchronized, no draw needed, no action needed.
984 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
985 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
986 EXPECT_FALSE(state.needs_redraw());
988 // Next BeginImplFrame should initiate second commit.
989 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
990 EXPECT_ACTION_UPDATE_STATE(
991 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
994 TEST(SchedulerStateMachineTest, TestRequestCommitInvisible) {
995 SchedulerSettings default_scheduler_settings;
996 StateMachine state(default_scheduler_settings);
997 state.SetCanStart();
998 state.UpdateState(state.NextAction());
999 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1000 state.SetNeedsCommit();
1001 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1004 TEST(SchedulerStateMachineTest, TestGoesInvisibleBeforeFinishCommit) {
1005 SchedulerSettings default_scheduler_settings;
1006 StateMachine state(default_scheduler_settings);
1007 state.SetCanStart();
1008 state.UpdateState(state.NextAction());
1009 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1010 state.SetVisible(true);
1011 state.SetCanDraw(true);
1013 // Start clean and set commit.
1014 state.SetNeedsCommit();
1016 // Begin the frame while visible.
1017 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1018 EXPECT_ACTION_UPDATE_STATE(
1019 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1020 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
1021 state.CommitState());
1022 EXPECT_FALSE(state.NeedsCommit());
1023 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1025 // Become invisible and abort BeginMainFrame.
1026 state.SetVisible(false);
1027 state.BeginMainFrameAborted(false);
1029 // We should now be back in the idle state as if we never started the frame.
1030 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1031 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1033 // We shouldn't do anything on the BeginImplFrame deadline.
1034 state.OnBeginImplFrameDeadline();
1035 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1037 // Become visible again.
1038 state.SetVisible(true);
1040 // Although we have aborted on this frame and haven't cancelled the commit
1041 // (i.e. need another), don't send another BeginMainFrame yet.
1042 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1043 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1044 EXPECT_TRUE(state.NeedsCommit());
1046 // Start a new frame.
1047 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1048 EXPECT_ACTION_UPDATE_STATE(
1049 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1051 // We should be starting the commit now.
1052 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
1053 state.CommitState());
1054 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1057 TEST(SchedulerStateMachineTest, AbortBeginMainFrameAndCancelCommit) {
1058 SchedulerSettings default_scheduler_settings;
1059 StateMachine state(default_scheduler_settings);
1060 state.SetCanStart();
1061 state.UpdateState(state.NextAction());
1062 state.DidCreateAndInitializeOutputSurface();
1063 state.SetVisible(true);
1064 state.SetCanDraw(true);
1066 // Get into a begin frame / commit state.
1067 state.SetNeedsCommit();
1069 EXPECT_ACTION_UPDATE_STATE(
1070 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1071 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
1072 state.CommitState());
1073 EXPECT_FALSE(state.NeedsCommit());
1074 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1076 // Abort the commit, cancelling future commits.
1077 state.BeginMainFrameAborted(true);
1079 // Verify that another commit doesn't start on the same frame.
1080 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1081 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1082 EXPECT_FALSE(state.NeedsCommit());
1084 // Start a new frame; draw because this is the first frame since output
1085 // surface init'd.
1086 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1087 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1088 state.OnBeginImplFrameDeadline();
1089 EXPECT_ACTION_UPDATE_STATE(
1090 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1092 // Verify another commit doesn't start on another frame either.
1093 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1094 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1095 EXPECT_FALSE(state.NeedsCommit());
1097 // Verify another commit can start if requested, though.
1098 state.SetNeedsCommit();
1099 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1100 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME,
1101 state.NextAction());
1104 TEST(SchedulerStateMachineTest, TestFirstContextCreation) {
1105 SchedulerSettings default_scheduler_settings;
1106 StateMachine state(default_scheduler_settings);
1107 state.SetCanStart();
1108 state.SetVisible(true);
1109 state.SetCanDraw(true);
1111 EXPECT_ACTION_UPDATE_STATE(
1112 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1113 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1114 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1116 // Check that the first init does not SetNeedsCommit.
1117 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1118 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1119 state.OnBeginImplFrameDeadline();
1120 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1122 // Check that a needs commit initiates a BeginMainFrame.
1123 state.SetNeedsCommit();
1124 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1125 EXPECT_ACTION_UPDATE_STATE(
1126 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1129 TEST(SchedulerStateMachineTest, TestContextLostWhenCompletelyIdle) {
1130 SchedulerSettings default_scheduler_settings;
1131 StateMachine state(default_scheduler_settings);
1132 state.SetCanStart();
1133 state.UpdateState(state.NextAction());
1134 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1136 state.SetVisible(true);
1137 state.SetCanDraw(true);
1139 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1140 state.NextAction());
1141 state.DidLoseOutputSurface();
1143 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1144 state.NextAction());
1145 state.UpdateState(state.NextAction());
1147 // Once context recreation begins, nothing should happen.
1148 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1150 // Recreate the context.
1151 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1153 // When the context is recreated, we should begin a commit.
1154 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1155 EXPECT_ACTION_UPDATE_STATE(
1156 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1159 TEST(SchedulerStateMachineTest,
1160 TestContextLostWhenIdleAndCommitRequestedWhileRecreating) {
1161 SchedulerSettings default_scheduler_settings;
1162 StateMachine state(default_scheduler_settings);
1163 state.SetCanStart();
1164 state.UpdateState(state.NextAction());
1165 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1166 state.SetVisible(true);
1167 state.SetCanDraw(true);
1169 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1170 state.NextAction());
1171 state.DidLoseOutputSurface();
1173 EXPECT_ACTION_UPDATE_STATE(
1174 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1175 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1177 // Once context recreation begins, nothing should happen.
1178 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1179 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1180 state.OnBeginImplFrameDeadline();
1181 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1183 // While context is recreating, commits shouldn't begin.
1184 state.SetNeedsCommit();
1185 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1186 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1187 state.OnBeginImplFrameDeadline();
1188 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1190 // Recreate the context
1191 state.DidCreateAndInitializeOutputSurface();
1192 EXPECT_FALSE(state.RedrawPending());
1194 // When the context is recreated, we should begin a commit
1195 EXPECT_ACTION_UPDATE_STATE(
1196 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1197 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1198 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
1199 state.CommitState());
1201 state.NotifyBeginMainFrameStarted();
1202 state.NotifyReadyToCommit();
1203 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1204 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1205 // Finishing the first commit after initializing an output surface should
1206 // automatically cause a redraw.
1207 EXPECT_TRUE(state.RedrawPending());
1209 // Once the context is recreated, whether we draw should be based on
1210 // SetCanDraw.
1211 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1212 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1213 state.OnBeginImplFrameDeadline();
1214 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
1215 state.NextAction());
1216 state.SetCanDraw(false);
1217 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT,
1218 state.NextAction());
1219 state.SetCanDraw(true);
1220 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
1221 state.NextAction());
1224 TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) {
1225 SchedulerSettings scheduler_settings;
1226 StateMachine state(scheduler_settings);
1227 state.SetCanStart();
1228 state.UpdateState(state.NextAction());
1229 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1230 state.SetVisible(true);
1231 state.SetCanDraw(true);
1233 // Get a commit in flight.
1234 state.SetNeedsCommit();
1236 // Set damage and expect a draw.
1237 state.SetNeedsRedraw(true);
1238 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1239 EXPECT_ACTION_UPDATE_STATE(
1240 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1241 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1242 state.OnBeginImplFrameDeadline();
1243 EXPECT_ACTION_UPDATE_STATE(
1244 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1245 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1247 // Cause a lost context while the BeginMainFrame is in flight.
1248 state.DidLoseOutputSurface();
1250 // Ask for another draw. Expect nothing happens.
1251 state.SetNeedsRedraw(true);
1252 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1254 // Finish the frame, and commit.
1255 state.NotifyBeginMainFrameStarted();
1256 state.NotifyReadyToCommit();
1257 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1259 // We will abort the draw when the output surface is lost if we are
1260 // waiting for the first draw to unblock the main thread.
1261 EXPECT_TRUE(state.active_tree_needs_first_draw());
1262 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1264 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1265 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE,
1266 state.begin_impl_frame_state());
1267 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1268 state.NextAction());
1270 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1271 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
1272 state.begin_impl_frame_state());
1273 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1275 state.OnBeginImplFrameDeadlinePending();
1276 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
1277 state.begin_impl_frame_state());
1278 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1280 state.OnBeginImplFrameDeadline();
1281 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE,
1282 state.begin_impl_frame_state());
1283 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1286 TEST(SchedulerStateMachineTest,
1287 TestContextLostWhileCommitInProgressAndAnotherCommitRequested) {
1288 SchedulerSettings scheduler_settings;
1289 StateMachine state(scheduler_settings);
1290 state.SetCanStart();
1291 state.UpdateState(state.NextAction());
1292 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1293 state.SetVisible(true);
1294 state.SetCanDraw(true);
1296 // Get a commit in flight.
1297 state.SetNeedsCommit();
1298 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1300 // Set damage and expect a draw.
1301 state.SetNeedsRedraw(true);
1302 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1303 EXPECT_ACTION_UPDATE_STATE(
1304 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1305 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1306 state.OnBeginImplFrameDeadline();
1307 EXPECT_ACTION_UPDATE_STATE(
1308 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1309 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1311 // Cause a lost context while the BeginMainFrame is in flight.
1312 state.DidLoseOutputSurface();
1314 // Ask for another draw and also set needs commit. Expect nothing happens.
1315 state.SetNeedsRedraw(true);
1316 state.SetNeedsCommit();
1317 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1319 // Finish the frame, and commit.
1320 state.NotifyBeginMainFrameStarted();
1321 state.NotifyReadyToCommit();
1322 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1323 EXPECT_TRUE(state.active_tree_needs_first_draw());
1325 // Because the output surface is missing, we expect the draw to abort.
1326 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1328 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1329 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE,
1330 state.begin_impl_frame_state());
1331 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1332 state.NextAction());
1334 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1335 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
1336 state.begin_impl_frame_state());
1337 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1339 state.OnBeginImplFrameDeadlinePending();
1340 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
1341 state.begin_impl_frame_state());
1342 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1344 state.OnBeginImplFrameDeadline();
1345 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE,
1346 state.begin_impl_frame_state());
1347 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1349 state.OnBeginImplFrameIdle();
1350 EXPECT_ACTION_UPDATE_STATE(
1351 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1353 // After we get a new output surface, the commit flow should start.
1354 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1355 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1356 EXPECT_ACTION_UPDATE_STATE(
1357 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1358 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1359 state.NotifyBeginMainFrameStarted();
1360 state.NotifyReadyToCommit();
1361 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1362 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1363 state.OnBeginImplFrameDeadline();
1364 EXPECT_ACTION_UPDATE_STATE(
1365 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1366 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1369 TEST(SchedulerStateMachineTest, TestFinishAllRenderingWhileContextLost) {
1370 SchedulerSettings default_scheduler_settings;
1371 StateMachine state(default_scheduler_settings);
1372 state.SetCanStart();
1373 state.UpdateState(state.NextAction());
1374 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1375 state.SetVisible(true);
1376 state.SetCanDraw(true);
1378 // Cause a lost context lost.
1379 state.DidLoseOutputSurface();
1381 // Ask a forced redraw for readback and verify it ocurrs.
1382 state.SetNeedsForcedRedrawForReadback();
1383 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1384 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK);
1385 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1387 // Forced redraws for readbacks need to be followed by a new commit
1388 // to replace the readback commit.
1389 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
1390 state.CommitState());
1391 state.NotifyBeginMainFrameStarted();
1392 state.NotifyReadyToCommit();
1393 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1395 // We don't yet have an output surface, so we the draw and swap should abort.
1396 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1398 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1399 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1401 state.OnBeginImplFrameDeadline();
1402 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1404 state.OnBeginImplFrameIdle();
1405 EXPECT_ACTION_UPDATE_STATE(
1406 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1408 // Ask a readback and verify it occurs.
1409 state.SetNeedsForcedRedrawForReadback();
1410 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK);
1411 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1414 TEST(SchedulerStateMachineTest, DontDrawBeforeCommitAfterLostOutputSurface) {
1415 SchedulerSettings default_scheduler_settings;
1416 StateMachine state(default_scheduler_settings);
1417 state.SetCanStart();
1418 state.UpdateState(state.NextAction());
1419 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1420 state.SetVisible(true);
1421 state.SetCanDraw(true);
1423 state.SetNeedsRedraw(true);
1425 // Cause a lost output surface, and restore it.
1426 state.DidLoseOutputSurface();
1427 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1428 state.NextAction());
1429 state.UpdateState(state.NextAction());
1430 state.DidCreateAndInitializeOutputSurface();
1432 EXPECT_FALSE(state.RedrawPending());
1433 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1434 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME,
1435 state.NextAction());
1438 TEST(SchedulerStateMachineTest,
1439 TestPendingActivationsShouldBeForcedAfterLostOutputSurface) {
1440 SchedulerSettings settings;
1441 settings.impl_side_painting = true;
1442 StateMachine state(settings);
1443 state.SetCanStart();
1444 state.UpdateState(state.NextAction());
1445 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1446 state.SetVisible(true);
1447 state.SetCanDraw(true);
1449 state.SetCommitState(
1450 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
1452 // Cause a lost context.
1453 state.DidLoseOutputSurface();
1455 state.NotifyBeginMainFrameStarted();
1456 state.NotifyReadyToCommit();
1457 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1459 EXPECT_TRUE(state.PendingActivationsShouldBeForced());
1460 EXPECT_ACTION_UPDATE_STATE(
1461 SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE);
1463 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1464 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1467 TEST(SchedulerStateMachineTest,
1468 TestSendBeginMainFrameWhenInvisibleAndForceCommit) {
1469 SchedulerSettings default_scheduler_settings;
1470 StateMachine state(default_scheduler_settings);
1471 state.SetCanStart();
1472 state.UpdateState(state.NextAction());
1473 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1474 state.SetVisible(false);
1475 state.SetNeedsForcedCommitForReadback();
1476 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME,
1477 state.NextAction());
1480 TEST(SchedulerStateMachineTest,
1481 TestSendBeginMainFrameWhenCanStartFalseAndForceCommit) {
1482 SchedulerSettings default_scheduler_settings;
1483 StateMachine state(default_scheduler_settings);
1484 state.SetVisible(true);
1485 state.SetCanDraw(true);
1486 state.SetNeedsForcedCommitForReadback();
1487 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME,
1488 state.NextAction());
1491 // If new commit is not requested explicitly after starting forced commit,
1492 // new commit should not scheduled after drawing the replacement commit.
1493 TEST(SchedulerStateMachineTest, DontMakeNewCommitAfterDrawingReplaceCommit) {
1494 SchedulerSettings default_scheduler_settings;
1495 StateMachine state(default_scheduler_settings);
1496 state.SetCanStart();
1497 state.UpdateState(state.NextAction());
1498 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1499 state.SetVisible(true);
1500 state.SetCanDraw(true);
1502 // There is a scheduled commit.
1503 state.SetCommitState(
1504 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
1506 // Request a forced commit.
1507 state.SetNeedsForcedCommitForReadback();
1509 state.NotifyBeginMainFrameStarted();
1510 state.NotifyReadyToCommit();
1511 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1512 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_READBACK,
1513 state.NextAction());
1514 state.UpdateState(state.NextAction());
1515 EXPECT_EQ(
1516 SchedulerStateMachine::READBACK_STATE_WAITING_FOR_REPLACEMENT_COMMIT,
1517 state.readback_state());
1518 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
1519 state.CommitState());
1521 // Finish the replacement commit.
1522 state.NotifyBeginMainFrameStarted();
1523 state.NotifyReadyToCommit();
1524 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1526 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1527 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1528 state.OnBeginImplFrameDeadline();
1529 EXPECT_ACTION_UPDATE_STATE(
1530 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1531 EXPECT_EQ(SchedulerStateMachine::READBACK_STATE_IDLE, state.readback_state());
1532 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1535 TEST(SchedulerStateMachineTest, TestFinishCommitWhenCommitInProgress) {
1536 SchedulerSettings default_scheduler_settings;
1537 StateMachine state(default_scheduler_settings);
1538 state.SetCanStart();
1539 state.UpdateState(state.NextAction());
1540 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1541 state.SetVisible(false);
1542 state.SetCommitState(
1543 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
1544 state.SetNeedsCommit();
1546 state.NotifyBeginMainFrameStarted();
1547 state.NotifyReadyToCommit();
1548 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
1549 state.UpdateState(state.NextAction());
1551 EXPECT_TRUE(state.active_tree_needs_first_draw());
1552 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1555 TEST(SchedulerStateMachineTest, TestFinishCommitWhenForcedCommitInProgress) {
1556 SchedulerSettings default_scheduler_settings;
1557 StateMachine state(default_scheduler_settings);
1558 state.SetCanStart();
1559 state.UpdateState(state.NextAction());
1560 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1561 state.SetVisible(false);
1562 state.SetCommitState(
1563 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
1564 state.SetNeedsForcedCommitForReadback();
1566 // The commit for readback interupts the normal commit.
1567 state.NotifyBeginMainFrameStarted();
1568 state.NotifyReadyToCommit();
1569 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1571 EXPECT_TRUE(state.active_tree_needs_first_draw());
1572 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK);
1574 // When the readback interrupts the normal commit, we should not get
1575 // another BeginMainFrame when the readback completes.
1576 EXPECT_NE(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME,
1577 state.NextAction());
1579 // The normal commit can then proceed.
1580 state.NotifyBeginMainFrameStarted();
1581 state.NotifyReadyToCommit();
1582 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1585 void TestForceCommitWhenReplacementActivationInProgress(
1586 bool main_frame_before_draw_enabled) {
1587 SchedulerSettings settings;
1588 settings.impl_side_painting = true;
1589 settings.main_frame_before_draw_enabled = main_frame_before_draw_enabled;
1590 StateMachine state(settings);
1591 state.SetCanStart();
1592 state.UpdateState(state.NextAction());
1593 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1594 state.SetVisible(true);
1595 state.SetCanDraw(true);
1597 // Impl-side painting of replacement commit is in-progress.
1598 if (settings.main_frame_before_draw_enabled) {
1599 state.SetCommitState(
1600 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION);
1601 } else {
1602 state.SetCommitState(
1603 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
1605 state.SetReadbackState(
1606 SchedulerStateMachine::READBACK_STATE_WAITING_FOR_REPLACEMENT_ACTIVATION);
1607 state.SetHasPendingTree(true);
1609 // Forced commit is requested during the impl-side painting.
1610 state.SetNeedsForcedCommitForReadback();
1611 EXPECT_FALSE(state.NeedsCommit());
1613 state.NotifyReadyToActivate();
1614 EXPECT_ACTION_UPDATE_STATE(
1615 SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE);
1616 // New replacement commit is needed for incoming forced commit.
1617 EXPECT_EQ(SchedulerStateMachine::READBACK_STATE_NEEDS_BEGIN_MAIN_FRAME,
1618 state.readback_state());
1619 EXPECT_TRUE(state.NeedsCommit());
1620 if (settings.main_frame_before_draw_enabled) {
1621 // New replacement commit is scheduled.
1622 EXPECT_ACTION_UPDATE_STATE(
1623 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1624 // Forced commit is started.
1625 EXPECT_EQ(SchedulerStateMachine::READBACK_STATE_WAITING_FOR_COMMIT,
1626 state.readback_state());
1628 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1630 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1631 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1632 // Perform the draw & swap of replacement commit.
1633 state.OnBeginImplFrameDeadline();
1634 EXPECT_ACTION_UPDATE_STATE(
1635 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1636 if (!settings.main_frame_before_draw_enabled) {
1637 // New replacement commit is scheduled.
1638 EXPECT_ACTION_UPDATE_STATE(
1639 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1640 // Forced commit is started.
1641 EXPECT_EQ(SchedulerStateMachine::READBACK_STATE_WAITING_FOR_COMMIT,
1642 state.readback_state());
1644 EXPECT_ACTION_UPDATE_STATE(
1645 SchedulerStateMachine::ACTION_NONE);
1647 // Finish the forced commit and draw it.
1648 state.NotifyBeginMainFrameStarted();
1649 state.NotifyReadyToCommit();
1650 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1651 state.NotifyReadyToActivate();
1652 EXPECT_ACTION_UPDATE_STATE(
1653 SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE);
1654 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK)
1655 EXPECT_EQ(
1656 SchedulerStateMachine::READBACK_STATE_WAITING_FOR_REPLACEMENT_COMMIT,
1657 state.readback_state());
1658 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
1659 state.CommitState());
1660 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1662 // Finish the replacement commit and draw it.
1663 state.NotifyBeginMainFrameStarted();
1664 state.NotifyReadyToCommit();
1665 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1666 state.NotifyReadyToActivate();
1667 EXPECT_ACTION_UPDATE_STATE(
1668 SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE);
1669 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1670 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1671 state.OnBeginImplFrameDeadline();
1672 EXPECT_ACTION_UPDATE_STATE(
1673 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1674 EXPECT_EQ(SchedulerStateMachine::READBACK_STATE_IDLE, state.readback_state());
1675 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1678 // Explicitly test when main_frame_before_draw_enabled = true.
1679 TEST(SchedulerStateMachineTest,
1680 ForceCommitWhenReplacementActivationInProgressAndMainFrameEnabled) {
1681 bool main_frame_before_draw_enabled = true;
1682 TestForceCommitWhenReplacementActivationInProgress(
1683 main_frame_before_draw_enabled);
1686 // Explicitly test when main_frame_before_draw_enabled = false.
1687 TEST(SchedulerStateMachineTest,
1688 ForceCommitWhenReplacementActivationInProgressAndMainFrameDisabled) {
1689 bool main_frame_before_draw_enabled = false;
1690 TestForceCommitWhenReplacementActivationInProgress(
1691 main_frame_before_draw_enabled);
1694 // Test with main_frame_before_activation_enable = true;
1695 TEST(SchedulerStateMachineTest,
1696 ForceCommitWhenReplacementActivationInProgressWithMFBA) {
1697 SchedulerSettings settings;
1698 settings.impl_side_painting = true;
1699 settings.main_frame_before_activation_enabled = true;
1700 StateMachine state(settings);
1701 state.SetCanStart();
1702 state.UpdateState(state.NextAction());
1703 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1704 state.SetVisible(true);
1705 state.SetCanDraw(true);
1707 // When impl-side painting of replacement commit is in-progress, commit state
1708 // is idle because main_frame_before_activation is enabled.
1709 state.SetCommitState(
1710 SchedulerStateMachine::COMMIT_STATE_IDLE);
1711 state.SetReadbackState(
1712 SchedulerStateMachine::READBACK_STATE_WAITING_FOR_REPLACEMENT_ACTIVATION);
1713 state.SetHasPendingTree(true);
1715 // New commit is requested and scheduled when impl-side painting is in
1716 // progress.
1717 state.SetNeedsCommit();
1718 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1719 EXPECT_ACTION_UPDATE_STATE(
1720 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1721 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1723 // Forced commit is requested during the impl-side painting.
1724 state.SetNeedsForcedCommitForReadback();
1725 EXPECT_FALSE(state.NeedsCommit());
1727 state.OnBeginImplFrameDeadline();
1728 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1730 state.NotifyReadyToActivate();
1731 EXPECT_ACTION_UPDATE_STATE(
1732 SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE);
1733 // Replacement commit for requested forced commit is already scheduled.
1734 EXPECT_EQ(SchedulerStateMachine::READBACK_STATE_WAITING_FOR_COMMIT,
1735 state.readback_state());
1736 EXPECT_FALSE(state.NeedsCommit());
1737 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1739 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1740 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1741 // Perform the draw & swap of replacement commit.
1742 state.OnBeginImplFrameDeadline();
1743 EXPECT_ACTION_UPDATE_STATE(
1744 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1745 EXPECT_ACTION_UPDATE_STATE(
1746 SchedulerStateMachine::ACTION_NONE);
1748 // forced commit is started.
1749 state.NotifyBeginMainFrameStarted();
1750 state.NotifyReadyToCommit();
1751 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1754 TEST(SchedulerStateMachineTest, TestInitialActionsWhenContextLost) {
1755 SchedulerSettings default_scheduler_settings;
1756 StateMachine state(default_scheduler_settings);
1757 state.SetCanStart();
1758 state.UpdateState(state.NextAction());
1759 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1760 state.SetVisible(true);
1761 state.SetCanDraw(true);
1762 state.SetNeedsCommit();
1763 state.DidLoseOutputSurface();
1765 // When we are visible, we normally want to begin output surface creation
1766 // as soon as possible.
1767 EXPECT_ACTION_UPDATE_STATE(
1768 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1770 state.DidCreateAndInitializeOutputSurface();
1771 EXPECT_EQ(state.output_surface_state(),
1772 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT);
1774 // We should not send a BeginMainFrame when we are invisible, even if we've
1775 // lost the output surface and are trying to get the first commit, since the
1776 // main thread will just abort anyway.
1777 state.SetVisible(false);
1778 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction())
1779 << *state.AsValue();
1781 // If there is a forced commit, however, we could be blocking a readback
1782 // on the main thread, so we need to unblock it before we can get our
1783 // output surface, even if we are not visible.
1784 state.SetNeedsForcedCommitForReadback();
1785 EXPECT_EQ(
1786 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME, state.NextAction())
1787 << *state.AsValue();
1790 TEST(SchedulerStateMachineTest, TestImmediateFinishCommit) {
1791 SchedulerSettings default_scheduler_settings;
1792 StateMachine state(default_scheduler_settings);
1793 state.SetCanStart();
1794 state.UpdateState(state.NextAction());
1795 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1796 state.SetVisible(true);
1797 state.SetCanDraw(true);
1799 // Schedule a readback, commit it, draw it.
1800 state.SetNeedsForcedCommitForReadback();
1801 EXPECT_ACTION_UPDATE_STATE(
1802 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1804 state.NotifyBeginMainFrameStarted();
1805 state.NotifyReadyToCommit();
1807 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
1808 state.CommitState());
1809 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1811 EXPECT_TRUE(state.active_tree_needs_first_draw());
1813 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK);
1814 state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS);
1816 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1818 // Should be waiting for the normal BeginMainFrame.
1819 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
1820 state.CommitState());
1823 TEST(SchedulerStateMachineTest, TestImmediateFinishCommitDuringCommit) {
1824 SchedulerSettings scheduler_settings;
1825 StateMachine state(scheduler_settings);
1826 state.SetCanStart();
1827 state.UpdateState(state.NextAction());
1828 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1829 state.SetVisible(true);
1830 state.SetCanDraw(true);
1832 // Start a normal commit.
1833 state.SetNeedsCommit();
1834 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1836 // Schedule a readback, commit it, draw it.
1837 state.SetNeedsForcedCommitForReadback();
1838 EXPECT_ACTION_UPDATE_STATE(
1839 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1840 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1841 state.NotifyBeginMainFrameStarted();
1842 state.NotifyReadyToCommit();
1843 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
1844 state.CommitState());
1845 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1847 EXPECT_TRUE(state.active_tree_needs_first_draw());
1849 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK);
1850 state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS);
1851 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1853 // Should be waiting for the normal BeginMainFrame.
1854 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
1855 state.CommitState())
1856 << *state.AsValue();
1859 TEST(SchedulerStateMachineTest, ImmediateBeginMainFrameAbortedWhileInvisible) {
1860 SchedulerSettings scheduler_settings;
1861 StateMachine state(scheduler_settings);
1862 state.SetCanStart();
1863 state.UpdateState(state.NextAction());
1864 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1865 state.SetVisible(true);
1866 state.SetCanDraw(true);
1868 state.SetNeedsCommit();
1869 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1871 state.SetNeedsForcedCommitForReadback();
1872 EXPECT_ACTION_UPDATE_STATE(
1873 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1874 state.NotifyBeginMainFrameStarted();
1875 state.NotifyReadyToCommit();
1877 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
1878 state.CommitState());
1879 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1881 EXPECT_TRUE(state.active_tree_needs_first_draw());
1883 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK);
1884 state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS);
1885 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1887 // Should be waiting for BeginMainFrame.
1888 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
1889 state.CommitState())
1890 << *state.AsValue();
1892 // Become invisible and abort BeginMainFrame.
1893 state.SetVisible(false);
1894 state.BeginMainFrameAborted(false);
1896 // Should be back in the idle state, but needing a commit.
1897 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1898 EXPECT_TRUE(state.NeedsCommit());
1901 TEST(SchedulerStateMachineTest, ImmediateFinishCommitWhileCantDraw) {
1902 SchedulerSettings default_scheduler_settings;
1903 StateMachine state(default_scheduler_settings);
1904 state.SetCanStart();
1905 state.UpdateState(state.NextAction());
1906 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1907 state.SetVisible(true);
1908 state.SetCanDraw(false);
1910 state.SetNeedsCommit();
1911 state.UpdateState(state.NextAction());
1913 state.SetNeedsForcedCommitForReadback();
1914 state.UpdateState(state.NextAction());
1915 state.NotifyBeginMainFrameStarted();
1916 state.NotifyReadyToCommit();
1918 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
1919 state.CommitState());
1920 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1922 EXPECT_TRUE(state.active_tree_needs_first_draw());
1924 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK);
1925 state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS);
1926 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1929 TEST(SchedulerStateMachineTest, ReportIfNotDrawing) {
1930 SchedulerSettings default_scheduler_settings;
1931 StateMachine state(default_scheduler_settings);
1932 state.SetCanStart();
1933 state.UpdateState(state.NextAction());
1934 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1936 state.SetCanDraw(true);
1937 state.SetVisible(true);
1938 EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
1940 state.SetCanDraw(false);
1941 state.SetVisible(true);
1942 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1944 state.SetCanDraw(true);
1945 state.SetVisible(false);
1946 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1948 state.SetCanDraw(false);
1949 state.SetVisible(false);
1950 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1952 state.SetCanDraw(true);
1953 state.SetVisible(true);
1954 EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
1957 TEST(SchedulerStateMachineTest, TestTriggerDeadlineEarlyAfterAbortedCommit) {
1958 SchedulerSettings settings;
1959 settings.impl_side_painting = true;
1960 StateMachine state(settings);
1961 state.SetCanStart();
1962 state.UpdateState(state.NextAction());
1963 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1964 state.SetVisible(true);
1965 state.SetCanDraw(true);
1967 // This test mirrors what happens during the first frame of a scroll gesture.
1968 // First we get the input event and a BeginFrame.
1969 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1971 // As a response the compositor requests a redraw and a commit to tell the
1972 // main thread about the new scroll offset.
1973 state.SetNeedsRedraw(true);
1974 state.SetNeedsCommit();
1976 // We should start the commit normally.
1977 EXPECT_ACTION_UPDATE_STATE(
1978 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1979 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1981 // Since only the scroll offset changed, the main thread will abort the
1982 // commit.
1983 state.BeginMainFrameAborted(true);
1985 // Since the commit was aborted, we should draw right away instead of waiting
1986 // for the deadline.
1987 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
1990 TEST(SchedulerStateMachineTest, TestTriggerDeadlineEarlyForSmoothness) {
1991 SchedulerSettings settings;
1992 settings.impl_side_painting = true;
1993 StateMachine state(settings);
1994 state.SetCanStart();
1995 state.UpdateState(state.NextAction());
1996 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1997 state.SetVisible(true);
1998 state.SetCanDraw(true);
2000 // This test ensures that impl-draws are prioritized over main thread updates
2001 // in prefer smoothness mode.
2002 state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
2003 state.SetNeedsRedraw(true);
2004 state.SetNeedsCommit();
2005 EXPECT_ACTION_UPDATE_STATE(
2006 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
2007 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
2009 // The deadline is not triggered early until we enter prefer smoothness mode.
2010 EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
2011 state.SetSmoothnessTakesPriority(true);
2012 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
2015 } // namespace
2016 } // namespace cc