1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/scheduler/scheduler_state_machine.h"
7 #include "base/trace_event/trace_event.h"
8 #include "cc/scheduler/scheduler.h"
9 #include "cc/test/begin_frame_args_test.h"
10 #include "testing/gtest/include/gtest/gtest.h"
12 // Macro to compare two enum values and get nice output.
14 // Value of: actual() Actual: 7
15 // Expected: expected() Which is: 0
17 // Value of: actual() Actual: "ACTION_ANIMATE"
18 // Expected: expected() Which is: "ACTION_NONE"
19 #define EXPECT_ENUM_EQ(enum_tostring, expected, actual) \
20 EXPECT_STREQ(SchedulerStateMachine::enum_tostring(expected), \
21 SchedulerStateMachine::enum_tostring(actual))
23 #define EXPECT_IMPL_FRAME_STATE(expected) \
24 EXPECT_ENUM_EQ(BeginImplFrameStateToString, expected, \
25 state.begin_impl_frame_state()) \
26 << state.AsValue()->ToString()
28 #define EXPECT_MAIN_FRAME_STATE(expected) \
29 EXPECT_ENUM_EQ(BeginMainFrameStateToString, expected, \
30 state.BeginMainFrameState())
32 #define EXPECT_ACTION(expected) \
33 EXPECT_ENUM_EQ(ActionToString, expected, state.NextAction()) \
34 << state.AsValue()->ToString()
36 #define EXPECT_ACTION_UPDATE_STATE(action) \
37 EXPECT_ACTION(action); \
38 if (action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE || \
39 action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED) { \
40 EXPECT_IMPL_FRAME_STATE( \
41 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE); \
43 WillPerformAction(&state, action); \
44 if (action == SchedulerStateMachine::ACTION_NONE) { \
45 if (state.begin_impl_frame_state() == \
46 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) \
47 state.OnBeginImplFrameDeadlinePending(); \
48 if (state.begin_impl_frame_state() == \
49 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) \
50 state.OnBeginImplFrameIdle(); \
53 #define SET_UP_STATE(state) \
54 state.SetCanStart(); \
55 state.SetVisible(true); \
56 EXPECT_ACTION_UPDATE_STATE( \
57 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION); \
58 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); \
59 state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); \
60 state.SetCanDraw(true);
66 void WillPerformAction(SchedulerStateMachine
* sm
,
67 SchedulerStateMachine::Action action
) {
69 case SchedulerStateMachine::ACTION_NONE
:
72 case SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
:
76 case SchedulerStateMachine::ACTION_ANIMATE
:
80 case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
:
81 sm
->WillSendBeginMainFrame();
84 case SchedulerStateMachine::ACTION_COMMIT
: {
85 bool commit_has_no_updates
= false;
86 sm
->WillCommit(commit_has_no_updates
);
90 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED
:
91 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
: {
92 bool did_request_swap
= true;
93 sm
->WillDraw(did_request_swap
);
97 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
: {
98 bool did_request_swap
= false;
99 sm
->WillDraw(did_request_swap
);
103 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
:
104 sm
->WillBeginOutputSurfaceCreation();
107 case SchedulerStateMachine::ACTION_PREPARE_TILES
:
108 sm
->WillPrepareTiles();
111 case SchedulerStateMachine::ACTION_INVALIDATE_OUTPUT_SURFACE
:
112 sm
->WillInvalidateOutputSurface();
117 const SchedulerStateMachine::BeginImplFrameState all_begin_impl_frame_states
[] =
118 {SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
,
119 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
120 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
,
121 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
, };
123 const SchedulerStateMachine::BeginMainFrameState begin_main_frame_states
[] = {
124 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
,
125 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
,
126 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED
,
127 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT
,
128 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_WAITING_FOR_ACTIVATION
,
129 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_WAITING_FOR_DRAW
};
131 // Exposes the protected state fields of the SchedulerStateMachine for testing
132 class StateMachine
: public SchedulerStateMachine
{
134 explicit StateMachine(const SchedulerSettings
& scheduler_settings
)
135 : SchedulerStateMachine(scheduler_settings
) {}
137 void CreateAndInitializeOutputSurfaceWithActivatedCommit() {
138 DidCreateAndInitializeOutputSurface();
139 output_surface_state_
= OUTPUT_SURFACE_ACTIVE
;
142 void SetBeginMainFrameState(BeginMainFrameState cs
) {
143 begin_main_frame_state_
= cs
;
145 BeginMainFrameState
BeginMainFrameState() const {
146 return begin_main_frame_state_
;
149 ForcedRedrawOnTimeoutState
ForcedRedrawState() const {
150 return forced_redraw_state_
;
153 void SetBeginImplFrameState(BeginImplFrameState bifs
) {
154 begin_impl_frame_state_
= bifs
;
157 BeginImplFrameState
begin_impl_frame_state() const {
158 return begin_impl_frame_state_
;
161 OutputSurfaceState
output_surface_state() const {
162 return output_surface_state_
;
165 void SetNeedsBeginMainFrameForTest(bool needs_begin_main_frame
) {
166 needs_begin_main_frame_
= needs_begin_main_frame
;
169 bool NeedsCommit() const { return needs_begin_main_frame_
; }
171 void SetNeedsAnimateForTest(bool needs_animate
) {
172 needs_animate_
= needs_animate
;
175 void SetNeedsRedraw(bool needs_redraw
) { needs_redraw_
= needs_redraw
; }
177 void SetNeedsForcedRedrawForTimeout(bool b
) {
178 forced_redraw_state_
= FORCED_REDRAW_STATE_WAITING_FOR_COMMIT
;
179 active_tree_needs_first_draw_
= true;
181 bool NeedsForcedRedrawForTimeout() const {
182 return forced_redraw_state_
!= FORCED_REDRAW_STATE_IDLE
;
185 void SetActiveTreeNeedsFirstDraw(bool needs_first_draw
) {
186 active_tree_needs_first_draw_
= needs_first_draw
;
189 bool CanDraw() const { return can_draw_
; }
190 bool Visible() const { return visible_
; }
192 bool PendingActivationsShouldBeForced() const {
193 return SchedulerStateMachine::PendingActivationsShouldBeForced();
196 void SetHasPendingTree(bool has_pending_tree
) {
197 has_pending_tree_
= has_pending_tree
;
200 using SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately
;
201 using SchedulerStateMachine::ProactiveBeginFrameWanted
;
202 using SchedulerStateMachine::WillCommit
;
205 TEST(SchedulerStateMachineTest
, BeginFrameNeeded
) {
206 SchedulerSettings default_scheduler_settings
;
207 StateMachine
state(default_scheduler_settings
);
209 state
.SetVisible(true);
210 EXPECT_ACTION_UPDATE_STATE(
211 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
212 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
213 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
214 state
.SetBeginMainFrameState(
215 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
217 // Don't request BeginFrames if we are idle.
218 state
.SetNeedsRedraw(false);
219 state
.SetNeedsAnimateForTest(false);
220 EXPECT_FALSE(state
.BeginFrameNeeded());
222 // Request BeginFrames if we are ready to draw.
223 state
.SetVisible(true);
224 state
.SetNeedsRedraw(true);
225 state
.SetNeedsAnimateForTest(false);
226 EXPECT_TRUE(state
.BeginFrameNeeded());
228 // Don't background tick for needs_redraw.
229 state
.SetVisible(false);
230 state
.SetNeedsRedraw(true);
231 state
.SetNeedsAnimateForTest(false);
232 EXPECT_FALSE(state
.BeginFrameNeeded());
234 // Proactively request BeginFrames when commit is pending.
235 state
.SetVisible(true);
236 state
.SetNeedsRedraw(false);
237 state
.SetNeedsAnimateForTest(false);
238 state
.SetNeedsBeginMainFrameForTest(true);
239 EXPECT_TRUE(state
.BeginFrameNeeded());
241 // Don't request BeginFrames when commit is pending if
242 // we are currently deferring commits.
243 state
.SetVisible(true);
244 state
.SetNeedsRedraw(false);
245 state
.SetNeedsAnimateForTest(false);
246 state
.SetNeedsBeginMainFrameForTest(true);
247 state
.SetDeferCommits(true);
248 EXPECT_FALSE(state
.BeginFrameNeeded());
251 TEST(SchedulerStateMachineTest
, TestNextActionBeginsMainFrameIfNeeded
) {
252 SchedulerSettings default_scheduler_settings
;
254 // If no commit needed, do nothing.
256 StateMachine
state(default_scheduler_settings
);
258 state
.SetVisible(true);
259 EXPECT_ACTION_UPDATE_STATE(
260 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
261 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
262 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
263 state
.SetBeginMainFrameState(
264 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
265 state
.SetNeedsRedraw(false);
267 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
268 EXPECT_FALSE(state
.NeedsCommit());
270 state
.OnBeginImplFrame();
271 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
273 state
.OnBeginImplFrameDeadline();
274 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
275 EXPECT_FALSE(state
.NeedsCommit());
278 // If commit requested but can_start is still false, do nothing.
280 StateMachine
state(default_scheduler_settings
);
281 state
.SetBeginMainFrameState(
282 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
283 state
.SetNeedsRedraw(false);
284 state
.SetVisible(true);
285 state
.SetNeedsBeginMainFrame();
287 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
288 EXPECT_TRUE(state
.NeedsCommit());
290 state
.OnBeginImplFrame();
291 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
293 state
.OnBeginImplFrameDeadline();
294 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
295 EXPECT_TRUE(state
.NeedsCommit());
298 // If commit requested, begin a main frame.
300 StateMachine
state(default_scheduler_settings
);
301 state
.SetBeginMainFrameState(
302 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
304 state
.SetVisible(true);
305 EXPECT_ACTION_UPDATE_STATE(
306 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
307 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
308 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
309 state
.SetNeedsRedraw(false);
310 state
.SetNeedsBeginMainFrame();
312 // Expect nothing to happen until after OnBeginImplFrame.
313 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
314 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
315 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
316 EXPECT_TRUE(state
.NeedsCommit());
317 EXPECT_TRUE(state
.BeginFrameNeeded());
319 state
.OnBeginImplFrame();
320 EXPECT_ACTION_UPDATE_STATE(
321 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
322 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
323 EXPECT_FALSE(state
.NeedsCommit());
326 // If commit requested and can't draw, still begin a main frame.
328 StateMachine
state(default_scheduler_settings
);
329 state
.SetBeginMainFrameState(
330 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
332 state
.SetVisible(true);
333 EXPECT_ACTION_UPDATE_STATE(
334 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
335 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
336 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
337 state
.SetNeedsRedraw(false);
338 state
.SetNeedsBeginMainFrame();
339 state
.SetCanDraw(false);
341 // Expect nothing to happen until after OnBeginImplFrame.
342 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
343 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
344 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
345 EXPECT_TRUE(state
.BeginFrameNeeded());
347 state
.OnBeginImplFrame();
348 EXPECT_ACTION_UPDATE_STATE(
349 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
350 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
351 EXPECT_FALSE(state
.NeedsCommit());
355 // Explicitly test main_frame_before_activation_enabled = true
356 TEST(SchedulerStateMachineTest
, MainFrameBeforeActivationEnabled
) {
357 SchedulerSettings scheduler_settings
;
358 scheduler_settings
.main_frame_before_activation_enabled
= true;
359 StateMachine
state(scheduler_settings
);
360 state
.SetBeginMainFrameState(
361 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
363 state
.SetNeedsRedraw(false);
364 state
.SetNeedsBeginMainFrame();
366 EXPECT_TRUE(state
.BeginFrameNeeded());
368 // Commit to the pending tree.
369 state
.OnBeginImplFrame();
370 EXPECT_ACTION_UPDATE_STATE(
371 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
372 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
374 state
.NotifyBeginMainFrameStarted();
375 state
.NotifyReadyToCommit();
376 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
377 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
378 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
380 state
.OnBeginImplFrameDeadline();
381 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
383 // Verify that the next commit starts while there is still a pending tree.
384 state
.SetNeedsBeginMainFrame();
385 state
.OnBeginImplFrame();
386 EXPECT_ACTION_UPDATE_STATE(
387 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
388 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
390 // Verify the pending commit doesn't overwrite the pending
391 // tree until the pending tree has been activated.
392 state
.NotifyBeginMainFrameStarted();
393 state
.NotifyReadyToCommit();
394 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
396 // Verify NotifyReadyToActivate unblocks activation, commit, and
397 // draw in that order.
398 state
.NotifyReadyToActivate();
399 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
400 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
401 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
403 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
404 state
.OnBeginImplFrameDeadline();
405 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
406 EXPECT_ACTION_UPDATE_STATE(
407 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
408 state
.DidSwapBuffers();
409 state
.DidSwapBuffersComplete();
410 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
411 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
414 TEST(SchedulerStateMachineTest
,
415 TestFailedDrawForAnimationCheckerboardSetsNeedsCommitAndDoesNotDrawAgain
) {
416 SchedulerSettings default_scheduler_settings
;
417 StateMachine
state(default_scheduler_settings
);
419 state
.SetNeedsRedraw(true);
420 EXPECT_TRUE(state
.RedrawPending());
421 EXPECT_TRUE(state
.BeginFrameNeeded());
422 state
.OnBeginImplFrame();
423 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
424 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
425 state
.OnBeginImplFrameDeadline();
427 // We're drawing now.
428 EXPECT_ACTION_UPDATE_STATE(
429 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
430 state
.DidSwapBuffers();
431 state
.DidSwapBuffersComplete();
432 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
434 EXPECT_FALSE(state
.RedrawPending());
435 EXPECT_FALSE(state
.CommitPending());
437 // Failing the draw makes us require a commit.
438 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
439 state
.OnBeginImplFrame();
440 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
441 EXPECT_ACTION_UPDATE_STATE(
442 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
443 EXPECT_TRUE(state
.RedrawPending());
444 EXPECT_TRUE(state
.CommitPending());
447 TEST(SchedulerStateMachineTest
, TestFailedDrawForMissingHighResNeedsCommit
) {
448 SchedulerSettings default_scheduler_settings
;
449 StateMachine
state(default_scheduler_settings
);
451 state
.SetNeedsRedraw(true);
452 EXPECT_TRUE(state
.RedrawPending());
453 EXPECT_TRUE(state
.BeginFrameNeeded());
455 state
.OnBeginImplFrame();
456 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
457 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
458 state
.OnBeginImplFrameDeadline();
459 EXPECT_ACTION_UPDATE_STATE(
460 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
461 state
.DidSwapBuffers();
462 state
.DidSwapBuffersComplete();
463 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
464 EXPECT_FALSE(state
.RedrawPending());
465 EXPECT_FALSE(state
.CommitPending());
467 // Missing high res content requires a commit (but not a redraw)
468 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
);
469 state
.OnBeginImplFrame();
470 EXPECT_ACTION_UPDATE_STATE(
471 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
472 EXPECT_FALSE(state
.RedrawPending());
473 EXPECT_TRUE(state
.CommitPending());
476 TEST(SchedulerStateMachineTest
,
477 TestsetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw
) {
478 SchedulerSettings default_scheduler_settings
;
479 StateMachine
state(default_scheduler_settings
);
481 state
.SetNeedsRedraw(true);
482 EXPECT_TRUE(state
.RedrawPending());
483 EXPECT_TRUE(state
.BeginFrameNeeded());
484 state
.OnBeginImplFrame();
485 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
486 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
487 state
.OnBeginImplFrameDeadline();
489 // We're drawing now.
490 EXPECT_ACTION_UPDATE_STATE(
491 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
492 state
.DidSwapBuffers();
493 state
.DidSwapBuffersComplete();
494 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
495 EXPECT_FALSE(state
.RedrawPending());
496 EXPECT_FALSE(state
.CommitPending());
498 // While still in the same BeginMainFrame callback on the main thread,
499 // set needs redraw again. This should not redraw.
500 state
.SetNeedsRedraw(true);
501 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
503 // Failing the draw for animation checkerboards makes us require a commit.
504 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
505 state
.OnBeginImplFrame();
506 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
507 EXPECT_ACTION_UPDATE_STATE(
508 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
509 EXPECT_TRUE(state
.RedrawPending());
512 TEST(SchedulerStateMachineTest
,
513 TestFailedDrawsEventuallyForceDrawAfterNextCommit
) {
514 SchedulerSettings scheduler_settings
;
515 scheduler_settings
.maximum_number_of_failed_draws_before_draw_is_forced
= 1;
516 StateMachine
state(scheduler_settings
);
520 state
.SetNeedsBeginMainFrame();
521 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
522 state
.OnBeginImplFrame();
523 EXPECT_ACTION_UPDATE_STATE(
524 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
525 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
526 EXPECT_TRUE(state
.CommitPending());
528 // Then initiate a draw.
529 state
.SetNeedsRedraw(true);
530 state
.OnBeginImplFrameDeadline();
531 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
532 EXPECT_ACTION_UPDATE_STATE(
533 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
536 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
537 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
538 EXPECT_TRUE(state
.BeginFrameNeeded());
539 EXPECT_TRUE(state
.RedrawPending());
540 // But the commit is ongoing.
541 EXPECT_TRUE(state
.CommitPending());
543 // Finish the commit. Note, we should not yet be forcing a draw, but should
544 // continue the commit as usual.
545 state
.NotifyBeginMainFrameStarted();
546 state
.NotifyReadyToCommit();
547 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
548 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
549 EXPECT_TRUE(state
.RedrawPending());
551 // Activate so we're ready for a new main frame.
552 state
.NotifyReadyToActivate();
553 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
554 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
555 EXPECT_TRUE(state
.RedrawPending());
557 // The redraw should be forced at the end of the next BeginImplFrame.
558 state
.OnBeginImplFrame();
559 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
560 EXPECT_ACTION_UPDATE_STATE(
561 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
562 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
563 state
.OnBeginImplFrameDeadline();
564 EXPECT_ACTION_UPDATE_STATE(
565 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED
);
566 state
.DidSwapBuffers();
567 state
.DidSwapBuffersComplete();
570 TEST(SchedulerStateMachineTest
, TestFailedDrawsDoNotRestartForcedDraw
) {
571 SchedulerSettings scheduler_settings
;
573 scheduler_settings
.maximum_number_of_failed_draws_before_draw_is_forced
=
575 StateMachine
state(scheduler_settings
);
579 state
.SetNeedsBeginMainFrame();
580 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
581 state
.OnBeginImplFrame();
582 EXPECT_ACTION_UPDATE_STATE(
583 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
584 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
585 EXPECT_TRUE(state
.CommitPending());
587 // Then initiate a draw.
588 state
.SetNeedsRedraw(true);
589 state
.OnBeginImplFrameDeadline();
590 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
591 EXPECT_ACTION_UPDATE_STATE(
592 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
594 // Fail the draw enough times to force a redraw,
595 // then once more for good measure.
596 for (int i
= 0; i
< draw_limit
+ 1; ++i
)
597 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
598 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
599 EXPECT_TRUE(state
.BeginFrameNeeded());
600 EXPECT_TRUE(state
.RedrawPending());
601 // But the commit is ongoing.
602 EXPECT_TRUE(state
.CommitPending());
603 EXPECT_TRUE(state
.ForcedRedrawState() ==
604 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_COMMIT
);
606 state
.NotifyBeginMainFrameStarted();
607 state
.NotifyReadyToCommit();
608 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
609 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
610 EXPECT_TRUE(state
.RedrawPending());
611 EXPECT_FALSE(state
.CommitPending());
613 // Now force redraw should be in waiting for activation
614 EXPECT_TRUE(state
.ForcedRedrawState() ==
615 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
);
617 // After failing additional draws, we should still be in a forced
618 // redraw, but not back in WAITING_FOR_COMMIT.
619 for (int i
= 0; i
< draw_limit
+ 1; ++i
)
620 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
621 EXPECT_TRUE(state
.RedrawPending());
622 EXPECT_TRUE(state
.ForcedRedrawState() ==
623 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
);
626 TEST(SchedulerStateMachineTest
, TestFailedDrawIsRetriedInNextBeginImplFrame
) {
627 SchedulerSettings default_scheduler_settings
;
628 StateMachine
state(default_scheduler_settings
);
632 state
.SetNeedsRedraw(true);
633 EXPECT_TRUE(state
.BeginFrameNeeded());
634 state
.OnBeginImplFrame();
635 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
636 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
637 state
.OnBeginImplFrameDeadline();
638 EXPECT_TRUE(state
.RedrawPending());
639 EXPECT_ACTION_UPDATE_STATE(
640 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
642 // Failing the draw for animation checkerboards makes us require a commit.
643 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
644 EXPECT_ACTION_UPDATE_STATE(
645 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
646 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
647 EXPECT_TRUE(state
.RedrawPending());
649 // We should not be trying to draw again now, but we have a commit pending.
650 EXPECT_TRUE(state
.BeginFrameNeeded());
651 state
.OnBeginImplFrame();
652 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
653 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
655 // We should try to draw again at the end of the next BeginImplFrame on
657 state
.OnBeginImplFrameDeadline();
658 EXPECT_ACTION_UPDATE_STATE(
659 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
660 state
.DidSwapBuffers();
661 state
.DidSwapBuffersComplete();
662 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
665 TEST(SchedulerStateMachineTest
, TestDoestDrawTwiceInSameFrame
) {
666 SchedulerSettings default_scheduler_settings
;
667 StateMachine
state(default_scheduler_settings
);
669 state
.SetNeedsRedraw(true);
671 // Draw the first frame.
672 EXPECT_TRUE(state
.BeginFrameNeeded());
673 state
.OnBeginImplFrame();
674 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
675 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
677 state
.OnBeginImplFrameDeadline();
678 EXPECT_ACTION_UPDATE_STATE(
679 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
680 state
.DidSwapBuffers();
681 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
682 state
.DidSwapBuffersComplete();
683 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
685 // Before the next BeginImplFrame, set needs redraw again.
686 // This should not redraw until the next BeginImplFrame.
687 state
.SetNeedsRedraw(true);
688 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
690 // Move to another frame. This should now draw.
691 EXPECT_TRUE(state
.BeginFrameNeeded());
692 state
.OnBeginImplFrame();
694 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
695 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
697 state
.OnBeginImplFrameDeadline();
698 EXPECT_ACTION_UPDATE_STATE(
699 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
700 state
.DidSwapBuffers();
701 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
702 state
.DidSwapBuffersComplete();
703 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
705 // We just swapped, so we should proactively request another BeginImplFrame.
706 EXPECT_TRUE(state
.BeginFrameNeeded());
709 TEST(SchedulerStateMachineTest
, TestNextActionDrawsOnBeginImplFrame
) {
710 SchedulerSettings default_scheduler_settings
;
712 // When not in BeginImplFrame deadline, or in BeginImplFrame deadline
713 // but not visible, don't draw.
714 size_t num_begin_main_frame_states
=
715 sizeof(begin_main_frame_states
) /
716 sizeof(SchedulerStateMachine::BeginMainFrameState
);
717 size_t num_begin_impl_frame_states
=
718 sizeof(all_begin_impl_frame_states
) /
719 sizeof(SchedulerStateMachine::BeginImplFrameState
);
720 for (size_t i
= 0; i
< num_begin_main_frame_states
; ++i
) {
721 for (size_t j
= 0; j
< num_begin_impl_frame_states
; ++j
) {
722 StateMachine
state(default_scheduler_settings
);
724 state
.SetVisible(true);
725 EXPECT_ACTION_UPDATE_STATE(
726 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
727 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
728 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
729 state
.SetBeginMainFrameState(begin_main_frame_states
[i
]);
730 state
.SetBeginImplFrameState(all_begin_impl_frame_states
[j
]);
732 (all_begin_impl_frame_states
[j
] !=
733 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
734 state
.SetVisible(visible
);
736 // Case 1: needs_begin_main_frame=false
737 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
740 // Case 2: needs_begin_main_frame=true
741 state
.SetNeedsBeginMainFrame();
742 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
744 << state
.AsValue()->ToString();
748 // When in BeginImplFrame deadline we should always draw for SetNeedsRedraw
749 // except if we're ready to commit, in which case we expect a commit first.
750 for (size_t i
= 0; i
< num_begin_main_frame_states
; ++i
) {
751 StateMachine
state(default_scheduler_settings
);
753 state
.SetVisible(true);
754 EXPECT_ACTION_UPDATE_STATE(
755 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
756 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
757 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
758 state
.SetCanDraw(true);
759 state
.SetBeginMainFrameState(begin_main_frame_states
[i
]);
760 state
.SetBeginImplFrameState(
761 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
763 state
.SetNeedsRedraw(true);
765 SchedulerStateMachine::Action expected_action
;
766 if (begin_main_frame_states
[i
] ==
767 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT
) {
768 expected_action
= SchedulerStateMachine::ACTION_COMMIT
;
770 expected_action
= SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
;
771 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
774 // Case 1: needs_begin_main_frame=false.
775 EXPECT_ACTION(expected_action
);
777 // Case 2: needs_begin_main_frame=true.
778 state
.SetNeedsBeginMainFrame();
779 EXPECT_ACTION(expected_action
);
783 TEST(SchedulerStateMachineTest
, TestNoBeginMainFrameStatesRedrawWhenInvisible
) {
784 SchedulerSettings default_scheduler_settings
;
786 size_t num_begin_main_frame_states
=
787 sizeof(begin_main_frame_states
) /
788 sizeof(SchedulerStateMachine::BeginMainFrameState
);
789 for (size_t i
= 0; i
< num_begin_main_frame_states
; ++i
) {
790 // There shouldn't be any drawing regardless of BeginImplFrame.
791 for (size_t j
= 0; j
< 2; ++j
) {
792 StateMachine
state(default_scheduler_settings
);
794 state
.SetVisible(true);
795 EXPECT_ACTION_UPDATE_STATE(
796 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
797 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
798 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
799 state
.SetBeginMainFrameState(begin_main_frame_states
[i
]);
800 state
.SetVisible(false);
801 state
.SetNeedsRedraw(true);
803 state
.SetBeginImplFrameState(
804 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
807 // Case 1: needs_begin_main_frame=false.
808 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
811 // Case 2: needs_begin_main_frame=true.
812 state
.SetNeedsBeginMainFrame();
813 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
815 << state
.AsValue()->ToString();
820 TEST(SchedulerStateMachineTest
, TestCanRedraw_StopsDraw
) {
821 SchedulerSettings default_scheduler_settings
;
823 size_t num_begin_main_frame_states
=
824 sizeof(begin_main_frame_states
) /
825 sizeof(SchedulerStateMachine::BeginMainFrameState
);
826 for (size_t i
= 0; i
< num_begin_main_frame_states
; ++i
) {
827 // There shouldn't be any drawing regardless of BeginImplFrame.
828 for (size_t j
= 0; j
< 2; ++j
) {
829 StateMachine
state(default_scheduler_settings
);
831 state
.SetVisible(true);
832 EXPECT_ACTION_UPDATE_STATE(
833 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
834 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
835 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
836 state
.SetBeginMainFrameState(begin_main_frame_states
[i
]);
837 state
.SetVisible(false);
838 state
.SetNeedsRedraw(true);
840 state
.OnBeginImplFrame();
842 state
.SetCanDraw(false);
843 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
849 TEST(SchedulerStateMachineTest
,
850 TestCanRedrawWithWaitingForFirstDrawMakesProgress
) {
851 SchedulerSettings default_scheduler_settings
;
852 StateMachine
state(default_scheduler_settings
);
854 state
.SetVisible(true);
855 EXPECT_ACTION_UPDATE_STATE(
856 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
857 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
858 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
860 state
.SetActiveTreeNeedsFirstDraw(true);
861 state
.SetNeedsBeginMainFrame();
862 state
.SetNeedsRedraw(true);
863 state
.SetCanDraw(false);
864 state
.OnBeginImplFrame();
865 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
866 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
867 EXPECT_ACTION_UPDATE_STATE(
868 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
869 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
870 state
.NotifyBeginMainFrameStarted();
871 state
.NotifyReadyToCommit();
872 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
873 state
.NotifyReadyToActivate();
874 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
875 state
.OnBeginImplFrameDeadline();
876 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
877 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
878 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
881 TEST(SchedulerStateMachineTest
, TestSetNeedsBeginMainFrameIsNotLost
) {
882 SchedulerSettings scheduler_settings
;
883 StateMachine
state(scheduler_settings
);
885 state
.SetNeedsBeginMainFrame();
887 EXPECT_TRUE(state
.BeginFrameNeeded());
890 state
.OnBeginImplFrame();
891 EXPECT_ACTION_UPDATE_STATE(
892 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
893 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
895 // Now, while the frame is in progress, set another commit.
896 state
.SetNeedsBeginMainFrame();
897 EXPECT_TRUE(state
.NeedsCommit());
899 // Let the frame finish.
900 state
.NotifyBeginMainFrameStarted();
901 state
.NotifyReadyToCommit();
902 EXPECT_MAIN_FRAME_STATE(
903 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT
);
905 // Expect to commit regardless of BeginImplFrame state.
906 EXPECT_IMPL_FRAME_STATE(
907 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
908 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
910 state
.OnBeginImplFrameDeadlinePending();
911 EXPECT_IMPL_FRAME_STATE(
912 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
);
913 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
915 state
.OnBeginImplFrameDeadline();
916 EXPECT_IMPL_FRAME_STATE(
917 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
918 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
920 state
.OnBeginImplFrameIdle();
921 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
922 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
924 state
.OnBeginImplFrame();
925 EXPECT_IMPL_FRAME_STATE(
926 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
927 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
929 // Finish the commit and activate, then make sure we start the next commit
930 // immediately and draw on the next BeginImplFrame.
931 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
932 state
.NotifyReadyToActivate();
933 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
934 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
935 EXPECT_ACTION_UPDATE_STATE(
936 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
937 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
939 state
.OnBeginImplFrameDeadline();
941 EXPECT_TRUE(state
.active_tree_needs_first_draw());
942 EXPECT_ACTION_UPDATE_STATE(
943 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
944 state
.DidSwapBuffers();
945 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
946 state
.DidSwapBuffersComplete();
947 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
950 TEST(SchedulerStateMachineTest
, TestFullCycle
) {
951 SchedulerSettings default_scheduler_settings
;
952 StateMachine
state(default_scheduler_settings
);
955 // Start clean and set commit.
956 state
.SetNeedsBeginMainFrame();
959 state
.OnBeginImplFrame();
960 EXPECT_ACTION_UPDATE_STATE(
961 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
962 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
963 EXPECT_FALSE(state
.NeedsCommit());
964 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
966 // Tell the scheduler the frame finished.
967 state
.NotifyBeginMainFrameStarted();
968 state
.NotifyReadyToCommit();
969 EXPECT_MAIN_FRAME_STATE(
970 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT
);
973 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
976 state
.NotifyReadyToActivate();
977 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
978 EXPECT_TRUE(state
.active_tree_needs_first_draw());
979 EXPECT_TRUE(state
.needs_redraw());
981 // Expect to do nothing until BeginImplFrame deadline
982 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
984 // At BeginImplFrame deadline, draw.
985 state
.OnBeginImplFrameDeadline();
986 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
987 EXPECT_ACTION_UPDATE_STATE(
988 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
989 state
.DidSwapBuffers();
990 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
991 state
.DidSwapBuffersComplete();
993 // Should be synchronized, no draw needed, no action needed.
994 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
995 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
996 EXPECT_FALSE(state
.needs_redraw());
999 TEST(SchedulerStateMachineTest
, CommitWithoutDrawWithPendingTree
) {
1000 SchedulerSettings default_scheduler_settings
;
1001 StateMachine
state(default_scheduler_settings
);
1004 // Start clean and set commit.
1005 state
.SetNeedsBeginMainFrame();
1007 // Make a main frame, commit and activate it. But don't draw it.
1008 state
.OnBeginImplFrame();
1009 EXPECT_ACTION_UPDATE_STATE(
1010 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1011 state
.NotifyBeginMainFrameStarted();
1012 state
.NotifyReadyToCommit();
1013 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1014 state
.NotifyReadyToActivate();
1015 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1017 // Try to make a new main frame before drawing. Since we will commit it to a
1018 // pending tree and not clobber the active tree, we're able to start a new
1019 // begin frame and commit it.
1020 state
.SetNeedsBeginMainFrame();
1021 state
.OnBeginImplFrame();
1022 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1023 EXPECT_ACTION_UPDATE_STATE(
1024 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1025 state
.NotifyBeginMainFrameStarted();
1026 state
.NotifyReadyToCommit();
1027 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1030 TEST(SchedulerStateMachineTest
, DontCommitWithoutDrawWithoutPendingTree
) {
1031 SchedulerSettings scheduler_settings
;
1032 scheduler_settings
.commit_to_active_tree
= true;
1033 StateMachine
state(scheduler_settings
);
1036 // Start clean and set commit.
1037 state
.SetNeedsBeginMainFrame();
1039 // Make a main frame, commit and activate it. But don't draw it.
1040 state
.OnBeginImplFrame();
1041 EXPECT_ACTION_UPDATE_STATE(
1042 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1043 state
.NotifyBeginMainFrameStarted();
1044 state
.NotifyReadyToCommit();
1045 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1046 state
.NotifyReadyToActivate();
1047 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1049 // Try to make a new main frame before drawing, but since we would clobber the
1050 // active tree, we will not do so.
1051 state
.SetNeedsBeginMainFrame();
1052 state
.OnBeginImplFrame();
1053 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1054 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1057 TEST(SchedulerStateMachineTest
, TestFullCycleWithCommitToActive
) {
1058 SchedulerSettings scheduler_settings
;
1059 scheduler_settings
.commit_to_active_tree
= true;
1060 StateMachine
state(scheduler_settings
);
1063 // Start clean and set commit.
1064 state
.SetNeedsBeginMainFrame();
1067 state
.OnBeginImplFrame();
1068 EXPECT_ACTION_UPDATE_STATE(
1069 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1070 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
1071 EXPECT_FALSE(state
.NeedsCommit());
1072 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1074 // Tell the scheduler the frame finished.
1075 state
.NotifyBeginMainFrameStarted();
1076 state
.NotifyReadyToCommit();
1077 EXPECT_MAIN_FRAME_STATE(
1078 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT
);
1081 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1083 // Now commit should wait for activation.
1084 EXPECT_MAIN_FRAME_STATE(
1085 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_WAITING_FOR_ACTIVATION
);
1087 // No activation yet, so this commit is not drawn yet. Force to draw this
1088 // frame, and still block BeginMainFrame.
1089 state
.SetNeedsRedraw(true);
1090 state
.SetNeedsBeginMainFrame();
1091 state
.OnBeginImplFrameDeadline();
1092 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1093 EXPECT_ACTION_UPDATE_STATE(
1094 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1095 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1097 // Cannot BeginMainFrame yet since last commit is not yet activated and drawn.
1098 state
.OnBeginImplFrame();
1099 EXPECT_MAIN_FRAME_STATE(
1100 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_WAITING_FOR_ACTIVATION
);
1101 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1103 // Now activate sync tree.
1104 state
.NotifyReadyToActivate();
1105 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1106 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1107 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1108 EXPECT_TRUE(state
.needs_redraw());
1109 EXPECT_MAIN_FRAME_STATE(
1110 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_WAITING_FOR_DRAW
);
1112 // Swap throttled. Do not draw.
1113 state
.DidSwapBuffers();
1114 state
.OnBeginImplFrameDeadline();
1115 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1116 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1117 state
.DidSwapBuffersComplete();
1119 // Haven't draw since last commit, do not begin new main frame.
1120 state
.OnBeginImplFrame();
1121 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1122 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1124 // At BeginImplFrame deadline, draw. This draws unblocks BeginMainFrame.
1125 state
.OnBeginImplFrameDeadline();
1126 EXPECT_ACTION_UPDATE_STATE(
1127 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1128 state
.DidSwapBuffers();
1129 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
1130 state
.DidSwapBuffersComplete();
1132 // Now will be able to start main frame.
1133 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
1134 EXPECT_FALSE(state
.needs_redraw());
1135 EXPECT_ACTION_UPDATE_STATE(
1136 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1139 TEST(SchedulerStateMachineTest
, TestFullCycleWithCommitRequestInbetween
) {
1140 SchedulerSettings default_scheduler_settings
;
1141 StateMachine
state(default_scheduler_settings
);
1144 // Start clean and set commit.
1145 state
.SetNeedsBeginMainFrame();
1148 state
.OnBeginImplFrame();
1149 EXPECT_ACTION_UPDATE_STATE(
1150 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1151 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
1152 EXPECT_FALSE(state
.NeedsCommit());
1153 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1155 // Request another commit while the commit is in flight.
1156 state
.SetNeedsBeginMainFrame();
1157 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1159 // Tell the scheduler the frame finished.
1160 state
.NotifyBeginMainFrameStarted();
1161 state
.NotifyReadyToCommit();
1162 EXPECT_MAIN_FRAME_STATE(
1163 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT
);
1165 // First commit and activate.
1166 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1167 state
.NotifyReadyToActivate();
1168 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1169 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1170 EXPECT_TRUE(state
.needs_redraw());
1172 // Expect to do nothing until BeginImplFrame deadline.
1173 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1175 // At BeginImplFrame deadline, draw.
1176 state
.OnBeginImplFrameDeadline();
1177 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1178 EXPECT_ACTION_UPDATE_STATE(
1179 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1180 state
.DidSwapBuffers();
1181 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
1182 state
.DidSwapBuffersComplete();
1184 // Should be synchronized, no draw needed, no action needed.
1185 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1186 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
1187 EXPECT_FALSE(state
.needs_redraw());
1189 // Next BeginImplFrame should initiate second commit.
1190 state
.OnBeginImplFrame();
1191 EXPECT_ACTION_UPDATE_STATE(
1192 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1195 TEST(SchedulerStateMachineTest
, TestNoRequestCommitWhenInvisible
) {
1196 SchedulerSettings default_scheduler_settings
;
1197 StateMachine
state(default_scheduler_settings
);
1198 state
.SetCanStart();
1199 state
.SetVisible(true);
1200 EXPECT_ACTION_UPDATE_STATE(
1201 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1202 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1203 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1204 state
.SetVisible(false);
1205 state
.SetNeedsBeginMainFrame();
1206 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1209 TEST(SchedulerStateMachineTest
, TestNoRequestOutputSurfaceWhenInvisible
) {
1210 SchedulerSettings default_scheduler_settings
;
1211 StateMachine
state(default_scheduler_settings
);
1212 state
.SetCanStart();
1213 // We should not request an OutputSurface when we are still invisible.
1214 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1215 state
.SetVisible(true);
1216 EXPECT_ACTION_UPDATE_STATE(
1217 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1218 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1219 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1220 state
.SetVisible(false);
1221 state
.DidLoseOutputSurface();
1222 state
.SetNeedsBeginMainFrame();
1223 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1224 state
.SetVisible(true);
1225 EXPECT_ACTION_UPDATE_STATE(
1226 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1229 // See ThreadProxy::BeginMainFrame "EarlyOut_NotVisible" /
1230 // "EarlyOut_OutputSurfaceLost" cases.
1231 TEST(SchedulerStateMachineTest
, TestAbortBeginMainFrameBecauseInvisible
) {
1232 SchedulerSettings default_scheduler_settings
;
1233 StateMachine
state(default_scheduler_settings
);
1236 // Start clean and set commit.
1237 state
.SetNeedsBeginMainFrame();
1239 // Begin the frame while visible.
1240 state
.OnBeginImplFrame();
1241 EXPECT_ACTION_UPDATE_STATE(
1242 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1243 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
1244 EXPECT_FALSE(state
.NeedsCommit());
1245 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1247 // Become invisible and abort BeginMainFrame.
1248 state
.SetVisible(false);
1249 state
.BeginMainFrameAborted(CommitEarlyOutReason::ABORTED_NOT_VISIBLE
);
1251 // NeedsCommit should now be true again because we never actually did a
1253 EXPECT_TRUE(state
.NeedsCommit());
1255 // We should now be back in the idle state as if we never started the frame.
1256 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
1257 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1259 // We shouldn't do anything on the BeginImplFrame deadline.
1260 state
.OnBeginImplFrameDeadline();
1261 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1263 // Become visible again.
1264 state
.SetVisible(true);
1266 // Although we have aborted on this frame and haven't cancelled the commit
1267 // (i.e. need another), don't send another BeginMainFrame yet.
1268 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
1269 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1270 EXPECT_TRUE(state
.NeedsCommit());
1272 // Start a new frame.
1273 state
.OnBeginImplFrame();
1274 EXPECT_ACTION_UPDATE_STATE(
1275 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1277 // We should be starting the commit now.
1278 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
1279 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1282 // See ThreadProxy::BeginMainFrame "EarlyOut_NoUpdates" case.
1283 TEST(SchedulerStateMachineTest
, TestAbortBeginMainFrameBecauseCommitNotNeeded
) {
1284 SchedulerSettings default_scheduler_settings
;
1285 StateMachine
state(default_scheduler_settings
);
1286 state
.SetCanStart();
1287 state
.SetVisible(true);
1288 EXPECT_ACTION_UPDATE_STATE(
1289 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1290 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1291 state
.DidCreateAndInitializeOutputSurface();
1292 state
.SetCanDraw(true);
1294 // Get into a begin frame / commit state.
1295 state
.SetNeedsBeginMainFrame();
1296 state
.OnBeginImplFrame();
1297 EXPECT_ACTION_UPDATE_STATE(
1298 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1299 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
1300 EXPECT_FALSE(state
.NeedsCommit());
1301 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1303 // Abort the commit, true means that the BeginMainFrame was sent but there
1304 // was no work to do on the main thread.
1305 state
.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES
);
1307 // NeedsCommit should now be false because the commit was actually handled.
1308 EXPECT_FALSE(state
.NeedsCommit());
1310 // Since the commit was aborted, we don't need to try and draw.
1311 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1312 state
.OnBeginImplFrameDeadline();
1313 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1315 // Verify another commit doesn't start on another frame either.
1316 EXPECT_FALSE(state
.NeedsCommit());
1317 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
1319 state
.OnBeginImplFrame();
1320 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1321 state
.OnBeginImplFrameDeadline();
1322 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1324 // Verify another commit can start if requested, though.
1325 state
.SetNeedsBeginMainFrame();
1326 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
1327 state
.OnBeginImplFrame();
1328 EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1331 TEST(SchedulerStateMachineTest
, TestFirstContextCreation
) {
1332 SchedulerSettings default_scheduler_settings
;
1333 StateMachine
state(default_scheduler_settings
);
1334 state
.SetCanStart();
1335 state
.SetVisible(true);
1336 state
.SetCanDraw(true);
1338 EXPECT_ACTION_UPDATE_STATE(
1339 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1340 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1341 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1343 // Check that the first init does not SetNeedsBeginMainFrame.
1344 state
.OnBeginImplFrame();
1345 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1346 state
.OnBeginImplFrameDeadline();
1347 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1349 // Check that a needs commit initiates a BeginMainFrame.
1350 state
.SetNeedsBeginMainFrame();
1351 state
.OnBeginImplFrame();
1352 EXPECT_ACTION_UPDATE_STATE(
1353 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1356 TEST(SchedulerStateMachineTest
, TestContextLostWhenCompletelyIdle
) {
1357 SchedulerSettings default_scheduler_settings
;
1358 StateMachine
state(default_scheduler_settings
);
1361 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1362 state
.NextAction());
1363 state
.DidLoseOutputSurface();
1365 EXPECT_ACTION_UPDATE_STATE(
1366 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1367 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1369 // Once context recreation begins, nothing should happen.
1370 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1372 // Recreate the context.
1373 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1375 // When the context is recreated, we should begin a commit.
1376 state
.OnBeginImplFrame();
1377 EXPECT_ACTION_UPDATE_STATE(
1378 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1381 TEST(SchedulerStateMachineTest
,
1382 TestContextLostWhenIdleAndCommitRequestedWhileRecreating
) {
1383 SchedulerSettings default_scheduler_settings
;
1384 StateMachine
state(default_scheduler_settings
);
1387 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1388 state
.NextAction());
1389 state
.DidLoseOutputSurface();
1390 EXPECT_EQ(state
.output_surface_state(),
1391 SchedulerStateMachine::OUTPUT_SURFACE_LOST
);
1393 EXPECT_ACTION_UPDATE_STATE(
1394 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1395 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1397 // Once context recreation begins, nothing should happen.
1398 state
.OnBeginImplFrame();
1399 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1400 state
.OnBeginImplFrameDeadline();
1401 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1403 // While context is recreating, commits shouldn't begin.
1404 state
.SetNeedsBeginMainFrame();
1405 state
.OnBeginImplFrame();
1406 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1407 state
.OnBeginImplFrameDeadline();
1408 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1410 // Recreate the context
1411 state
.DidCreateAndInitializeOutputSurface();
1412 EXPECT_EQ(state
.output_surface_state(),
1413 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT
);
1414 EXPECT_FALSE(state
.RedrawPending());
1416 // When the context is recreated, we wait until the next BeginImplFrame
1418 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1420 // When the BeginFrame comes in we should begin a commit
1421 state
.OnBeginImplFrame();
1422 EXPECT_ACTION_UPDATE_STATE(
1423 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1424 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1425 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
1427 // Until that commit finishes, we shouldn't be drawing or animate.
1428 state
.OnBeginImplFrameDeadline();
1429 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1431 // Finish the commit, which should make the surface active.
1432 state
.NotifyBeginMainFrameStarted();
1433 state
.NotifyReadyToCommit();
1434 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1435 EXPECT_EQ(state
.output_surface_state(),
1436 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION
);
1437 state
.NotifyReadyToActivate();
1438 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1439 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1440 EXPECT_EQ(state
.output_surface_state(),
1441 SchedulerStateMachine::OUTPUT_SURFACE_ACTIVE
);
1443 // Finishing the first commit after initializing an output surface should
1444 // automatically cause a redraw.
1445 EXPECT_TRUE(state
.RedrawPending());
1446 state
.OnBeginImplFrame();
1447 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1448 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1449 state
.OnBeginImplFrameDeadline();
1450 EXPECT_ACTION_UPDATE_STATE(
1451 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1452 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1453 EXPECT_FALSE(state
.RedrawPending());
1455 // Next frame as no work to do.
1456 state
.OnBeginImplFrame();
1457 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1458 state
.OnBeginImplFrameDeadline();
1459 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1461 // Once the context is recreated, whether we draw should be based on
1462 // SetCanDraw if waiting on first draw after activate.
1463 state
.SetNeedsRedraw(true);
1464 state
.OnBeginImplFrame();
1465 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1466 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1467 state
.OnBeginImplFrameDeadline();
1468 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1469 state
.SetCanDraw(false);
1470 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1471 state
.SetCanDraw(true);
1472 EXPECT_ACTION_UPDATE_STATE(
1473 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1474 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1476 // Once the context is recreated, whether we draw should be based on
1477 // SetCanDraw if waiting on first draw after activate.
1478 state
.SetNeedsRedraw(true);
1479 state
.SetNeedsBeginMainFrame();
1480 state
.OnBeginImplFrame();
1481 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1482 EXPECT_ACTION_UPDATE_STATE(
1483 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1484 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1485 // Activate so we need the first draw
1486 state
.NotifyBeginMainFrameStarted();
1487 state
.NotifyReadyToCommit();
1488 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1489 state
.NotifyReadyToActivate();
1490 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1491 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1492 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1493 EXPECT_TRUE(state
.needs_redraw());
1495 state
.OnBeginImplFrameDeadline();
1496 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1497 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1498 state
.SetCanDraw(false);
1499 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1500 state
.SetCanDraw(true);
1501 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1504 TEST(SchedulerStateMachineTest
, TestContextLostWhileCommitInProgress
) {
1505 SchedulerSettings scheduler_settings
;
1506 StateMachine
state(scheduler_settings
);
1509 // Get a commit in flight.
1510 state
.SetNeedsBeginMainFrame();
1512 // Set damage and expect a draw.
1513 state
.SetNeedsRedraw(true);
1514 state
.OnBeginImplFrame();
1515 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1516 EXPECT_ACTION_UPDATE_STATE(
1517 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1518 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1519 state
.OnBeginImplFrameDeadline();
1520 EXPECT_ACTION_UPDATE_STATE(
1521 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1522 state
.DidSwapBuffers();
1523 state
.DidSwapBuffersComplete();
1524 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1526 // Cause a lost context while the BeginMainFrame is in flight.
1527 state
.DidLoseOutputSurface();
1529 // Ask for another draw. Expect nothing happens.
1530 state
.SetNeedsRedraw(true);
1531 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1533 // Finish the frame, commit and activate.
1534 state
.NotifyBeginMainFrameStarted();
1535 state
.NotifyReadyToCommit();
1536 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1537 state
.NotifyReadyToActivate();
1538 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1540 // We will abort the draw when the output surface is lost if we are
1541 // waiting for the first draw to unblock the main thread.
1542 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1543 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1545 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1546 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
1547 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1549 state
.OnBeginImplFrame();
1550 EXPECT_IMPL_FRAME_STATE(
1551 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
1552 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1554 state
.OnBeginImplFrameDeadlinePending();
1555 EXPECT_IMPL_FRAME_STATE(
1556 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
);
1557 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1559 state
.OnBeginImplFrameDeadline();
1560 EXPECT_IMPL_FRAME_STATE(
1561 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
1562 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1565 TEST(SchedulerStateMachineTest
,
1566 TestContextLostWhileCommitInProgressAndAnotherCommitRequested
) {
1567 SchedulerSettings scheduler_settings
;
1568 StateMachine
state(scheduler_settings
);
1571 // Get a commit in flight.
1572 state
.SetNeedsBeginMainFrame();
1573 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1575 // Set damage and expect a draw.
1576 state
.SetNeedsRedraw(true);
1577 state
.OnBeginImplFrame();
1578 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1579 EXPECT_ACTION_UPDATE_STATE(
1580 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1581 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1582 state
.OnBeginImplFrameDeadline();
1583 EXPECT_ACTION_UPDATE_STATE(
1584 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1585 state
.DidSwapBuffers();
1586 state
.DidSwapBuffersComplete();
1587 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1589 // Cause a lost context while the BeginMainFrame is in flight.
1590 state
.DidLoseOutputSurface();
1592 // Ask for another draw and also set needs commit. Expect nothing happens.
1593 state
.SetNeedsRedraw(true);
1594 state
.SetNeedsBeginMainFrame();
1595 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1597 // Finish the frame, and commit and activate.
1598 state
.NotifyBeginMainFrameStarted();
1599 state
.NotifyReadyToCommit();
1600 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1601 state
.NotifyReadyToActivate();
1602 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1603 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1605 // Because the output surface is missing, we expect the draw to abort.
1606 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1608 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1609 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
1610 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1612 state
.OnBeginImplFrame();
1613 EXPECT_IMPL_FRAME_STATE(
1614 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
1615 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1617 state
.OnBeginImplFrameDeadlinePending();
1618 EXPECT_IMPL_FRAME_STATE(
1619 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
);
1620 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1622 state
.OnBeginImplFrameDeadline();
1623 EXPECT_IMPL_FRAME_STATE(
1624 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
1625 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1627 state
.OnBeginImplFrameIdle();
1628 EXPECT_ACTION_UPDATE_STATE(
1629 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1631 // After we get a new output surface, the commit flow should start.
1632 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1633 state
.OnBeginImplFrame();
1634 EXPECT_ACTION_UPDATE_STATE(
1635 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1636 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1637 state
.NotifyBeginMainFrameStarted();
1638 state
.NotifyReadyToCommit();
1639 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1640 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1641 state
.NotifyReadyToActivate();
1642 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1643 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1644 state
.OnBeginImplFrameDeadline();
1645 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1646 EXPECT_ACTION_UPDATE_STATE(
1647 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1648 state
.DidSwapBuffers();
1649 state
.DidSwapBuffersComplete();
1650 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1653 TEST(SchedulerStateMachineTest
, DontDrawBeforeCommitAfterLostOutputSurface
) {
1654 SchedulerSettings default_scheduler_settings
;
1655 StateMachine
state(default_scheduler_settings
);
1658 state
.SetNeedsRedraw(true);
1660 // Cause a lost output surface, and restore it.
1661 state
.DidLoseOutputSurface();
1662 EXPECT_ACTION_UPDATE_STATE(
1663 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1664 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1665 state
.DidCreateAndInitializeOutputSurface();
1667 EXPECT_FALSE(state
.RedrawPending());
1668 state
.OnBeginImplFrame();
1669 EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1672 TEST(SchedulerStateMachineTest
,
1673 TestPendingActivationsShouldBeForcedAfterLostOutputSurface
) {
1674 SchedulerSettings default_scheduler_settings
;
1675 StateMachine
state(default_scheduler_settings
);
1678 state
.SetBeginMainFrameState(
1679 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
1681 // Cause a lost context.
1682 state
.DidLoseOutputSurface();
1684 state
.NotifyBeginMainFrameStarted();
1685 state
.NotifyReadyToCommit();
1686 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1688 EXPECT_TRUE(state
.PendingActivationsShouldBeForced());
1689 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1691 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1692 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1695 TEST(SchedulerStateMachineTest
, TestNoBeginFrameNeededWhenInvisible
) {
1696 SchedulerSettings default_scheduler_settings
;
1697 StateMachine
state(default_scheduler_settings
);
1698 state
.SetCanStart();
1699 state
.SetVisible(true);
1700 EXPECT_ACTION_UPDATE_STATE(
1701 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1702 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1703 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1705 EXPECT_FALSE(state
.BeginFrameNeeded());
1706 state
.SetNeedsRedraw(true);
1707 EXPECT_TRUE(state
.BeginFrameNeeded());
1709 state
.SetVisible(false);
1710 EXPECT_FALSE(state
.BeginFrameNeeded());
1712 state
.SetVisible(true);
1713 EXPECT_TRUE(state
.BeginFrameNeeded());
1716 TEST(SchedulerStateMachineTest
, TestNoBeginMainFrameWhenInvisible
) {
1717 SchedulerSettings default_scheduler_settings
;
1718 StateMachine
state(default_scheduler_settings
);
1719 state
.SetCanStart();
1720 state
.SetVisible(true);
1721 EXPECT_ACTION_UPDATE_STATE(
1722 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1723 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1724 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1725 state
.SetVisible(false);
1726 state
.SetNeedsBeginMainFrame();
1727 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1728 EXPECT_FALSE(state
.BeginFrameNeeded());
1730 // When become visible again, the needs commit should still be pending.
1731 state
.SetVisible(true);
1732 EXPECT_TRUE(state
.BeginFrameNeeded());
1733 state
.OnBeginImplFrame();
1734 EXPECT_ACTION_UPDATE_STATE(
1735 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1738 TEST(SchedulerStateMachineTest
, TestFinishCommitWhenCommitInProgress
) {
1739 SchedulerSettings default_scheduler_settings
;
1740 StateMachine
state(default_scheduler_settings
);
1741 state
.SetCanStart();
1742 state
.SetVisible(true);
1743 EXPECT_ACTION_UPDATE_STATE(
1744 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1745 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1746 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1747 state
.SetVisible(false);
1748 state
.SetBeginMainFrameState(
1749 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
1750 state
.SetNeedsBeginMainFrame();
1752 // After the commit completes, activation and draw happen immediately
1753 // because we are not visible.
1754 state
.NotifyBeginMainFrameStarted();
1755 state
.NotifyReadyToCommit();
1756 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1757 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1758 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1759 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1760 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1763 TEST(SchedulerStateMachineTest
, TestInitialActionsWhenContextLost
) {
1764 SchedulerSettings default_scheduler_settings
;
1765 StateMachine
state(default_scheduler_settings
);
1767 state
.SetNeedsBeginMainFrame();
1768 state
.DidLoseOutputSurface();
1770 // When we are visible, we normally want to begin output surface creation
1771 // as soon as possible.
1772 EXPECT_ACTION_UPDATE_STATE(
1773 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1775 state
.DidCreateAndInitializeOutputSurface();
1776 EXPECT_EQ(state
.output_surface_state(),
1777 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT
);
1779 // We should not send a BeginMainFrame when we are invisible, even if we've
1780 // lost the output surface and are trying to get the first commit, since the
1781 // main thread will just abort anyway.
1782 state
.SetVisible(false);
1783 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1786 TEST(SchedulerStateMachineTest
, ReportIfNotDrawing
) {
1787 SchedulerSettings default_scheduler_settings
;
1788 StateMachine
state(default_scheduler_settings
);
1790 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1792 state
.SetCanDraw(false);
1793 state
.SetVisible(true);
1794 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1796 state
.SetCanDraw(true);
1797 state
.SetVisible(false);
1798 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1800 state
.SetCanDraw(false);
1801 state
.SetVisible(false);
1802 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1804 state
.SetCanDraw(true);
1805 state
.SetVisible(true);
1806 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1809 TEST(SchedulerStateMachineTest
,
1810 TestTriggerDeadlineImmediatelyAfterAbortedCommit
) {
1811 SchedulerSettings default_scheduler_settings
;
1812 StateMachine
state(default_scheduler_settings
);
1815 // This test mirrors what happens during the first frame of a scroll gesture.
1816 // First we get the input event and a BeginFrame.
1817 state
.OnBeginImplFrame();
1819 // As a response the compositor requests a redraw and a commit to tell the
1820 // main thread about the new scroll offset.
1821 state
.SetNeedsRedraw(true);
1822 state
.SetNeedsBeginMainFrame();
1824 // We should start the commit normally.
1825 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1826 EXPECT_ACTION_UPDATE_STATE(
1827 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1828 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1830 // Since only the scroll offset changed, the main thread will abort the
1832 state
.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES
);
1834 // Since the commit was aborted, we should draw right away instead of waiting
1835 // for the deadline.
1836 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1839 void FinishPreviousCommitAndDrawWithoutExitingDeadline(
1840 StateMachine
* state_ptr
) {
1841 // Gross, but allows us to use macros below.
1842 StateMachine
& state
= *state_ptr
;
1844 state
.NotifyBeginMainFrameStarted();
1845 state
.NotifyReadyToCommit();
1846 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1847 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1848 state
.NotifyReadyToActivate();
1849 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1850 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1852 state
.OnBeginImplFrame();
1853 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1854 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1856 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1857 state
.OnBeginImplFrameDeadline();
1858 EXPECT_ACTION_UPDATE_STATE(
1859 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1860 state
.DidSwapBuffers();
1863 TEST(SchedulerStateMachineTest
, TestImplLatencyTakesPriority
) {
1864 SchedulerSettings default_scheduler_settings
;
1865 StateMachine
state(default_scheduler_settings
);
1868 // This test ensures that impl-draws are prioritized over main thread updates
1869 // in prefer impl latency mode.
1870 state
.SetNeedsRedraw(true);
1871 state
.SetNeedsBeginMainFrame();
1872 state
.OnBeginImplFrame();
1873 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1874 EXPECT_ACTION_UPDATE_STATE(
1875 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1876 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1878 // Verify the deadline is not triggered early until we enter
1879 // prefer impl latency mode.
1880 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1881 state
.SetImplLatencyTakesPriority(true);
1882 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1884 // Trigger the deadline.
1885 state
.OnBeginImplFrameDeadline();
1886 EXPECT_ACTION_UPDATE_STATE(
1887 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1888 state
.DidSwapBuffers();
1889 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1890 state
.DidSwapBuffersComplete();
1892 // Request a new commit and finish the previous one.
1893 state
.SetNeedsBeginMainFrame();
1894 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state
);
1895 EXPECT_ACTION_UPDATE_STATE(
1896 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1897 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1898 state
.DidSwapBuffersComplete();
1899 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1901 // Finish the previous commit and draw it.
1902 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state
);
1903 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1905 // Verify we do not send another BeginMainFrame if was are swap throttled
1906 // and did not just swap.
1907 state
.SetNeedsBeginMainFrame();
1908 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1909 state
.OnBeginImplFrame();
1910 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1911 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1912 state
.OnBeginImplFrameDeadline();
1913 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1916 TEST(SchedulerStateMachineTest
,
1917 TestTriggerDeadlineImmediatelyOnLostOutputSurface
) {
1918 SchedulerSettings default_scheduler_settings
;
1919 StateMachine
state(default_scheduler_settings
);
1922 state
.SetNeedsBeginMainFrame();
1924 state
.OnBeginImplFrame();
1925 EXPECT_ACTION_UPDATE_STATE(
1926 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1927 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1928 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1930 state
.DidLoseOutputSurface();
1931 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1932 // The deadline should be triggered immediately when output surface is lost.
1933 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1936 TEST(SchedulerStateMachineTest
, TestTriggerDeadlineImmediatelyWhenInvisible
) {
1937 SchedulerSettings default_scheduler_settings
;
1938 StateMachine
state(default_scheduler_settings
);
1941 state
.SetNeedsBeginMainFrame();
1943 state
.OnBeginImplFrame();
1944 EXPECT_ACTION_UPDATE_STATE(
1945 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1946 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1947 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1949 state
.SetVisible(false);
1950 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1951 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1954 TEST(SchedulerStateMachineTest
, TestSetNeedsAnimate
) {
1955 SchedulerSettings default_scheduler_settings
;
1956 StateMachine
state(default_scheduler_settings
);
1959 // Test requesting an animation that, when run, causes us to draw.
1960 state
.SetNeedsAnimate();
1961 EXPECT_TRUE(state
.BeginFrameNeeded());
1962 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1964 state
.OnBeginImplFrame();
1965 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1967 state
.OnBeginImplFrameDeadlinePending();
1968 state
.OnBeginImplFrameDeadline();
1969 EXPECT_ACTION_UPDATE_STATE(
1970 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1973 TEST(SchedulerStateMachineTest
, TestAnimateBeforeCommit
) {
1974 SchedulerSettings default_scheduler_settings
;
1975 StateMachine
state(default_scheduler_settings
);
1978 // Check that animations are updated before we start a commit.
1979 state
.SetNeedsAnimate();
1980 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1981 state
.SetNeedsBeginMainFrame();
1982 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1983 EXPECT_TRUE(state
.BeginFrameNeeded());
1985 state
.OnBeginImplFrame();
1986 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1987 EXPECT_ACTION_UPDATE_STATE(
1988 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1990 state
.OnBeginImplFrameDeadlinePending();
1991 state
.OnBeginImplFrameDeadline();
1992 EXPECT_ACTION_UPDATE_STATE(
1993 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1996 TEST(SchedulerStateMachineTest
, TestAnimateAfterCommitBeforeDraw
) {
1997 SchedulerSettings default_scheduler_settings
;
1998 StateMachine
state(default_scheduler_settings
);
2001 // Check that animations are updated before we start a commit.
2002 state
.SetNeedsAnimate();
2003 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
2004 state
.SetNeedsBeginMainFrame();
2005 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
2006 EXPECT_TRUE(state
.BeginFrameNeeded());
2008 state
.OnBeginImplFrame();
2009 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
2010 EXPECT_ACTION_UPDATE_STATE(
2011 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
2013 state
.NotifyBeginMainFrameStarted();
2014 state
.NotifyReadyToCommit();
2015 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
2017 state
.OnBeginImplFrameDeadlinePending();
2018 state
.OnBeginImplFrameDeadline();
2019 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
2020 EXPECT_ACTION_UPDATE_STATE(
2021 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
2024 TEST(SchedulerStateMachineTest
, TestSetNeedsAnimateAfterAnimate
) {
2025 SchedulerSettings default_scheduler_settings
;
2026 StateMachine
state(default_scheduler_settings
);
2029 // Test requesting an animation after we have already animated during this
2031 state
.SetNeedsRedraw(true);
2032 EXPECT_TRUE(state
.BeginFrameNeeded());
2033 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
2035 state
.OnBeginImplFrame();
2036 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
2038 state
.SetNeedsAnimate();
2039 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
2041 state
.OnBeginImplFrameDeadline();
2042 EXPECT_ACTION_UPDATE_STATE(
2043 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
2046 TEST(SchedulerStateMachineTest
, TestForwardBeginFramesToChildren
) {
2047 SchedulerSettings settings
;
2048 StateMachine
state(settings
);
2051 EXPECT_FALSE(state
.BeginFrameNeeded());
2052 state
.SetChildrenNeedBeginFrames(true);
2053 EXPECT_TRUE(state
.BeginFrameNeeded());
2056 TEST(SchedulerStateMachineTest
, TestDeferCommit
) {
2057 SchedulerSettings settings
;
2058 StateMachine
state(settings
);
2061 state
.SetDeferCommits(true);
2063 state
.SetNeedsBeginMainFrame();
2064 EXPECT_FALSE(state
.BeginFrameNeeded());
2065 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
2067 state
.OnBeginImplFrame();
2068 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
2070 state
.OnBeginImplFrameDeadline();
2071 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
2073 state
.SetDeferCommits(false);
2074 state
.OnBeginImplFrame();
2075 EXPECT_ACTION_UPDATE_STATE(
2076 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
2079 TEST(SchedulerStateMachineTest
, EarlyOutCommitWantsProactiveBeginFrame
) {
2080 SchedulerSettings settings
;
2081 StateMachine
state(settings
);
2082 SET_UP_STATE(state
);
2084 EXPECT_FALSE(state
.ProactiveBeginFrameWanted());
2085 bool commit_has_no_updates
= true;
2086 state
.WillCommit(commit_has_no_updates
);
2087 EXPECT_TRUE(state
.ProactiveBeginFrameWanted());
2088 state
.OnBeginImplFrame();
2089 EXPECT_FALSE(state
.ProactiveBeginFrameWanted());