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 "base/debug/trace_event.h"
8 #include "cc/scheduler/scheduler.h"
9 #include "cc/test/begin_frame_args_test.h"
10 #include "testing/gtest/include/gtest/gtest.h"
12 #define EXPECT_ACTION_UPDATE_STATE(action) \
13 EXPECT_STREQ(SchedulerStateMachine::ActionToString(action), \
14 SchedulerStateMachine::ActionToString(state.NextAction())) \
15 << state.AsValue()->ToString(); \
16 if (action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE || \
17 action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED) { \
18 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE, \
19 state.begin_impl_frame_state()) \
20 << state.AsValue()->ToString(); \
22 state.UpdateState(action); \
23 if (action == SchedulerStateMachine::ACTION_NONE) { \
24 if (state.begin_impl_frame_state() == \
25 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) \
26 state.OnBeginImplFrameDeadlinePending(); \
27 if (state.begin_impl_frame_state() == \
28 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) \
29 state.OnBeginImplFrameIdle(); \
36 const SchedulerStateMachine::BeginImplFrameState all_begin_impl_frame_states
[] =
37 {SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
,
38 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
39 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
,
40 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
, };
42 const SchedulerStateMachine::CommitState all_commit_states
[] = {
43 SchedulerStateMachine::COMMIT_STATE_IDLE
,
44 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
45 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED
,
46 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
47 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION
};
49 // Exposes the protected state fields of the SchedulerStateMachine for testing
50 class StateMachine
: public SchedulerStateMachine
{
52 explicit StateMachine(const SchedulerSettings
& scheduler_settings
)
53 : SchedulerStateMachine(scheduler_settings
) {}
55 void CreateAndInitializeOutputSurfaceWithActivatedCommit() {
56 DidCreateAndInitializeOutputSurface();
57 output_surface_state_
= OUTPUT_SURFACE_ACTIVE
;
60 void SetCommitState(CommitState cs
) { commit_state_
= cs
; }
61 CommitState
CommitState() const { return commit_state_
; }
63 ForcedRedrawOnTimeoutState
ForcedRedrawState() const {
64 return forced_redraw_state_
;
67 void SetBeginImplFrameState(BeginImplFrameState bifs
) {
68 begin_impl_frame_state_
= bifs
;
71 BeginImplFrameState
begin_impl_frame_state() const {
72 return begin_impl_frame_state_
;
75 OutputSurfaceState
output_surface_state() const {
76 return output_surface_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 SetActiveTreeNeedsFirstDraw(bool needs_first_draw
) {
92 active_tree_needs_first_draw_
= needs_first_draw
;
95 bool CanDraw() const { return can_draw_
; }
96 bool Visible() const { return visible_
; }
98 bool PendingActivationsShouldBeForced() const {
99 return SchedulerStateMachine::PendingActivationsShouldBeForced();
102 void SetHasPendingTree(bool has_pending_tree
) {
103 has_pending_tree_
= has_pending_tree
;
107 TEST(SchedulerStateMachineTest
, TestNextActionBeginsMainFrameIfNeeded
) {
108 SchedulerSettings default_scheduler_settings
;
110 // If no commit needed, do nothing.
112 StateMachine
state(default_scheduler_settings
);
114 EXPECT_ACTION_UPDATE_STATE(
115 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
)
116 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
117 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
118 state
.SetNeedsRedraw(false);
119 state
.SetVisible(true);
121 EXPECT_FALSE(state
.BeginFrameNeeded());
123 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
124 EXPECT_FALSE(state
.BeginFrameNeeded());
125 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
127 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
128 state
.OnBeginImplFrameDeadline();
131 // If commit requested but can_start is still false, do nothing.
133 StateMachine
state(default_scheduler_settings
);
134 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
135 state
.SetNeedsRedraw(false);
136 state
.SetVisible(true);
137 state
.SetNeedsCommit();
139 EXPECT_FALSE(state
.BeginFrameNeeded());
141 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
142 EXPECT_FALSE(state
.BeginFrameNeeded());
143 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
144 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
145 state
.OnBeginImplFrameDeadline();
148 // If commit requested, begin a main frame.
150 StateMachine
state(default_scheduler_settings
);
151 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
153 state
.UpdateState(state
.NextAction());
154 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
155 state
.SetNeedsRedraw(false);
156 state
.SetVisible(true);
157 state
.SetNeedsCommit();
159 EXPECT_TRUE(state
.BeginFrameNeeded());
161 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
162 EXPECT_ACTION_UPDATE_STATE(
163 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
166 // Begin the frame, make sure needs_commit and commit_state update correctly.
168 StateMachine
state(default_scheduler_settings
);
170 state
.UpdateState(state
.NextAction());
171 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
172 state
.SetVisible(true);
173 state
.UpdateState(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
174 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
175 state
.CommitState());
176 EXPECT_FALSE(state
.NeedsCommit());
180 // Explicitly test main_frame_before_activation_enabled = true
181 TEST(SchedulerStateMachineTest
, MainFrameBeforeActivationEnabled
) {
182 SchedulerSettings scheduler_settings
;
183 scheduler_settings
.impl_side_painting
= true;
184 scheduler_settings
.main_frame_before_activation_enabled
= true;
185 StateMachine
state(scheduler_settings
);
186 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
188 state
.UpdateState(state
.NextAction());
189 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
190 state
.SetNeedsRedraw(false);
191 state
.SetVisible(true);
192 state
.SetCanDraw(true);
193 state
.SetNeedsCommit();
195 EXPECT_TRUE(state
.BeginFrameNeeded());
197 // Commit to the pending tree.
198 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
199 EXPECT_ACTION_UPDATE_STATE(
200 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
201 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
203 state
.NotifyBeginMainFrameStarted();
204 state
.NotifyReadyToCommit();
205 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
206 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
207 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
209 state
.OnBeginImplFrameDeadline();
210 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
212 // Verify that the next commit starts while there is still a pending tree.
213 state
.SetNeedsCommit();
214 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
215 EXPECT_ACTION_UPDATE_STATE(
216 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
217 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
219 // Verify the pending commit doesn't overwrite the pending
220 // tree until the pending tree has been activated.
221 state
.NotifyBeginMainFrameStarted();
222 state
.NotifyReadyToCommit();
223 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
225 // Verify NotifyReadyToActivate unblocks activation, draw, and
226 // commit in that order.
227 state
.NotifyReadyToActivate();
228 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
229 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
231 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
232 state
.OnBeginImplFrameDeadline();
233 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
234 EXPECT_ACTION_UPDATE_STATE(
235 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
236 state
.DidSwapBuffers();
237 state
.DidSwapBuffersComplete();
238 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
239 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
240 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
243 TEST(SchedulerStateMachineTest
,
244 TestFailedDrawForAnimationCheckerboardSetsNeedsCommitAndDoesNotDrawAgain
) {
245 SchedulerSettings default_scheduler_settings
;
246 StateMachine
state(default_scheduler_settings
);
248 state
.UpdateState(state
.NextAction());
249 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
250 state
.SetVisible(true);
251 state
.SetCanDraw(true);
252 state
.SetNeedsRedraw(true);
253 EXPECT_TRUE(state
.RedrawPending());
254 EXPECT_TRUE(state
.BeginFrameNeeded());
255 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
256 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
257 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
258 state
.OnBeginImplFrameDeadline();
260 // We're drawing now.
261 EXPECT_ACTION_UPDATE_STATE(
262 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
263 state
.DidSwapBuffers();
264 state
.DidSwapBuffersComplete();
265 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
267 EXPECT_FALSE(state
.RedrawPending());
268 EXPECT_FALSE(state
.CommitPending());
270 // Failing the draw makes us require a commit.
271 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
272 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
273 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
274 EXPECT_ACTION_UPDATE_STATE(
275 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
276 EXPECT_TRUE(state
.RedrawPending());
277 EXPECT_TRUE(state
.CommitPending());
280 TEST(SchedulerStateMachineTest
, TestFailedDrawForMissingHighResNeedsCommit
) {
281 SchedulerSettings default_scheduler_settings
;
282 StateMachine
state(default_scheduler_settings
);
284 state
.UpdateState(state
.NextAction());
285 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
286 state
.SetVisible(true);
287 state
.SetCanDraw(true);
288 state
.SetNeedsRedraw(true);
289 EXPECT_TRUE(state
.RedrawPending());
290 EXPECT_TRUE(state
.BeginFrameNeeded());
292 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
293 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
294 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
295 state
.OnBeginImplFrameDeadline();
296 EXPECT_ACTION_UPDATE_STATE(
297 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
298 state
.DidSwapBuffers();
299 state
.DidSwapBuffersComplete();
300 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
301 EXPECT_FALSE(state
.RedrawPending());
302 EXPECT_FALSE(state
.CommitPending());
304 // Missing high res content requires a commit (but not a redraw)
305 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
);
306 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
307 EXPECT_ACTION_UPDATE_STATE(
308 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
309 EXPECT_FALSE(state
.RedrawPending());
310 EXPECT_TRUE(state
.CommitPending());
313 TEST(SchedulerStateMachineTest
,
314 TestsetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw
) {
315 SchedulerSettings default_scheduler_settings
;
316 StateMachine
state(default_scheduler_settings
);
318 state
.UpdateState(state
.NextAction());
319 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
321 state
.SetVisible(true);
322 state
.SetCanDraw(true);
323 state
.SetNeedsRedraw(true);
324 EXPECT_TRUE(state
.RedrawPending());
325 EXPECT_TRUE(state
.BeginFrameNeeded());
326 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
327 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
328 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
329 state
.OnBeginImplFrameDeadline();
331 // We're drawing now.
332 EXPECT_ACTION_UPDATE_STATE(
333 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
334 state
.DidSwapBuffers();
335 state
.DidSwapBuffersComplete();
336 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
337 EXPECT_FALSE(state
.RedrawPending());
338 EXPECT_FALSE(state
.CommitPending());
340 // While still in the same BeginMainFrame callback on the main thread,
341 // set needs redraw again. This should not redraw.
342 state
.SetNeedsRedraw(true);
343 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
345 // Failing the draw for animation checkerboards makes us require a commit.
346 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
347 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
348 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
349 EXPECT_ACTION_UPDATE_STATE(
350 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
351 EXPECT_TRUE(state
.RedrawPending());
354 TEST(SchedulerStateMachineTest
,
355 TestFailedDrawsEventuallyForceDrawAfterNextCommit
) {
356 SchedulerSettings scheduler_settings
;
357 scheduler_settings
.maximum_number_of_failed_draws_before_draw_is_forced_
= 1;
358 StateMachine
state(scheduler_settings
);
360 state
.UpdateState(state
.NextAction());
361 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
362 state
.SetVisible(true);
363 state
.SetCanDraw(true);
366 state
.SetNeedsCommit();
367 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
368 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
369 EXPECT_ACTION_UPDATE_STATE(
370 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
371 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
372 EXPECT_TRUE(state
.CommitPending());
374 // Then initiate a draw.
375 state
.SetNeedsRedraw(true);
376 state
.OnBeginImplFrameDeadline();
377 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
378 EXPECT_ACTION_UPDATE_STATE(
379 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
382 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
383 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
384 EXPECT_TRUE(state
.BeginFrameNeeded());
385 EXPECT_TRUE(state
.RedrawPending());
386 // But the commit is ongoing.
387 EXPECT_TRUE(state
.CommitPending());
389 // Finish the commit. Note, we should not yet be forcing a draw, but should
390 // continue the commit as usual.
391 state
.NotifyBeginMainFrameStarted();
392 state
.NotifyReadyToCommit();
393 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
394 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
395 EXPECT_TRUE(state
.RedrawPending());
397 // The redraw should be forced at the end of the next BeginImplFrame.
398 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
399 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
400 EXPECT_ACTION_UPDATE_STATE(
401 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
402 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
403 state
.OnBeginImplFrameDeadline();
404 EXPECT_ACTION_UPDATE_STATE(
405 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED
);
406 state
.DidSwapBuffers();
407 state
.DidSwapBuffersComplete();
410 TEST(SchedulerStateMachineTest
, TestFailedDrawsDoNotRestartForcedDraw
) {
411 SchedulerSettings scheduler_settings
;
413 scheduler_settings
.maximum_number_of_failed_draws_before_draw_is_forced_
=
415 scheduler_settings
.impl_side_painting
= true;
416 StateMachine
state(scheduler_settings
);
418 state
.UpdateState(state
.NextAction());
419 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
420 state
.SetVisible(true);
421 state
.SetCanDraw(true);
424 state
.SetNeedsCommit();
425 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
426 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
427 EXPECT_ACTION_UPDATE_STATE(
428 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
429 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
430 EXPECT_TRUE(state
.CommitPending());
432 // Then initiate a draw.
433 state
.SetNeedsRedraw(true);
434 state
.OnBeginImplFrameDeadline();
435 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
436 EXPECT_ACTION_UPDATE_STATE(
437 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
439 // Fail the draw enough times to force a redraw,
440 // then once more for good measure.
441 for (int i
= 0; i
< draw_limit
+ 1; ++i
)
442 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
443 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
444 EXPECT_TRUE(state
.BeginFrameNeeded());
445 EXPECT_TRUE(state
.RedrawPending());
446 // But the commit is ongoing.
447 EXPECT_TRUE(state
.CommitPending());
448 EXPECT_TRUE(state
.ForcedRedrawState() ==
449 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_COMMIT
);
451 state
.NotifyBeginMainFrameStarted();
452 state
.NotifyReadyToCommit();
453 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
454 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
455 EXPECT_TRUE(state
.RedrawPending());
456 EXPECT_FALSE(state
.CommitPending());
458 // Now force redraw should be in waiting for activation
459 EXPECT_TRUE(state
.ForcedRedrawState() ==
460 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
);
462 // After failing additional draws, we should still be in a forced
463 // redraw, but not back in WAITING_FOR_COMMIT.
464 for (int i
= 0; i
< draw_limit
+ 1; ++i
)
465 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
466 EXPECT_TRUE(state
.RedrawPending());
467 EXPECT_TRUE(state
.ForcedRedrawState() ==
468 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
);
471 TEST(SchedulerStateMachineTest
, TestFailedDrawIsRetriedInNextBeginImplFrame
) {
472 SchedulerSettings default_scheduler_settings
;
473 StateMachine
state(default_scheduler_settings
);
475 state
.UpdateState(state
.NextAction());
476 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
477 state
.SetVisible(true);
478 state
.SetCanDraw(true);
481 state
.SetNeedsRedraw(true);
482 EXPECT_TRUE(state
.BeginFrameNeeded());
483 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
484 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
485 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
486 state
.OnBeginImplFrameDeadline();
487 EXPECT_TRUE(state
.RedrawPending());
488 EXPECT_ACTION_UPDATE_STATE(
489 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
491 // Failing the draw for animation checkerboards makes us require a commit.
492 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
493 EXPECT_ACTION_UPDATE_STATE(
494 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
495 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
496 EXPECT_TRUE(state
.RedrawPending());
498 // We should not be trying to draw again now, but we have a commit pending.
499 EXPECT_TRUE(state
.BeginFrameNeeded());
500 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
501 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
502 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
504 // We should try to draw again at the end of the next BeginImplFrame on
506 state
.OnBeginImplFrameDeadline();
507 EXPECT_ACTION_UPDATE_STATE(
508 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
509 state
.DidSwapBuffers();
510 state
.DidSwapBuffersComplete();
511 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
514 TEST(SchedulerStateMachineTest
, TestDoestDrawTwiceInSameFrame
) {
515 SchedulerSettings default_scheduler_settings
;
516 StateMachine
state(default_scheduler_settings
);
518 state
.UpdateState(state
.NextAction());
519 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
520 state
.SetVisible(true);
521 state
.SetCanDraw(true);
522 state
.SetNeedsRedraw(true);
524 // Draw the first frame.
525 EXPECT_TRUE(state
.BeginFrameNeeded());
526 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
527 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
528 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
530 state
.OnBeginImplFrameDeadline();
531 EXPECT_ACTION_UPDATE_STATE(
532 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
533 state
.DidSwapBuffers();
534 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
535 state
.DidSwapBuffersComplete();
536 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
538 // Before the next BeginImplFrame, set needs redraw again.
539 // This should not redraw until the next BeginImplFrame.
540 state
.SetNeedsRedraw(true);
541 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
543 // Move to another frame. This should now draw.
544 EXPECT_TRUE(state
.BeginFrameNeeded());
545 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
547 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
548 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
550 state
.OnBeginImplFrameDeadline();
551 EXPECT_ACTION_UPDATE_STATE(
552 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
553 state
.DidSwapBuffers();
554 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
555 state
.DidSwapBuffersComplete();
556 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
558 // We just swapped, so we should proactively request another BeginImplFrame.
559 EXPECT_TRUE(state
.BeginFrameNeeded());
562 TEST(SchedulerStateMachineTest
, TestNextActionDrawsOnBeginImplFrame
) {
563 SchedulerSettings default_scheduler_settings
;
565 // When not in BeginImplFrame deadline, or in BeginImplFrame deadline
566 // but not visible, don't draw.
567 size_t num_commit_states
=
568 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
569 size_t num_begin_impl_frame_states
=
570 sizeof(all_begin_impl_frame_states
) /
571 sizeof(SchedulerStateMachine::BeginImplFrameState
);
572 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
573 for (size_t j
= 0; j
< num_begin_impl_frame_states
; ++j
) {
574 StateMachine
state(default_scheduler_settings
);
576 state
.UpdateState(state
.NextAction());
577 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
578 state
.SetCommitState(all_commit_states
[i
]);
579 state
.SetBeginImplFrameState(all_begin_impl_frame_states
[j
]);
581 (all_begin_impl_frame_states
[j
] !=
582 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
583 state
.SetVisible(visible
);
585 // Case 1: needs_commit=false
586 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
589 // Case 2: needs_commit=true
590 state
.SetNeedsCommit();
591 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
593 << state
.AsValue()->ToString();
597 // When in BeginImplFrame deadline we should always draw for SetNeedsRedraw
598 // except if we're ready to commit, in which case we expect a commit first.
599 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
600 StateMachine
state(default_scheduler_settings
);
602 state
.UpdateState(state
.NextAction());
603 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
604 state
.SetCanDraw(true);
605 state
.SetCommitState(all_commit_states
[i
]);
606 state
.SetBeginImplFrameState(
607 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
609 state
.SetNeedsRedraw(true);
610 state
.SetVisible(true);
612 SchedulerStateMachine::Action expected_action
;
613 if (all_commit_states
[i
] ==
614 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
) {
615 expected_action
= SchedulerStateMachine::ACTION_COMMIT
;
617 expected_action
= SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
;
618 EXPECT_EQ(state
.NextAction(), SchedulerStateMachine::ACTION_ANIMATE
)
619 << state
.AsValue()->ToString();
620 state
.UpdateState(state
.NextAction());
623 // Case 1: needs_commit=false.
624 EXPECT_EQ(state
.NextAction(), expected_action
)
625 << state
.AsValue()->ToString();
627 // Case 2: needs_commit=true.
628 state
.SetNeedsCommit();
629 EXPECT_EQ(state
.NextAction(), expected_action
)
630 << state
.AsValue()->ToString();
634 TEST(SchedulerStateMachineTest
, TestNoCommitStatesRedrawWhenInvisible
) {
635 SchedulerSettings default_scheduler_settings
;
637 size_t num_commit_states
=
638 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
639 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
640 // There shouldn't be any drawing regardless of BeginImplFrame.
641 for (size_t j
= 0; j
< 2; ++j
) {
642 StateMachine
state(default_scheduler_settings
);
644 state
.UpdateState(state
.NextAction());
645 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
646 state
.SetCommitState(all_commit_states
[i
]);
647 state
.SetVisible(false);
648 state
.SetNeedsRedraw(true);
650 state
.SetBeginImplFrameState(
651 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
654 // Case 1: needs_commit=false.
655 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
658 // Case 2: needs_commit=true.
659 state
.SetNeedsCommit();
660 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
662 << state
.AsValue()->ToString();
667 TEST(SchedulerStateMachineTest
, TestCanRedraw_StopsDraw
) {
668 SchedulerSettings default_scheduler_settings
;
670 size_t num_commit_states
=
671 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
672 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
673 // There shouldn't be any drawing regardless of BeginImplFrame.
674 for (size_t j
= 0; j
< 2; ++j
) {
675 StateMachine
state(default_scheduler_settings
);
677 state
.UpdateState(state
.NextAction());
678 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
679 state
.SetCommitState(all_commit_states
[i
]);
680 state
.SetVisible(false);
681 state
.SetNeedsRedraw(true);
683 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
685 state
.SetCanDraw(false);
686 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
692 TEST(SchedulerStateMachineTest
,
693 TestCanRedrawWithWaitingForFirstDrawMakesProgress
) {
694 SchedulerSettings default_scheduler_settings
;
695 StateMachine
state(default_scheduler_settings
);
697 state
.UpdateState(state
.NextAction());
698 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
700 state
.SetActiveTreeNeedsFirstDraw(true);
701 state
.SetNeedsCommit();
702 state
.SetNeedsRedraw(true);
703 state
.SetVisible(true);
704 state
.SetCanDraw(false);
705 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
706 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
707 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
708 EXPECT_ACTION_UPDATE_STATE(
709 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
710 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
711 state
.NotifyBeginMainFrameStarted();
712 state
.NotifyReadyToCommit();
713 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
714 state
.OnBeginImplFrameDeadline();
715 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
716 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
717 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
720 TEST(SchedulerStateMachineTest
, TestSetNeedsCommitIsNotLost
) {
721 SchedulerSettings scheduler_settings
;
722 StateMachine
state(scheduler_settings
);
724 state
.UpdateState(state
.NextAction());
725 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
726 state
.SetNeedsCommit();
727 state
.SetVisible(true);
728 state
.SetCanDraw(true);
730 EXPECT_TRUE(state
.BeginFrameNeeded());
733 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
734 EXPECT_ACTION_UPDATE_STATE(
735 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
736 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
737 state
.CommitState());
739 // Now, while the frame is in progress, set another commit.
740 state
.SetNeedsCommit();
741 EXPECT_TRUE(state
.NeedsCommit());
743 // Let the frame finish.
744 state
.NotifyBeginMainFrameStarted();
745 state
.NotifyReadyToCommit();
746 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
747 state
.CommitState());
749 // Expect to commit regardless of BeginImplFrame state.
750 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
751 state
.begin_impl_frame_state());
752 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
754 state
.OnBeginImplFrameDeadlinePending();
755 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
,
756 state
.begin_impl_frame_state());
757 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
759 state
.OnBeginImplFrameDeadline();
760 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
,
761 state
.begin_impl_frame_state());
762 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
764 state
.OnBeginImplFrameIdle();
765 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
,
766 state
.begin_impl_frame_state());
767 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
769 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
770 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
771 state
.begin_impl_frame_state());
772 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
774 // Finish the commit, then make sure we start the next commit immediately
775 // and draw on the next BeginImplFrame.
776 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
777 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
778 EXPECT_ACTION_UPDATE_STATE(
779 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
780 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
782 state
.OnBeginImplFrameDeadline();
784 EXPECT_TRUE(state
.active_tree_needs_first_draw());
785 EXPECT_ACTION_UPDATE_STATE(
786 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
787 state
.DidSwapBuffers();
788 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
789 state
.DidSwapBuffersComplete();
790 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
793 TEST(SchedulerStateMachineTest
, TestFullCycle
) {
794 SchedulerSettings default_scheduler_settings
;
795 StateMachine
state(default_scheduler_settings
);
797 state
.UpdateState(state
.NextAction());
798 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
799 state
.SetVisible(true);
800 state
.SetCanDraw(true);
802 // Start clean and set commit.
803 state
.SetNeedsCommit();
806 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
807 EXPECT_ACTION_UPDATE_STATE(
808 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
809 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
810 state
.CommitState());
811 EXPECT_FALSE(state
.NeedsCommit());
812 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
814 // Tell the scheduler the frame finished.
815 state
.NotifyBeginMainFrameStarted();
816 state
.NotifyReadyToCommit();
817 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
818 state
.CommitState());
821 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
822 EXPECT_TRUE(state
.active_tree_needs_first_draw());
823 EXPECT_TRUE(state
.needs_redraw());
825 // Expect to do nothing until BeginImplFrame deadline
826 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
828 // At BeginImplFrame deadline, draw.
829 state
.OnBeginImplFrameDeadline();
830 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
831 EXPECT_ACTION_UPDATE_STATE(
832 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
833 state
.DidSwapBuffers();
834 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
835 state
.DidSwapBuffersComplete();
837 // Should be synchronized, no draw needed, no action needed.
838 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
839 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
840 EXPECT_FALSE(state
.needs_redraw());
843 TEST(SchedulerStateMachineTest
, TestFullCycleWithCommitRequestInbetween
) {
844 SchedulerSettings default_scheduler_settings
;
845 StateMachine
state(default_scheduler_settings
);
847 state
.UpdateState(state
.NextAction());
848 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
849 state
.SetVisible(true);
850 state
.SetCanDraw(true);
852 // Start clean and set commit.
853 state
.SetNeedsCommit();
856 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
857 EXPECT_ACTION_UPDATE_STATE(
858 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
859 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
860 state
.CommitState());
861 EXPECT_FALSE(state
.NeedsCommit());
862 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
864 // Request another commit while the commit is in flight.
865 state
.SetNeedsCommit();
866 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
868 // Tell the scheduler the frame finished.
869 state
.NotifyBeginMainFrameStarted();
870 state
.NotifyReadyToCommit();
871 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
872 state
.CommitState());
875 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
876 EXPECT_TRUE(state
.active_tree_needs_first_draw());
877 EXPECT_TRUE(state
.needs_redraw());
879 // Expect to do nothing until BeginImplFrame deadline.
880 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
882 // At BeginImplFrame deadline, draw.
883 state
.OnBeginImplFrameDeadline();
884 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
885 EXPECT_ACTION_UPDATE_STATE(
886 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
887 state
.DidSwapBuffers();
888 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
889 state
.DidSwapBuffersComplete();
891 // Should be synchronized, no draw needed, no action needed.
892 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
893 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
894 EXPECT_FALSE(state
.needs_redraw());
896 // Next BeginImplFrame should initiate second commit.
897 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
898 EXPECT_ACTION_UPDATE_STATE(
899 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
902 TEST(SchedulerStateMachineTest
, TestRequestCommitInvisible
) {
903 SchedulerSettings default_scheduler_settings
;
904 StateMachine
state(default_scheduler_settings
);
906 state
.UpdateState(state
.NextAction());
907 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
908 state
.SetNeedsCommit();
909 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
912 TEST(SchedulerStateMachineTest
, TestGoesInvisibleBeforeFinishCommit
) {
913 SchedulerSettings default_scheduler_settings
;
914 StateMachine
state(default_scheduler_settings
);
916 state
.UpdateState(state
.NextAction());
917 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
918 state
.SetVisible(true);
919 state
.SetCanDraw(true);
921 // Start clean and set commit.
922 state
.SetNeedsCommit();
924 // Begin the frame while visible.
925 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
926 EXPECT_ACTION_UPDATE_STATE(
927 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
928 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
929 state
.CommitState());
930 EXPECT_FALSE(state
.NeedsCommit());
931 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
933 // Become invisible and abort BeginMainFrame.
934 state
.SetVisible(false);
935 state
.BeginMainFrameAborted(false);
937 // We should now be back in the idle state as if we never started the frame.
938 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
939 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
941 // We shouldn't do anything on the BeginImplFrame deadline.
942 state
.OnBeginImplFrameDeadline();
943 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
945 // Become visible again.
946 state
.SetVisible(true);
948 // Although we have aborted on this frame and haven't cancelled the commit
949 // (i.e. need another), don't send another BeginMainFrame yet.
950 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
951 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
952 EXPECT_TRUE(state
.NeedsCommit());
954 // Start a new frame.
955 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
956 EXPECT_ACTION_UPDATE_STATE(
957 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
959 // We should be starting the commit now.
960 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
961 state
.CommitState());
962 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
965 TEST(SchedulerStateMachineTest
, AbortBeginMainFrameAndCancelCommit
) {
966 SchedulerSettings default_scheduler_settings
;
967 StateMachine
state(default_scheduler_settings
);
969 state
.UpdateState(state
.NextAction());
970 state
.DidCreateAndInitializeOutputSurface();
971 state
.SetVisible(true);
972 state
.SetCanDraw(true);
974 // Get into a begin frame / commit state.
975 state
.SetNeedsCommit();
977 EXPECT_ACTION_UPDATE_STATE(
978 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
979 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
980 state
.CommitState());
981 EXPECT_FALSE(state
.NeedsCommit());
982 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
984 // Abort the commit, cancelling future commits.
985 state
.BeginMainFrameAborted(true);
987 // Verify that another commit doesn't start on the same frame.
988 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
989 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
990 EXPECT_FALSE(state
.NeedsCommit());
992 // Start a new frame; draw because this is the first frame since output
994 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
995 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
996 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
997 state
.OnBeginImplFrameDeadline();
998 EXPECT_ACTION_UPDATE_STATE(
999 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1000 state
.DidSwapBuffers();
1001 state
.DidSwapBuffersComplete();
1003 // Verify another commit doesn't start on another frame either.
1004 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1005 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1006 EXPECT_FALSE(state
.NeedsCommit());
1008 // Verify another commit can start if requested, though.
1009 state
.SetNeedsCommit();
1010 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1011 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
,
1012 state
.NextAction());
1015 TEST(SchedulerStateMachineTest
,
1016 AbortBeginMainFrameAndCancelCommitWhenInvisible
) {
1017 SchedulerSettings default_scheduler_settings
;
1018 StateMachine
state(default_scheduler_settings
);
1019 state
.SetCanStart();
1020 state
.UpdateState(state
.NextAction());
1021 state
.DidCreateAndInitializeOutputSurface();
1022 state
.SetVisible(true);
1023 state
.SetCanDraw(true);
1025 // Get into a begin frame / commit state.
1026 state
.SetNeedsCommit();
1028 EXPECT_ACTION_UPDATE_STATE(
1029 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1030 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1031 state
.CommitState());
1032 EXPECT_FALSE(state
.NeedsCommit());
1033 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1035 // Become invisible and abort BeginMainFrame.
1036 state
.SetVisible(false);
1037 state
.BeginMainFrameAborted(true);
1039 // Verify that another commit doesn't start on the same frame.
1040 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1041 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1042 EXPECT_FALSE(state
.NeedsCommit());
1044 // Become visible and start a new frame.
1045 state
.SetVisible(true);
1046 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1047 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1048 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1050 // Draw because this is the first frame since output surface init'd.
1051 state
.OnBeginImplFrameDeadline();
1052 EXPECT_ACTION_UPDATE_STATE(
1053 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1054 state
.DidSwapBuffers();
1055 state
.DidSwapBuffersComplete();
1057 // Verify another commit doesn't start on another frame either.
1058 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1059 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1060 EXPECT_FALSE(state
.NeedsCommit());
1062 // Verify another commit can start if requested, though.
1063 state
.SetNeedsCommit();
1064 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1065 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
,
1066 state
.NextAction());
1069 TEST(SchedulerStateMachineTest
,
1070 AbortBeginMainFrameAndRequestCommitWhenInvisible
) {
1071 SchedulerSettings default_scheduler_settings
;
1072 StateMachine
state(default_scheduler_settings
);
1073 state
.SetCanStart();
1074 state
.UpdateState(state
.NextAction());
1075 state
.DidCreateAndInitializeOutputSurface();
1076 state
.SetVisible(true);
1077 state
.SetCanDraw(true);
1079 // Get into a begin frame / commit state.
1080 state
.SetNeedsCommit();
1082 EXPECT_ACTION_UPDATE_STATE(
1083 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1084 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1085 state
.CommitState());
1086 EXPECT_FALSE(state
.NeedsCommit());
1087 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1089 // Become invisible and abort BeginMainFrame.
1090 state
.SetVisible(false);
1091 state
.BeginMainFrameAborted(true);
1093 // Verify that another commit doesn't start on the same frame.
1094 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1095 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1096 EXPECT_FALSE(state
.NeedsCommit());
1098 // Asking for a commit while not visible won't make it happen.
1099 state
.SetNeedsCommit();
1100 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1101 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1102 EXPECT_TRUE(state
.NeedsCommit());
1104 // Become visible but nothing happens until the next frame.
1105 state
.SetVisible(true);
1106 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1107 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1108 EXPECT_TRUE(state
.NeedsCommit());
1110 // We should get that commit when we begin the next frame.
1111 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1112 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1113 EXPECT_ACTION_UPDATE_STATE(
1114 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1117 TEST(SchedulerStateMachineTest
,
1118 AbortBeginMainFrameAndRequestCommitAndBeginImplFrameWhenInvisible
) {
1119 SchedulerSettings default_scheduler_settings
;
1120 StateMachine
state(default_scheduler_settings
);
1121 state
.SetCanStart();
1122 state
.UpdateState(state
.NextAction());
1123 state
.DidCreateAndInitializeOutputSurface();
1124 state
.SetVisible(true);
1125 state
.SetCanDraw(true);
1127 // Get into a begin frame / commit state.
1128 state
.SetNeedsCommit();
1130 EXPECT_ACTION_UPDATE_STATE(
1131 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1132 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1133 state
.CommitState());
1134 EXPECT_FALSE(state
.NeedsCommit());
1135 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1137 // Become invisible and abort BeginMainFrame.
1138 state
.SetVisible(false);
1139 state
.BeginMainFrameAborted(true);
1141 // Asking for a commit while not visible won't make it happen.
1142 state
.SetNeedsCommit();
1143 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1144 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1145 EXPECT_TRUE(state
.NeedsCommit());
1147 // Begin a frame when not visible, the scheduler animates but does not commit.
1148 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1149 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1150 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1151 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1152 EXPECT_TRUE(state
.NeedsCommit());
1154 // Become visible and the requested commit happens immediately.
1155 state
.SetVisible(true);
1156 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1157 EXPECT_ACTION_UPDATE_STATE(
1158 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1161 TEST(SchedulerStateMachineTest
, TestFirstContextCreation
) {
1162 SchedulerSettings default_scheduler_settings
;
1163 StateMachine
state(default_scheduler_settings
);
1164 state
.SetCanStart();
1165 state
.SetVisible(true);
1166 state
.SetCanDraw(true);
1168 EXPECT_ACTION_UPDATE_STATE(
1169 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1170 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1171 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1173 // Check that the first init does not SetNeedsCommit.
1174 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1175 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1176 state
.OnBeginImplFrameDeadline();
1177 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1179 // Check that a needs commit initiates a BeginMainFrame.
1180 state
.SetNeedsCommit();
1181 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1182 EXPECT_ACTION_UPDATE_STATE(
1183 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1186 TEST(SchedulerStateMachineTest
, TestContextLostWhenCompletelyIdle
) {
1187 SchedulerSettings default_scheduler_settings
;
1188 StateMachine
state(default_scheduler_settings
);
1189 state
.SetCanStart();
1190 state
.UpdateState(state
.NextAction());
1191 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1193 state
.SetVisible(true);
1194 state
.SetCanDraw(true);
1196 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1197 state
.NextAction());
1198 state
.DidLoseOutputSurface();
1200 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1201 state
.NextAction());
1202 state
.UpdateState(state
.NextAction());
1204 // Once context recreation begins, nothing should happen.
1205 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1207 // Recreate the context.
1208 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1210 // When the context is recreated, we should begin a commit.
1211 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1212 EXPECT_ACTION_UPDATE_STATE(
1213 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1216 TEST(SchedulerStateMachineTest
,
1217 TestContextLostWhenIdleAndCommitRequestedWhileRecreating
) {
1218 SchedulerSettings default_scheduler_settings
;
1219 StateMachine
state(default_scheduler_settings
);
1220 state
.SetCanStart();
1221 state
.UpdateState(state
.NextAction());
1222 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1223 state
.SetVisible(true);
1224 state
.SetCanDraw(true);
1226 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1227 state
.NextAction());
1228 state
.DidLoseOutputSurface();
1230 EXPECT_ACTION_UPDATE_STATE(
1231 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1232 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1234 // Once context recreation begins, nothing should happen.
1235 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1236 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1237 state
.OnBeginImplFrameDeadline();
1238 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1240 // While context is recreating, commits shouldn't begin.
1241 state
.SetNeedsCommit();
1242 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1243 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1244 state
.OnBeginImplFrameDeadline();
1245 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1247 // Recreate the context
1248 state
.DidCreateAndInitializeOutputSurface();
1249 EXPECT_FALSE(state
.RedrawPending());
1251 // When the context is recreated, we should begin a commit
1252 EXPECT_ACTION_UPDATE_STATE(
1253 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1254 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1255 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1256 state
.CommitState());
1258 state
.NotifyBeginMainFrameStarted();
1259 state
.NotifyReadyToCommit();
1260 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1261 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1262 // Finishing the first commit after initializing an output surface should
1263 // automatically cause a redraw.
1264 EXPECT_TRUE(state
.RedrawPending());
1266 // Once the context is recreated, whether we draw should be based on
1268 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1269 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1270 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1271 state
.OnBeginImplFrameDeadline();
1272 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
1273 state
.NextAction());
1274 state
.SetCanDraw(false);
1275 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
,
1276 state
.NextAction());
1277 state
.SetCanDraw(true);
1278 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
1279 state
.NextAction());
1282 TEST(SchedulerStateMachineTest
, TestContextLostWhileCommitInProgress
) {
1283 SchedulerSettings scheduler_settings
;
1284 StateMachine
state(scheduler_settings
);
1285 state
.SetCanStart();
1286 state
.UpdateState(state
.NextAction());
1287 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1288 state
.SetVisible(true);
1289 state
.SetCanDraw(true);
1291 // Get a commit in flight.
1292 state
.SetNeedsCommit();
1294 // Set damage and expect a draw.
1295 state
.SetNeedsRedraw(true);
1296 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1297 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1298 EXPECT_ACTION_UPDATE_STATE(
1299 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1300 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1301 state
.OnBeginImplFrameDeadline();
1302 EXPECT_ACTION_UPDATE_STATE(
1303 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1304 state
.DidSwapBuffers();
1305 state
.DidSwapBuffersComplete();
1306 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1308 // Cause a lost context while the BeginMainFrame is in flight.
1309 state
.DidLoseOutputSurface();
1311 // Ask for another draw. Expect nothing happens.
1312 state
.SetNeedsRedraw(true);
1313 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1315 // Finish the frame, and commit.
1316 state
.NotifyBeginMainFrameStarted();
1317 state
.NotifyReadyToCommit();
1318 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1320 // We will abort the draw when the output surface is lost if we are
1321 // waiting for the first draw to unblock the main thread.
1322 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1323 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1325 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1326 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
,
1327 state
.begin_impl_frame_state());
1328 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1329 state
.NextAction());
1331 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1332 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
1333 state
.begin_impl_frame_state());
1334 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1336 state
.OnBeginImplFrameDeadlinePending();
1337 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
,
1338 state
.begin_impl_frame_state());
1339 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1341 state
.OnBeginImplFrameDeadline();
1342 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
,
1343 state
.begin_impl_frame_state());
1344 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1347 TEST(SchedulerStateMachineTest
,
1348 TestContextLostWhileCommitInProgressAndAnotherCommitRequested
) {
1349 SchedulerSettings scheduler_settings
;
1350 StateMachine
state(scheduler_settings
);
1351 state
.SetCanStart();
1352 state
.UpdateState(state
.NextAction());
1353 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1354 state
.SetVisible(true);
1355 state
.SetCanDraw(true);
1357 // Get a commit in flight.
1358 state
.SetNeedsCommit();
1359 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1361 // Set damage and expect a draw.
1362 state
.SetNeedsRedraw(true);
1363 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1364 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1365 EXPECT_ACTION_UPDATE_STATE(
1366 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1367 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1368 state
.OnBeginImplFrameDeadline();
1369 EXPECT_ACTION_UPDATE_STATE(
1370 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1371 state
.DidSwapBuffers();
1372 state
.DidSwapBuffersComplete();
1373 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1375 // Cause a lost context while the BeginMainFrame is in flight.
1376 state
.DidLoseOutputSurface();
1378 // Ask for another draw and also set needs commit. Expect nothing happens.
1379 state
.SetNeedsRedraw(true);
1380 state
.SetNeedsCommit();
1381 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1383 // Finish the frame, and commit.
1384 state
.NotifyBeginMainFrameStarted();
1385 state
.NotifyReadyToCommit();
1386 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1387 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1389 // Because the output surface is missing, we expect the draw to abort.
1390 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1392 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1393 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
,
1394 state
.begin_impl_frame_state());
1395 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1396 state
.NextAction());
1398 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1399 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
1400 state
.begin_impl_frame_state());
1401 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1403 state
.OnBeginImplFrameDeadlinePending();
1404 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
,
1405 state
.begin_impl_frame_state());
1406 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1408 state
.OnBeginImplFrameDeadline();
1409 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
,
1410 state
.begin_impl_frame_state());
1411 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1413 state
.OnBeginImplFrameIdle();
1414 EXPECT_ACTION_UPDATE_STATE(
1415 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1417 // After we get a new output surface, the commit flow should start.
1418 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1419 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1420 EXPECT_ACTION_UPDATE_STATE(
1421 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1422 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1423 state
.NotifyBeginMainFrameStarted();
1424 state
.NotifyReadyToCommit();
1425 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1426 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1427 state
.OnBeginImplFrameDeadline();
1428 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1429 EXPECT_ACTION_UPDATE_STATE(
1430 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1431 state
.DidSwapBuffers();
1432 state
.DidSwapBuffersComplete();
1433 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1436 TEST(SchedulerStateMachineTest
, DontDrawBeforeCommitAfterLostOutputSurface
) {
1437 SchedulerSettings default_scheduler_settings
;
1438 StateMachine
state(default_scheduler_settings
);
1439 state
.SetCanStart();
1440 state
.UpdateState(state
.NextAction());
1441 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1442 state
.SetVisible(true);
1443 state
.SetCanDraw(true);
1445 state
.SetNeedsRedraw(true);
1447 // Cause a lost output surface, and restore it.
1448 state
.DidLoseOutputSurface();
1449 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1450 state
.NextAction());
1451 state
.UpdateState(state
.NextAction());
1452 state
.DidCreateAndInitializeOutputSurface();
1454 EXPECT_FALSE(state
.RedrawPending());
1455 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1456 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
,
1457 state
.NextAction());
1460 TEST(SchedulerStateMachineTest
,
1461 TestPendingActivationsShouldBeForcedAfterLostOutputSurface
) {
1462 SchedulerSettings settings
;
1463 settings
.impl_side_painting
= true;
1464 StateMachine
state(settings
);
1465 state
.SetCanStart();
1466 state
.UpdateState(state
.NextAction());
1467 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1468 state
.SetVisible(true);
1469 state
.SetCanDraw(true);
1471 state
.SetCommitState(
1472 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1474 // Cause a lost context.
1475 state
.DidLoseOutputSurface();
1477 state
.NotifyBeginMainFrameStarted();
1478 state
.NotifyReadyToCommit();
1479 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1481 EXPECT_TRUE(state
.PendingActivationsShouldBeForced());
1482 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1484 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1485 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1488 TEST(SchedulerStateMachineTest
, TestNoBeginMainFrameWhenInvisible
) {
1489 SchedulerSettings default_scheduler_settings
;
1490 StateMachine
state(default_scheduler_settings
);
1491 state
.SetCanStart();
1492 state
.UpdateState(state
.NextAction());
1493 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1494 state
.SetVisible(false);
1495 state
.SetNeedsCommit();
1496 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1499 TEST(SchedulerStateMachineTest
, TestFinishCommitWhenCommitInProgress
) {
1500 SchedulerSettings default_scheduler_settings
;
1501 StateMachine
state(default_scheduler_settings
);
1502 state
.SetCanStart();
1503 state
.UpdateState(state
.NextAction());
1504 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1505 state
.SetVisible(false);
1506 state
.SetCommitState(
1507 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1508 state
.SetNeedsCommit();
1510 state
.NotifyBeginMainFrameStarted();
1511 state
.NotifyReadyToCommit();
1512 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
1513 state
.UpdateState(state
.NextAction());
1515 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1516 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1519 TEST(SchedulerStateMachineTest
, TestInitialActionsWhenContextLost
) {
1520 SchedulerSettings default_scheduler_settings
;
1521 StateMachine
state(default_scheduler_settings
);
1522 state
.SetCanStart();
1523 state
.UpdateState(state
.NextAction());
1524 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1525 state
.SetVisible(true);
1526 state
.SetCanDraw(true);
1527 state
.SetNeedsCommit();
1528 state
.DidLoseOutputSurface();
1530 // When we are visible, we normally want to begin output surface creation
1531 // as soon as possible.
1532 EXPECT_ACTION_UPDATE_STATE(
1533 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1535 state
.DidCreateAndInitializeOutputSurface();
1536 EXPECT_EQ(state
.output_surface_state(),
1537 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT
);
1539 // We should not send a BeginMainFrame when we are invisible, even if we've
1540 // lost the output surface and are trying to get the first commit, since the
1541 // main thread will just abort anyway.
1542 state
.SetVisible(false);
1543 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction())
1544 << state
.AsValue()->ToString();
1547 TEST(SchedulerStateMachineTest
, ReportIfNotDrawing
) {
1548 SchedulerSettings default_scheduler_settings
;
1549 StateMachine
state(default_scheduler_settings
);
1550 state
.SetCanStart();
1551 state
.UpdateState(state
.NextAction());
1552 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1554 state
.SetCanDraw(true);
1555 state
.SetVisible(true);
1556 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1558 state
.SetCanDraw(false);
1559 state
.SetVisible(true);
1560 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1562 state
.SetCanDraw(true);
1563 state
.SetVisible(false);
1564 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1566 state
.SetCanDraw(false);
1567 state
.SetVisible(false);
1568 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1570 state
.SetCanDraw(true);
1571 state
.SetVisible(true);
1572 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1575 TEST(SchedulerStateMachineTest
, TestTriggerDeadlineEarlyAfterAbortedCommit
) {
1576 SchedulerSettings settings
;
1577 settings
.impl_side_painting
= true;
1578 StateMachine
state(settings
);
1579 state
.SetCanStart();
1580 state
.UpdateState(state
.NextAction());
1581 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1582 state
.SetVisible(true);
1583 state
.SetCanDraw(true);
1585 // This test mirrors what happens during the first frame of a scroll gesture.
1586 // First we get the input event and a BeginFrame.
1587 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1589 // As a response the compositor requests a redraw and a commit to tell the
1590 // main thread about the new scroll offset.
1591 state
.SetNeedsRedraw(true);
1592 state
.SetNeedsCommit();
1594 // We should start the commit normally.
1595 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1596 EXPECT_ACTION_UPDATE_STATE(
1597 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1598 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1600 // Since only the scroll offset changed, the main thread will abort the
1602 state
.BeginMainFrameAborted(true);
1604 // Since the commit was aborted, we should draw right away instead of waiting
1605 // for the deadline.
1606 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1609 void FinishPreviousCommitAndDrawWithoutExitingDeadline(
1610 StateMachine
* state_ptr
) {
1611 // Gross, but allows us to use macros below.
1612 StateMachine
& state
= *state_ptr
;
1614 state
.NotifyBeginMainFrameStarted();
1615 state
.NotifyReadyToCommit();
1616 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1617 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1618 state
.NotifyReadyToActivate();
1619 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1620 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1622 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1623 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1624 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1626 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1627 state
.OnBeginImplFrameDeadline();
1628 EXPECT_ACTION_UPDATE_STATE(
1629 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1630 state
.DidSwapBuffers();
1633 TEST(SchedulerStateMachineTest
, TestImplLatencyTakesPriority
) {
1634 SchedulerSettings settings
;
1635 settings
.impl_side_painting
= true;
1636 StateMachine
state(settings
);
1637 state
.SetCanStart();
1638 state
.UpdateState(state
.NextAction());
1639 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1640 state
.SetVisible(true);
1641 state
.SetCanDraw(true);
1643 // This test ensures that impl-draws are prioritized over main thread updates
1644 // in prefer impl latency mode.
1645 state
.SetNeedsRedraw(true);
1646 state
.SetNeedsCommit();
1647 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1648 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1649 EXPECT_ACTION_UPDATE_STATE(
1650 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1651 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1653 // Verify the deadline is not triggered early until we enter
1654 // prefer impl latency mode.
1655 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1656 state
.SetImplLatencyTakesPriority(true);
1657 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1659 // Trigger the deadline.
1660 state
.OnBeginImplFrameDeadline();
1661 EXPECT_ACTION_UPDATE_STATE(
1662 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1663 state
.DidSwapBuffers();
1664 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1665 state
.DidSwapBuffersComplete();
1667 // Request a new commit and finish the previous one.
1668 state
.SetNeedsCommit();
1669 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state
);
1670 EXPECT_ACTION_UPDATE_STATE(
1671 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1672 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1673 state
.DidSwapBuffersComplete();
1674 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1676 // Finish the previous commit and draw it.
1677 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state
);
1678 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1680 // Verify we do not send another BeginMainFrame if was are swap throttled
1681 // and did not just swap.
1682 state
.SetNeedsCommit();
1683 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1684 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1685 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1686 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1687 state
.OnBeginImplFrameDeadline();
1688 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1691 TEST(SchedulerStateMachineTest
, TestTriggerDeadlineEarlyOnLostOutputSurface
) {
1692 SchedulerSettings default_scheduler_settings
;
1693 StateMachine
state(default_scheduler_settings
);
1694 state
.SetCanStart();
1695 state
.UpdateState(state
.NextAction());
1696 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1697 state
.SetVisible(true);
1698 state
.SetCanDraw(true);
1700 state
.SetNeedsCommit();
1702 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1703 EXPECT_ACTION_UPDATE_STATE(
1704 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1705 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1706 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1708 state
.DidLoseOutputSurface();
1709 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1710 // The deadline should be triggered immediately when output surface is lost.
1711 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1714 TEST(SchedulerStateMachineTest
, TestSetNeedsAnimate
) {
1715 SchedulerSettings settings
;
1716 settings
.impl_side_painting
= true;
1717 StateMachine
state(settings
);
1718 state
.SetCanStart();
1719 state
.UpdateState(state
.NextAction());
1720 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1721 state
.SetVisible(true);
1722 state
.SetCanDraw(true);
1724 // Test requesting an animation that, when run, causes us to draw.
1725 state
.SetNeedsAnimate();
1726 EXPECT_TRUE(state
.BeginFrameNeeded());
1727 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1729 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1730 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1732 state
.OnBeginImplFrameDeadlinePending();
1733 state
.OnBeginImplFrameDeadline();
1734 EXPECT_ACTION_UPDATE_STATE(
1735 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1738 TEST(SchedulerStateMachineTest
, TestAnimateBeforeCommit
) {
1739 SchedulerSettings settings
;
1740 settings
.impl_side_painting
= true;
1741 StateMachine
state(settings
);
1742 state
.SetCanStart();
1743 state
.UpdateState(state
.NextAction());
1744 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1745 state
.SetVisible(true);
1746 state
.SetCanDraw(true);
1748 // Check that animations are updated before we start a commit.
1749 state
.SetNeedsAnimate();
1750 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1751 state
.SetNeedsCommit();
1752 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1753 EXPECT_TRUE(state
.BeginFrameNeeded());
1755 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1756 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1757 EXPECT_ACTION_UPDATE_STATE(
1758 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1760 state
.OnBeginImplFrameDeadlinePending();
1761 state
.OnBeginImplFrameDeadline();
1762 EXPECT_ACTION_UPDATE_STATE(
1763 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1766 TEST(SchedulerStateMachineTest
, TestAnimateAfterCommitBeforeDraw
) {
1767 SchedulerSettings settings
;
1768 settings
.impl_side_painting
= true;
1769 StateMachine
state(settings
);
1770 state
.SetCanStart();
1771 state
.UpdateState(state
.NextAction());
1772 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1773 state
.SetVisible(true);
1774 state
.SetCanDraw(true);
1776 // Check that animations are updated before we start a commit.
1777 state
.SetNeedsAnimate();
1778 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1779 state
.SetNeedsCommit();
1780 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1781 EXPECT_TRUE(state
.BeginFrameNeeded());
1783 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1784 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1785 EXPECT_ACTION_UPDATE_STATE(
1786 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1788 state
.NotifyBeginMainFrameStarted();
1789 state
.NotifyReadyToCommit();
1790 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1792 state
.OnBeginImplFrameDeadlinePending();
1793 state
.OnBeginImplFrameDeadline();
1794 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1795 EXPECT_ACTION_UPDATE_STATE(
1796 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1799 TEST(SchedulerStateMachineTest
, TestSetNeedsAnimateAfterAnimate
) {
1800 SchedulerSettings settings
;
1801 settings
.impl_side_painting
= true;
1802 StateMachine
state(settings
);
1803 state
.SetCanStart();
1804 state
.UpdateState(state
.NextAction());
1805 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1806 state
.SetVisible(true);
1807 state
.SetCanDraw(true);
1809 // Test requesting an animation after we have already animated during this
1811 state
.SetNeedsRedraw(true);
1812 EXPECT_TRUE(state
.BeginFrameNeeded());
1813 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1815 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1816 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1818 state
.SetNeedsAnimate();
1819 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1821 state
.OnBeginImplFrameDeadline();
1822 EXPECT_ACTION_UPDATE_STATE(
1823 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);