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(); \
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(); \
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
{
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
429 state
.UpdateState(state
.NextAction());
430 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
431 state
.SetVisible(true);
432 state
.SetCanDraw(true);
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
);
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
;
495 scheduler_settings
.maximum_number_of_failed_draws_before_draw_is_forced_
=
497 scheduler_settings
.impl_side_painting
= true;
498 StateMachine
state(scheduler_settings
);
500 state
.UpdateState(state
.NextAction());
501 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
502 state
.SetVisible(true);
503 state
.SetCanDraw(true);
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
);
560 state
.UpdateState(state
.NextAction());
561 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
562 state
.SetVisible(true);
563 state
.SetCanDraw(true);
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
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
);
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
);
652 state
.UpdateState(state
.NextAction());
653 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
654 state
.SetCommitState(all_commit_states
[i
]);
655 state
.SetBeginImplFrameState(all_begin_impl_frame_states
[j
]);
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
,
665 // Case 2: needs_commit=true
666 state
.SetNeedsCommit();
667 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
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
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
);
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();
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
;
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
);
729 state
.UpdateState(state
.NextAction());
730 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
731 state
.SetCommitState(all_commit_states
[i
]);
732 state
.SetVisible(false);
733 state
.SetNeedsRedraw(true);
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
,
743 // Case 2: needs_commit=true.
744 state
.SetNeedsCommit();
745 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
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
);
762 state
.UpdateState(state
.NextAction());
763 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
764 state
.SetCommitState(all_commit_states
[i
]);
765 state
.SetVisible(false);
766 state
.SetNeedsRedraw(true);
768 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
770 state
.SetCanDraw(false);
771 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
777 TEST(SchedulerStateMachineTest
,
778 TestCanRedrawWithWaitingForFirstDrawMakesProgress
) {
779 SchedulerSettings default_scheduler_settings
;
780 StateMachine
state(default_scheduler_settings
);
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
);
809 state
.UpdateState(state
.NextAction());
810 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
811 state
.SetNeedsCommit();
812 state
.SetVisible(true);
813 state
.SetCanDraw(true);
815 EXPECT_TRUE(state
.BeginFrameNeeded());
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
);
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();
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());
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
);
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();
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());
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
);
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
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
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());
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
);
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
)
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
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();
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
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());