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 if (SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW == \
15 state.CommitState() && \
16 SchedulerStateMachine::OUTPUT_SURFACE_ACTIVE != \
17 state.output_surface_state()) \
19 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE, \
20 state.begin_impl_frame_state()) \
21 << *state.AsValue(); \
23 state.UpdateState(action); \
24 if (action == SchedulerStateMachine::ACTION_NONE) { \
25 if (state.begin_impl_frame_state() == \
26 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) \
27 state.OnBeginImplFrameDeadlinePending(); \
28 if (state.begin_impl_frame_state() == \
29 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) \
30 state.OnBeginImplFrameIdle(); \
37 const SchedulerStateMachine::BeginImplFrameState all_begin_impl_frame_states
[] =
38 {SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
,
39 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
40 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
,
41 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
, };
43 const SchedulerStateMachine::CommitState all_commit_states
[] = {
44 SchedulerStateMachine::COMMIT_STATE_IDLE
,
45 SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
46 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
47 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
, };
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 commit_state_
= COMMIT_STATE_WAITING_FOR_FIRST_DRAW
;
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 commit_state_
= COMMIT_STATE_WAITING_FOR_FIRST_DRAW
;
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();
112 TEST(SchedulerStateMachineTest
, TestNextActionBeginsMainFrameIfNeeded
) {
113 SchedulerSettings default_scheduler_settings
;
115 // If no commit needed, do nothing.
117 StateMachine
state(default_scheduler_settings
);
119 EXPECT_ACTION_UPDATE_STATE(
120 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
)
121 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
122 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
123 state
.SetNeedsRedraw(false);
124 state
.SetVisible(true);
126 EXPECT_FALSE(state
.BeginImplFrameNeeded());
128 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
129 EXPECT_FALSE(state
.BeginImplFrameNeeded());
130 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
132 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
133 state
.OnBeginImplFrameDeadline();
136 // If commit requested but can_start is still false, do nothing.
138 StateMachine
state(default_scheduler_settings
);
139 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
140 state
.SetNeedsRedraw(false);
141 state
.SetVisible(true);
143 EXPECT_FALSE(state
.BeginImplFrameNeeded());
145 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
146 EXPECT_FALSE(state
.BeginImplFrameNeeded());
147 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
148 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
149 state
.OnBeginImplFrameDeadline();
152 // If commit requested, begin a main frame.
154 StateMachine
state(default_scheduler_settings
);
155 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
157 state
.SetNeedsRedraw(false);
158 state
.SetVisible(true);
159 EXPECT_FALSE(state
.BeginImplFrameNeeded());
162 // Begin the frame, make sure needs_commit and commit_state update correctly.
164 StateMachine
state(default_scheduler_settings
);
166 state
.UpdateState(state
.NextAction());
167 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
168 state
.SetVisible(true);
169 state
.UpdateState(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
170 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
171 state
.CommitState());
172 EXPECT_FALSE(state
.NeedsCommit());
176 TEST(SchedulerStateMachineTest
,
177 TestFailedDrawSetsNeedsCommitAndDoesNotDrawAgain
) {
178 SchedulerSettings default_scheduler_settings
;
179 StateMachine
state(default_scheduler_settings
);
181 state
.UpdateState(state
.NextAction());
182 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
183 state
.SetVisible(true);
184 state
.SetCanDraw(true);
185 state
.SetNeedsRedraw(true);
186 EXPECT_TRUE(state
.RedrawPending());
187 EXPECT_TRUE(state
.BeginImplFrameNeeded());
188 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
189 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
190 state
.OnBeginImplFrameDeadline();
192 // We're drawing now.
193 EXPECT_ACTION_UPDATE_STATE(
194 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
195 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
197 EXPECT_FALSE(state
.RedrawPending());
198 EXPECT_FALSE(state
.CommitPending());
200 // Failing the draw makes us require a commit.
201 state
.DidDrawIfPossibleCompleted(false);
202 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
203 EXPECT_ACTION_UPDATE_STATE(
204 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
205 EXPECT_TRUE(state
.RedrawPending());
206 EXPECT_TRUE(state
.CommitPending());
209 TEST(SchedulerStateMachineTest
,
210 TestsetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw
) {
211 SchedulerSettings default_scheduler_settings
;
212 StateMachine
state(default_scheduler_settings
);
214 state
.UpdateState(state
.NextAction());
215 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
217 state
.SetVisible(true);
218 state
.SetCanDraw(true);
219 state
.SetNeedsRedraw(true);
220 EXPECT_TRUE(state
.RedrawPending());
221 EXPECT_TRUE(state
.BeginImplFrameNeeded());
222 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
223 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
224 state
.OnBeginImplFrameDeadline();
226 // We're drawing now.
227 EXPECT_ACTION_UPDATE_STATE(
228 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
229 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
230 EXPECT_FALSE(state
.RedrawPending());
231 EXPECT_FALSE(state
.CommitPending());
233 // While still in the same BeginMainFrame callback on the main thread,
234 // set needs redraw again. This should not redraw.
235 state
.SetNeedsRedraw(true);
236 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
238 // Failing the draw makes us require a commit.
239 state
.DidDrawIfPossibleCompleted(false);
240 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
241 EXPECT_ACTION_UPDATE_STATE(
242 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
243 EXPECT_TRUE(state
.RedrawPending());
246 void TestFailedDrawsWillEventuallyForceADrawAfterTheNextCommit(
247 bool deadline_scheduling_enabled
) {
248 SchedulerSettings scheduler_settings
;
249 scheduler_settings
.maximum_number_of_failed_draws_before_draw_is_forced_
= 1;
250 scheduler_settings
.deadline_scheduling_enabled
= deadline_scheduling_enabled
;
251 StateMachine
state(scheduler_settings
);
253 state
.UpdateState(state
.NextAction());
254 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
255 state
.SetVisible(true);
256 state
.SetCanDraw(true);
259 state
.SetNeedsCommit();
260 if (!deadline_scheduling_enabled
) {
261 EXPECT_ACTION_UPDATE_STATE(
262 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
264 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
265 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
266 if (deadline_scheduling_enabled
) {
267 EXPECT_ACTION_UPDATE_STATE(
268 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
270 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
271 EXPECT_TRUE(state
.CommitPending());
273 // Then initiate a draw.
274 state
.SetNeedsRedraw(true);
275 state
.OnBeginImplFrameDeadline();
276 EXPECT_ACTION_UPDATE_STATE(
277 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
280 state
.DidDrawIfPossibleCompleted(false);
281 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
282 EXPECT_TRUE(state
.BeginImplFrameNeeded());
283 EXPECT_TRUE(state
.RedrawPending());
284 // But the commit is ongoing.
285 EXPECT_TRUE(state
.CommitPending());
287 // Finish the commit. Note, we should not yet be forcing a draw, but should
288 // continue the commit as usual.
289 state
.FinishCommit();
290 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
291 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
292 EXPECT_TRUE(state
.RedrawPending());
294 // The redraw should be forced at the end of the next BeginImplFrame.
295 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
296 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
297 state
.OnBeginImplFrameDeadline();
298 EXPECT_ACTION_UPDATE_STATE(
299 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED
);
302 TEST(SchedulerStateMachineTest
,
303 TestFailedDrawsWillEventuallyForceADrawAfterTheNextCommit
) {
304 bool deadline_scheduling_enabled
= false;
305 TestFailedDrawsWillEventuallyForceADrawAfterTheNextCommit(
306 deadline_scheduling_enabled
);
309 TEST(SchedulerStateMachineTest
,
310 TestFailedDrawsWillEventuallyForceADrawAfterTheNextCommit_Deadline
) {
311 bool deadline_scheduling_enabled
= true;
312 TestFailedDrawsWillEventuallyForceADrawAfterTheNextCommit(
313 deadline_scheduling_enabled
);
316 void TestFailedDrawsDoNotRestartForcedDraw(
317 bool deadline_scheduling_enabled
) {
318 SchedulerSettings scheduler_settings
;
320 scheduler_settings
.maximum_number_of_failed_draws_before_draw_is_forced_
=
322 scheduler_settings
.deadline_scheduling_enabled
= deadline_scheduling_enabled
;
323 scheduler_settings
.impl_side_painting
= true;
324 StateMachine
state(scheduler_settings
);
326 state
.UpdateState(state
.NextAction());
327 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
328 state
.SetVisible(true);
329 state
.SetCanDraw(true);
332 state
.SetNeedsCommit();
333 if (!deadline_scheduling_enabled
) {
334 EXPECT_ACTION_UPDATE_STATE(
335 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
337 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
338 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
339 if (deadline_scheduling_enabled
) {
340 EXPECT_ACTION_UPDATE_STATE(
341 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
343 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
344 EXPECT_TRUE(state
.CommitPending());
346 // Then initiate a draw.
347 state
.SetNeedsRedraw(true);
348 state
.OnBeginImplFrameDeadline();
349 EXPECT_ACTION_UPDATE_STATE(
350 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
352 // Fail the draw enough times to force a redraw,
353 // then once more for good measure.
354 for (int i
= 0; i
< drawLimit
; ++i
)
355 state
.DidDrawIfPossibleCompleted(false);
356 state
.DidDrawIfPossibleCompleted(false);
357 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
358 EXPECT_TRUE(state
.BeginImplFrameNeeded());
359 EXPECT_TRUE(state
.RedrawPending());
360 // But the commit is ongoing.
361 EXPECT_TRUE(state
.CommitPending());
362 EXPECT_TRUE(state
.ForcedRedrawState() ==
363 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_COMMIT
);
365 state
.FinishCommit();
366 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
367 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
368 EXPECT_TRUE(state
.RedrawPending());
369 EXPECT_FALSE(state
.CommitPending());
371 // Now force redraw should be in waiting for activation
372 EXPECT_TRUE(state
.ForcedRedrawState() ==
373 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
);
375 // After failing additional draws, we should still be in a forced
376 // redraw, but not back in WAITING_FOR_COMMIT.
377 for (int i
= 0; i
< drawLimit
; ++i
)
378 state
.DidDrawIfPossibleCompleted(false);
379 state
.DidDrawIfPossibleCompleted(false);
380 EXPECT_TRUE(state
.RedrawPending());
381 EXPECT_TRUE(state
.ForcedRedrawState() ==
382 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
);
385 TEST(SchedulerStateMachineTest
,
386 TestFailedDrawsDoNotRestartForcedDraw
) {
387 bool deadline_scheduling_enabled
= false;
388 TestFailedDrawsDoNotRestartForcedDraw(
389 deadline_scheduling_enabled
);
392 TEST(SchedulerStateMachineTest
,
393 TestFailedDrawsDoNotRestartForcedDraw_Deadline
) {
394 bool deadline_scheduling_enabled
= true;
395 TestFailedDrawsDoNotRestartForcedDraw(
396 deadline_scheduling_enabled
);
399 TEST(SchedulerStateMachineTest
, TestFailedDrawIsRetriedInNextBeginImplFrame
) {
400 SchedulerSettings default_scheduler_settings
;
401 StateMachine
state(default_scheduler_settings
);
403 state
.UpdateState(state
.NextAction());
404 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
405 state
.SetVisible(true);
406 state
.SetCanDraw(true);
409 state
.SetNeedsRedraw(true);
410 EXPECT_TRUE(state
.BeginImplFrameNeeded());
411 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
412 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
413 state
.OnBeginImplFrameDeadline();
414 EXPECT_TRUE(state
.RedrawPending());
415 EXPECT_ACTION_UPDATE_STATE(
416 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
419 state
.DidDrawIfPossibleCompleted(false);
420 EXPECT_ACTION_UPDATE_STATE(
421 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
422 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
423 EXPECT_TRUE(state
.RedrawPending());
425 // We should not be trying to draw again now, but we have a commit pending.
426 EXPECT_TRUE(state
.BeginImplFrameNeeded());
427 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
428 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
430 // We should try to draw again at the end of the next BeginImplFrame on
432 state
.OnBeginImplFrameDeadline();
433 EXPECT_ACTION_UPDATE_STATE(
434 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
435 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
438 TEST(SchedulerStateMachineTest
, TestDoestDrawTwiceInSameFrame
) {
439 SchedulerSettings default_scheduler_settings
;
440 StateMachine
state(default_scheduler_settings
);
442 state
.UpdateState(state
.NextAction());
443 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
444 state
.SetVisible(true);
445 state
.SetCanDraw(true);
446 state
.SetNeedsRedraw(true);
448 // Draw the first frame.
449 EXPECT_TRUE(state
.BeginImplFrameNeeded());
450 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
451 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
453 state
.OnBeginImplFrameDeadline();
454 EXPECT_ACTION_UPDATE_STATE(
455 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
456 state
.DidDrawIfPossibleCompleted(true);
457 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
459 // Before the next BeginImplFrame, set needs redraw again.
460 // This should not redraw until the next BeginImplFrame.
461 state
.SetNeedsRedraw(true);
462 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
464 // Move to another frame. This should now draw.
465 EXPECT_TRUE(state
.BeginImplFrameNeeded());
466 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
468 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
470 state
.OnBeginImplFrameDeadline();
471 EXPECT_ACTION_UPDATE_STATE(
472 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
473 state
.DidDrawIfPossibleCompleted(true);
474 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
476 // We just swapped, so we should proactively request another BeginImplFrame.
477 EXPECT_TRUE(state
.BeginImplFrameNeeded());
480 TEST(SchedulerStateMachineTest
, TestNextActionDrawsOnBeginImplFrame
) {
481 SchedulerSettings default_scheduler_settings
;
483 // When not in BeginImplFrame deadline, or in BeginImplFrame deadline
484 // but not visible, don't draw.
485 size_t num_commit_states
=
486 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
487 size_t num_begin_impl_frame_states
=
488 sizeof(all_begin_impl_frame_states
) /
489 sizeof(SchedulerStateMachine::BeginImplFrameState
);
490 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
491 for (size_t j
= 0; j
< num_begin_impl_frame_states
; ++j
) {
492 StateMachine
state(default_scheduler_settings
);
494 state
.UpdateState(state
.NextAction());
495 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
496 state
.SetCommitState(all_commit_states
[i
]);
497 state
.SetBeginImplFrameState(all_begin_impl_frame_states
[j
]);
499 (all_begin_impl_frame_states
[j
] !=
500 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
501 state
.SetVisible(visible
);
503 // Case 1: needs_commit=false
504 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
507 // Case 2: needs_commit=true
508 state
.SetNeedsCommit();
509 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
515 // When in BeginImplFrame deadline we should always draw for SetNeedsRedraw or
516 // SetNeedsForcedRedrawForReadback have been called... except if we're
517 // ready to commit, in which case we expect a commit first.
518 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
519 for (size_t j
= 0; j
< 2; ++j
) {
520 bool request_readback
= j
;
522 // Skip invalid states
523 if (request_readback
&&
524 (SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
!=
525 all_commit_states
[i
]))
528 StateMachine
state(default_scheduler_settings
);
530 state
.UpdateState(state
.NextAction());
531 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
532 state
.SetCanDraw(true);
533 state
.SetCommitState(all_commit_states
[i
]);
534 state
.SetBeginImplFrameState(
535 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
536 if (request_readback
) {
537 state
.SetNeedsForcedRedrawForReadback();
539 state
.SetNeedsRedraw(true);
540 state
.SetVisible(true);
543 SchedulerStateMachine::Action expected_action
;
544 if (all_commit_states
[i
] ==
545 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
) {
546 expected_action
= SchedulerStateMachine::ACTION_COMMIT
;
547 } else if (request_readback
) {
548 if (all_commit_states
[i
] ==
549 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
)
550 expected_action
= SchedulerStateMachine::ACTION_DRAW_AND_READBACK
;
552 expected_action
= SchedulerStateMachine::ACTION_NONE
;
555 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
;
558 // Case 1: needs_commit=false.
559 EXPECT_NE(state
.BeginImplFrameNeeded(), request_readback
)
561 EXPECT_EQ(expected_action
, state
.NextAction()) << *state
.AsValue();
563 // Case 2: needs_commit=true.
564 state
.SetNeedsCommit();
565 EXPECT_NE(state
.BeginImplFrameNeeded(), request_readback
)
567 EXPECT_EQ(expected_action
, state
.NextAction()) << *state
.AsValue();
572 TEST(SchedulerStateMachineTest
, TestNoCommitStatesRedrawWhenInvisible
) {
573 SchedulerSettings default_scheduler_settings
;
575 size_t num_commit_states
=
576 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
577 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
578 // There shouldn't be any drawing regardless of BeginImplFrame.
579 for (size_t j
= 0; j
< 2; ++j
) {
580 StateMachine
state(default_scheduler_settings
);
582 state
.UpdateState(state
.NextAction());
583 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
584 state
.SetCommitState(all_commit_states
[i
]);
585 state
.SetVisible(false);
586 state
.SetNeedsRedraw(true);
588 state
.SetBeginImplFrameState(
589 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
592 // Case 1: needs_commit=false.
593 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
596 // Case 2: needs_commit=true.
597 state
.SetNeedsCommit();
598 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
605 TEST(SchedulerStateMachineTest
, TestCanRedraw_StopsDraw
) {
606 SchedulerSettings default_scheduler_settings
;
608 size_t num_commit_states
=
609 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
610 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
611 // There shouldn't be any drawing regardless of BeginImplFrame.
612 for (size_t j
= 0; j
< 2; ++j
) {
613 StateMachine
state(default_scheduler_settings
);
615 state
.UpdateState(state
.NextAction());
616 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
617 state
.SetCommitState(all_commit_states
[i
]);
618 state
.SetVisible(false);
619 state
.SetNeedsRedraw(true);
621 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
623 state
.SetCanDraw(false);
624 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
630 TEST(SchedulerStateMachineTest
,
631 TestCanRedrawWithWaitingForFirstDrawMakesProgress
) {
632 SchedulerSettings default_scheduler_settings
;
633 StateMachine
state(default_scheduler_settings
);
635 state
.UpdateState(state
.NextAction());
636 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
638 state
.SetCommitState(
639 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
);
640 state
.SetActiveTreeNeedsFirstDraw(true);
641 state
.SetNeedsCommit();
642 state
.SetNeedsRedraw(true);
643 state
.SetVisible(true);
644 state
.SetCanDraw(false);
645 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
646 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
647 EXPECT_ACTION_UPDATE_STATE(
648 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
649 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
650 state
.FinishCommit();
651 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
652 state
.OnBeginImplFrameDeadline();
653 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
654 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
657 TEST(SchedulerStateMachineTest
, TestsetNeedsCommitIsNotLost
) {
658 SchedulerSettings default_scheduler_settings
;
659 StateMachine
state(default_scheduler_settings
);
661 state
.UpdateState(state
.NextAction());
662 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
663 state
.SetNeedsCommit();
664 state
.SetVisible(true);
665 state
.SetCanDraw(true);
667 EXPECT_TRUE(state
.BeginImplFrameNeeded());
670 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
671 EXPECT_ACTION_UPDATE_STATE(
672 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
673 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
674 state
.CommitState());
676 // Now, while the frame is in progress, set another commit.
677 state
.SetNeedsCommit();
678 EXPECT_TRUE(state
.NeedsCommit());
680 // Let the frame finish.
681 state
.FinishCommit();
682 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
683 state
.CommitState());
685 // Expect to commit regardless of BeginImplFrame state.
686 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
687 state
.begin_impl_frame_state());
688 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
690 state
.OnBeginImplFrameDeadlinePending();
691 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
,
692 state
.begin_impl_frame_state());
693 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
695 state
.OnBeginImplFrameDeadline();
696 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
,
697 state
.begin_impl_frame_state());
698 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
700 state
.OnBeginImplFrameIdle();
701 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
,
702 state
.begin_impl_frame_state());
703 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
705 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
706 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
707 state
.begin_impl_frame_state());
708 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
710 // Commit and make sure we draw on next BeginImplFrame
711 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
712 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
713 state
.OnBeginImplFrameDeadline();
714 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
,
715 state
.CommitState());
716 EXPECT_ACTION_UPDATE_STATE(
717 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
718 state
.DidDrawIfPossibleCompleted(true);
720 // Verify that another commit will start immediately after draw.
721 EXPECT_ACTION_UPDATE_STATE(
722 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
723 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
726 TEST(SchedulerStateMachineTest
, TestFullCycle
) {
727 SchedulerSettings default_scheduler_settings
;
728 StateMachine
state(default_scheduler_settings
);
730 state
.UpdateState(state
.NextAction());
731 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
732 state
.SetVisible(true);
733 state
.SetCanDraw(true);
735 // Start clean and set commit.
736 state
.SetNeedsCommit();
739 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
740 EXPECT_ACTION_UPDATE_STATE(
741 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
742 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
743 state
.CommitState());
744 EXPECT_FALSE(state
.NeedsCommit());
745 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
747 // Tell the scheduler the frame finished.
748 state
.FinishCommit();
749 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
750 state
.CommitState());
753 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
754 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
,
755 state
.CommitState());
756 EXPECT_TRUE(state
.needs_redraw());
758 // Expect to do nothing until BeginImplFrame deadline
759 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
761 // At BeginImplFrame deadline, draw.
762 state
.OnBeginImplFrameDeadline();
763 EXPECT_ACTION_UPDATE_STATE(
764 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
765 state
.DidDrawIfPossibleCompleted(true);
767 // Should be synchronized, no draw needed, no action needed.
768 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
769 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
770 EXPECT_FALSE(state
.needs_redraw());
773 TEST(SchedulerStateMachineTest
, TestFullCycleWithCommitRequestInbetween
) {
774 SchedulerSettings default_scheduler_settings
;
775 StateMachine
state(default_scheduler_settings
);
777 state
.UpdateState(state
.NextAction());
778 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
779 state
.SetVisible(true);
780 state
.SetCanDraw(true);
782 // Start clean and set commit.
783 state
.SetNeedsCommit();
786 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
787 EXPECT_ACTION_UPDATE_STATE(
788 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
789 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
790 state
.CommitState());
791 EXPECT_FALSE(state
.NeedsCommit());
792 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
794 // Request another commit while the commit is in flight.
795 state
.SetNeedsCommit();
796 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
798 // Tell the scheduler the frame finished.
799 state
.FinishCommit();
800 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
801 state
.CommitState());
804 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
805 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
,
806 state
.CommitState());
807 EXPECT_TRUE(state
.needs_redraw());
809 // Expect to do nothing until BeginImplFrame deadline.
810 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
812 // At BeginImplFrame deadline, draw.
813 state
.OnBeginImplFrameDeadline();
814 EXPECT_ACTION_UPDATE_STATE(
815 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
816 state
.DidDrawIfPossibleCompleted(true);
818 // Should be synchronized, no draw needed, no action needed.
819 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
820 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
821 EXPECT_FALSE(state
.needs_redraw());
823 // Next BeginImplFrame should initiate second commit.
824 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
825 EXPECT_ACTION_UPDATE_STATE(
826 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
829 TEST(SchedulerStateMachineTest
, TestRequestCommitInvisible
) {
830 SchedulerSettings default_scheduler_settings
;
831 StateMachine
state(default_scheduler_settings
);
833 state
.UpdateState(state
.NextAction());
834 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
835 state
.SetNeedsCommit();
836 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
839 TEST(SchedulerStateMachineTest
, TestGoesInvisibleBeforeFinishCommit
) {
840 SchedulerSettings default_scheduler_settings
;
841 StateMachine
state(default_scheduler_settings
);
843 state
.UpdateState(state
.NextAction());
844 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
845 state
.SetVisible(true);
846 state
.SetCanDraw(true);
848 // Start clean and set commit.
849 state
.SetNeedsCommit();
851 // Begin the frame while visible.
852 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
853 EXPECT_ACTION_UPDATE_STATE(
854 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
855 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
856 state
.CommitState());
857 EXPECT_FALSE(state
.NeedsCommit());
858 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
860 // Become invisible and abort BeginMainFrame.
861 state
.SetVisible(false);
862 state
.BeginMainFrameAborted(false);
864 // We should now be back in the idle state as if we never started the frame.
865 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
866 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
868 // We shouldn't do anything on the BeginImplFrame deadline.
869 state
.OnBeginImplFrameDeadline();
870 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
872 // Become visible again.
873 state
.SetVisible(true);
875 // Although we have aborted on this frame and haven't cancelled the commit
876 // (i.e. need another), don't send another BeginMainFrame yet.
877 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
878 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
879 EXPECT_TRUE(state
.NeedsCommit());
881 // Start a new frame.
882 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
883 EXPECT_ACTION_UPDATE_STATE(
884 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
886 // We should be starting the commit now.
887 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
888 state
.CommitState());
889 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
892 TEST(SchedulerStateMachineTest
, AbortBeginMainFrameAndCancelCommit
) {
893 SchedulerSettings default_scheduler_settings
;
894 StateMachine
state(default_scheduler_settings
);
896 state
.UpdateState(state
.NextAction());
897 state
.DidCreateAndInitializeOutputSurface();
898 state
.SetVisible(true);
899 state
.SetCanDraw(true);
901 // Get into a begin frame / commit state.
902 state
.SetNeedsCommit();
904 EXPECT_ACTION_UPDATE_STATE(
905 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
906 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
907 state
.CommitState());
908 EXPECT_FALSE(state
.NeedsCommit());
909 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
911 // Abort the commit, cancelling future commits.
912 state
.BeginMainFrameAborted(true);
914 // Verify that another commit doesn't start on the same frame.
915 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
916 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
917 EXPECT_FALSE(state
.NeedsCommit());
919 // Start a new frame; draw because this is the first frame since output
921 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
922 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
923 state
.OnBeginImplFrameDeadline();
924 EXPECT_ACTION_UPDATE_STATE(
925 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
927 // Verify another commit doesn't start on another frame either.
928 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
929 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
930 EXPECT_FALSE(state
.NeedsCommit());
932 // Verify another commit can start if requested, though.
933 state
.SetNeedsCommit();
934 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
935 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
,
939 TEST(SchedulerStateMachineTest
, TestFirstContextCreation
) {
940 SchedulerSettings default_scheduler_settings
;
941 StateMachine
state(default_scheduler_settings
);
943 state
.SetVisible(true);
944 state
.SetCanDraw(true);
946 EXPECT_ACTION_UPDATE_STATE(
947 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
948 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
949 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
951 // Check that the first init does not SetNeedsCommit.
952 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
953 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
954 state
.OnBeginImplFrameDeadline();
955 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
957 // Check that a needs commit initiates a BeginMainFrame.
958 state
.SetNeedsCommit();
959 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
960 EXPECT_ACTION_UPDATE_STATE(
961 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
964 TEST(SchedulerStateMachineTest
, TestContextLostWhenCompletelyIdle
) {
965 SchedulerSettings default_scheduler_settings
;
966 StateMachine
state(default_scheduler_settings
);
968 state
.UpdateState(state
.NextAction());
969 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
971 state
.SetVisible(true);
972 state
.SetCanDraw(true);
974 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
976 state
.DidLoseOutputSurface();
978 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
980 state
.UpdateState(state
.NextAction());
982 // Once context recreation begins, nothing should happen.
983 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
985 // Recreate the context.
986 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
988 // When the context is recreated, we should begin a commit.
989 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
990 EXPECT_ACTION_UPDATE_STATE(
991 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
994 TEST(SchedulerStateMachineTest
,
995 TestContextLostWhenIdleAndCommitRequestedWhileRecreating
) {
996 SchedulerSettings default_scheduler_settings
;
997 StateMachine
state(default_scheduler_settings
);
999 state
.UpdateState(state
.NextAction());
1000 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1001 state
.SetVisible(true);
1002 state
.SetCanDraw(true);
1004 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1005 state
.NextAction());
1006 state
.DidLoseOutputSurface();
1008 EXPECT_ACTION_UPDATE_STATE(
1009 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1010 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1012 // Once context recreation begins, nothing should happen.
1013 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1014 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1015 state
.OnBeginImplFrameDeadline();
1016 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1018 // While context is recreating, commits shouldn't begin.
1019 state
.SetNeedsCommit();
1020 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1021 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1022 state
.OnBeginImplFrameDeadline();
1023 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1025 // Recreate the context
1026 state
.DidCreateAndInitializeOutputSurface();
1027 EXPECT_FALSE(state
.RedrawPending());
1029 // When the context is recreated, we should begin a commit
1030 EXPECT_ACTION_UPDATE_STATE(
1031 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1032 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1033 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
1034 state
.CommitState());
1035 state
.FinishCommit();
1036 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1037 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1038 // Finishing the first commit after initializing an output surface should
1039 // automatically cause a redraw.
1040 EXPECT_TRUE(state
.RedrawPending());
1042 // Once the context is recreated, whether we draw should be based on
1044 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1045 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1046 state
.OnBeginImplFrameDeadline();
1047 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
1048 state
.NextAction());
1049 state
.SetCanDraw(false);
1050 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
,
1051 state
.NextAction());
1052 state
.SetCanDraw(true);
1053 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
1054 state
.NextAction());
1057 void TestContextLostWhileCommitInProgress(bool deadline_scheduling_enabled
) {
1058 SchedulerSettings scheduler_settings
;
1059 scheduler_settings
.deadline_scheduling_enabled
= deadline_scheduling_enabled
;
1060 StateMachine
state(scheduler_settings
);
1061 state
.SetCanStart();
1062 state
.UpdateState(state
.NextAction());
1063 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1064 state
.SetVisible(true);
1065 state
.SetCanDraw(true);
1067 // Get a commit in flight.
1068 state
.SetNeedsCommit();
1069 if (!deadline_scheduling_enabled
) {
1070 EXPECT_ACTION_UPDATE_STATE(
1071 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1074 // Set damage and expect a draw.
1075 state
.SetNeedsRedraw(true);
1076 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1077 if (deadline_scheduling_enabled
) {
1078 EXPECT_ACTION_UPDATE_STATE(
1079 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1081 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1082 state
.OnBeginImplFrameDeadline();
1083 EXPECT_ACTION_UPDATE_STATE(
1084 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1085 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1087 // Cause a lost context while the BeginMainFrame is in flight.
1088 state
.DidLoseOutputSurface();
1090 // Ask for another draw. Expect nothing happens.
1091 state
.SetNeedsRedraw(true);
1092 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1094 // Finish the frame, and commit.
1095 state
.FinishCommit();
1096 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1098 // We will abort the draw when the output surface is lost if we are
1099 // waiting for the first draw to unblock the main thread.
1100 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
,
1101 state
.CommitState());
1102 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1104 // Expect to be told to begin context recreation, independent of
1105 // BeginImplFrame state.
1106 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
,
1107 state
.begin_impl_frame_state());
1108 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1109 state
.NextAction());
1111 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1112 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
1113 state
.begin_impl_frame_state());
1114 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1115 state
.NextAction());
1117 state
.OnBeginImplFrameDeadlinePending();
1118 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
,
1119 state
.begin_impl_frame_state());
1120 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1121 state
.NextAction());
1123 state
.OnBeginImplFrameDeadline();
1124 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
,
1125 state
.begin_impl_frame_state());
1126 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1127 state
.NextAction());
1130 TEST(SchedulerStateMachineTest
, TestContextLostWhileCommitInProgress
) {
1131 bool deadline_scheduling_enabled
= false;
1132 TestContextLostWhileCommitInProgress(deadline_scheduling_enabled
);
1135 TEST(SchedulerStateMachineTest
, TestContextLostWhileCommitInProgress_Deadline
) {
1136 bool deadline_scheduling_enabled
= true;
1137 TestContextLostWhileCommitInProgress(deadline_scheduling_enabled
);
1140 void TestContextLostWhileCommitInProgressAndAnotherCommitRequested(
1141 bool deadline_scheduling_enabled
) {
1142 SchedulerSettings scheduler_settings
;
1143 scheduler_settings
.deadline_scheduling_enabled
= deadline_scheduling_enabled
;
1144 StateMachine
state(scheduler_settings
);
1145 state
.SetCanStart();
1146 state
.UpdateState(state
.NextAction());
1147 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1148 state
.SetVisible(true);
1149 state
.SetCanDraw(true);
1151 // Get a commit in flight.
1152 state
.SetNeedsCommit();
1153 if (!deadline_scheduling_enabled
) {
1154 EXPECT_ACTION_UPDATE_STATE(
1155 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1157 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1159 // Set damage and expect a draw.
1160 state
.SetNeedsRedraw(true);
1161 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1162 if (deadline_scheduling_enabled
) {
1163 EXPECT_ACTION_UPDATE_STATE(
1164 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1166 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1167 state
.OnBeginImplFrameDeadline();
1168 EXPECT_ACTION_UPDATE_STATE(
1169 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1170 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1172 // Cause a lost context while the BeginMainFrame is in flight.
1173 state
.DidLoseOutputSurface();
1175 // Ask for another draw and also set needs commit. Expect nothing happens.
1176 state
.SetNeedsRedraw(true);
1177 state
.SetNeedsCommit();
1178 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1180 // Finish the frame, and commit.
1181 state
.FinishCommit();
1182 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1183 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
,
1184 state
.CommitState());
1186 // Because the output surface is missing, we expect the draw to abort.
1187 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1189 // Expect to be told to begin context recreation, independent of
1190 // BeginImplFrame state
1191 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
,
1192 state
.begin_impl_frame_state());
1193 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1194 state
.NextAction());
1196 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1197 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
1198 state
.begin_impl_frame_state());
1199 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1200 state
.NextAction());
1202 state
.OnBeginImplFrameDeadlinePending();
1203 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
,
1204 state
.begin_impl_frame_state());
1205 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1206 state
.NextAction());
1208 state
.OnBeginImplFrameDeadline();
1209 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
,
1210 state
.begin_impl_frame_state());
1211 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1212 state
.NextAction());
1214 // After we get a new output surface, the commit flow should start.
1215 EXPECT_ACTION_UPDATE_STATE(
1216 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1217 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1218 state
.OnBeginImplFrameIdle();
1219 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1220 EXPECT_ACTION_UPDATE_STATE(
1221 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1222 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1223 state
.FinishCommit();
1224 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1225 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1226 state
.OnBeginImplFrameDeadline();
1227 EXPECT_ACTION_UPDATE_STATE(
1228 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1229 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1232 TEST(SchedulerStateMachineTest
,
1233 TestContextLostWhileCommitInProgressAndAnotherCommitRequested
) {
1234 bool deadline_scheduling_enabled
= false;
1235 TestContextLostWhileCommitInProgressAndAnotherCommitRequested(
1236 deadline_scheduling_enabled
);
1239 TEST(SchedulerStateMachineTest
,
1240 TestContextLostWhileCommitInProgressAndAnotherCommitRequested_Deadline
) {
1241 bool deadline_scheduling_enabled
= true;
1242 TestContextLostWhileCommitInProgressAndAnotherCommitRequested(
1243 deadline_scheduling_enabled
);
1246 TEST(SchedulerStateMachineTest
, TestFinishAllRenderingWhileContextLost
) {
1247 SchedulerSettings default_scheduler_settings
;
1248 StateMachine
state(default_scheduler_settings
);
1249 state
.SetCanStart();
1250 state
.UpdateState(state
.NextAction());
1251 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1252 state
.SetVisible(true);
1253 state
.SetCanDraw(true);
1255 // Cause a lost context lost.
1256 state
.DidLoseOutputSurface();
1258 // Ask a forced redraw for readback and verify it ocurrs.
1259 state
.SetCommitState(
1260 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
);
1261 state
.SetNeedsForcedRedrawForReadback();
1262 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1263 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK
);
1264 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1266 // Forced redraws for readbacks need to be followed by a new commit
1267 // to replace the readback commit.
1268 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
1269 state
.CommitState());
1270 state
.FinishCommit();
1271 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1273 // We don't yet have an output surface, so we the draw and swap should abort.
1274 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1276 // Expect to be told to begin context recreation, independent of
1277 // BeginImplFrame state
1278 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1279 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1280 state
.NextAction());
1282 state
.OnBeginImplFrameDeadline();
1283 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1284 state
.NextAction());
1286 // Ask a readback and verify it occurs.
1287 state
.SetCommitState(
1288 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
);
1289 state
.SetNeedsForcedRedrawForReadback();
1290 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK
);
1291 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1294 TEST(SchedulerStateMachineTest
, DontDrawBeforeCommitAfterLostOutputSurface
) {
1295 SchedulerSettings default_scheduler_settings
;
1296 StateMachine
state(default_scheduler_settings
);
1297 state
.SetCanStart();
1298 state
.UpdateState(state
.NextAction());
1299 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1300 state
.SetVisible(true);
1301 state
.SetCanDraw(true);
1303 state
.SetNeedsRedraw(true);
1305 // Cause a lost output surface, and restore it.
1306 state
.DidLoseOutputSurface();
1307 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1308 state
.NextAction());
1309 state
.UpdateState(state
.NextAction());
1310 state
.DidCreateAndInitializeOutputSurface();
1312 EXPECT_FALSE(state
.RedrawPending());
1313 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1314 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
,
1315 state
.NextAction());
1318 TEST(SchedulerStateMachineTest
,
1319 TestSendBeginMainFrameWhenInvisibleAndForceCommit
) {
1320 SchedulerSettings default_scheduler_settings
;
1321 StateMachine
state(default_scheduler_settings
);
1322 state
.SetCanStart();
1323 state
.UpdateState(state
.NextAction());
1324 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1325 state
.SetVisible(false);
1326 state
.SetNeedsCommit();
1327 state
.SetNeedsForcedCommitForReadback();
1328 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
,
1329 state
.NextAction());
1332 TEST(SchedulerStateMachineTest
,
1333 TestSendBeginMainFrameWhenCanStartFalseAndForceCommit
) {
1334 SchedulerSettings default_scheduler_settings
;
1335 StateMachine
state(default_scheduler_settings
);
1336 state
.SetVisible(true);
1337 state
.SetCanDraw(true);
1338 state
.SetNeedsCommit();
1339 state
.SetNeedsForcedCommitForReadback();
1340 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
,
1341 state
.NextAction());
1344 TEST(SchedulerStateMachineTest
, TestFinishCommitWhenCommitInProgress
) {
1345 SchedulerSettings default_scheduler_settings
;
1346 StateMachine
state(default_scheduler_settings
);
1347 state
.SetCanStart();
1348 state
.UpdateState(state
.NextAction());
1349 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1350 state
.SetVisible(false);
1351 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
);
1352 state
.SetNeedsCommit();
1354 state
.FinishCommit();
1355 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
1356 state
.UpdateState(state
.NextAction());
1358 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
,
1359 state
.CommitState());
1360 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1363 TEST(SchedulerStateMachineTest
, TestFinishCommitWhenForcedCommitInProgress
) {
1364 SchedulerSettings default_scheduler_settings
;
1365 StateMachine
state(default_scheduler_settings
);
1366 state
.SetCanStart();
1367 state
.UpdateState(state
.NextAction());
1368 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1369 state
.SetVisible(false);
1370 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
);
1371 state
.SetNeedsCommit();
1372 state
.SetNeedsForcedCommitForReadback();
1374 // The commit for readback interupts the normal commit.
1375 state
.FinishCommit();
1376 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1378 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
,
1379 state
.CommitState());
1380 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK
);
1382 // When the readback interrupts the normal commit, we should not get
1383 // another BeginMainFrame when the readback completes.
1384 EXPECT_NE(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
,
1385 state
.NextAction());
1387 // The normal commit can then proceed.
1388 state
.FinishCommit();
1389 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1392 TEST(SchedulerStateMachineTest
, TestInitialActionsWhenContextLost
) {
1393 SchedulerSettings default_scheduler_settings
;
1394 StateMachine
state(default_scheduler_settings
);
1395 state
.SetCanStart();
1396 state
.UpdateState(state
.NextAction());
1397 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1398 state
.SetVisible(true);
1399 state
.SetCanDraw(true);
1400 state
.SetNeedsCommit();
1401 state
.DidLoseOutputSurface();
1403 // When we are visible, we normally want to begin output surface creation
1404 // as soon as possible.
1405 EXPECT_ACTION_UPDATE_STATE(
1406 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1408 state
.DidCreateAndInitializeOutputSurface();
1409 EXPECT_EQ(state
.output_surface_state(),
1410 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT
);
1412 // We should not send a BeginMainFrame when we are invisible, even if we've
1413 // lost the output surface and are trying to get the first commit, since the
1414 // main thread will just abort anyway.
1415 state
.SetVisible(false);
1416 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction())
1417 << *state
.AsValue();
1419 // If there is a forced commit, however, we could be blocking a readback
1420 // on the main thread, so we need to unblock it before we can get our
1421 // output surface, even if we are not visible.
1422 state
.SetNeedsForcedCommitForReadback();
1424 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
, state
.NextAction())
1425 << *state
.AsValue();
1428 TEST(SchedulerStateMachineTest
, TestImmediateFinishCommit
) {
1429 SchedulerSettings default_scheduler_settings
;
1430 StateMachine
state(default_scheduler_settings
);
1431 state
.SetCanStart();
1432 state
.UpdateState(state
.NextAction());
1433 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1434 state
.SetVisible(true);
1435 state
.SetCanDraw(true);
1437 // Schedule a readback, commit it, draw it.
1438 state
.SetNeedsCommit();
1439 state
.SetNeedsForcedCommitForReadback();
1440 EXPECT_ACTION_UPDATE_STATE(
1441 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1442 state
.FinishCommit();
1444 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
1445 state
.CommitState());
1446 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1448 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
,
1449 state
.CommitState());
1451 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK
);
1452 state
.DidDrawIfPossibleCompleted(true);
1454 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1456 // Should be waiting for the normal BeginMainFrame.
1457 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
1458 state
.CommitState());
1461 void TestImmediateFinishCommitDuringCommit(bool deadline_scheduling_enabled
) {
1462 SchedulerSettings scheduler_settings
;
1463 scheduler_settings
.deadline_scheduling_enabled
= deadline_scheduling_enabled
;
1464 StateMachine
state(scheduler_settings
);
1465 state
.SetCanStart();
1466 state
.UpdateState(state
.NextAction());
1467 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1468 state
.SetVisible(true);
1469 state
.SetCanDraw(true);
1471 // Start a normal commit.
1472 state
.SetNeedsCommit();
1473 if (!deadline_scheduling_enabled
) {
1474 EXPECT_ACTION_UPDATE_STATE(
1475 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1477 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1479 // Schedule a readback, commit it, draw it.
1480 state
.SetNeedsForcedCommitForReadback();
1481 if (deadline_scheduling_enabled
) {
1482 EXPECT_ACTION_UPDATE_STATE(
1483 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1485 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1486 state
.FinishCommit();
1487 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
1488 state
.CommitState());
1489 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1491 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
,
1492 state
.CommitState());
1494 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK
);
1495 state
.DidDrawIfPossibleCompleted(true);
1496 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1498 // Should be waiting for the normal BeginMainFrame.
1499 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
1500 state
.CommitState())
1501 << *state
.AsValue();
1504 TEST(SchedulerStateMachineTest
, TestImmediateFinishCommitDuringCommit
) {
1505 bool deadline_scheduling_enabled
= false;
1506 TestImmediateFinishCommitDuringCommit(deadline_scheduling_enabled
);
1509 TEST(SchedulerStateMachineTest
,
1510 TestImmediateFinishCommitDuringCommit_Deadline
) {
1511 bool deadline_scheduling_enabled
= true;
1512 TestImmediateFinishCommitDuringCommit(deadline_scheduling_enabled
);
1515 void ImmediateBeginMainFrameAbortedWhileInvisible(
1516 bool deadline_scheduling_enabled
) {
1517 SchedulerSettings scheduler_settings
;
1518 scheduler_settings
.deadline_scheduling_enabled
= deadline_scheduling_enabled
;
1519 StateMachine
state(scheduler_settings
);
1520 state
.SetCanStart();
1521 state
.UpdateState(state
.NextAction());
1522 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1523 state
.SetVisible(true);
1524 state
.SetCanDraw(true);
1526 state
.SetNeedsCommit();
1527 if (!deadline_scheduling_enabled
) {
1528 EXPECT_ACTION_UPDATE_STATE(
1529 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1531 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1533 state
.SetNeedsCommit();
1534 state
.SetNeedsForcedCommitForReadback();
1535 if (deadline_scheduling_enabled
) {
1536 EXPECT_ACTION_UPDATE_STATE(
1537 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1539 state
.FinishCommit();
1541 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
1542 state
.CommitState());
1543 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1545 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
,
1546 state
.CommitState());
1548 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK
);
1549 state
.DidDrawIfPossibleCompleted(true);
1550 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1552 // Should be waiting for BeginMainFrame.
1553 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
1554 state
.CommitState())
1555 << *state
.AsValue();
1557 // Become invisible and abort BeginMainFrame.
1558 state
.SetVisible(false);
1559 state
.BeginMainFrameAborted(false);
1561 // Should be back in the idle state, but needing a commit.
1562 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1563 EXPECT_TRUE(state
.NeedsCommit());
1566 TEST(SchedulerStateMachineTest
,
1567 ImmediateBeginMainFrameAbortedWhileInvisible
) {
1568 bool deadline_scheduling_enabled
= false;
1569 ImmediateBeginMainFrameAbortedWhileInvisible(
1570 deadline_scheduling_enabled
);
1573 TEST(SchedulerStateMachineTest
,
1574 ImmediateBeginMainFrameAbortedWhileInvisible_Deadline
) {
1575 bool deadline_scheduling_enabled
= true;
1576 ImmediateBeginMainFrameAbortedWhileInvisible(
1577 deadline_scheduling_enabled
);
1580 TEST(SchedulerStateMachineTest
, ImmediateFinishCommitWhileCantDraw
) {
1581 SchedulerSettings default_scheduler_settings
;
1582 StateMachine
state(default_scheduler_settings
);
1583 state
.SetCanStart();
1584 state
.UpdateState(state
.NextAction());
1585 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1586 state
.SetVisible(true);
1587 state
.SetCanDraw(false);
1589 state
.SetNeedsCommit();
1590 state
.UpdateState(state
.NextAction());
1592 state
.SetNeedsCommit();
1593 state
.SetNeedsForcedCommitForReadback();
1594 state
.UpdateState(state
.NextAction());
1595 state
.FinishCommit();
1597 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
1598 state
.CommitState());
1599 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1601 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
,
1602 state
.CommitState());
1604 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK
);
1605 state
.DidDrawIfPossibleCompleted(true);
1606 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1609 TEST(SchedulerStateMachineTest
, ReportIfNotDrawing
) {
1610 SchedulerSettings default_scheduler_settings
;
1611 StateMachine
state(default_scheduler_settings
);
1612 state
.SetCanStart();
1613 state
.UpdateState(state
.NextAction());
1614 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1616 state
.SetCanDraw(true);
1617 state
.SetVisible(true);
1618 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1620 state
.SetCanDraw(false);
1621 state
.SetVisible(true);
1622 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1624 state
.SetCanDraw(true);
1625 state
.SetVisible(false);
1626 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1628 state
.SetCanDraw(false);
1629 state
.SetVisible(false);
1630 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1632 state
.SetCanDraw(true);
1633 state
.SetVisible(true);
1634 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1637 TEST(SchedulerStateMachineTest
, ReportIfNotDrawingFromAcquiredTextures
) {
1638 SchedulerSettings default_scheduler_settings
;
1639 StateMachine
state(default_scheduler_settings
);
1640 state
.SetCanStart();
1641 state
.UpdateState(state
.NextAction());
1642 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1643 state
.SetCanDraw(true);
1644 state
.SetVisible(true);
1645 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1647 state
.SetMainThreadNeedsLayerTextures();
1648 EXPECT_ACTION_UPDATE_STATE(
1649 SchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD
);
1650 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1651 EXPECT_TRUE(state
.PendingActivationsShouldBeForced());
1653 state
.SetNeedsCommit();
1654 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1655 EXPECT_ACTION_UPDATE_STATE(
1656 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1657 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1658 EXPECT_TRUE(state
.PendingActivationsShouldBeForced());
1660 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1662 state
.FinishCommit();
1663 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1665 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
1667 state
.UpdateState(state
.NextAction());
1668 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1671 TEST(SchedulerStateMachineTest
, AcquireTexturesWithAbort
) {
1672 SchedulerSettings default_scheduler_settings
;
1673 StateMachine
state(default_scheduler_settings
);
1674 state
.SetCanStart();
1675 state
.UpdateState(state
.NextAction());
1676 state
.DidCreateAndInitializeOutputSurface();
1677 state
.SetCanDraw(true);
1678 state
.SetVisible(true);
1680 state
.SetMainThreadNeedsLayerTextures();
1682 SchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD
,
1683 state
.NextAction());
1684 state
.UpdateState(state
.NextAction());
1685 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1687 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1689 state
.SetNeedsCommit();
1690 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
,
1691 state
.NextAction());
1692 state
.UpdateState(state
.NextAction());
1693 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1695 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1697 state
.BeginMainFrameAborted(true);
1699 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1700 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1703 TEST(SchedulerStateMachineTest
,
1704 TestTriggerDeadlineEarlyAfterAbortedCommit
) {
1705 SchedulerSettings settings
;
1706 settings
.deadline_scheduling_enabled
= true;
1707 settings
.impl_side_painting
= true;
1708 StateMachine
state(settings
);
1709 state
.SetCanStart();
1710 state
.UpdateState(state
.NextAction());
1711 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1712 state
.SetVisible(true);
1713 state
.SetCanDraw(true);
1715 // This test mirrors what happens during the first frame of a scroll gesture.
1716 // First we get the input event and a BeginFrame.
1717 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1719 // As a response the compositor requests a redraw and a commit to tell the
1720 // main thread about the new scroll offset.
1721 state
.SetNeedsRedraw(true);
1722 state
.SetNeedsCommit();
1724 // We should start the commit normally.
1725 EXPECT_ACTION_UPDATE_STATE(
1726 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1727 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1729 // Since only the scroll offset changed, the main thread will abort the
1731 state
.BeginMainFrameAborted(true);
1733 // Since the commit was aborted, we should draw right away instead of waiting
1734 // for the deadline.
1735 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1738 TEST(SchedulerStateMachineTest
, TestTriggerDeadlineEarlyForSmoothness
) {
1739 SchedulerSettings settings
;
1740 settings
.deadline_scheduling_enabled
= true;
1741 settings
.impl_side_painting
= true;
1742 StateMachine
state(settings
);
1743 state
.SetCanStart();
1744 state
.UpdateState(state
.NextAction());
1745 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1746 state
.SetVisible(true);
1747 state
.SetCanDraw(true);
1749 // This test ensures that impl-draws are prioritized over main thread updates
1750 // in prefer smoothness mode.
1751 state
.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
1752 state
.SetNeedsRedraw(true);
1753 state
.SetNeedsCommit();
1754 EXPECT_ACTION_UPDATE_STATE(
1755 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1756 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1758 // The deadline is not triggered early until we enter prefer smoothness mode.
1759 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1760 state
.SetSmoothnessTakesPriority(true);
1761 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());