[Media Router] Filter non-display MediaRoutes before sending them to the UI.
[chromium-blink-merge.git] / cc / scheduler / scheduler_state_machine_unittest.cc
blob56d64323c272c497c8deeafd8a5150b886df5f54
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.
13 // Without:
14 // Value of: actual() Actual: 7
15 // Expected: expected() Which is: 0
16 // With:
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); \
42 } \
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);
62 namespace cc {
64 namespace {
66 void WillPerformAction(SchedulerStateMachine* sm,
67 SchedulerStateMachine::Action action) {
68 switch (action) {
69 case SchedulerStateMachine::ACTION_NONE:
70 return;
72 case SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE:
73 sm->WillActivate();
74 return;
76 case SchedulerStateMachine::ACTION_ANIMATE:
77 sm->WillAnimate();
78 return;
80 case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME:
81 sm->WillSendBeginMainFrame();
82 return;
84 case SchedulerStateMachine::ACTION_COMMIT: {
85 bool commit_has_no_updates = false;
86 sm->WillCommit(commit_has_no_updates);
87 return;
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);
94 return;
97 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT: {
98 bool did_request_swap = false;
99 sm->WillDraw(did_request_swap);
100 return;
103 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
104 sm->WillBeginOutputSurfaceCreation();
105 return;
107 case SchedulerStateMachine::ACTION_PREPARE_TILES:
108 sm->WillPrepareTiles();
109 return;
111 case SchedulerStateMachine::ACTION_INVALIDATE_OUTPUT_SURFACE:
112 sm->WillInvalidateOutputSurface();
113 return;
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 {
133 public:
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);
208 state.SetCanStart();
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);
257 state.SetCanStart();
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);
303 state.SetCanStart();
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);
331 state.SetCanStart();
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);
362 SET_UP_STATE(state)
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);
418 SET_UP_STATE(state)
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);
450 SET_UP_STATE(state)
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);
480 SET_UP_STATE(state)
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);
517 SET_UP_STATE(state)
519 // Start a commit.
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);
535 // Fail the draw.
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;
572 int draw_limit = 1;
573 scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced =
574 draw_limit;
575 StateMachine state(scheduler_settings);
576 SET_UP_STATE(state)
578 // Start a commit.
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);
629 SET_UP_STATE(state)
631 // Start a draw.
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
656 // the impl thread.
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);
668 SET_UP_STATE(state)
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);
723 state.SetCanStart();
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]);
730 bool visible =
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,
737 state.NextAction());
739 // Case 2: needs_begin_main_frame=true
740 state.SetNeedsBeginMainFrame();
741 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
742 state.NextAction())
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);
751 state.SetCanStart();
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;
768 } else {
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);
792 state.SetCanStart();
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);
800 if (j == 1) {
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,
807 state.NextAction());
809 // Case 2: needs_begin_main_frame=true.
810 state.SetNeedsBeginMainFrame();
811 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
812 state.NextAction())
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);
828 state.SetCanStart();
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);
836 if (j == 1)
837 state.OnBeginImplFrame();
839 state.SetCanDraw(false);
840 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
841 state.NextAction());
846 TEST(SchedulerStateMachineTest,
847 TestCanRedrawWithWaitingForFirstDrawMakesProgress) {
848 SchedulerSettings default_scheduler_settings;
849 StateMachine state(default_scheduler_settings);
850 state.SetCanStart();
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);
881 SET_UP_STATE(state)
882 state.SetNeedsBeginMainFrame();
884 EXPECT_TRUE(state.BeginFrameNeeded());
886 // Begin the frame.
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);
950 SET_UP_STATE(state)
952 // Start clean and set commit.
953 state.SetNeedsBeginMainFrame();
955 // Begin the frame.
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);
969 // Commit.
970 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
972 // Activate.
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);
999 SET_UP_STATE(state)
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);
1031 SET_UP_STATE(state)
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);
1058 SET_UP_STATE(state)
1060 // Start clean and set commit.
1061 state.SetNeedsBeginMainFrame();
1063 // Begin the frame.
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);
1077 // 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);
1139 SET_UP_STATE(state)
1141 // Start clean and set commit.
1142 state.SetNeedsBeginMainFrame();
1144 // Begin the frame.
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);
1209 SET_UP_STATE(state)
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
1227 // commit.
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);
1334 SET_UP_STATE(state)
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);
1360 SET_UP_STATE(state)
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
1392 // before starting.
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);
1482 SET_UP_STATE(state)
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);
1544 SET_UP_STATE(state)
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);
1631 SET_UP_STATE(state)
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);
1651 SET_UP_STATE(state)
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);
1739 SET_UP_STATE(state)
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);
1762 SET_UP_STATE(state)
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);
1786 SET_UP_STATE(state)
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
1804 // commit.
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);
1839 SET_UP_STATE(state)
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);
1893 SET_UP_STATE(state)
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);
1912 SET_UP_STATE(state)
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);
1930 SET_UP_STATE(state)
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);
1949 SET_UP_STATE(state)
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);
1972 SET_UP_STATE(state)
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);
2000 SET_UP_STATE(state)
2002 // Test requesting an animation after we have already animated during this
2003 // frame.
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);
2022 SET_UP_STATE(state)
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);
2032 SET_UP_STATE(state)
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());
2065 } // namespace
2066 } // namespace cc