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 EXPECT_ACTION_UPDATE_STATE( \
56 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION); \
57 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); \
58 state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); \
59 state.SetVisible(true); \
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 EXPECT_ACTION_UPDATE_STATE(
210 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
211 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
212 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
213 state
.SetBeginMainFrameState(
214 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
216 // Don't request BeginFrames if we are idle.
217 state
.SetVisible(true);
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 EXPECT_ACTION_UPDATE_STATE(
259 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
260 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
261 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
262 state
.SetBeginMainFrameState(
263 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
264 state
.SetNeedsRedraw(false);
265 state
.SetVisible(true);
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 EXPECT_ACTION_UPDATE_STATE(
305 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
306 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
307 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
308 state
.SetNeedsRedraw(false);
309 state
.SetVisible(true);
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 EXPECT_ACTION_UPDATE_STATE(
333 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
334 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
335 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
336 state
.SetNeedsRedraw(false);
337 state
.SetVisible(true);
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 EXPECT_ACTION_UPDATE_STATE(
725 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
726 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
727 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
728 state
.SetBeginMainFrameState(begin_main_frame_states
[i
]);
729 state
.SetBeginImplFrameState(all_begin_impl_frame_states
[j
]);
731 (all_begin_impl_frame_states
[j
] !=
732 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
733 state
.SetVisible(visible
);
735 // Case 1: needs_begin_main_frame=false
736 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
739 // Case 2: needs_begin_main_frame=true
740 state
.SetNeedsBeginMainFrame();
741 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
743 << state
.AsValue()->ToString();
747 // When in BeginImplFrame deadline we should always draw for SetNeedsRedraw
748 // except if we're ready to commit, in which case we expect a commit first.
749 for (size_t i
= 0; i
< num_begin_main_frame_states
; ++i
) {
750 StateMachine
state(default_scheduler_settings
);
752 EXPECT_ACTION_UPDATE_STATE(
753 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
754 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
755 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
756 state
.SetCanDraw(true);
757 state
.SetBeginMainFrameState(begin_main_frame_states
[i
]);
758 state
.SetBeginImplFrameState(
759 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
761 state
.SetNeedsRedraw(true);
762 state
.SetVisible(true);
764 SchedulerStateMachine::Action expected_action
;
765 if (begin_main_frame_states
[i
] ==
766 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT
) {
767 expected_action
= SchedulerStateMachine::ACTION_COMMIT
;
769 expected_action
= SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
;
770 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
773 // Case 1: needs_begin_main_frame=false.
774 EXPECT_ACTION(expected_action
);
776 // Case 2: needs_begin_main_frame=true.
777 state
.SetNeedsBeginMainFrame();
778 EXPECT_ACTION(expected_action
);
782 TEST(SchedulerStateMachineTest
, TestNoBeginMainFrameStatesRedrawWhenInvisible
) {
783 SchedulerSettings default_scheduler_settings
;
785 size_t num_begin_main_frame_states
=
786 sizeof(begin_main_frame_states
) /
787 sizeof(SchedulerStateMachine::BeginMainFrameState
);
788 for (size_t i
= 0; i
< num_begin_main_frame_states
; ++i
) {
789 // There shouldn't be any drawing regardless of BeginImplFrame.
790 for (size_t j
= 0; j
< 2; ++j
) {
791 StateMachine
state(default_scheduler_settings
);
793 EXPECT_ACTION_UPDATE_STATE(
794 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
795 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
796 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
797 state
.SetBeginMainFrameState(begin_main_frame_states
[i
]);
798 state
.SetVisible(false);
799 state
.SetNeedsRedraw(true);
801 state
.SetBeginImplFrameState(
802 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
805 // Case 1: needs_begin_main_frame=false.
806 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
809 // Case 2: needs_begin_main_frame=true.
810 state
.SetNeedsBeginMainFrame();
811 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
813 << state
.AsValue()->ToString();
818 TEST(SchedulerStateMachineTest
, TestCanRedraw_StopsDraw
) {
819 SchedulerSettings default_scheduler_settings
;
821 size_t num_begin_main_frame_states
=
822 sizeof(begin_main_frame_states
) /
823 sizeof(SchedulerStateMachine::BeginMainFrameState
);
824 for (size_t i
= 0; i
< num_begin_main_frame_states
; ++i
) {
825 // There shouldn't be any drawing regardless of BeginImplFrame.
826 for (size_t j
= 0; j
< 2; ++j
) {
827 StateMachine
state(default_scheduler_settings
);
829 EXPECT_ACTION_UPDATE_STATE(
830 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
831 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
832 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
833 state
.SetBeginMainFrameState(begin_main_frame_states
[i
]);
834 state
.SetVisible(false);
835 state
.SetNeedsRedraw(true);
837 state
.OnBeginImplFrame();
839 state
.SetCanDraw(false);
840 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
846 TEST(SchedulerStateMachineTest
,
847 TestCanRedrawWithWaitingForFirstDrawMakesProgress
) {
848 SchedulerSettings default_scheduler_settings
;
849 StateMachine
state(default_scheduler_settings
);
851 EXPECT_ACTION_UPDATE_STATE(
852 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
853 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
854 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
856 state
.SetActiveTreeNeedsFirstDraw(true);
857 state
.SetNeedsBeginMainFrame();
858 state
.SetNeedsRedraw(true);
859 state
.SetVisible(true);
860 state
.SetCanDraw(false);
861 state
.OnBeginImplFrame();
862 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
863 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
864 EXPECT_ACTION_UPDATE_STATE(
865 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
866 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
867 state
.NotifyBeginMainFrameStarted();
868 state
.NotifyReadyToCommit();
869 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
870 state
.NotifyReadyToActivate();
871 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
872 state
.OnBeginImplFrameDeadline();
873 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
874 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
875 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
878 TEST(SchedulerStateMachineTest
, TestSetNeedsBeginMainFrameIsNotLost
) {
879 SchedulerSettings scheduler_settings
;
880 StateMachine
state(scheduler_settings
);
882 state
.SetNeedsBeginMainFrame();
884 EXPECT_TRUE(state
.BeginFrameNeeded());
887 state
.OnBeginImplFrame();
888 EXPECT_ACTION_UPDATE_STATE(
889 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
890 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
892 // Now, while the frame is in progress, set another commit.
893 state
.SetNeedsBeginMainFrame();
894 EXPECT_TRUE(state
.NeedsCommit());
896 // Let the frame finish.
897 state
.NotifyBeginMainFrameStarted();
898 state
.NotifyReadyToCommit();
899 EXPECT_MAIN_FRAME_STATE(
900 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT
);
902 // Expect to commit regardless of BeginImplFrame state.
903 EXPECT_IMPL_FRAME_STATE(
904 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
905 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
907 state
.OnBeginImplFrameDeadlinePending();
908 EXPECT_IMPL_FRAME_STATE(
909 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
);
910 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
912 state
.OnBeginImplFrameDeadline();
913 EXPECT_IMPL_FRAME_STATE(
914 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
915 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
917 state
.OnBeginImplFrameIdle();
918 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
919 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
921 state
.OnBeginImplFrame();
922 EXPECT_IMPL_FRAME_STATE(
923 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
924 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
926 // Finish the commit and activate, then make sure we start the next commit
927 // immediately and draw on the next BeginImplFrame.
928 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
929 state
.NotifyReadyToActivate();
930 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
931 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
932 EXPECT_ACTION_UPDATE_STATE(
933 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
934 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
936 state
.OnBeginImplFrameDeadline();
938 EXPECT_TRUE(state
.active_tree_needs_first_draw());
939 EXPECT_ACTION_UPDATE_STATE(
940 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
941 state
.DidSwapBuffers();
942 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
943 state
.DidSwapBuffersComplete();
944 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
947 TEST(SchedulerStateMachineTest
, TestFullCycle
) {
948 SchedulerSettings default_scheduler_settings
;
949 StateMachine
state(default_scheduler_settings
);
952 // Start clean and set commit.
953 state
.SetNeedsBeginMainFrame();
956 state
.OnBeginImplFrame();
957 EXPECT_ACTION_UPDATE_STATE(
958 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
959 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
960 EXPECT_FALSE(state
.NeedsCommit());
961 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
963 // Tell the scheduler the frame finished.
964 state
.NotifyBeginMainFrameStarted();
965 state
.NotifyReadyToCommit();
966 EXPECT_MAIN_FRAME_STATE(
967 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT
);
970 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
973 state
.NotifyReadyToActivate();
974 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
975 EXPECT_TRUE(state
.active_tree_needs_first_draw());
976 EXPECT_TRUE(state
.needs_redraw());
978 // Expect to do nothing until BeginImplFrame deadline
979 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
981 // At BeginImplFrame deadline, draw.
982 state
.OnBeginImplFrameDeadline();
983 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
984 EXPECT_ACTION_UPDATE_STATE(
985 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
986 state
.DidSwapBuffers();
987 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
988 state
.DidSwapBuffersComplete();
990 // Should be synchronized, no draw needed, no action needed.
991 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
992 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
993 EXPECT_FALSE(state
.needs_redraw());
996 TEST(SchedulerStateMachineTest
, CommitWithoutDrawWithPendingTree
) {
997 SchedulerSettings default_scheduler_settings
;
998 StateMachine
state(default_scheduler_settings
);
1001 // Start clean and set commit.
1002 state
.SetNeedsBeginMainFrame();
1004 // Make a main frame, commit and activate it. But don't draw it.
1005 state
.OnBeginImplFrame();
1006 EXPECT_ACTION_UPDATE_STATE(
1007 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1008 state
.NotifyBeginMainFrameStarted();
1009 state
.NotifyReadyToCommit();
1010 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1011 state
.NotifyReadyToActivate();
1012 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1014 // Try to make a new main frame before drawing. Since we will commit it to a
1015 // pending tree and not clobber the active tree, we're able to start a new
1016 // begin frame and commit it.
1017 state
.SetNeedsBeginMainFrame();
1018 state
.OnBeginImplFrame();
1019 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1020 EXPECT_ACTION_UPDATE_STATE(
1021 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1022 state
.NotifyBeginMainFrameStarted();
1023 state
.NotifyReadyToCommit();
1024 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1027 TEST(SchedulerStateMachineTest
, DontCommitWithoutDrawWithoutPendingTree
) {
1028 SchedulerSettings scheduler_settings
;
1029 scheduler_settings
.commit_to_active_tree
= true;
1030 StateMachine
state(scheduler_settings
);
1033 // Start clean and set commit.
1034 state
.SetNeedsBeginMainFrame();
1036 // Make a main frame, commit and activate it. But don't draw it.
1037 state
.OnBeginImplFrame();
1038 EXPECT_ACTION_UPDATE_STATE(
1039 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1040 state
.NotifyBeginMainFrameStarted();
1041 state
.NotifyReadyToCommit();
1042 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1043 state
.NotifyReadyToActivate();
1044 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1046 // Try to make a new main frame before drawing, but since we would clobber the
1047 // active tree, we will not do so.
1048 state
.SetNeedsBeginMainFrame();
1049 state
.OnBeginImplFrame();
1050 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1051 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1054 TEST(SchedulerStateMachineTest
, TestFullCycleWithCommitToActive
) {
1055 SchedulerSettings scheduler_settings
;
1056 scheduler_settings
.commit_to_active_tree
= true;
1057 StateMachine
state(scheduler_settings
);
1060 // Start clean and set commit.
1061 state
.SetNeedsBeginMainFrame();
1064 state
.OnBeginImplFrame();
1065 EXPECT_ACTION_UPDATE_STATE(
1066 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1067 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
1068 EXPECT_FALSE(state
.NeedsCommit());
1069 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1071 // Tell the scheduler the frame finished.
1072 state
.NotifyBeginMainFrameStarted();
1073 state
.NotifyReadyToCommit();
1074 EXPECT_MAIN_FRAME_STATE(
1075 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT
);
1078 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1080 // Now commit should wait for activation.
1081 EXPECT_MAIN_FRAME_STATE(
1082 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_WAITING_FOR_ACTIVATION
);
1084 // No activation yet, so this commit is not drawn yet. Force to draw this
1085 // frame, and still block BeginMainFrame.
1086 state
.SetNeedsRedraw(true);
1087 state
.SetNeedsBeginMainFrame();
1088 state
.OnBeginImplFrameDeadline();
1089 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1090 EXPECT_ACTION_UPDATE_STATE(
1091 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1092 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1094 // Cannot BeginMainFrame yet since last commit is not yet activated and drawn.
1095 state
.OnBeginImplFrame();
1096 EXPECT_MAIN_FRAME_STATE(
1097 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_WAITING_FOR_ACTIVATION
);
1098 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1100 // Now activate sync tree.
1101 state
.NotifyReadyToActivate();
1102 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1103 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1104 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1105 EXPECT_TRUE(state
.needs_redraw());
1106 EXPECT_MAIN_FRAME_STATE(
1107 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_WAITING_FOR_DRAW
);
1109 // Swap throttled. Do not draw.
1110 state
.DidSwapBuffers();
1111 state
.OnBeginImplFrameDeadline();
1112 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1113 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1114 state
.DidSwapBuffersComplete();
1116 // Haven't draw since last commit, do not begin new main frame.
1117 state
.OnBeginImplFrame();
1118 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1119 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1121 // At BeginImplFrame deadline, draw. This draws unblocks BeginMainFrame.
1122 state
.OnBeginImplFrameDeadline();
1123 EXPECT_ACTION_UPDATE_STATE(
1124 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1125 state
.DidSwapBuffers();
1126 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
1127 state
.DidSwapBuffersComplete();
1129 // Now will be able to start main frame.
1130 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
1131 EXPECT_FALSE(state
.needs_redraw());
1132 EXPECT_ACTION_UPDATE_STATE(
1133 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1136 TEST(SchedulerStateMachineTest
, TestFullCycleWithCommitRequestInbetween
) {
1137 SchedulerSettings default_scheduler_settings
;
1138 StateMachine
state(default_scheduler_settings
);
1141 // Start clean and set commit.
1142 state
.SetNeedsBeginMainFrame();
1145 state
.OnBeginImplFrame();
1146 EXPECT_ACTION_UPDATE_STATE(
1147 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1148 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
1149 EXPECT_FALSE(state
.NeedsCommit());
1150 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1152 // Request another commit while the commit is in flight.
1153 state
.SetNeedsBeginMainFrame();
1154 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1156 // Tell the scheduler the frame finished.
1157 state
.NotifyBeginMainFrameStarted();
1158 state
.NotifyReadyToCommit();
1159 EXPECT_MAIN_FRAME_STATE(
1160 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT
);
1162 // First commit and activate.
1163 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1164 state
.NotifyReadyToActivate();
1165 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1166 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1167 EXPECT_TRUE(state
.needs_redraw());
1169 // Expect to do nothing until BeginImplFrame deadline.
1170 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1172 // At BeginImplFrame deadline, draw.
1173 state
.OnBeginImplFrameDeadline();
1174 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1175 EXPECT_ACTION_UPDATE_STATE(
1176 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1177 state
.DidSwapBuffers();
1178 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
1179 state
.DidSwapBuffersComplete();
1181 // Should be synchronized, no draw needed, no action needed.
1182 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1183 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
1184 EXPECT_FALSE(state
.needs_redraw());
1186 // Next BeginImplFrame should initiate second commit.
1187 state
.OnBeginImplFrame();
1188 EXPECT_ACTION_UPDATE_STATE(
1189 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1192 TEST(SchedulerStateMachineTest
, TestRequestCommitInvisible
) {
1193 SchedulerSettings default_scheduler_settings
;
1194 StateMachine
state(default_scheduler_settings
);
1195 state
.SetCanStart();
1196 EXPECT_ACTION_UPDATE_STATE(
1197 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1198 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1199 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1200 state
.SetNeedsBeginMainFrame();
1201 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1204 // See ThreadProxy::BeginMainFrame "EarlyOut_NotVisible" /
1205 // "EarlyOut_OutputSurfaceLost" cases.
1206 TEST(SchedulerStateMachineTest
, TestAbortBeginMainFrameBecauseInvisible
) {
1207 SchedulerSettings default_scheduler_settings
;
1208 StateMachine
state(default_scheduler_settings
);
1211 // Start clean and set commit.
1212 state
.SetNeedsBeginMainFrame();
1214 // Begin the frame while visible.
1215 state
.OnBeginImplFrame();
1216 EXPECT_ACTION_UPDATE_STATE(
1217 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1218 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
1219 EXPECT_FALSE(state
.NeedsCommit());
1220 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1222 // Become invisible and abort BeginMainFrame.
1223 state
.SetVisible(false);
1224 state
.BeginMainFrameAborted(CommitEarlyOutReason::ABORTED_NOT_VISIBLE
);
1226 // NeedsCommit should now be true again because we never actually did a
1228 EXPECT_TRUE(state
.NeedsCommit());
1230 // We should now be back in the idle state as if we never started the frame.
1231 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
1232 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1234 // We shouldn't do anything on the BeginImplFrame deadline.
1235 state
.OnBeginImplFrameDeadline();
1236 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1238 // Become visible again.
1239 state
.SetVisible(true);
1241 // Although we have aborted on this frame and haven't cancelled the commit
1242 // (i.e. need another), don't send another BeginMainFrame yet.
1243 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
1244 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1245 EXPECT_TRUE(state
.NeedsCommit());
1247 // Start a new frame.
1248 state
.OnBeginImplFrame();
1249 EXPECT_ACTION_UPDATE_STATE(
1250 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1252 // We should be starting the commit now.
1253 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
1254 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1257 // See ThreadProxy::BeginMainFrame "EarlyOut_NoUpdates" case.
1258 TEST(SchedulerStateMachineTest
, TestAbortBeginMainFrameBecauseCommitNotNeeded
) {
1259 SchedulerSettings default_scheduler_settings
;
1260 StateMachine
state(default_scheduler_settings
);
1261 state
.SetCanStart();
1262 EXPECT_ACTION_UPDATE_STATE(
1263 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1264 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1265 state
.DidCreateAndInitializeOutputSurface();
1266 state
.SetVisible(true);
1267 state
.SetCanDraw(true);
1269 // Get into a begin frame / commit state.
1270 state
.SetNeedsBeginMainFrame();
1271 state
.OnBeginImplFrame();
1272 EXPECT_ACTION_UPDATE_STATE(
1273 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1274 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
1275 EXPECT_FALSE(state
.NeedsCommit());
1276 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1278 // Abort the commit, true means that the BeginMainFrame was sent but there
1279 // was no work to do on the main thread.
1280 state
.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES
);
1282 // NeedsCommit should now be false because the commit was actually handled.
1283 EXPECT_FALSE(state
.NeedsCommit());
1285 // Since the commit was aborted, we don't need to try and draw.
1286 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1287 state
.OnBeginImplFrameDeadline();
1288 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1290 // Verify another commit doesn't start on another frame either.
1291 EXPECT_FALSE(state
.NeedsCommit());
1292 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
1294 state
.OnBeginImplFrame();
1295 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1296 state
.OnBeginImplFrameDeadline();
1297 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1299 // Verify another commit can start if requested, though.
1300 state
.SetNeedsBeginMainFrame();
1301 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE
);
1302 state
.OnBeginImplFrame();
1303 EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1306 TEST(SchedulerStateMachineTest
, TestFirstContextCreation
) {
1307 SchedulerSettings default_scheduler_settings
;
1308 StateMachine
state(default_scheduler_settings
);
1309 state
.SetCanStart();
1310 state
.SetVisible(true);
1311 state
.SetCanDraw(true);
1313 EXPECT_ACTION_UPDATE_STATE(
1314 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1315 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1316 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1318 // Check that the first init does not SetNeedsBeginMainFrame.
1319 state
.OnBeginImplFrame();
1320 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1321 state
.OnBeginImplFrameDeadline();
1322 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1324 // Check that a needs commit initiates a BeginMainFrame.
1325 state
.SetNeedsBeginMainFrame();
1326 state
.OnBeginImplFrame();
1327 EXPECT_ACTION_UPDATE_STATE(
1328 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1331 TEST(SchedulerStateMachineTest
, TestContextLostWhenCompletelyIdle
) {
1332 SchedulerSettings default_scheduler_settings
;
1333 StateMachine
state(default_scheduler_settings
);
1336 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1337 state
.NextAction());
1338 state
.DidLoseOutputSurface();
1340 EXPECT_ACTION_UPDATE_STATE(
1341 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1342 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1344 // Once context recreation begins, nothing should happen.
1345 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1347 // Recreate the context.
1348 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1350 // When the context is recreated, we should begin a commit.
1351 state
.OnBeginImplFrame();
1352 EXPECT_ACTION_UPDATE_STATE(
1353 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1356 TEST(SchedulerStateMachineTest
,
1357 TestContextLostWhenIdleAndCommitRequestedWhileRecreating
) {
1358 SchedulerSettings default_scheduler_settings
;
1359 StateMachine
state(default_scheduler_settings
);
1362 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1363 state
.NextAction());
1364 state
.DidLoseOutputSurface();
1365 EXPECT_EQ(state
.output_surface_state(),
1366 SchedulerStateMachine::OUTPUT_SURFACE_LOST
);
1368 EXPECT_ACTION_UPDATE_STATE(
1369 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1370 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1372 // Once context recreation begins, nothing should happen.
1373 state
.OnBeginImplFrame();
1374 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1375 state
.OnBeginImplFrameDeadline();
1376 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1378 // While context is recreating, commits shouldn't begin.
1379 state
.SetNeedsBeginMainFrame();
1380 state
.OnBeginImplFrame();
1381 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1382 state
.OnBeginImplFrameDeadline();
1383 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1385 // Recreate the context
1386 state
.DidCreateAndInitializeOutputSurface();
1387 EXPECT_EQ(state
.output_surface_state(),
1388 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT
);
1389 EXPECT_FALSE(state
.RedrawPending());
1391 // When the context is recreated, we wait until the next BeginImplFrame
1393 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1395 // When the BeginFrame comes in we should begin a commit
1396 state
.OnBeginImplFrame();
1397 EXPECT_ACTION_UPDATE_STATE(
1398 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1399 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1400 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
1402 // Until that commit finishes, we shouldn't be drawing or animate.
1403 state
.OnBeginImplFrameDeadline();
1404 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1406 // Finish the commit, which should make the surface active.
1407 state
.NotifyBeginMainFrameStarted();
1408 state
.NotifyReadyToCommit();
1409 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1410 EXPECT_EQ(state
.output_surface_state(),
1411 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION
);
1412 state
.NotifyReadyToActivate();
1413 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1414 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1415 EXPECT_EQ(state
.output_surface_state(),
1416 SchedulerStateMachine::OUTPUT_SURFACE_ACTIVE
);
1418 // Finishing the first commit after initializing an output surface should
1419 // automatically cause a redraw.
1420 EXPECT_TRUE(state
.RedrawPending());
1421 state
.OnBeginImplFrame();
1422 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1423 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1424 state
.OnBeginImplFrameDeadline();
1425 EXPECT_ACTION_UPDATE_STATE(
1426 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1427 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1428 EXPECT_FALSE(state
.RedrawPending());
1430 // Next frame as no work to do.
1431 state
.OnBeginImplFrame();
1432 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1433 state
.OnBeginImplFrameDeadline();
1434 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1436 // Once the context is recreated, whether we draw should be based on
1437 // SetCanDraw if waiting on first draw after activate.
1438 state
.SetNeedsRedraw(true);
1439 state
.OnBeginImplFrame();
1440 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1441 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1442 state
.OnBeginImplFrameDeadline();
1443 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1444 state
.SetCanDraw(false);
1445 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1446 state
.SetCanDraw(true);
1447 EXPECT_ACTION_UPDATE_STATE(
1448 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1449 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1451 // Once the context is recreated, whether we draw should be based on
1452 // SetCanDraw if waiting on first draw after activate.
1453 state
.SetNeedsRedraw(true);
1454 state
.SetNeedsBeginMainFrame();
1455 state
.OnBeginImplFrame();
1456 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1457 EXPECT_ACTION_UPDATE_STATE(
1458 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1459 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1460 // Activate so we need the first draw
1461 state
.NotifyBeginMainFrameStarted();
1462 state
.NotifyReadyToCommit();
1463 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1464 state
.NotifyReadyToActivate();
1465 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1466 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1467 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1468 EXPECT_TRUE(state
.needs_redraw());
1470 state
.OnBeginImplFrameDeadline();
1471 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1472 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1473 state
.SetCanDraw(false);
1474 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1475 state
.SetCanDraw(true);
1476 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1479 TEST(SchedulerStateMachineTest
, TestContextLostWhileCommitInProgress
) {
1480 SchedulerSettings scheduler_settings
;
1481 StateMachine
state(scheduler_settings
);
1484 // Get a commit in flight.
1485 state
.SetNeedsBeginMainFrame();
1487 // Set damage and expect a draw.
1488 state
.SetNeedsRedraw(true);
1489 state
.OnBeginImplFrame();
1490 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1491 EXPECT_ACTION_UPDATE_STATE(
1492 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1493 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1494 state
.OnBeginImplFrameDeadline();
1495 EXPECT_ACTION_UPDATE_STATE(
1496 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1497 state
.DidSwapBuffers();
1498 state
.DidSwapBuffersComplete();
1499 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1501 // Cause a lost context while the BeginMainFrame is in flight.
1502 state
.DidLoseOutputSurface();
1504 // Ask for another draw. Expect nothing happens.
1505 state
.SetNeedsRedraw(true);
1506 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1508 // Finish the frame, commit and activate.
1509 state
.NotifyBeginMainFrameStarted();
1510 state
.NotifyReadyToCommit();
1511 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1512 state
.NotifyReadyToActivate();
1513 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1515 // We will abort the draw when the output surface is lost if we are
1516 // waiting for the first draw to unblock the main thread.
1517 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1518 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1520 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1521 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
1522 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1524 state
.OnBeginImplFrame();
1525 EXPECT_IMPL_FRAME_STATE(
1526 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
1527 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1529 state
.OnBeginImplFrameDeadlinePending();
1530 EXPECT_IMPL_FRAME_STATE(
1531 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
);
1532 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1534 state
.OnBeginImplFrameDeadline();
1535 EXPECT_IMPL_FRAME_STATE(
1536 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
1537 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1540 TEST(SchedulerStateMachineTest
,
1541 TestContextLostWhileCommitInProgressAndAnotherCommitRequested
) {
1542 SchedulerSettings scheduler_settings
;
1543 StateMachine
state(scheduler_settings
);
1546 // Get a commit in flight.
1547 state
.SetNeedsBeginMainFrame();
1548 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1550 // Set damage and expect a draw.
1551 state
.SetNeedsRedraw(true);
1552 state
.OnBeginImplFrame();
1553 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1554 EXPECT_ACTION_UPDATE_STATE(
1555 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1556 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1557 state
.OnBeginImplFrameDeadline();
1558 EXPECT_ACTION_UPDATE_STATE(
1559 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1560 state
.DidSwapBuffers();
1561 state
.DidSwapBuffersComplete();
1562 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1564 // Cause a lost context while the BeginMainFrame is in flight.
1565 state
.DidLoseOutputSurface();
1567 // Ask for another draw and also set needs commit. Expect nothing happens.
1568 state
.SetNeedsRedraw(true);
1569 state
.SetNeedsBeginMainFrame();
1570 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1572 // Finish the frame, and commit and activate.
1573 state
.NotifyBeginMainFrameStarted();
1574 state
.NotifyReadyToCommit();
1575 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1576 state
.NotifyReadyToActivate();
1577 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1578 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1580 // Because the output surface is missing, we expect the draw to abort.
1581 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1583 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1584 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
1585 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1587 state
.OnBeginImplFrame();
1588 EXPECT_IMPL_FRAME_STATE(
1589 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
1590 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1592 state
.OnBeginImplFrameDeadlinePending();
1593 EXPECT_IMPL_FRAME_STATE(
1594 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
);
1595 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1597 state
.OnBeginImplFrameDeadline();
1598 EXPECT_IMPL_FRAME_STATE(
1599 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
1600 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1602 state
.OnBeginImplFrameIdle();
1603 EXPECT_ACTION_UPDATE_STATE(
1604 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1606 // After we get a new output surface, the commit flow should start.
1607 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1608 state
.OnBeginImplFrame();
1609 EXPECT_ACTION_UPDATE_STATE(
1610 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1611 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1612 state
.NotifyBeginMainFrameStarted();
1613 state
.NotifyReadyToCommit();
1614 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1615 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1616 state
.NotifyReadyToActivate();
1617 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1618 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1619 state
.OnBeginImplFrameDeadline();
1620 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1621 EXPECT_ACTION_UPDATE_STATE(
1622 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1623 state
.DidSwapBuffers();
1624 state
.DidSwapBuffersComplete();
1625 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1628 TEST(SchedulerStateMachineTest
, DontDrawBeforeCommitAfterLostOutputSurface
) {
1629 SchedulerSettings default_scheduler_settings
;
1630 StateMachine
state(default_scheduler_settings
);
1633 state
.SetNeedsRedraw(true);
1635 // Cause a lost output surface, and restore it.
1636 state
.DidLoseOutputSurface();
1637 EXPECT_ACTION_UPDATE_STATE(
1638 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1639 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1640 state
.DidCreateAndInitializeOutputSurface();
1642 EXPECT_FALSE(state
.RedrawPending());
1643 state
.OnBeginImplFrame();
1644 EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1647 TEST(SchedulerStateMachineTest
,
1648 TestPendingActivationsShouldBeForcedAfterLostOutputSurface
) {
1649 SchedulerSettings default_scheduler_settings
;
1650 StateMachine
state(default_scheduler_settings
);
1653 state
.SetBeginMainFrameState(
1654 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
1656 // Cause a lost context.
1657 state
.DidLoseOutputSurface();
1659 state
.NotifyBeginMainFrameStarted();
1660 state
.NotifyReadyToCommit();
1661 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1663 EXPECT_TRUE(state
.PendingActivationsShouldBeForced());
1664 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1666 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1667 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1670 TEST(SchedulerStateMachineTest
, TestNoBeginFrameNeededWhenInvisible
) {
1671 SchedulerSettings default_scheduler_settings
;
1672 StateMachine
state(default_scheduler_settings
);
1673 state
.SetCanStart();
1674 EXPECT_ACTION_UPDATE_STATE(
1675 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1676 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1677 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1678 state
.SetVisible(true);
1680 EXPECT_FALSE(state
.BeginFrameNeeded());
1681 state
.SetNeedsRedraw(true);
1682 EXPECT_TRUE(state
.BeginFrameNeeded());
1684 state
.SetVisible(false);
1685 EXPECT_FALSE(state
.BeginFrameNeeded());
1687 state
.SetVisible(true);
1688 EXPECT_TRUE(state
.BeginFrameNeeded());
1691 TEST(SchedulerStateMachineTest
, TestNoBeginMainFrameWhenInvisible
) {
1692 SchedulerSettings default_scheduler_settings
;
1693 StateMachine
state(default_scheduler_settings
);
1694 state
.SetCanStart();
1695 EXPECT_ACTION_UPDATE_STATE(
1696 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1697 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1698 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1699 state
.SetVisible(false);
1700 state
.SetNeedsBeginMainFrame();
1701 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1702 EXPECT_FALSE(state
.BeginFrameNeeded());
1704 // When become visible again, the needs commit should still be pending.
1705 state
.SetVisible(true);
1706 EXPECT_TRUE(state
.BeginFrameNeeded());
1707 state
.OnBeginImplFrame();
1708 EXPECT_ACTION_UPDATE_STATE(
1709 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1712 TEST(SchedulerStateMachineTest
, TestFinishCommitWhenCommitInProgress
) {
1713 SchedulerSettings default_scheduler_settings
;
1714 StateMachine
state(default_scheduler_settings
);
1715 state
.SetCanStart();
1716 EXPECT_ACTION_UPDATE_STATE(
1717 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1718 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1719 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1720 state
.SetVisible(false);
1721 state
.SetBeginMainFrameState(
1722 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT
);
1723 state
.SetNeedsBeginMainFrame();
1725 // After the commit completes, activation and draw happen immediately
1726 // because we are not visible.
1727 state
.NotifyBeginMainFrameStarted();
1728 state
.NotifyReadyToCommit();
1729 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1730 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1731 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1732 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1733 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1736 TEST(SchedulerStateMachineTest
, TestInitialActionsWhenContextLost
) {
1737 SchedulerSettings default_scheduler_settings
;
1738 StateMachine
state(default_scheduler_settings
);
1740 state
.SetNeedsBeginMainFrame();
1741 state
.DidLoseOutputSurface();
1743 // When we are visible, we normally want to begin output surface creation
1744 // as soon as possible.
1745 EXPECT_ACTION_UPDATE_STATE(
1746 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1748 state
.DidCreateAndInitializeOutputSurface();
1749 EXPECT_EQ(state
.output_surface_state(),
1750 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT
);
1752 // We should not send a BeginMainFrame when we are invisible, even if we've
1753 // lost the output surface and are trying to get the first commit, since the
1754 // main thread will just abort anyway.
1755 state
.SetVisible(false);
1756 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1759 TEST(SchedulerStateMachineTest
, ReportIfNotDrawing
) {
1760 SchedulerSettings default_scheduler_settings
;
1761 StateMachine
state(default_scheduler_settings
);
1763 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1765 state
.SetCanDraw(false);
1766 state
.SetVisible(true);
1767 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1769 state
.SetCanDraw(true);
1770 state
.SetVisible(false);
1771 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1773 state
.SetCanDraw(false);
1774 state
.SetVisible(false);
1775 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1777 state
.SetCanDraw(true);
1778 state
.SetVisible(true);
1779 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1782 TEST(SchedulerStateMachineTest
,
1783 TestTriggerDeadlineImmediatelyAfterAbortedCommit
) {
1784 SchedulerSettings default_scheduler_settings
;
1785 StateMachine
state(default_scheduler_settings
);
1788 // This test mirrors what happens during the first frame of a scroll gesture.
1789 // First we get the input event and a BeginFrame.
1790 state
.OnBeginImplFrame();
1792 // As a response the compositor requests a redraw and a commit to tell the
1793 // main thread about the new scroll offset.
1794 state
.SetNeedsRedraw(true);
1795 state
.SetNeedsBeginMainFrame();
1797 // We should start the commit normally.
1798 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1799 EXPECT_ACTION_UPDATE_STATE(
1800 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1801 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1803 // Since only the scroll offset changed, the main thread will abort the
1805 state
.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES
);
1807 // Since the commit was aborted, we should draw right away instead of waiting
1808 // for the deadline.
1809 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1812 void FinishPreviousCommitAndDrawWithoutExitingDeadline(
1813 StateMachine
* state_ptr
) {
1814 // Gross, but allows us to use macros below.
1815 StateMachine
& state
= *state_ptr
;
1817 state
.NotifyBeginMainFrameStarted();
1818 state
.NotifyReadyToCommit();
1819 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1820 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1821 state
.NotifyReadyToActivate();
1822 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1823 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1825 state
.OnBeginImplFrame();
1826 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1827 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1829 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1830 state
.OnBeginImplFrameDeadline();
1831 EXPECT_ACTION_UPDATE_STATE(
1832 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1833 state
.DidSwapBuffers();
1836 TEST(SchedulerStateMachineTest
, TestImplLatencyTakesPriority
) {
1837 SchedulerSettings default_scheduler_settings
;
1838 StateMachine
state(default_scheduler_settings
);
1841 // This test ensures that impl-draws are prioritized over main thread updates
1842 // in prefer impl latency mode.
1843 state
.SetNeedsRedraw(true);
1844 state
.SetNeedsBeginMainFrame();
1845 state
.OnBeginImplFrame();
1846 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1847 EXPECT_ACTION_UPDATE_STATE(
1848 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1849 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1851 // Verify the deadline is not triggered early until we enter
1852 // prefer impl latency mode.
1853 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1854 state
.SetImplLatencyTakesPriority(true);
1855 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1857 // Trigger the deadline.
1858 state
.OnBeginImplFrameDeadline();
1859 EXPECT_ACTION_UPDATE_STATE(
1860 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1861 state
.DidSwapBuffers();
1862 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1863 state
.DidSwapBuffersComplete();
1865 // Request a new commit and finish the previous one.
1866 state
.SetNeedsBeginMainFrame();
1867 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state
);
1868 EXPECT_ACTION_UPDATE_STATE(
1869 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1870 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1871 state
.DidSwapBuffersComplete();
1872 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1874 // Finish the previous commit and draw it.
1875 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state
);
1876 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1878 // Verify we do not send another BeginMainFrame if was are swap throttled
1879 // and did not just swap.
1880 state
.SetNeedsBeginMainFrame();
1881 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1882 state
.OnBeginImplFrame();
1883 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1884 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1885 state
.OnBeginImplFrameDeadline();
1886 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1889 TEST(SchedulerStateMachineTest
,
1890 TestTriggerDeadlineImmediatelyOnLostOutputSurface
) {
1891 SchedulerSettings default_scheduler_settings
;
1892 StateMachine
state(default_scheduler_settings
);
1895 state
.SetNeedsBeginMainFrame();
1897 state
.OnBeginImplFrame();
1898 EXPECT_ACTION_UPDATE_STATE(
1899 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1900 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1901 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1903 state
.DidLoseOutputSurface();
1904 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1905 // The deadline should be triggered immediately when output surface is lost.
1906 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1909 TEST(SchedulerStateMachineTest
, TestTriggerDeadlineImmediatelyWhenInvisible
) {
1910 SchedulerSettings default_scheduler_settings
;
1911 StateMachine
state(default_scheduler_settings
);
1914 state
.SetNeedsBeginMainFrame();
1916 state
.OnBeginImplFrame();
1917 EXPECT_ACTION_UPDATE_STATE(
1918 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1919 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1920 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1922 state
.SetVisible(false);
1923 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1924 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1927 TEST(SchedulerStateMachineTest
, TestSetNeedsAnimate
) {
1928 SchedulerSettings default_scheduler_settings
;
1929 StateMachine
state(default_scheduler_settings
);
1932 // Test requesting an animation that, when run, causes us to draw.
1933 state
.SetNeedsAnimate();
1934 EXPECT_TRUE(state
.BeginFrameNeeded());
1935 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1937 state
.OnBeginImplFrame();
1938 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1940 state
.OnBeginImplFrameDeadlinePending();
1941 state
.OnBeginImplFrameDeadline();
1942 EXPECT_ACTION_UPDATE_STATE(
1943 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1946 TEST(SchedulerStateMachineTest
, TestAnimateBeforeCommit
) {
1947 SchedulerSettings default_scheduler_settings
;
1948 StateMachine
state(default_scheduler_settings
);
1951 // Check that animations are updated before we start a commit.
1952 state
.SetNeedsAnimate();
1953 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1954 state
.SetNeedsBeginMainFrame();
1955 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1956 EXPECT_TRUE(state
.BeginFrameNeeded());
1958 state
.OnBeginImplFrame();
1959 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1960 EXPECT_ACTION_UPDATE_STATE(
1961 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1963 state
.OnBeginImplFrameDeadlinePending();
1964 state
.OnBeginImplFrameDeadline();
1965 EXPECT_ACTION_UPDATE_STATE(
1966 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1969 TEST(SchedulerStateMachineTest
, TestAnimateAfterCommitBeforeDraw
) {
1970 SchedulerSettings default_scheduler_settings
;
1971 StateMachine
state(default_scheduler_settings
);
1974 // Check that animations are updated before we start a commit.
1975 state
.SetNeedsAnimate();
1976 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1977 state
.SetNeedsBeginMainFrame();
1978 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1979 EXPECT_TRUE(state
.BeginFrameNeeded());
1981 state
.OnBeginImplFrame();
1982 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1983 EXPECT_ACTION_UPDATE_STATE(
1984 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1986 state
.NotifyBeginMainFrameStarted();
1987 state
.NotifyReadyToCommit();
1988 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1990 state
.OnBeginImplFrameDeadlinePending();
1991 state
.OnBeginImplFrameDeadline();
1992 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1993 EXPECT_ACTION_UPDATE_STATE(
1994 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1997 TEST(SchedulerStateMachineTest
, TestSetNeedsAnimateAfterAnimate
) {
1998 SchedulerSettings default_scheduler_settings
;
1999 StateMachine
state(default_scheduler_settings
);
2002 // Test requesting an animation after we have already animated during this
2004 state
.SetNeedsRedraw(true);
2005 EXPECT_TRUE(state
.BeginFrameNeeded());
2006 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
2008 state
.OnBeginImplFrame();
2009 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
2011 state
.SetNeedsAnimate();
2012 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
2014 state
.OnBeginImplFrameDeadline();
2015 EXPECT_ACTION_UPDATE_STATE(
2016 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
2019 TEST(SchedulerStateMachineTest
, TestForwardBeginFramesToChildren
) {
2020 SchedulerSettings settings
;
2021 StateMachine
state(settings
);
2024 EXPECT_FALSE(state
.BeginFrameNeeded());
2025 state
.SetChildrenNeedBeginFrames(true);
2026 EXPECT_TRUE(state
.BeginFrameNeeded());
2029 TEST(SchedulerStateMachineTest
, TestDeferCommit
) {
2030 SchedulerSettings settings
;
2031 StateMachine
state(settings
);
2034 state
.SetDeferCommits(true);
2036 state
.SetNeedsBeginMainFrame();
2037 EXPECT_FALSE(state
.BeginFrameNeeded());
2038 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
2040 state
.OnBeginImplFrame();
2041 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
2043 state
.OnBeginImplFrameDeadline();
2044 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
2046 state
.SetDeferCommits(false);
2047 state
.OnBeginImplFrame();
2048 EXPECT_ACTION_UPDATE_STATE(
2049 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
2052 TEST(SchedulerStateMachineTest
, EarlyOutCommitWantsProactiveBeginFrame
) {
2053 SchedulerSettings settings
;
2054 StateMachine
state(settings
);
2055 SET_UP_STATE(state
);
2057 EXPECT_FALSE(state
.ProactiveBeginFrameWanted());
2058 bool commit_has_no_updates
= true;
2059 state
.WillCommit(commit_has_no_updates
);
2060 EXPECT_TRUE(state
.ProactiveBeginFrameWanted());
2061 state
.OnBeginImplFrame();
2062 EXPECT_FALSE(state
.ProactiveBeginFrameWanted());