cc: Rename NeedsCommit to NeedsBeginMainFrame.
[chromium-blink-merge.git] / cc / scheduler / scheduler_state_machine_unittest.cc
blob8f07c8672ee4e19fe48a93dd941dd6e10dac064d
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 state.UpdateState(action); \
44 if (action == SchedulerStateMachine::ACTION_NONE) { \
45 if (state.begin_impl_frame_state() == \
46 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) \
47 state.OnBeginImplFrameDeadlinePending(); \
48 if (state.begin_impl_frame_state() == \
49 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) \
50 state.OnBeginImplFrameIdle(); \
53 #define SET_UP_STATE(state) \
54 state.SetCanStart(); \
55 state.UpdateState(state.NextAction()); \
56 state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); \
57 state.SetVisible(true); \
58 state.SetCanDraw(true);
60 namespace cc {
62 namespace {
64 const SchedulerStateMachine::BeginImplFrameState all_begin_impl_frame_states[] =
65 {SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE,
66 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
67 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
68 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE, };
70 const SchedulerStateMachine::BeginMainFrameState begin_main_frame_states[] = {
71 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE,
72 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT,
73 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED,
74 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT,
75 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_WAITING_FOR_ACTIVATION,
76 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_WAITING_FOR_DRAW};
78 // Exposes the protected state fields of the SchedulerStateMachine for testing
79 class StateMachine : public SchedulerStateMachine {
80 public:
81 explicit StateMachine(const SchedulerSettings& scheduler_settings)
82 : SchedulerStateMachine(scheduler_settings) {}
84 void CreateAndInitializeOutputSurfaceWithActivatedCommit() {
85 DidCreateAndInitializeOutputSurface();
86 output_surface_state_ = OUTPUT_SURFACE_ACTIVE;
89 void SetBeginMainFrameState(BeginMainFrameState cs) {
90 begin_main_frame_state_ = cs;
92 BeginMainFrameState BeginMainFrameState() const {
93 return begin_main_frame_state_;
96 ForcedRedrawOnTimeoutState ForcedRedrawState() const {
97 return forced_redraw_state_;
100 void SetBeginImplFrameState(BeginImplFrameState bifs) {
101 begin_impl_frame_state_ = bifs;
104 BeginImplFrameState begin_impl_frame_state() const {
105 return begin_impl_frame_state_;
108 OutputSurfaceState output_surface_state() const {
109 return output_surface_state_;
112 void SetNeedsBeginMainFrameForTest(bool needs_begin_main_frame) {
113 needs_begin_main_frame_ = needs_begin_main_frame;
116 bool NeedsCommit() const { return needs_begin_main_frame_; }
118 void SetNeedsAnimateForTest(bool needs_animate) {
119 needs_animate_ = needs_animate;
122 void SetNeedsRedraw(bool needs_redraw) { needs_redraw_ = needs_redraw; }
124 void SetNeedsForcedRedrawForTimeout(bool b) {
125 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_COMMIT;
126 active_tree_needs_first_draw_ = true;
128 bool NeedsForcedRedrawForTimeout() const {
129 return forced_redraw_state_ != FORCED_REDRAW_STATE_IDLE;
132 void SetActiveTreeNeedsFirstDraw(bool needs_first_draw) {
133 active_tree_needs_first_draw_ = needs_first_draw;
136 bool CanDraw() const { return can_draw_; }
137 bool Visible() const { return visible_; }
139 bool PendingActivationsShouldBeForced() const {
140 return SchedulerStateMachine::PendingActivationsShouldBeForced();
143 void SetHasPendingTree(bool has_pending_tree) {
144 has_pending_tree_ = has_pending_tree;
147 using SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately;
148 using SchedulerStateMachine::ProactiveBeginFrameWanted;
149 using SchedulerStateMachine::UpdateStateOnCommit;
152 TEST(SchedulerStateMachineTest, BeginFrameNeeded) {
153 SchedulerSettings default_scheduler_settings;
154 StateMachine state(default_scheduler_settings);
155 state.SetCanStart();
156 EXPECT_ACTION_UPDATE_STATE(
157 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION)
158 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
159 state.SetBeginMainFrameState(
160 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE);
162 // Don't request BeginFrames if we are idle.
163 state.SetVisible(true);
164 state.SetNeedsRedraw(false);
165 state.SetNeedsAnimateForTest(false);
166 EXPECT_FALSE(state.BeginFrameNeeded());
168 // Request BeginFrames if we are ready to draw.
169 state.SetVisible(true);
170 state.SetNeedsRedraw(true);
171 state.SetNeedsAnimateForTest(false);
172 EXPECT_TRUE(state.BeginFrameNeeded());
174 // Don't background tick for needs_redraw.
175 state.SetVisible(false);
176 state.SetNeedsRedraw(true);
177 state.SetNeedsAnimateForTest(false);
178 EXPECT_FALSE(state.BeginFrameNeeded());
180 // Proactively request BeginFrames when commit is pending.
181 state.SetVisible(true);
182 state.SetNeedsRedraw(false);
183 state.SetNeedsAnimateForTest(false);
184 state.SetNeedsBeginMainFrameForTest(true);
185 EXPECT_TRUE(state.BeginFrameNeeded());
187 // Don't request BeginFrames when commit is pending if
188 // we are currently deferring commits.
189 state.SetVisible(true);
190 state.SetNeedsRedraw(false);
191 state.SetNeedsAnimateForTest(false);
192 state.SetNeedsBeginMainFrameForTest(true);
193 state.SetDeferCommits(true);
194 EXPECT_FALSE(state.BeginFrameNeeded());
197 TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) {
198 SchedulerSettings default_scheduler_settings;
200 // If no commit needed, do nothing.
202 StateMachine state(default_scheduler_settings);
203 state.SetCanStart();
204 EXPECT_ACTION_UPDATE_STATE(
205 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION)
206 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
207 state.SetBeginMainFrameState(
208 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE);
209 state.SetNeedsRedraw(false);
210 state.SetVisible(true);
212 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
213 EXPECT_FALSE(state.NeedsCommit());
215 state.OnBeginImplFrame();
216 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
218 state.OnBeginImplFrameDeadline();
219 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
220 EXPECT_FALSE(state.NeedsCommit());
223 // If commit requested but can_start is still false, do nothing.
225 StateMachine state(default_scheduler_settings);
226 state.SetBeginMainFrameState(
227 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE);
228 state.SetNeedsRedraw(false);
229 state.SetVisible(true);
230 state.SetNeedsBeginMainFrame();
232 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
233 EXPECT_TRUE(state.NeedsCommit());
235 state.OnBeginImplFrame();
236 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
238 state.OnBeginImplFrameDeadline();
239 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
240 EXPECT_TRUE(state.NeedsCommit());
243 // If commit requested, begin a main frame.
245 StateMachine state(default_scheduler_settings);
246 state.SetBeginMainFrameState(
247 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE);
248 state.SetCanStart();
249 state.UpdateState(state.NextAction());
250 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
251 state.SetNeedsRedraw(false);
252 state.SetVisible(true);
253 state.SetNeedsBeginMainFrame();
255 // Expect nothing to happen until after OnBeginImplFrame.
256 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
257 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE);
258 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
259 EXPECT_TRUE(state.NeedsCommit());
260 EXPECT_TRUE(state.BeginFrameNeeded());
262 state.OnBeginImplFrame();
263 EXPECT_ACTION_UPDATE_STATE(
264 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
265 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT);
266 EXPECT_FALSE(state.NeedsCommit());
269 // If commit requested and can't draw, still begin a main frame.
271 StateMachine state(default_scheduler_settings);
272 state.SetBeginMainFrameState(
273 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE);
274 state.SetCanStart();
275 state.UpdateState(state.NextAction());
276 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
277 state.SetNeedsRedraw(false);
278 state.SetVisible(true);
279 state.SetNeedsBeginMainFrame();
280 state.SetCanDraw(false);
282 // Expect nothing to happen until after OnBeginImplFrame.
283 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
284 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE);
285 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
286 EXPECT_TRUE(state.BeginFrameNeeded());
288 state.OnBeginImplFrame();
289 EXPECT_ACTION_UPDATE_STATE(
290 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
291 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT);
292 EXPECT_FALSE(state.NeedsCommit());
296 // Explicitly test main_frame_before_activation_enabled = true
297 TEST(SchedulerStateMachineTest, MainFrameBeforeActivationEnabled) {
298 SchedulerSettings scheduler_settings;
299 scheduler_settings.main_frame_before_activation_enabled = true;
300 StateMachine state(scheduler_settings);
301 state.SetBeginMainFrameState(
302 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE);
303 SET_UP_STATE(state)
304 state.SetNeedsRedraw(false);
305 state.SetNeedsBeginMainFrame();
307 EXPECT_TRUE(state.BeginFrameNeeded());
309 // Commit to the pending tree.
310 state.OnBeginImplFrame();
311 EXPECT_ACTION_UPDATE_STATE(
312 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
313 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
315 state.NotifyBeginMainFrameStarted();
316 state.NotifyReadyToCommit();
317 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
318 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
319 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE);
321 state.OnBeginImplFrameDeadline();
322 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
324 // Verify that the next commit starts while there is still a pending tree.
325 state.SetNeedsBeginMainFrame();
326 state.OnBeginImplFrame();
327 EXPECT_ACTION_UPDATE_STATE(
328 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
329 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
331 // Verify the pending commit doesn't overwrite the pending
332 // tree until the pending tree has been activated.
333 state.NotifyBeginMainFrameStarted();
334 state.NotifyReadyToCommit();
335 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
337 // Verify NotifyReadyToActivate unblocks activation, commit, and
338 // draw in that order.
339 state.NotifyReadyToActivate();
340 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
341 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
342 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
344 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
345 state.OnBeginImplFrameDeadline();
346 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
347 EXPECT_ACTION_UPDATE_STATE(
348 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
349 state.DidSwapBuffers();
350 state.DidSwapBuffersComplete();
351 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
352 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE);
355 TEST(SchedulerStateMachineTest,
356 TestFailedDrawForAnimationCheckerboardSetsNeedsCommitAndDoesNotDrawAgain) {
357 SchedulerSettings default_scheduler_settings;
358 StateMachine state(default_scheduler_settings);
359 SET_UP_STATE(state)
360 state.SetNeedsRedraw(true);
361 EXPECT_TRUE(state.RedrawPending());
362 EXPECT_TRUE(state.BeginFrameNeeded());
363 state.OnBeginImplFrame();
364 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
365 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
366 state.OnBeginImplFrameDeadline();
368 // We're drawing now.
369 EXPECT_ACTION_UPDATE_STATE(
370 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
371 state.DidSwapBuffers();
372 state.DidSwapBuffersComplete();
373 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
375 EXPECT_FALSE(state.RedrawPending());
376 EXPECT_FALSE(state.CommitPending());
378 // Failing the draw makes us require a commit.
379 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
380 state.OnBeginImplFrame();
381 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
382 EXPECT_ACTION_UPDATE_STATE(
383 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
384 EXPECT_TRUE(state.RedrawPending());
385 EXPECT_TRUE(state.CommitPending());
388 TEST(SchedulerStateMachineTest, TestFailedDrawForMissingHighResNeedsCommit) {
389 SchedulerSettings default_scheduler_settings;
390 StateMachine state(default_scheduler_settings);
391 SET_UP_STATE(state)
392 state.SetNeedsRedraw(true);
393 EXPECT_TRUE(state.RedrawPending());
394 EXPECT_TRUE(state.BeginFrameNeeded());
396 state.OnBeginImplFrame();
397 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
398 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
399 state.OnBeginImplFrameDeadline();
400 EXPECT_ACTION_UPDATE_STATE(
401 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
402 state.DidSwapBuffers();
403 state.DidSwapBuffersComplete();
404 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
405 EXPECT_FALSE(state.RedrawPending());
406 EXPECT_FALSE(state.CommitPending());
408 // Missing high res content requires a commit (but not a redraw)
409 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT);
410 state.OnBeginImplFrame();
411 EXPECT_ACTION_UPDATE_STATE(
412 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
413 EXPECT_FALSE(state.RedrawPending());
414 EXPECT_TRUE(state.CommitPending());
417 TEST(SchedulerStateMachineTest,
418 TestsetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw) {
419 SchedulerSettings default_scheduler_settings;
420 StateMachine state(default_scheduler_settings);
421 SET_UP_STATE(state)
422 state.SetNeedsRedraw(true);
423 EXPECT_TRUE(state.RedrawPending());
424 EXPECT_TRUE(state.BeginFrameNeeded());
425 state.OnBeginImplFrame();
426 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
427 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
428 state.OnBeginImplFrameDeadline();
430 // We're drawing now.
431 EXPECT_ACTION_UPDATE_STATE(
432 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
433 state.DidSwapBuffers();
434 state.DidSwapBuffersComplete();
435 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
436 EXPECT_FALSE(state.RedrawPending());
437 EXPECT_FALSE(state.CommitPending());
439 // While still in the same BeginMainFrame callback on the main thread,
440 // set needs redraw again. This should not redraw.
441 state.SetNeedsRedraw(true);
442 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
444 // Failing the draw for animation checkerboards makes us require a commit.
445 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
446 state.OnBeginImplFrame();
447 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
448 EXPECT_ACTION_UPDATE_STATE(
449 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
450 EXPECT_TRUE(state.RedrawPending());
453 TEST(SchedulerStateMachineTest,
454 TestFailedDrawsEventuallyForceDrawAfterNextCommit) {
455 SchedulerSettings scheduler_settings;
456 scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced = 1;
457 StateMachine state(scheduler_settings);
458 SET_UP_STATE(state)
460 // Start a commit.
461 state.SetNeedsBeginMainFrame();
462 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
463 state.OnBeginImplFrame();
464 EXPECT_ACTION_UPDATE_STATE(
465 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
466 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
467 EXPECT_TRUE(state.CommitPending());
469 // Then initiate a draw.
470 state.SetNeedsRedraw(true);
471 state.OnBeginImplFrameDeadline();
472 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
473 EXPECT_ACTION_UPDATE_STATE(
474 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
476 // Fail the draw.
477 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
478 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
479 EXPECT_TRUE(state.BeginFrameNeeded());
480 EXPECT_TRUE(state.RedrawPending());
481 // But the commit is ongoing.
482 EXPECT_TRUE(state.CommitPending());
484 // Finish the commit. Note, we should not yet be forcing a draw, but should
485 // continue the commit as usual.
486 state.NotifyBeginMainFrameStarted();
487 state.NotifyReadyToCommit();
488 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
489 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
490 EXPECT_TRUE(state.RedrawPending());
492 // Activate so we're ready for a new main frame.
493 state.NotifyReadyToActivate();
494 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
495 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
496 EXPECT_TRUE(state.RedrawPending());
498 // The redraw should be forced at the end of the next BeginImplFrame.
499 state.OnBeginImplFrame();
500 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
501 EXPECT_ACTION_UPDATE_STATE(
502 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
503 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
504 state.OnBeginImplFrameDeadline();
505 EXPECT_ACTION_UPDATE_STATE(
506 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED);
507 state.DidSwapBuffers();
508 state.DidSwapBuffersComplete();
511 TEST(SchedulerStateMachineTest, TestFailedDrawsDoNotRestartForcedDraw) {
512 SchedulerSettings scheduler_settings;
513 int draw_limit = 1;
514 scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced =
515 draw_limit;
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 enough times to force a redraw,
536 // then once more for good measure.
537 for (int i = 0; i < draw_limit + 1; ++i)
538 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
539 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
540 EXPECT_TRUE(state.BeginFrameNeeded());
541 EXPECT_TRUE(state.RedrawPending());
542 // But the commit is ongoing.
543 EXPECT_TRUE(state.CommitPending());
544 EXPECT_TRUE(state.ForcedRedrawState() ==
545 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_COMMIT);
547 state.NotifyBeginMainFrameStarted();
548 state.NotifyReadyToCommit();
549 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
550 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
551 EXPECT_TRUE(state.RedrawPending());
552 EXPECT_FALSE(state.CommitPending());
554 // Now force redraw should be in waiting for activation
555 EXPECT_TRUE(state.ForcedRedrawState() ==
556 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION);
558 // After failing additional draws, we should still be in a forced
559 // redraw, but not back in WAITING_FOR_COMMIT.
560 for (int i = 0; i < draw_limit + 1; ++i)
561 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
562 EXPECT_TRUE(state.RedrawPending());
563 EXPECT_TRUE(state.ForcedRedrawState() ==
564 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION);
567 TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedInNextBeginImplFrame) {
568 SchedulerSettings default_scheduler_settings;
569 StateMachine state(default_scheduler_settings);
570 SET_UP_STATE(state)
572 // Start a draw.
573 state.SetNeedsRedraw(true);
574 EXPECT_TRUE(state.BeginFrameNeeded());
575 state.OnBeginImplFrame();
576 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
577 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
578 state.OnBeginImplFrameDeadline();
579 EXPECT_TRUE(state.RedrawPending());
580 EXPECT_ACTION_UPDATE_STATE(
581 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
583 // Failing the draw for animation checkerboards makes us require a commit.
584 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
585 EXPECT_ACTION_UPDATE_STATE(
586 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
587 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
588 EXPECT_TRUE(state.RedrawPending());
590 // We should not be trying to draw again now, but we have a commit pending.
591 EXPECT_TRUE(state.BeginFrameNeeded());
592 state.OnBeginImplFrame();
593 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
594 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
596 // We should try to draw again at the end of the next BeginImplFrame on
597 // the impl thread.
598 state.OnBeginImplFrameDeadline();
599 EXPECT_ACTION_UPDATE_STATE(
600 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
601 state.DidSwapBuffers();
602 state.DidSwapBuffersComplete();
603 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
606 TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) {
607 SchedulerSettings default_scheduler_settings;
608 StateMachine state(default_scheduler_settings);
609 SET_UP_STATE(state)
610 state.SetNeedsRedraw(true);
612 // Draw the first frame.
613 EXPECT_TRUE(state.BeginFrameNeeded());
614 state.OnBeginImplFrame();
615 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
616 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
618 state.OnBeginImplFrameDeadline();
619 EXPECT_ACTION_UPDATE_STATE(
620 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
621 state.DidSwapBuffers();
622 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
623 state.DidSwapBuffersComplete();
624 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
626 // Before the next BeginImplFrame, set needs redraw again.
627 // This should not redraw until the next BeginImplFrame.
628 state.SetNeedsRedraw(true);
629 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
631 // Move to another frame. This should now draw.
632 EXPECT_TRUE(state.BeginFrameNeeded());
633 state.OnBeginImplFrame();
635 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
636 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
638 state.OnBeginImplFrameDeadline();
639 EXPECT_ACTION_UPDATE_STATE(
640 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
641 state.DidSwapBuffers();
642 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
643 state.DidSwapBuffersComplete();
644 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
646 // We just swapped, so we should proactively request another BeginImplFrame.
647 EXPECT_TRUE(state.BeginFrameNeeded());
650 TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) {
651 SchedulerSettings default_scheduler_settings;
653 // When not in BeginImplFrame deadline, or in BeginImplFrame deadline
654 // but not visible, don't draw.
655 size_t num_begin_main_frame_states =
656 sizeof(begin_main_frame_states) /
657 sizeof(SchedulerStateMachine::BeginMainFrameState);
658 size_t num_begin_impl_frame_states =
659 sizeof(all_begin_impl_frame_states) /
660 sizeof(SchedulerStateMachine::BeginImplFrameState);
661 for (size_t i = 0; i < num_begin_main_frame_states; ++i) {
662 for (size_t j = 0; j < num_begin_impl_frame_states; ++j) {
663 StateMachine state(default_scheduler_settings);
664 state.SetCanStart();
665 state.UpdateState(state.NextAction());
666 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
667 state.SetBeginMainFrameState(begin_main_frame_states[i]);
668 state.SetBeginImplFrameState(all_begin_impl_frame_states[j]);
669 bool visible =
670 (all_begin_impl_frame_states[j] !=
671 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
672 state.SetVisible(visible);
674 // Case 1: needs_begin_main_frame=false
675 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
676 state.NextAction());
678 // Case 2: needs_begin_main_frame=true
679 state.SetNeedsBeginMainFrame();
680 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
681 state.NextAction())
682 << state.AsValue()->ToString();
686 // When in BeginImplFrame deadline we should always draw for SetNeedsRedraw
687 // except if we're ready to commit, in which case we expect a commit first.
688 for (size_t i = 0; i < num_begin_main_frame_states; ++i) {
689 StateMachine state(default_scheduler_settings);
690 state.SetCanStart();
691 state.UpdateState(state.NextAction());
692 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
693 state.SetCanDraw(true);
694 state.SetBeginMainFrameState(begin_main_frame_states[i]);
695 state.SetBeginImplFrameState(
696 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
698 state.SetNeedsRedraw(true);
699 state.SetVisible(true);
701 SchedulerStateMachine::Action expected_action;
702 if (begin_main_frame_states[i] ==
703 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT) {
704 expected_action = SchedulerStateMachine::ACTION_COMMIT;
705 } else {
706 expected_action = SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
707 EXPECT_ACTION(SchedulerStateMachine::ACTION_ANIMATE);
708 state.UpdateState(state.NextAction());
711 // Case 1: needs_begin_main_frame=false.
712 EXPECT_ACTION(expected_action);
714 // Case 2: needs_begin_main_frame=true.
715 state.SetNeedsBeginMainFrame();
716 EXPECT_ACTION(expected_action);
720 TEST(SchedulerStateMachineTest, TestNoBeginMainFrameStatesRedrawWhenInvisible) {
721 SchedulerSettings default_scheduler_settings;
723 size_t num_begin_main_frame_states =
724 sizeof(begin_main_frame_states) /
725 sizeof(SchedulerStateMachine::BeginMainFrameState);
726 for (size_t i = 0; i < num_begin_main_frame_states; ++i) {
727 // There shouldn't be any drawing regardless of BeginImplFrame.
728 for (size_t j = 0; j < 2; ++j) {
729 StateMachine state(default_scheduler_settings);
730 state.SetCanStart();
731 state.UpdateState(state.NextAction());
732 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
733 state.SetBeginMainFrameState(begin_main_frame_states[i]);
734 state.SetVisible(false);
735 state.SetNeedsRedraw(true);
736 if (j == 1) {
737 state.SetBeginImplFrameState(
738 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
741 // Case 1: needs_begin_main_frame=false.
742 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
743 state.NextAction());
745 // Case 2: needs_begin_main_frame=true.
746 state.SetNeedsBeginMainFrame();
747 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
748 state.NextAction())
749 << state.AsValue()->ToString();
754 TEST(SchedulerStateMachineTest, TestCanRedraw_StopsDraw) {
755 SchedulerSettings default_scheduler_settings;
757 size_t num_begin_main_frame_states =
758 sizeof(begin_main_frame_states) /
759 sizeof(SchedulerStateMachine::BeginMainFrameState);
760 for (size_t i = 0; i < num_begin_main_frame_states; ++i) {
761 // There shouldn't be any drawing regardless of BeginImplFrame.
762 for (size_t j = 0; j < 2; ++j) {
763 StateMachine state(default_scheduler_settings);
764 state.SetCanStart();
765 state.UpdateState(state.NextAction());
766 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
767 state.SetBeginMainFrameState(begin_main_frame_states[i]);
768 state.SetVisible(false);
769 state.SetNeedsRedraw(true);
770 if (j == 1)
771 state.OnBeginImplFrame();
773 state.SetCanDraw(false);
774 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
775 state.NextAction());
780 TEST(SchedulerStateMachineTest,
781 TestCanRedrawWithWaitingForFirstDrawMakesProgress) {
782 SchedulerSettings default_scheduler_settings;
783 StateMachine state(default_scheduler_settings);
784 state.SetCanStart();
785 state.UpdateState(state.NextAction());
786 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
788 state.SetActiveTreeNeedsFirstDraw(true);
789 state.SetNeedsBeginMainFrame();
790 state.SetNeedsRedraw(true);
791 state.SetVisible(true);
792 state.SetCanDraw(false);
793 state.OnBeginImplFrame();
794 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
795 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
796 EXPECT_ACTION_UPDATE_STATE(
797 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
798 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
799 state.NotifyBeginMainFrameStarted();
800 state.NotifyReadyToCommit();
801 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
802 state.NotifyReadyToActivate();
803 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
804 state.OnBeginImplFrameDeadline();
805 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
806 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
807 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
810 TEST(SchedulerStateMachineTest, TestSetNeedsBeginMainFrameIsNotLost) {
811 SchedulerSettings scheduler_settings;
812 StateMachine state(scheduler_settings);
813 SET_UP_STATE(state)
814 state.SetNeedsBeginMainFrame();
816 EXPECT_TRUE(state.BeginFrameNeeded());
818 // Begin the frame.
819 state.OnBeginImplFrame();
820 EXPECT_ACTION_UPDATE_STATE(
821 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
822 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT);
824 // Now, while the frame is in progress, set another commit.
825 state.SetNeedsBeginMainFrame();
826 EXPECT_TRUE(state.NeedsCommit());
828 // Let the frame finish.
829 state.NotifyBeginMainFrameStarted();
830 state.NotifyReadyToCommit();
831 EXPECT_MAIN_FRAME_STATE(
832 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT);
834 // Expect to commit regardless of BeginImplFrame state.
835 EXPECT_IMPL_FRAME_STATE(
836 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING);
837 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
839 state.OnBeginImplFrameDeadlinePending();
840 EXPECT_IMPL_FRAME_STATE(
841 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME);
842 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
844 state.OnBeginImplFrameDeadline();
845 EXPECT_IMPL_FRAME_STATE(
846 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
847 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
849 state.OnBeginImplFrameIdle();
850 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
851 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
853 state.OnBeginImplFrame();
854 EXPECT_IMPL_FRAME_STATE(
855 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING);
856 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
858 // Finish the commit and activate, then make sure we start the next commit
859 // immediately and draw on the next BeginImplFrame.
860 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
861 state.NotifyReadyToActivate();
862 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
863 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
864 EXPECT_ACTION_UPDATE_STATE(
865 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
866 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
868 state.OnBeginImplFrameDeadline();
870 EXPECT_TRUE(state.active_tree_needs_first_draw());
871 EXPECT_ACTION_UPDATE_STATE(
872 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
873 state.DidSwapBuffers();
874 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
875 state.DidSwapBuffersComplete();
876 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
879 TEST(SchedulerStateMachineTest, TestFullCycle) {
880 SchedulerSettings default_scheduler_settings;
881 StateMachine state(default_scheduler_settings);
882 SET_UP_STATE(state)
884 // Start clean and set commit.
885 state.SetNeedsBeginMainFrame();
887 // Begin the frame.
888 state.OnBeginImplFrame();
889 EXPECT_ACTION_UPDATE_STATE(
890 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
891 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT);
892 EXPECT_FALSE(state.NeedsCommit());
893 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
895 // Tell the scheduler the frame finished.
896 state.NotifyBeginMainFrameStarted();
897 state.NotifyReadyToCommit();
898 EXPECT_MAIN_FRAME_STATE(
899 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT);
901 // Commit.
902 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
904 // Activate.
905 state.NotifyReadyToActivate();
906 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
907 EXPECT_TRUE(state.active_tree_needs_first_draw());
908 EXPECT_TRUE(state.needs_redraw());
910 // Expect to do nothing until BeginImplFrame deadline
911 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
913 // At BeginImplFrame deadline, draw.
914 state.OnBeginImplFrameDeadline();
915 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
916 EXPECT_ACTION_UPDATE_STATE(
917 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
918 state.DidSwapBuffers();
919 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
920 state.DidSwapBuffersComplete();
922 // Should be synchronized, no draw needed, no action needed.
923 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
924 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE);
925 EXPECT_FALSE(state.needs_redraw());
928 TEST(SchedulerStateMachineTest, CommitWithoutDrawWithPendingTree) {
929 SchedulerSettings default_scheduler_settings;
930 StateMachine state(default_scheduler_settings);
931 SET_UP_STATE(state)
933 // Start clean and set commit.
934 state.SetNeedsBeginMainFrame();
936 // Make a main frame, commit and activate it. But don't draw it.
937 state.OnBeginImplFrame();
938 EXPECT_ACTION_UPDATE_STATE(
939 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
940 state.NotifyBeginMainFrameStarted();
941 state.NotifyReadyToCommit();
942 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
943 state.NotifyReadyToActivate();
944 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
946 // Try to make a new main frame before drawing. Since we will commit it to a
947 // pending tree and not clobber the active tree, we're able to start a new
948 // begin frame and commit it.
949 state.SetNeedsBeginMainFrame();
950 state.OnBeginImplFrame();
951 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
952 EXPECT_ACTION_UPDATE_STATE(
953 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
954 state.NotifyBeginMainFrameStarted();
955 state.NotifyReadyToCommit();
956 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
959 TEST(SchedulerStateMachineTest, DontCommitWithoutDrawWithoutPendingTree) {
960 SchedulerSettings scheduler_settings;
961 scheduler_settings.commit_to_active_tree = true;
962 StateMachine state(scheduler_settings);
963 SET_UP_STATE(state)
965 // Start clean and set commit.
966 state.SetNeedsBeginMainFrame();
968 // Make a main frame, commit and activate it. But don't draw it.
969 state.OnBeginImplFrame();
970 EXPECT_ACTION_UPDATE_STATE(
971 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
972 state.NotifyBeginMainFrameStarted();
973 state.NotifyReadyToCommit();
974 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
975 state.NotifyReadyToActivate();
976 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
978 // Try to make a new main frame before drawing, but since we would clobber the
979 // active tree, we will not do so.
980 state.SetNeedsBeginMainFrame();
981 state.OnBeginImplFrame();
982 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
983 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
986 TEST(SchedulerStateMachineTest, TestFullCycleWithCommitToActive) {
987 SchedulerSettings scheduler_settings;
988 scheduler_settings.commit_to_active_tree = true;
989 StateMachine state(scheduler_settings);
990 SET_UP_STATE(state)
992 // Start clean and set commit.
993 state.SetNeedsBeginMainFrame();
995 // Begin the frame.
996 state.OnBeginImplFrame();
997 EXPECT_ACTION_UPDATE_STATE(
998 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
999 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT);
1000 EXPECT_FALSE(state.NeedsCommit());
1001 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1003 // Tell the scheduler the frame finished.
1004 state.NotifyBeginMainFrameStarted();
1005 state.NotifyReadyToCommit();
1006 EXPECT_MAIN_FRAME_STATE(
1007 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT);
1009 // Commit.
1010 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1012 // Now commit should wait for activation.
1013 EXPECT_MAIN_FRAME_STATE(
1014 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_WAITING_FOR_ACTIVATION);
1016 // No activation yet, so this commit is not drawn yet. Force to draw this
1017 // frame, and still block BeginMainFrame.
1018 state.SetNeedsRedraw(true);
1019 state.SetNeedsBeginMainFrame();
1020 state.OnBeginImplFrameDeadline();
1021 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1022 EXPECT_ACTION_UPDATE_STATE(
1023 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1024 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1026 // Cannot BeginMainFrame yet since last commit is not yet activated and drawn.
1027 state.OnBeginImplFrame();
1028 EXPECT_MAIN_FRAME_STATE(
1029 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_WAITING_FOR_ACTIVATION);
1030 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1032 // Now activate sync tree.
1033 state.NotifyReadyToActivate();
1034 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1035 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1036 EXPECT_TRUE(state.active_tree_needs_first_draw());
1037 EXPECT_TRUE(state.needs_redraw());
1038 EXPECT_MAIN_FRAME_STATE(
1039 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_WAITING_FOR_DRAW);
1041 // Swap throttled. Do not draw.
1042 state.DidSwapBuffers();
1043 state.OnBeginImplFrameDeadline();
1044 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1045 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1046 state.DidSwapBuffersComplete();
1048 // Haven't draw since last commit, do not begin new main frame.
1049 state.OnBeginImplFrame();
1050 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1051 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1053 // At BeginImplFrame deadline, draw. This draws unblocks BeginMainFrame.
1054 state.OnBeginImplFrameDeadline();
1055 EXPECT_ACTION_UPDATE_STATE(
1056 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1057 state.DidSwapBuffers();
1058 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
1059 state.DidSwapBuffersComplete();
1061 // Now will be able to start main frame.
1062 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE);
1063 EXPECT_FALSE(state.needs_redraw());
1064 EXPECT_ACTION_UPDATE_STATE(
1065 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1068 TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween) {
1069 SchedulerSettings default_scheduler_settings;
1070 StateMachine state(default_scheduler_settings);
1071 SET_UP_STATE(state)
1073 // Start clean and set commit.
1074 state.SetNeedsBeginMainFrame();
1076 // Begin the frame.
1077 state.OnBeginImplFrame();
1078 EXPECT_ACTION_UPDATE_STATE(
1079 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1080 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT);
1081 EXPECT_FALSE(state.NeedsCommit());
1082 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1084 // Request another commit while the commit is in flight.
1085 state.SetNeedsBeginMainFrame();
1086 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1088 // Tell the scheduler the frame finished.
1089 state.NotifyBeginMainFrameStarted();
1090 state.NotifyReadyToCommit();
1091 EXPECT_MAIN_FRAME_STATE(
1092 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT);
1094 // First commit and activate.
1095 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1096 state.NotifyReadyToActivate();
1097 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1098 EXPECT_TRUE(state.active_tree_needs_first_draw());
1099 EXPECT_TRUE(state.needs_redraw());
1101 // Expect to do nothing until BeginImplFrame deadline.
1102 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1104 // At BeginImplFrame deadline, draw.
1105 state.OnBeginImplFrameDeadline();
1106 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1107 EXPECT_ACTION_UPDATE_STATE(
1108 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1109 state.DidSwapBuffers();
1110 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
1111 state.DidSwapBuffersComplete();
1113 // Should be synchronized, no draw needed, no action needed.
1114 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1115 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE);
1116 EXPECT_FALSE(state.needs_redraw());
1118 // Next BeginImplFrame should initiate second commit.
1119 state.OnBeginImplFrame();
1120 EXPECT_ACTION_UPDATE_STATE(
1121 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1124 TEST(SchedulerStateMachineTest, TestRequestCommitInvisible) {
1125 SchedulerSettings default_scheduler_settings;
1126 StateMachine state(default_scheduler_settings);
1127 state.SetCanStart();
1128 state.UpdateState(state.NextAction());
1129 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1130 state.SetNeedsBeginMainFrame();
1131 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1134 // See ThreadProxy::BeginMainFrame "EarlyOut_NotVisible" /
1135 // "EarlyOut_OutputSurfaceLost" cases.
1136 TEST(SchedulerStateMachineTest, TestAbortBeginMainFrameBecauseInvisible) {
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 while visible.
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 // Become invisible and abort BeginMainFrame.
1153 state.SetVisible(false);
1154 state.BeginMainFrameAborted(CommitEarlyOutReason::ABORTED_NOT_VISIBLE);
1156 // NeedsCommit should now be true again because we never actually did a
1157 // commit.
1158 EXPECT_TRUE(state.NeedsCommit());
1160 // We should now be back in the idle state as if we never started the frame.
1161 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE);
1162 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1164 // We shouldn't do anything on the BeginImplFrame deadline.
1165 state.OnBeginImplFrameDeadline();
1166 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1168 // Become visible again.
1169 state.SetVisible(true);
1171 // Although we have aborted on this frame and haven't cancelled the commit
1172 // (i.e. need another), don't send another BeginMainFrame yet.
1173 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE);
1174 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1175 EXPECT_TRUE(state.NeedsCommit());
1177 // Start a new frame.
1178 state.OnBeginImplFrame();
1179 EXPECT_ACTION_UPDATE_STATE(
1180 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1182 // We should be starting the commit now.
1183 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT);
1184 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1187 // See ThreadProxy::BeginMainFrame "EarlyOut_NoUpdates" case.
1188 TEST(SchedulerStateMachineTest, TestAbortBeginMainFrameBecauseCommitNotNeeded) {
1189 SchedulerSettings default_scheduler_settings;
1190 StateMachine state(default_scheduler_settings);
1191 state.SetCanStart();
1192 state.UpdateState(state.NextAction());
1193 state.DidCreateAndInitializeOutputSurface();
1194 state.SetVisible(true);
1195 state.SetCanDraw(true);
1197 // Get into a begin frame / commit state.
1198 state.SetNeedsBeginMainFrame();
1199 state.OnBeginImplFrame();
1200 EXPECT_ACTION_UPDATE_STATE(
1201 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1202 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT);
1203 EXPECT_FALSE(state.NeedsCommit());
1204 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1206 // Abort the commit, true means that the BeginMainFrame was sent but there
1207 // was no work to do on the main thread.
1208 state.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES);
1210 // NeedsCommit should now be false because the commit was actually handled.
1211 EXPECT_FALSE(state.NeedsCommit());
1213 // Even though the commit was aborted, we still expect to draw the new frame.
1214 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1215 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1216 state.OnBeginImplFrameDeadline();
1217 EXPECT_ACTION_UPDATE_STATE(
1218 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1219 state.DidSwapBuffers();
1220 state.DidSwapBuffersComplete();
1221 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1223 // Verify another commit doesn't start on another frame either.
1224 EXPECT_FALSE(state.NeedsCommit());
1225 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE);
1227 state.OnBeginImplFrame();
1228 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1229 state.OnBeginImplFrameDeadline();
1230 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1232 // Verify another commit can start if requested, though.
1233 state.SetNeedsBeginMainFrame();
1234 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE);
1235 state.OnBeginImplFrame();
1236 EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1239 TEST(SchedulerStateMachineTest, TestFirstContextCreation) {
1240 SchedulerSettings default_scheduler_settings;
1241 StateMachine state(default_scheduler_settings);
1242 state.SetCanStart();
1243 state.SetVisible(true);
1244 state.SetCanDraw(true);
1246 EXPECT_ACTION_UPDATE_STATE(
1247 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1248 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1249 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1251 // Check that the first init does not SetNeedsBeginMainFrame.
1252 state.OnBeginImplFrame();
1253 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1254 state.OnBeginImplFrameDeadline();
1255 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1257 // Check that a needs commit initiates a BeginMainFrame.
1258 state.SetNeedsBeginMainFrame();
1259 state.OnBeginImplFrame();
1260 EXPECT_ACTION_UPDATE_STATE(
1261 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1264 TEST(SchedulerStateMachineTest, TestContextLostWhenCompletelyIdle) {
1265 SchedulerSettings default_scheduler_settings;
1266 StateMachine state(default_scheduler_settings);
1267 SET_UP_STATE(state)
1269 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1270 state.NextAction());
1271 state.DidLoseOutputSurface();
1273 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1274 state.UpdateState(state.NextAction());
1276 // Once context recreation begins, nothing should happen.
1277 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1279 // Recreate the context.
1280 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1282 // When the context is recreated, we should begin a commit.
1283 state.OnBeginImplFrame();
1284 EXPECT_ACTION_UPDATE_STATE(
1285 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1288 TEST(SchedulerStateMachineTest,
1289 TestContextLostWhenIdleAndCommitRequestedWhileRecreating) {
1290 SchedulerSettings default_scheduler_settings;
1291 StateMachine state(default_scheduler_settings);
1292 SET_UP_STATE(state)
1294 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1295 state.NextAction());
1296 state.DidLoseOutputSurface();
1297 EXPECT_EQ(state.output_surface_state(),
1298 SchedulerStateMachine::OUTPUT_SURFACE_LOST);
1300 EXPECT_ACTION_UPDATE_STATE(
1301 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1302 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1304 // Once context recreation begins, nothing should happen.
1305 state.OnBeginImplFrame();
1306 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1307 state.OnBeginImplFrameDeadline();
1308 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1310 // While context is recreating, commits shouldn't begin.
1311 state.SetNeedsBeginMainFrame();
1312 state.OnBeginImplFrame();
1313 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1314 state.OnBeginImplFrameDeadline();
1315 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1317 // Recreate the context
1318 state.DidCreateAndInitializeOutputSurface();
1319 EXPECT_EQ(state.output_surface_state(),
1320 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT);
1321 EXPECT_FALSE(state.RedrawPending());
1323 // When the context is recreated, we wait until the next BeginImplFrame
1324 // before starting.
1325 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1327 // When the BeginFrame comes in we should begin a commit
1328 state.OnBeginImplFrame();
1329 EXPECT_ACTION_UPDATE_STATE(
1330 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1331 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1332 EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT);
1334 // Until that commit finishes, we shouldn't be drawing or animate.
1335 state.OnBeginImplFrameDeadline();
1336 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1338 // Finish the commit, which should make the surface active.
1339 state.NotifyBeginMainFrameStarted();
1340 state.NotifyReadyToCommit();
1341 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1342 EXPECT_EQ(state.output_surface_state(),
1343 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION);
1344 state.NotifyReadyToActivate();
1345 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1346 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1347 EXPECT_EQ(state.output_surface_state(),
1348 SchedulerStateMachine::OUTPUT_SURFACE_ACTIVE);
1350 // Finishing the first commit after initializing an output surface should
1351 // automatically cause a redraw.
1352 EXPECT_TRUE(state.RedrawPending());
1353 state.OnBeginImplFrame();
1354 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1355 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1356 state.OnBeginImplFrameDeadline();
1357 EXPECT_ACTION_UPDATE_STATE(
1358 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1359 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1360 EXPECT_FALSE(state.RedrawPending());
1362 // Next frame as no work to do.
1363 state.OnBeginImplFrame();
1364 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1365 state.OnBeginImplFrameDeadline();
1366 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1368 // Once the context is recreated, whether we draw should be based on
1369 // SetCanDraw if waiting on first draw after activate.
1370 state.SetNeedsRedraw(true);
1371 state.OnBeginImplFrame();
1372 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1373 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1374 state.OnBeginImplFrameDeadline();
1375 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1376 state.SetCanDraw(false);
1377 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1378 state.SetCanDraw(true);
1379 EXPECT_ACTION_UPDATE_STATE(
1380 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1381 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1383 // Once the context is recreated, whether we draw should be based on
1384 // SetCanDraw if waiting on first draw after activate.
1385 state.SetNeedsRedraw(true);
1386 state.SetNeedsBeginMainFrame();
1387 state.OnBeginImplFrame();
1388 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1389 EXPECT_ACTION_UPDATE_STATE(
1390 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1391 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1392 // Activate so we need the first draw
1393 state.NotifyBeginMainFrameStarted();
1394 state.NotifyReadyToCommit();
1395 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1396 state.NotifyReadyToActivate();
1397 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1398 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1399 EXPECT_TRUE(state.active_tree_needs_first_draw());
1400 EXPECT_TRUE(state.needs_redraw());
1402 state.OnBeginImplFrameDeadline();
1403 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1404 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1405 state.SetCanDraw(false);
1406 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1407 state.SetCanDraw(true);
1408 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1411 TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) {
1412 SchedulerSettings scheduler_settings;
1413 StateMachine state(scheduler_settings);
1414 SET_UP_STATE(state)
1416 // Get a commit in flight.
1417 state.SetNeedsBeginMainFrame();
1419 // Set damage and expect a draw.
1420 state.SetNeedsRedraw(true);
1421 state.OnBeginImplFrame();
1422 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1423 EXPECT_ACTION_UPDATE_STATE(
1424 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1425 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1426 state.OnBeginImplFrameDeadline();
1427 EXPECT_ACTION_UPDATE_STATE(
1428 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1429 state.DidSwapBuffers();
1430 state.DidSwapBuffersComplete();
1431 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1433 // Cause a lost context while the BeginMainFrame is in flight.
1434 state.DidLoseOutputSurface();
1436 // Ask for another draw. Expect nothing happens.
1437 state.SetNeedsRedraw(true);
1438 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1440 // Finish the frame, commit and activate.
1441 state.NotifyBeginMainFrameStarted();
1442 state.NotifyReadyToCommit();
1443 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1444 state.NotifyReadyToActivate();
1445 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1447 // We will abort the draw when the output surface is lost if we are
1448 // waiting for the first draw to unblock the main thread.
1449 EXPECT_TRUE(state.active_tree_needs_first_draw());
1450 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1452 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1453 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
1454 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1456 state.OnBeginImplFrame();
1457 EXPECT_IMPL_FRAME_STATE(
1458 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING);
1459 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1461 state.OnBeginImplFrameDeadlinePending();
1462 EXPECT_IMPL_FRAME_STATE(
1463 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME);
1464 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1466 state.OnBeginImplFrameDeadline();
1467 EXPECT_IMPL_FRAME_STATE(
1468 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
1469 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1472 TEST(SchedulerStateMachineTest,
1473 TestContextLostWhileCommitInProgressAndAnotherCommitRequested) {
1474 SchedulerSettings scheduler_settings;
1475 StateMachine state(scheduler_settings);
1476 SET_UP_STATE(state)
1478 // Get a commit in flight.
1479 state.SetNeedsBeginMainFrame();
1480 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1482 // Set damage and expect a draw.
1483 state.SetNeedsRedraw(true);
1484 state.OnBeginImplFrame();
1485 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1486 EXPECT_ACTION_UPDATE_STATE(
1487 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1488 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1489 state.OnBeginImplFrameDeadline();
1490 EXPECT_ACTION_UPDATE_STATE(
1491 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1492 state.DidSwapBuffers();
1493 state.DidSwapBuffersComplete();
1494 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1496 // Cause a lost context while the BeginMainFrame is in flight.
1497 state.DidLoseOutputSurface();
1499 // Ask for another draw and also set needs commit. Expect nothing happens.
1500 state.SetNeedsRedraw(true);
1501 state.SetNeedsBeginMainFrame();
1502 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1504 // Finish the frame, and commit and activate.
1505 state.NotifyBeginMainFrameStarted();
1506 state.NotifyReadyToCommit();
1507 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1508 state.NotifyReadyToActivate();
1509 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1510 EXPECT_TRUE(state.active_tree_needs_first_draw());
1512 // Because the output surface is missing, we expect the draw to abort.
1513 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1515 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1516 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
1517 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1519 state.OnBeginImplFrame();
1520 EXPECT_IMPL_FRAME_STATE(
1521 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING);
1522 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1524 state.OnBeginImplFrameDeadlinePending();
1525 EXPECT_IMPL_FRAME_STATE(
1526 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME);
1527 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1529 state.OnBeginImplFrameDeadline();
1530 EXPECT_IMPL_FRAME_STATE(
1531 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
1532 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1534 state.OnBeginImplFrameIdle();
1535 EXPECT_ACTION_UPDATE_STATE(
1536 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1538 // After we get a new output surface, the commit flow should start.
1539 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1540 state.OnBeginImplFrame();
1541 EXPECT_ACTION_UPDATE_STATE(
1542 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1543 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1544 state.NotifyBeginMainFrameStarted();
1545 state.NotifyReadyToCommit();
1546 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1547 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1548 state.NotifyReadyToActivate();
1549 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1550 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1551 state.OnBeginImplFrameDeadline();
1552 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1553 EXPECT_ACTION_UPDATE_STATE(
1554 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1555 state.DidSwapBuffers();
1556 state.DidSwapBuffersComplete();
1557 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1560 TEST(SchedulerStateMachineTest, DontDrawBeforeCommitAfterLostOutputSurface) {
1561 SchedulerSettings default_scheduler_settings;
1562 StateMachine state(default_scheduler_settings);
1563 SET_UP_STATE(state)
1565 state.SetNeedsRedraw(true);
1567 // Cause a lost output surface, and restore it.
1568 state.DidLoseOutputSurface();
1569 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1570 state.UpdateState(state.NextAction());
1571 state.DidCreateAndInitializeOutputSurface();
1573 EXPECT_FALSE(state.RedrawPending());
1574 state.OnBeginImplFrame();
1575 EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1578 TEST(SchedulerStateMachineTest,
1579 TestPendingActivationsShouldBeForcedAfterLostOutputSurface) {
1580 SchedulerSettings default_scheduler_settings;
1581 StateMachine state(default_scheduler_settings);
1582 SET_UP_STATE(state)
1584 state.SetBeginMainFrameState(
1585 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT);
1587 // Cause a lost context.
1588 state.DidLoseOutputSurface();
1590 state.NotifyBeginMainFrameStarted();
1591 state.NotifyReadyToCommit();
1592 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1594 EXPECT_TRUE(state.PendingActivationsShouldBeForced());
1595 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1597 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1598 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1601 TEST(SchedulerStateMachineTest, TestNoBeginFrameNeededWhenInvisible) {
1602 SchedulerSettings default_scheduler_settings;
1603 StateMachine state(default_scheduler_settings);
1604 state.SetCanStart();
1605 state.UpdateState(state.NextAction());
1606 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1607 state.SetVisible(true);
1609 EXPECT_FALSE(state.BeginFrameNeeded());
1610 state.SetNeedsRedraw(true);
1611 EXPECT_TRUE(state.BeginFrameNeeded());
1613 state.SetVisible(false);
1614 EXPECT_FALSE(state.BeginFrameNeeded());
1616 state.SetVisible(true);
1617 EXPECT_TRUE(state.BeginFrameNeeded());
1620 TEST(SchedulerStateMachineTest, TestNoBeginMainFrameWhenInvisible) {
1621 SchedulerSettings default_scheduler_settings;
1622 StateMachine state(default_scheduler_settings);
1623 state.SetCanStart();
1624 state.UpdateState(state.NextAction());
1625 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1626 state.SetVisible(false);
1627 state.SetNeedsBeginMainFrame();
1628 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1629 EXPECT_FALSE(state.BeginFrameNeeded());
1631 // When become visible again, the needs commit should still be pending.
1632 state.SetVisible(true);
1633 EXPECT_TRUE(state.BeginFrameNeeded());
1634 state.OnBeginImplFrame();
1635 EXPECT_ACTION_UPDATE_STATE(
1636 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1639 TEST(SchedulerStateMachineTest, TestFinishCommitWhenCommitInProgress) {
1640 SchedulerSettings default_scheduler_settings;
1641 StateMachine state(default_scheduler_settings);
1642 state.SetCanStart();
1643 state.UpdateState(state.NextAction());
1644 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1645 state.SetVisible(false);
1646 state.SetBeginMainFrameState(
1647 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT);
1648 state.SetNeedsBeginMainFrame();
1650 state.NotifyBeginMainFrameStarted();
1651 state.NotifyReadyToCommit();
1652 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
1653 state.UpdateState(state.NextAction());
1654 state.NotifyReadyToActivate();
1655 EXPECT_ACTION(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1656 state.UpdateState(state.NextAction());
1658 EXPECT_TRUE(state.active_tree_needs_first_draw());
1659 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1662 TEST(SchedulerStateMachineTest, TestInitialActionsWhenContextLost) {
1663 SchedulerSettings default_scheduler_settings;
1664 StateMachine state(default_scheduler_settings);
1665 SET_UP_STATE(state)
1666 state.SetNeedsBeginMainFrame();
1667 state.DidLoseOutputSurface();
1669 // When we are visible, we normally want to begin output surface creation
1670 // as soon as possible.
1671 EXPECT_ACTION_UPDATE_STATE(
1672 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1674 state.DidCreateAndInitializeOutputSurface();
1675 EXPECT_EQ(state.output_surface_state(),
1676 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT);
1678 // We should not send a BeginMainFrame when we are invisible, even if we've
1679 // lost the output surface and are trying to get the first commit, since the
1680 // main thread will just abort anyway.
1681 state.SetVisible(false);
1682 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1685 TEST(SchedulerStateMachineTest, ReportIfNotDrawing) {
1686 SchedulerSettings default_scheduler_settings;
1687 StateMachine state(default_scheduler_settings);
1688 SET_UP_STATE(state)
1689 EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
1691 state.SetCanDraw(false);
1692 state.SetVisible(true);
1693 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1695 state.SetCanDraw(true);
1696 state.SetVisible(false);
1697 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1699 state.SetCanDraw(false);
1700 state.SetVisible(false);
1701 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1703 state.SetCanDraw(true);
1704 state.SetVisible(true);
1705 EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
1708 TEST(SchedulerStateMachineTest,
1709 TestTriggerDeadlineImmediatelyAfterAbortedCommit) {
1710 SchedulerSettings default_scheduler_settings;
1711 StateMachine state(default_scheduler_settings);
1712 SET_UP_STATE(state)
1714 // This test mirrors what happens during the first frame of a scroll gesture.
1715 // First we get the input event and a BeginFrame.
1716 state.OnBeginImplFrame();
1718 // As a response the compositor requests a redraw and a commit to tell the
1719 // main thread about the new scroll offset.
1720 state.SetNeedsRedraw(true);
1721 state.SetNeedsBeginMainFrame();
1723 // We should start the commit normally.
1724 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1725 EXPECT_ACTION_UPDATE_STATE(
1726 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1727 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1729 // Since only the scroll offset changed, the main thread will abort the
1730 // commit.
1731 state.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES);
1733 // Since the commit was aborted, we should draw right away instead of waiting
1734 // for the deadline.
1735 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1738 void FinishPreviousCommitAndDrawWithoutExitingDeadline(
1739 StateMachine* state_ptr) {
1740 // Gross, but allows us to use macros below.
1741 StateMachine& state = *state_ptr;
1743 state.NotifyBeginMainFrameStarted();
1744 state.NotifyReadyToCommit();
1745 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1746 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1747 state.NotifyReadyToActivate();
1748 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1749 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1751 state.OnBeginImplFrame();
1752 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1753 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1755 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1756 state.OnBeginImplFrameDeadline();
1757 EXPECT_ACTION_UPDATE_STATE(
1758 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1759 state.DidSwapBuffers();
1762 TEST(SchedulerStateMachineTest, TestImplLatencyTakesPriority) {
1763 SchedulerSettings default_scheduler_settings;
1764 StateMachine state(default_scheduler_settings);
1765 SET_UP_STATE(state)
1767 // This test ensures that impl-draws are prioritized over main thread updates
1768 // in prefer impl latency mode.
1769 state.SetNeedsRedraw(true);
1770 state.SetNeedsBeginMainFrame();
1771 state.OnBeginImplFrame();
1772 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1773 EXPECT_ACTION_UPDATE_STATE(
1774 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1775 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1777 // Verify the deadline is not triggered early until we enter
1778 // prefer impl latency mode.
1779 EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1780 state.SetImplLatencyTakesPriority(true);
1781 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1783 // Trigger the deadline.
1784 state.OnBeginImplFrameDeadline();
1785 EXPECT_ACTION_UPDATE_STATE(
1786 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1787 state.DidSwapBuffers();
1788 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1789 state.DidSwapBuffersComplete();
1791 // Request a new commit and finish the previous one.
1792 state.SetNeedsBeginMainFrame();
1793 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state);
1794 EXPECT_ACTION_UPDATE_STATE(
1795 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1796 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1797 state.DidSwapBuffersComplete();
1798 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1800 // Finish the previous commit and draw it.
1801 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state);
1802 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1804 // Verify we do not send another BeginMainFrame if was are swap throttled
1805 // and did not just swap.
1806 state.SetNeedsBeginMainFrame();
1807 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1808 state.OnBeginImplFrame();
1809 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1810 EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1811 state.OnBeginImplFrameDeadline();
1812 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1815 TEST(SchedulerStateMachineTest,
1816 TestTriggerDeadlineImmediatelyOnLostOutputSurface) {
1817 SchedulerSettings default_scheduler_settings;
1818 StateMachine state(default_scheduler_settings);
1819 SET_UP_STATE(state)
1821 state.SetNeedsBeginMainFrame();
1823 state.OnBeginImplFrame();
1824 EXPECT_ACTION_UPDATE_STATE(
1825 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1826 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1827 EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1829 state.DidLoseOutputSurface();
1830 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1831 // The deadline should be triggered immediately when output surface is lost.
1832 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1835 TEST(SchedulerStateMachineTest, TestTriggerDeadlineImmediatelyWhenInvisible) {
1836 SchedulerSettings default_scheduler_settings;
1837 StateMachine state(default_scheduler_settings);
1838 SET_UP_STATE(state)
1840 state.SetNeedsBeginMainFrame();
1842 state.OnBeginImplFrame();
1843 EXPECT_ACTION_UPDATE_STATE(
1844 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1845 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1846 EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1848 state.SetVisible(false);
1849 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1850 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1853 TEST(SchedulerStateMachineTest, TestSetNeedsAnimate) {
1854 SchedulerSettings default_scheduler_settings;
1855 StateMachine state(default_scheduler_settings);
1856 SET_UP_STATE(state)
1858 // Test requesting an animation that, when run, causes us to draw.
1859 state.SetNeedsAnimate();
1860 EXPECT_TRUE(state.BeginFrameNeeded());
1861 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1863 state.OnBeginImplFrame();
1864 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1866 state.OnBeginImplFrameDeadlinePending();
1867 state.OnBeginImplFrameDeadline();
1868 EXPECT_ACTION_UPDATE_STATE(
1869 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1872 TEST(SchedulerStateMachineTest, TestAnimateBeforeCommit) {
1873 SchedulerSettings default_scheduler_settings;
1874 StateMachine state(default_scheduler_settings);
1875 SET_UP_STATE(state)
1877 // Check that animations are updated before we start a commit.
1878 state.SetNeedsAnimate();
1879 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1880 state.SetNeedsBeginMainFrame();
1881 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1882 EXPECT_TRUE(state.BeginFrameNeeded());
1884 state.OnBeginImplFrame();
1885 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1886 EXPECT_ACTION_UPDATE_STATE(
1887 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1889 state.OnBeginImplFrameDeadlinePending();
1890 state.OnBeginImplFrameDeadline();
1891 EXPECT_ACTION_UPDATE_STATE(
1892 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1895 TEST(SchedulerStateMachineTest, TestAnimateAfterCommitBeforeDraw) {
1896 SchedulerSettings default_scheduler_settings;
1897 StateMachine state(default_scheduler_settings);
1898 SET_UP_STATE(state)
1900 // Check that animations are updated before we start a commit.
1901 state.SetNeedsAnimate();
1902 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1903 state.SetNeedsBeginMainFrame();
1904 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1905 EXPECT_TRUE(state.BeginFrameNeeded());
1907 state.OnBeginImplFrame();
1908 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1909 EXPECT_ACTION_UPDATE_STATE(
1910 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1912 state.NotifyBeginMainFrameStarted();
1913 state.NotifyReadyToCommit();
1914 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1916 state.OnBeginImplFrameDeadlinePending();
1917 state.OnBeginImplFrameDeadline();
1918 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1919 EXPECT_ACTION_UPDATE_STATE(
1920 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1923 TEST(SchedulerStateMachineTest, TestSetNeedsAnimateAfterAnimate) {
1924 SchedulerSettings default_scheduler_settings;
1925 StateMachine state(default_scheduler_settings);
1926 SET_UP_STATE(state)
1928 // Test requesting an animation after we have already animated during this
1929 // frame.
1930 state.SetNeedsRedraw(true);
1931 EXPECT_TRUE(state.BeginFrameNeeded());
1932 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1934 state.OnBeginImplFrame();
1935 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1937 state.SetNeedsAnimate();
1938 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1940 state.OnBeginImplFrameDeadline();
1941 EXPECT_ACTION_UPDATE_STATE(
1942 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1945 TEST(SchedulerStateMachineTest, TestForwardBeginFramesToChildren) {
1946 SchedulerSettings settings;
1947 StateMachine state(settings);
1948 SET_UP_STATE(state)
1950 EXPECT_FALSE(state.BeginFrameNeeded());
1951 state.SetChildrenNeedBeginFrames(true);
1952 EXPECT_TRUE(state.BeginFrameNeeded());
1955 TEST(SchedulerStateMachineTest, TestDeferCommit) {
1956 SchedulerSettings settings;
1957 StateMachine state(settings);
1958 SET_UP_STATE(state)
1960 state.SetDeferCommits(true);
1962 state.SetNeedsBeginMainFrame();
1963 EXPECT_FALSE(state.BeginFrameNeeded());
1964 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1966 state.OnBeginImplFrame();
1967 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1969 state.OnBeginImplFrameDeadline();
1970 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1972 state.SetDeferCommits(false);
1973 state.OnBeginImplFrame();
1974 EXPECT_ACTION_UPDATE_STATE(
1975 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1978 TEST(SchedulerStateMachineTest, EarlyOutCommitWantsProactiveBeginFrame) {
1979 SchedulerSettings settings;
1980 StateMachine state(settings);
1981 SET_UP_STATE(state);
1983 EXPECT_FALSE(state.ProactiveBeginFrameWanted());
1984 bool commit_has_no_updates = true;
1985 state.UpdateStateOnCommit(commit_has_no_updates);
1986 EXPECT_TRUE(state.ProactiveBeginFrameWanted());
1987 state.OnBeginImplFrame();
1988 EXPECT_FALSE(state.ProactiveBeginFrameWanted());
1991 } // namespace
1992 } // namespace cc