cc: Do not pass BeginFrameArgs to state machine.
[chromium-blink-merge.git] / cc / scheduler / scheduler_state_machine_unittest.cc
blob0846fabb047f4c32a45b2de14daaa7cb8ee9a2ff
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_COMMIT_STATE(expected) \
29 EXPECT_ENUM_EQ(CommitStateToString, expected, state.CommitState())
31 #define EXPECT_ACTION(expected) \
32 EXPECT_ENUM_EQ(ActionToString, expected, state.NextAction()) \
33 << state.AsValue()->ToString()
35 #define EXPECT_ACTION_UPDATE_STATE(action) \
36 EXPECT_ACTION(action); \
37 if (action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE || \
38 action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED) { \
39 EXPECT_IMPL_FRAME_STATE( \
40 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE); \
41 } \
42 state.UpdateState(action); \
43 if (action == SchedulerStateMachine::ACTION_NONE) { \
44 if (state.begin_impl_frame_state() == \
45 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) \
46 state.OnBeginImplFrameDeadlinePending(); \
47 if (state.begin_impl_frame_state() == \
48 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) \
49 state.OnBeginImplFrameIdle(); \
52 #define SET_UP_STATE(state) \
53 state.SetCanStart(); \
54 state.UpdateState(state.NextAction()); \
55 state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); \
56 state.SetVisible(true); \
57 state.SetCanDraw(true);
59 namespace cc {
61 namespace {
63 const SchedulerStateMachine::BeginImplFrameState all_begin_impl_frame_states[] =
64 {SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE,
65 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
66 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
67 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE, };
69 const SchedulerStateMachine::CommitState all_commit_states[] = {
70 SchedulerStateMachine::COMMIT_STATE_IDLE,
71 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
72 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED,
73 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
74 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION,
75 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW};
77 // Exposes the protected state fields of the SchedulerStateMachine for testing
78 class StateMachine : public SchedulerStateMachine {
79 public:
80 explicit StateMachine(const SchedulerSettings& scheduler_settings)
81 : SchedulerStateMachine(scheduler_settings) {}
83 void CreateAndInitializeOutputSurfaceWithActivatedCommit() {
84 DidCreateAndInitializeOutputSurface();
85 output_surface_state_ = OUTPUT_SURFACE_ACTIVE;
88 void SetCommitState(CommitState cs) { commit_state_ = cs; }
89 CommitState CommitState() const { return commit_state_; }
91 ForcedRedrawOnTimeoutState ForcedRedrawState() const {
92 return forced_redraw_state_;
95 void SetBeginImplFrameState(BeginImplFrameState bifs) {
96 begin_impl_frame_state_ = bifs;
99 BeginImplFrameState begin_impl_frame_state() const {
100 return begin_impl_frame_state_;
103 OutputSurfaceState output_surface_state() const {
104 return output_surface_state_;
107 bool NeedsCommit() const { return needs_commit_; }
109 void SetNeedsRedraw(bool b) { needs_redraw_ = b; }
111 void SetNeedsForcedRedrawForTimeout(bool b) {
112 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_COMMIT;
113 active_tree_needs_first_draw_ = true;
115 bool NeedsForcedRedrawForTimeout() const {
116 return forced_redraw_state_ != FORCED_REDRAW_STATE_IDLE;
119 void SetActiveTreeNeedsFirstDraw(bool needs_first_draw) {
120 active_tree_needs_first_draw_ = needs_first_draw;
123 bool CanDraw() const { return can_draw_; }
124 bool Visible() const { return visible_; }
126 bool PendingActivationsShouldBeForced() const {
127 return SchedulerStateMachine::PendingActivationsShouldBeForced();
130 void SetHasPendingTree(bool has_pending_tree) {
131 has_pending_tree_ = has_pending_tree;
134 using SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately;
137 TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) {
138 SchedulerSettings default_scheduler_settings;
140 // If no commit needed, do nothing.
142 StateMachine state(default_scheduler_settings);
143 state.SetCanStart();
144 EXPECT_ACTION_UPDATE_STATE(
145 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION)
146 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
147 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
148 state.SetNeedsRedraw(false);
149 state.SetVisible(true);
151 EXPECT_FALSE(state.BeginFrameNeeded());
153 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
154 EXPECT_FALSE(state.BeginFrameNeeded());
155 state.OnBeginImplFrame();
157 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
158 state.OnBeginImplFrameDeadline();
161 // If commit requested but can_start is still false, do nothing.
163 StateMachine state(default_scheduler_settings);
164 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
165 state.SetNeedsRedraw(false);
166 state.SetVisible(true);
167 state.SetNeedsCommit();
169 EXPECT_FALSE(state.BeginFrameNeeded());
171 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
172 EXPECT_FALSE(state.BeginFrameNeeded());
173 state.OnBeginImplFrame();
174 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
175 state.OnBeginImplFrameDeadline();
178 // If commit requested, begin a main frame.
180 StateMachine state(default_scheduler_settings);
181 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
182 state.SetCanStart();
183 state.UpdateState(state.NextAction());
184 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
185 state.SetNeedsRedraw(false);
186 state.SetVisible(true);
187 state.SetNeedsCommit();
189 EXPECT_TRUE(state.BeginFrameNeeded());
191 state.OnBeginImplFrame();
192 EXPECT_ACTION_UPDATE_STATE(
193 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
196 // Begin the frame, make sure needs_commit and commit_state update correctly.
198 StateMachine state(default_scheduler_settings);
199 state.SetCanStart();
200 state.UpdateState(state.NextAction());
201 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
202 state.SetVisible(true);
203 state.UpdateState(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
204 EXPECT_COMMIT_STATE(
205 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
206 EXPECT_FALSE(state.NeedsCommit());
210 // Explicitly test main_frame_before_activation_enabled = true
211 TEST(SchedulerStateMachineTest, MainFrameBeforeActivationEnabled) {
212 SchedulerSettings scheduler_settings;
213 scheduler_settings.impl_side_painting = true;
214 scheduler_settings.main_frame_before_activation_enabled = true;
215 StateMachine state(scheduler_settings);
216 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
217 SET_UP_STATE(state)
218 state.SetNeedsRedraw(false);
219 state.SetNeedsCommit();
221 EXPECT_TRUE(state.BeginFrameNeeded());
223 // Commit to the pending tree.
224 state.OnBeginImplFrame();
225 EXPECT_ACTION_UPDATE_STATE(
226 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
227 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
229 state.NotifyBeginMainFrameStarted();
230 state.NotifyReadyToCommit();
231 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
232 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
233 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
235 state.OnBeginImplFrameDeadline();
236 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
238 // Verify that the next commit starts while there is still a pending tree.
239 state.SetNeedsCommit();
240 state.OnBeginImplFrame();
241 EXPECT_ACTION_UPDATE_STATE(
242 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
243 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
245 // Verify the pending commit doesn't overwrite the pending
246 // tree until the pending tree has been activated.
247 state.NotifyBeginMainFrameStarted();
248 state.NotifyReadyToCommit();
249 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
251 // Verify NotifyReadyToActivate unblocks activation, draw, and
252 // commit in that order.
253 state.NotifyReadyToActivate();
254 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
255 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
257 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
258 state.OnBeginImplFrameDeadline();
259 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
260 EXPECT_ACTION_UPDATE_STATE(
261 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
262 state.DidSwapBuffers();
263 state.DidSwapBuffersComplete();
264 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
265 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
266 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
269 TEST(SchedulerStateMachineTest,
270 TestFailedDrawForAnimationCheckerboardSetsNeedsCommitAndDoesNotDrawAgain) {
271 SchedulerSettings default_scheduler_settings;
272 StateMachine state(default_scheduler_settings);
273 SET_UP_STATE(state)
274 state.SetNeedsRedraw(true);
275 EXPECT_TRUE(state.RedrawPending());
276 EXPECT_TRUE(state.BeginFrameNeeded());
277 state.OnBeginImplFrame();
278 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
279 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
280 state.OnBeginImplFrameDeadline();
282 // We're drawing now.
283 EXPECT_ACTION_UPDATE_STATE(
284 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
285 state.DidSwapBuffers();
286 state.DidSwapBuffersComplete();
287 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
289 EXPECT_FALSE(state.RedrawPending());
290 EXPECT_FALSE(state.CommitPending());
292 // Failing the draw makes us require a commit.
293 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
294 state.OnBeginImplFrame();
295 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
296 EXPECT_ACTION_UPDATE_STATE(
297 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
298 EXPECT_TRUE(state.RedrawPending());
299 EXPECT_TRUE(state.CommitPending());
302 TEST(SchedulerStateMachineTest, TestFailedDrawForMissingHighResNeedsCommit) {
303 SchedulerSettings default_scheduler_settings;
304 StateMachine state(default_scheduler_settings);
305 SET_UP_STATE(state)
306 state.SetNeedsRedraw(true);
307 EXPECT_TRUE(state.RedrawPending());
308 EXPECT_TRUE(state.BeginFrameNeeded());
310 state.OnBeginImplFrame();
311 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
312 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
313 state.OnBeginImplFrameDeadline();
314 EXPECT_ACTION_UPDATE_STATE(
315 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
316 state.DidSwapBuffers();
317 state.DidSwapBuffersComplete();
318 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
319 EXPECT_FALSE(state.RedrawPending());
320 EXPECT_FALSE(state.CommitPending());
322 // Missing high res content requires a commit (but not a redraw)
323 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT);
324 state.OnBeginImplFrame();
325 EXPECT_ACTION_UPDATE_STATE(
326 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
327 EXPECT_FALSE(state.RedrawPending());
328 EXPECT_TRUE(state.CommitPending());
331 TEST(SchedulerStateMachineTest,
332 TestsetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw) {
333 SchedulerSettings default_scheduler_settings;
334 StateMachine state(default_scheduler_settings);
335 SET_UP_STATE(state)
336 state.SetNeedsRedraw(true);
337 EXPECT_TRUE(state.RedrawPending());
338 EXPECT_TRUE(state.BeginFrameNeeded());
339 state.OnBeginImplFrame();
340 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
341 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
342 state.OnBeginImplFrameDeadline();
344 // We're drawing now.
345 EXPECT_ACTION_UPDATE_STATE(
346 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
347 state.DidSwapBuffers();
348 state.DidSwapBuffersComplete();
349 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
350 EXPECT_FALSE(state.RedrawPending());
351 EXPECT_FALSE(state.CommitPending());
353 // While still in the same BeginMainFrame callback on the main thread,
354 // set needs redraw again. This should not redraw.
355 state.SetNeedsRedraw(true);
356 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
358 // Failing the draw for animation checkerboards makes us require a commit.
359 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
360 state.OnBeginImplFrame();
361 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
362 EXPECT_ACTION_UPDATE_STATE(
363 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
364 EXPECT_TRUE(state.RedrawPending());
367 TEST(SchedulerStateMachineTest,
368 TestFailedDrawsEventuallyForceDrawAfterNextCommit) {
369 SchedulerSettings scheduler_settings;
370 scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ = 1;
371 StateMachine state(scheduler_settings);
372 SET_UP_STATE(state)
374 // Start a commit.
375 state.SetNeedsCommit();
376 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
377 state.OnBeginImplFrame();
378 EXPECT_ACTION_UPDATE_STATE(
379 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
380 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
381 EXPECT_TRUE(state.CommitPending());
383 // Then initiate a draw.
384 state.SetNeedsRedraw(true);
385 state.OnBeginImplFrameDeadline();
386 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
387 EXPECT_ACTION_UPDATE_STATE(
388 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
390 // Fail the draw.
391 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
392 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
393 EXPECT_TRUE(state.BeginFrameNeeded());
394 EXPECT_TRUE(state.RedrawPending());
395 // But the commit is ongoing.
396 EXPECT_TRUE(state.CommitPending());
398 // Finish the commit. Note, we should not yet be forcing a draw, but should
399 // continue the commit as usual.
400 state.NotifyBeginMainFrameStarted();
401 state.NotifyReadyToCommit();
402 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
403 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
404 EXPECT_TRUE(state.RedrawPending());
406 // The redraw should be forced at the end of the next BeginImplFrame.
407 state.OnBeginImplFrame();
408 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
409 EXPECT_ACTION_UPDATE_STATE(
410 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
411 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
412 state.OnBeginImplFrameDeadline();
413 EXPECT_ACTION_UPDATE_STATE(
414 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED);
415 state.DidSwapBuffers();
416 state.DidSwapBuffersComplete();
419 TEST(SchedulerStateMachineTest, TestFailedDrawsDoNotRestartForcedDraw) {
420 SchedulerSettings scheduler_settings;
421 int draw_limit = 1;
422 scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ =
423 draw_limit;
424 scheduler_settings.impl_side_painting = true;
425 StateMachine state(scheduler_settings);
426 SET_UP_STATE(state)
428 // Start a commit.
429 state.SetNeedsCommit();
430 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
431 state.OnBeginImplFrame();
432 EXPECT_ACTION_UPDATE_STATE(
433 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
434 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
435 EXPECT_TRUE(state.CommitPending());
437 // Then initiate a draw.
438 state.SetNeedsRedraw(true);
439 state.OnBeginImplFrameDeadline();
440 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
441 EXPECT_ACTION_UPDATE_STATE(
442 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
444 // Fail the draw enough times to force a redraw,
445 // then once more for good measure.
446 for (int i = 0; i < draw_limit + 1; ++i)
447 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
448 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
449 EXPECT_TRUE(state.BeginFrameNeeded());
450 EXPECT_TRUE(state.RedrawPending());
451 // But the commit is ongoing.
452 EXPECT_TRUE(state.CommitPending());
453 EXPECT_TRUE(state.ForcedRedrawState() ==
454 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_COMMIT);
456 state.NotifyBeginMainFrameStarted();
457 state.NotifyReadyToCommit();
458 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
459 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
460 EXPECT_TRUE(state.RedrawPending());
461 EXPECT_FALSE(state.CommitPending());
463 // Now force redraw should be in waiting for activation
464 EXPECT_TRUE(state.ForcedRedrawState() ==
465 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION);
467 // After failing additional draws, we should still be in a forced
468 // redraw, but not back in WAITING_FOR_COMMIT.
469 for (int i = 0; i < draw_limit + 1; ++i)
470 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
471 EXPECT_TRUE(state.RedrawPending());
472 EXPECT_TRUE(state.ForcedRedrawState() ==
473 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION);
476 TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedInNextBeginImplFrame) {
477 SchedulerSettings default_scheduler_settings;
478 StateMachine state(default_scheduler_settings);
479 SET_UP_STATE(state)
481 // Start a draw.
482 state.SetNeedsRedraw(true);
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();
488 EXPECT_TRUE(state.RedrawPending());
489 EXPECT_ACTION_UPDATE_STATE(
490 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
492 // Failing the draw for animation checkerboards makes us require a commit.
493 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
494 EXPECT_ACTION_UPDATE_STATE(
495 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
496 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
497 EXPECT_TRUE(state.RedrawPending());
499 // We should not be trying to draw again now, but we have a commit pending.
500 EXPECT_TRUE(state.BeginFrameNeeded());
501 state.OnBeginImplFrame();
502 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
503 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
505 // We should try to draw again at the end of the next BeginImplFrame on
506 // the impl thread.
507 state.OnBeginImplFrameDeadline();
508 EXPECT_ACTION_UPDATE_STATE(
509 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
510 state.DidSwapBuffers();
511 state.DidSwapBuffersComplete();
512 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
515 TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) {
516 SchedulerSettings default_scheduler_settings;
517 StateMachine state(default_scheduler_settings);
518 SET_UP_STATE(state)
519 state.SetNeedsRedraw(true);
521 // Draw the first frame.
522 EXPECT_TRUE(state.BeginFrameNeeded());
523 state.OnBeginImplFrame();
524 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
525 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
527 state.OnBeginImplFrameDeadline();
528 EXPECT_ACTION_UPDATE_STATE(
529 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
530 state.DidSwapBuffers();
531 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
532 state.DidSwapBuffersComplete();
533 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
535 // Before the next BeginImplFrame, set needs redraw again.
536 // This should not redraw until the next BeginImplFrame.
537 state.SetNeedsRedraw(true);
538 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
540 // Move to another frame. This should now draw.
541 EXPECT_TRUE(state.BeginFrameNeeded());
542 state.OnBeginImplFrame();
544 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
545 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
547 state.OnBeginImplFrameDeadline();
548 EXPECT_ACTION_UPDATE_STATE(
549 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
550 state.DidSwapBuffers();
551 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
552 state.DidSwapBuffersComplete();
553 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
555 // We just swapped, so we should proactively request another BeginImplFrame.
556 EXPECT_TRUE(state.BeginFrameNeeded());
559 TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) {
560 SchedulerSettings default_scheduler_settings;
562 // When not in BeginImplFrame deadline, or in BeginImplFrame deadline
563 // but not visible, don't draw.
564 size_t num_commit_states =
565 sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState);
566 size_t num_begin_impl_frame_states =
567 sizeof(all_begin_impl_frame_states) /
568 sizeof(SchedulerStateMachine::BeginImplFrameState);
569 for (size_t i = 0; i < num_commit_states; ++i) {
570 for (size_t j = 0; j < num_begin_impl_frame_states; ++j) {
571 StateMachine state(default_scheduler_settings);
572 state.SetCanStart();
573 state.UpdateState(state.NextAction());
574 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
575 state.SetCommitState(all_commit_states[i]);
576 state.SetBeginImplFrameState(all_begin_impl_frame_states[j]);
577 bool visible =
578 (all_begin_impl_frame_states[j] !=
579 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
580 state.SetVisible(visible);
582 // Case 1: needs_commit=false
583 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
584 state.NextAction());
586 // Case 2: needs_commit=true
587 state.SetNeedsCommit();
588 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
589 state.NextAction())
590 << state.AsValue()->ToString();
594 // When in BeginImplFrame deadline we should always draw for SetNeedsRedraw
595 // except if we're ready to commit, in which case we expect a commit first.
596 for (size_t i = 0; i < num_commit_states; ++i) {
597 StateMachine state(default_scheduler_settings);
598 state.SetCanStart();
599 state.UpdateState(state.NextAction());
600 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
601 state.SetCanDraw(true);
602 state.SetCommitState(all_commit_states[i]);
603 state.SetBeginImplFrameState(
604 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
606 state.SetNeedsRedraw(true);
607 state.SetVisible(true);
609 SchedulerStateMachine::Action expected_action;
610 if (all_commit_states[i] ==
611 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT) {
612 expected_action = SchedulerStateMachine::ACTION_COMMIT;
613 } else {
614 expected_action = SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
615 EXPECT_ACTION(SchedulerStateMachine::ACTION_ANIMATE);
616 state.UpdateState(state.NextAction());
619 // Case 1: needs_commit=false.
620 EXPECT_ACTION(expected_action);
622 // Case 2: needs_commit=true.
623 state.SetNeedsCommit();
624 EXPECT_ACTION(expected_action);
628 TEST(SchedulerStateMachineTest, TestNoCommitStatesRedrawWhenInvisible) {
629 SchedulerSettings default_scheduler_settings;
631 size_t num_commit_states =
632 sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState);
633 for (size_t i = 0; i < num_commit_states; ++i) {
634 // There shouldn't be any drawing regardless of BeginImplFrame.
635 for (size_t j = 0; j < 2; ++j) {
636 StateMachine state(default_scheduler_settings);
637 state.SetCanStart();
638 state.UpdateState(state.NextAction());
639 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
640 state.SetCommitState(all_commit_states[i]);
641 state.SetVisible(false);
642 state.SetNeedsRedraw(true);
643 if (j == 1) {
644 state.SetBeginImplFrameState(
645 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
648 // Case 1: needs_commit=false.
649 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
650 state.NextAction());
652 // Case 2: needs_commit=true.
653 state.SetNeedsCommit();
654 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
655 state.NextAction())
656 << state.AsValue()->ToString();
661 TEST(SchedulerStateMachineTest, TestCanRedraw_StopsDraw) {
662 SchedulerSettings default_scheduler_settings;
664 size_t num_commit_states =
665 sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState);
666 for (size_t i = 0; i < num_commit_states; ++i) {
667 // There shouldn't be any drawing regardless of BeginImplFrame.
668 for (size_t j = 0; j < 2; ++j) {
669 StateMachine state(default_scheduler_settings);
670 state.SetCanStart();
671 state.UpdateState(state.NextAction());
672 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
673 state.SetCommitState(all_commit_states[i]);
674 state.SetVisible(false);
675 state.SetNeedsRedraw(true);
676 if (j == 1)
677 state.OnBeginImplFrame();
679 state.SetCanDraw(false);
680 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
681 state.NextAction());
686 TEST(SchedulerStateMachineTest,
687 TestCanRedrawWithWaitingForFirstDrawMakesProgress) {
688 SchedulerSettings default_scheduler_settings;
689 StateMachine state(default_scheduler_settings);
690 state.SetCanStart();
691 state.UpdateState(state.NextAction());
692 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
694 state.SetActiveTreeNeedsFirstDraw(true);
695 state.SetNeedsCommit();
696 state.SetNeedsRedraw(true);
697 state.SetVisible(true);
698 state.SetCanDraw(false);
699 state.OnBeginImplFrame();
700 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
701 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
702 EXPECT_ACTION_UPDATE_STATE(
703 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
704 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
705 state.NotifyBeginMainFrameStarted();
706 state.NotifyReadyToCommit();
707 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
708 state.OnBeginImplFrameDeadline();
709 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
710 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
711 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
714 TEST(SchedulerStateMachineTest, TestSetNeedsCommitIsNotLost) {
715 SchedulerSettings scheduler_settings;
716 StateMachine state(scheduler_settings);
717 SET_UP_STATE(state)
718 state.SetNeedsCommit();
720 EXPECT_TRUE(state.BeginFrameNeeded());
722 // Begin the frame.
723 state.OnBeginImplFrame();
724 EXPECT_ACTION_UPDATE_STATE(
725 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
726 EXPECT_COMMIT_STATE(
727 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
729 // Now, while the frame is in progress, set another commit.
730 state.SetNeedsCommit();
731 EXPECT_TRUE(state.NeedsCommit());
733 // Let the frame finish.
734 state.NotifyBeginMainFrameStarted();
735 state.NotifyReadyToCommit();
736 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
738 // Expect to commit regardless of BeginImplFrame state.
739 EXPECT_IMPL_FRAME_STATE(
740 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING);
741 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
743 state.OnBeginImplFrameDeadlinePending();
744 EXPECT_IMPL_FRAME_STATE(
745 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME);
746 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
748 state.OnBeginImplFrameDeadline();
749 EXPECT_IMPL_FRAME_STATE(
750 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
751 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
753 state.OnBeginImplFrameIdle();
754 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
755 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
757 state.OnBeginImplFrame();
758 EXPECT_IMPL_FRAME_STATE(
759 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING);
760 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
762 // Finish the commit, then make sure we start the next commit immediately
763 // and draw on the next BeginImplFrame.
764 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
765 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
766 EXPECT_ACTION_UPDATE_STATE(
767 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
768 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
770 state.OnBeginImplFrameDeadline();
772 EXPECT_TRUE(state.active_tree_needs_first_draw());
773 EXPECT_ACTION_UPDATE_STATE(
774 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
775 state.DidSwapBuffers();
776 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
777 state.DidSwapBuffersComplete();
778 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
781 TEST(SchedulerStateMachineTest, TestFullCycle) {
782 SchedulerSettings default_scheduler_settings;
783 StateMachine state(default_scheduler_settings);
784 SET_UP_STATE(state)
786 // Start clean and set commit.
787 state.SetNeedsCommit();
789 // Begin the frame.
790 state.OnBeginImplFrame();
791 EXPECT_ACTION_UPDATE_STATE(
792 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
793 EXPECT_COMMIT_STATE(
794 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
795 EXPECT_FALSE(state.NeedsCommit());
796 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
798 // Tell the scheduler the frame finished.
799 state.NotifyBeginMainFrameStarted();
800 state.NotifyReadyToCommit();
801 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
803 // Commit.
804 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
805 EXPECT_TRUE(state.active_tree_needs_first_draw());
806 EXPECT_TRUE(state.needs_redraw());
808 // Expect to do nothing until BeginImplFrame deadline
809 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
811 // At BeginImplFrame deadline, draw.
812 state.OnBeginImplFrameDeadline();
813 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
814 EXPECT_ACTION_UPDATE_STATE(
815 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
816 state.DidSwapBuffers();
817 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
818 state.DidSwapBuffersComplete();
820 // Should be synchronized, no draw needed, no action needed.
821 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
822 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
823 EXPECT_FALSE(state.needs_redraw());
826 TEST(SchedulerStateMachineTest, TestFullCycleWithMainThreadLowLatencyMode) {
827 SchedulerSettings scheduler_settings;
828 scheduler_settings.main_thread_should_always_be_low_latency = true;
829 StateMachine state(scheduler_settings);
830 SET_UP_STATE(state)
832 // Start clean and set commit.
833 state.SetNeedsCommit();
835 // Begin the frame.
836 state.OnBeginImplFrame();
837 EXPECT_ACTION_UPDATE_STATE(
838 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
839 EXPECT_COMMIT_STATE(
840 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
841 EXPECT_FALSE(state.NeedsCommit());
842 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
844 // Tell the scheduler the frame finished.
845 state.NotifyBeginMainFrameStarted();
846 state.NotifyReadyToCommit();
847 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
849 // Commit.
850 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
851 EXPECT_TRUE(state.active_tree_needs_first_draw());
852 EXPECT_TRUE(state.needs_redraw());
854 // Now commit should wait for draw.
855 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW);
857 // Swap throttled. Do not draw.
858 state.DidSwapBuffers();
859 state.OnBeginImplFrameDeadline();
860 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
861 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
862 state.DidSwapBuffersComplete();
864 // Haven't draw since last commit, do not begin new main frame.
865 state.SetNeedsCommit();
866 state.OnBeginImplFrame();
867 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
868 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
870 // At BeginImplFrame deadline, draw.
871 state.OnBeginImplFrameDeadline();
872 EXPECT_ACTION_UPDATE_STATE(
873 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
874 state.DidSwapBuffers();
875 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
876 state.DidSwapBuffersComplete();
878 // Now will be able to start main frame.
879 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
880 EXPECT_FALSE(state.needs_redraw());
881 EXPECT_ACTION_UPDATE_STATE(
882 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
885 TEST(SchedulerStateMachineTest,
886 TestFullCycleWithMainThreadLowLatencyMode_ImplSidePaint) {
887 SchedulerSettings scheduler_settings;
888 scheduler_settings.main_thread_should_always_be_low_latency = true;
889 scheduler_settings.impl_side_painting = true;
890 StateMachine state(scheduler_settings);
891 SET_UP_STATE(state)
893 // Start clean and set commit.
894 state.SetNeedsCommit();
896 // Begin the frame.
897 state.OnBeginImplFrame();
898 EXPECT_ACTION_UPDATE_STATE(
899 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
900 EXPECT_COMMIT_STATE(
901 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
902 EXPECT_FALSE(state.NeedsCommit());
903 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
905 // Tell the scheduler the frame finished.
906 state.NotifyBeginMainFrameStarted();
907 state.NotifyReadyToCommit();
908 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
910 // Commit.
911 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
913 // Now commit should wait for activation.
914 EXPECT_COMMIT_STATE(
915 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION);
917 // No activation yet, so this commit is not drawn yet. Force to draw this
918 // frame, and still block BeginMainFrame.
919 state.SetNeedsRedraw(true);
920 state.SetNeedsCommit();
921 state.OnBeginImplFrameDeadline();
922 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
923 EXPECT_ACTION_UPDATE_STATE(
924 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
925 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
927 // Cannot BeginMainFrame yet since last commit is not yet activated and drawn.
928 state.OnBeginImplFrame();
929 EXPECT_COMMIT_STATE(
930 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION);
931 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
933 // Now activate sync tree.
934 state.NotifyReadyToActivate();
935 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
936 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
937 EXPECT_TRUE(state.active_tree_needs_first_draw());
938 EXPECT_TRUE(state.needs_redraw());
939 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW);
941 // Swap throttled. Do not draw.
942 state.DidSwapBuffers();
943 state.OnBeginImplFrameDeadline();
944 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
945 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
946 state.DidSwapBuffersComplete();
948 // Haven't draw since last commit, do not begin new main frame.
949 state.OnBeginImplFrame();
950 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
951 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
953 // At BeginImplFrame deadline, draw. This draws unblocks BeginMainFrame.
954 state.OnBeginImplFrameDeadline();
955 EXPECT_ACTION_UPDATE_STATE(
956 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
957 state.DidSwapBuffers();
958 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
959 state.DidSwapBuffersComplete();
961 // Now will be able to start main frame.
962 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
963 EXPECT_FALSE(state.needs_redraw());
964 EXPECT_ACTION_UPDATE_STATE(
965 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
968 TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween) {
969 SchedulerSettings default_scheduler_settings;
970 StateMachine state(default_scheduler_settings);
971 SET_UP_STATE(state)
973 // Start clean and set commit.
974 state.SetNeedsCommit();
976 // Begin the frame.
977 state.OnBeginImplFrame();
978 EXPECT_ACTION_UPDATE_STATE(
979 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
980 EXPECT_COMMIT_STATE(
981 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
982 EXPECT_FALSE(state.NeedsCommit());
983 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
985 // Request another commit while the commit is in flight.
986 state.SetNeedsCommit();
987 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
989 // Tell the scheduler the frame finished.
990 state.NotifyBeginMainFrameStarted();
991 state.NotifyReadyToCommit();
992 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
994 // First commit.
995 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
996 EXPECT_TRUE(state.active_tree_needs_first_draw());
997 EXPECT_TRUE(state.needs_redraw());
999 // Expect to do nothing until BeginImplFrame deadline.
1000 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1002 // At BeginImplFrame deadline, draw.
1003 state.OnBeginImplFrameDeadline();
1004 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1005 EXPECT_ACTION_UPDATE_STATE(
1006 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1007 state.DidSwapBuffers();
1008 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
1009 state.DidSwapBuffersComplete();
1011 // Should be synchronized, no draw needed, no action needed.
1012 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1013 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
1014 EXPECT_FALSE(state.needs_redraw());
1016 // Next BeginImplFrame should initiate second commit.
1017 state.OnBeginImplFrame();
1018 EXPECT_ACTION_UPDATE_STATE(
1019 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1022 TEST(SchedulerStateMachineTest, TestRequestCommitInvisible) {
1023 SchedulerSettings default_scheduler_settings;
1024 StateMachine state(default_scheduler_settings);
1025 state.SetCanStart();
1026 state.UpdateState(state.NextAction());
1027 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1028 state.SetNeedsCommit();
1029 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1032 // See ThreadProxy::BeginMainFrame "EarlyOut_NotVisible" /
1033 // "EarlyOut_OutputSurfaceLost" cases.
1034 TEST(SchedulerStateMachineTest, TestAbortBeginMainFrameBecauseInvisible) {
1035 SchedulerSettings default_scheduler_settings;
1036 StateMachine state(default_scheduler_settings);
1037 SET_UP_STATE(state)
1039 // Start clean and set commit.
1040 state.SetNeedsCommit();
1042 // Begin the frame while visible.
1043 state.OnBeginImplFrame();
1044 EXPECT_ACTION_UPDATE_STATE(
1045 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1046 EXPECT_COMMIT_STATE(
1047 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
1048 EXPECT_FALSE(state.NeedsCommit());
1049 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1051 // Become invisible and abort BeginMainFrame.
1052 state.SetVisible(false);
1053 state.BeginMainFrameAborted(CommitEarlyOutReason::ABORTED_NOT_VISIBLE);
1055 // NeedsCommit should now be true again because we never actually did a
1056 // commit.
1057 EXPECT_TRUE(state.NeedsCommit());
1059 // We should now be back in the idle state as if we never started the frame.
1060 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
1061 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1063 // We shouldn't do anything on the BeginImplFrame deadline.
1064 state.OnBeginImplFrameDeadline();
1065 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1067 // Become visible again.
1068 state.SetVisible(true);
1070 // Although we have aborted on this frame and haven't cancelled the commit
1071 // (i.e. need another), don't send another BeginMainFrame yet.
1072 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
1073 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1074 EXPECT_TRUE(state.NeedsCommit());
1076 // Start a new frame.
1077 state.OnBeginImplFrame();
1078 EXPECT_ACTION_UPDATE_STATE(
1079 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1081 // We should be starting the commit now.
1082 EXPECT_COMMIT_STATE(
1083 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
1084 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1087 // See ThreadProxy::BeginMainFrame "EarlyOut_NoUpdates" case.
1088 TEST(SchedulerStateMachineTest, TestAbortBeginMainFrameBecauseCommitNotNeeded) {
1089 SchedulerSettings default_scheduler_settings;
1090 StateMachine state(default_scheduler_settings);
1091 state.SetCanStart();
1092 state.UpdateState(state.NextAction());
1093 state.DidCreateAndInitializeOutputSurface();
1094 state.SetVisible(true);
1095 state.SetCanDraw(true);
1097 // Get into a begin frame / commit state.
1098 state.SetNeedsCommit();
1099 state.OnBeginImplFrame();
1100 EXPECT_ACTION_UPDATE_STATE(
1101 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1102 EXPECT_COMMIT_STATE(
1103 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
1104 EXPECT_FALSE(state.NeedsCommit());
1105 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1107 // Abort the commit, true means that the BeginMainFrame was sent but there
1108 // was no work to do on the main thread.
1109 state.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES);
1111 // NeedsCommit should now be false because the commit was actually handled.
1112 EXPECT_FALSE(state.NeedsCommit());
1114 // Even though the commit was aborted, we still expect to draw the new frame.
1115 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1116 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1117 state.OnBeginImplFrameDeadline();
1118 EXPECT_ACTION_UPDATE_STATE(
1119 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1120 state.DidSwapBuffers();
1121 state.DidSwapBuffersComplete();
1122 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1124 // Verify another commit doesn't start on another frame either.
1125 EXPECT_FALSE(state.NeedsCommit());
1126 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
1128 state.OnBeginImplFrame();
1129 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1130 state.OnBeginImplFrameDeadline();
1131 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1133 // Verify another commit can start if requested, though.
1134 state.SetNeedsCommit();
1135 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
1136 state.OnBeginImplFrame();
1137 EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1140 TEST(SchedulerStateMachineTest, TestFirstContextCreation) {
1141 SchedulerSettings default_scheduler_settings;
1142 StateMachine state(default_scheduler_settings);
1143 state.SetCanStart();
1144 state.SetVisible(true);
1145 state.SetCanDraw(true);
1147 EXPECT_ACTION_UPDATE_STATE(
1148 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1149 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1150 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1152 // Check that the first init does not SetNeedsCommit.
1153 state.OnBeginImplFrame();
1154 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1155 state.OnBeginImplFrameDeadline();
1156 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1158 // Check that a needs commit initiates a BeginMainFrame.
1159 state.SetNeedsCommit();
1160 state.OnBeginImplFrame();
1161 EXPECT_ACTION_UPDATE_STATE(
1162 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1165 TEST(SchedulerStateMachineTest, TestContextLostWhenCompletelyIdle) {
1166 SchedulerSettings default_scheduler_settings;
1167 StateMachine state(default_scheduler_settings);
1168 SET_UP_STATE(state)
1170 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1171 state.NextAction());
1172 state.DidLoseOutputSurface();
1174 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1175 state.UpdateState(state.NextAction());
1177 // Once context recreation begins, nothing should happen.
1178 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1180 // Recreate the context.
1181 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1183 // When the context is recreated, we should begin a commit.
1184 state.OnBeginImplFrame();
1185 EXPECT_ACTION_UPDATE_STATE(
1186 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1189 TEST(SchedulerStateMachineTest,
1190 TestContextLostWhenIdleAndCommitRequestedWhileRecreating) {
1191 SchedulerSettings default_scheduler_settings;
1192 // We use impl side painting because it's the more complicated version.
1193 default_scheduler_settings.impl_side_painting = true;
1194 StateMachine state(default_scheduler_settings);
1195 SET_UP_STATE(state)
1197 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1198 state.NextAction());
1199 state.DidLoseOutputSurface();
1200 EXPECT_EQ(state.output_surface_state(),
1201 SchedulerStateMachine::OUTPUT_SURFACE_LOST);
1203 EXPECT_ACTION_UPDATE_STATE(
1204 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1205 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1207 // Once context recreation begins, nothing should happen.
1208 state.OnBeginImplFrame();
1209 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1210 state.OnBeginImplFrameDeadline();
1211 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1213 // While context is recreating, commits shouldn't begin.
1214 state.SetNeedsCommit();
1215 state.OnBeginImplFrame();
1216 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1217 state.OnBeginImplFrameDeadline();
1218 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1220 // Recreate the context
1221 state.DidCreateAndInitializeOutputSurface();
1222 EXPECT_EQ(state.output_surface_state(),
1223 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT);
1224 EXPECT_FALSE(state.RedrawPending());
1226 // When the context is recreated, we wait until the next BeginImplFrame
1227 // before starting.
1228 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1230 // When the BeginFrame comes in we should begin a commit
1231 state.OnBeginImplFrame();
1232 EXPECT_ACTION_UPDATE_STATE(
1233 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1234 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1235 EXPECT_COMMIT_STATE(
1236 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
1238 // Until that commit finishes, we shouldn't be drawing or animate.
1239 state.OnBeginImplFrameDeadline();
1240 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1242 // Finish the commit, which should make the surface active.
1243 state.NotifyBeginMainFrameStarted();
1244 state.NotifyReadyToCommit();
1245 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1246 EXPECT_EQ(state.output_surface_state(),
1247 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION);
1248 state.NotifyReadyToActivate();
1249 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1250 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1251 EXPECT_EQ(state.output_surface_state(),
1252 SchedulerStateMachine::OUTPUT_SURFACE_ACTIVE);
1254 // Finishing the first commit after initializing an output surface should
1255 // automatically cause a redraw.
1256 EXPECT_TRUE(state.RedrawPending());
1257 state.OnBeginImplFrame();
1258 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1259 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1260 state.OnBeginImplFrameDeadline();
1261 EXPECT_ACTION_UPDATE_STATE(
1262 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1263 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1264 EXPECT_FALSE(state.RedrawPending());
1266 // Next frame as no work to do.
1267 state.OnBeginImplFrame();
1268 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1269 state.OnBeginImplFrameDeadline();
1270 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1272 // Once the context is recreated, whether we draw should be based on
1273 // SetCanDraw if waiting on first draw after activate.
1274 state.SetNeedsRedraw(true);
1275 state.OnBeginImplFrame();
1276 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1277 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1278 state.OnBeginImplFrameDeadline();
1279 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1280 state.SetCanDraw(false);
1281 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1282 state.SetCanDraw(true);
1283 EXPECT_ACTION_UPDATE_STATE(
1284 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1285 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1287 // Once the context is recreated, whether we draw should be based on
1288 // SetCanDraw if waiting on first draw after activate.
1289 state.SetNeedsRedraw(true);
1290 state.SetNeedsCommit();
1291 state.OnBeginImplFrame();
1292 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1293 EXPECT_ACTION_UPDATE_STATE(
1294 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1295 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1296 // Activate so we need the first draw
1297 state.NotifyBeginMainFrameStarted();
1298 state.NotifyReadyToCommit();
1299 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1300 state.NotifyReadyToActivate();
1301 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1302 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1303 EXPECT_TRUE(state.active_tree_needs_first_draw());
1304 EXPECT_TRUE(state.needs_redraw());
1306 state.OnBeginImplFrameDeadline();
1307 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1308 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1309 state.SetCanDraw(false);
1310 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1311 state.SetCanDraw(true);
1312 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1315 TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) {
1316 SchedulerSettings scheduler_settings;
1317 StateMachine state(scheduler_settings);
1318 SET_UP_STATE(state)
1320 // Get a commit in flight.
1321 state.SetNeedsCommit();
1323 // Set damage and expect a draw.
1324 state.SetNeedsRedraw(true);
1325 state.OnBeginImplFrame();
1326 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1327 EXPECT_ACTION_UPDATE_STATE(
1328 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1329 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1330 state.OnBeginImplFrameDeadline();
1331 EXPECT_ACTION_UPDATE_STATE(
1332 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1333 state.DidSwapBuffers();
1334 state.DidSwapBuffersComplete();
1335 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1337 // Cause a lost context while the BeginMainFrame is in flight.
1338 state.DidLoseOutputSurface();
1340 // Ask for another draw. Expect nothing happens.
1341 state.SetNeedsRedraw(true);
1342 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1344 // Finish the frame, and commit.
1345 state.NotifyBeginMainFrameStarted();
1346 state.NotifyReadyToCommit();
1347 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1349 // We will abort the draw when the output surface is lost if we are
1350 // waiting for the first draw to unblock the main thread.
1351 EXPECT_TRUE(state.active_tree_needs_first_draw());
1352 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1354 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1355 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
1356 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1358 state.OnBeginImplFrame();
1359 EXPECT_IMPL_FRAME_STATE(
1360 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING);
1361 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1363 state.OnBeginImplFrameDeadlinePending();
1364 EXPECT_IMPL_FRAME_STATE(
1365 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME);
1366 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1368 state.OnBeginImplFrameDeadline();
1369 EXPECT_IMPL_FRAME_STATE(
1370 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
1371 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1374 TEST(SchedulerStateMachineTest,
1375 TestContextLostWhileCommitInProgressAndAnotherCommitRequested) {
1376 SchedulerSettings scheduler_settings;
1377 StateMachine state(scheduler_settings);
1378 SET_UP_STATE(state)
1380 // Get a commit in flight.
1381 state.SetNeedsCommit();
1382 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1384 // Set damage and expect a draw.
1385 state.SetNeedsRedraw(true);
1386 state.OnBeginImplFrame();
1387 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1388 EXPECT_ACTION_UPDATE_STATE(
1389 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1390 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1391 state.OnBeginImplFrameDeadline();
1392 EXPECT_ACTION_UPDATE_STATE(
1393 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1394 state.DidSwapBuffers();
1395 state.DidSwapBuffersComplete();
1396 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1398 // Cause a lost context while the BeginMainFrame is in flight.
1399 state.DidLoseOutputSurface();
1401 // Ask for another draw and also set needs commit. Expect nothing happens.
1402 state.SetNeedsRedraw(true);
1403 state.SetNeedsCommit();
1404 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1406 // Finish the frame, and commit.
1407 state.NotifyBeginMainFrameStarted();
1408 state.NotifyReadyToCommit();
1409 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1410 EXPECT_TRUE(state.active_tree_needs_first_draw());
1412 // Because the output surface is missing, we expect the draw to abort.
1413 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1415 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1416 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
1417 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1419 state.OnBeginImplFrame();
1420 EXPECT_IMPL_FRAME_STATE(
1421 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING);
1422 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1424 state.OnBeginImplFrameDeadlinePending();
1425 EXPECT_IMPL_FRAME_STATE(
1426 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME);
1427 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1429 state.OnBeginImplFrameDeadline();
1430 EXPECT_IMPL_FRAME_STATE(
1431 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
1432 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1434 state.OnBeginImplFrameIdle();
1435 EXPECT_ACTION_UPDATE_STATE(
1436 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1438 // After we get a new output surface, the commit flow should start.
1439 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1440 state.OnBeginImplFrame();
1441 EXPECT_ACTION_UPDATE_STATE(
1442 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1443 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1444 state.NotifyBeginMainFrameStarted();
1445 state.NotifyReadyToCommit();
1446 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1447 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1448 state.OnBeginImplFrameDeadline();
1449 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1450 EXPECT_ACTION_UPDATE_STATE(
1451 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1452 state.DidSwapBuffers();
1453 state.DidSwapBuffersComplete();
1454 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1457 TEST(SchedulerStateMachineTest, DontDrawBeforeCommitAfterLostOutputSurface) {
1458 SchedulerSettings default_scheduler_settings;
1459 StateMachine state(default_scheduler_settings);
1460 SET_UP_STATE(state)
1462 state.SetNeedsRedraw(true);
1464 // Cause a lost output surface, and restore it.
1465 state.DidLoseOutputSurface();
1466 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1467 state.UpdateState(state.NextAction());
1468 state.DidCreateAndInitializeOutputSurface();
1470 EXPECT_FALSE(state.RedrawPending());
1471 state.OnBeginImplFrame();
1472 EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1475 TEST(SchedulerStateMachineTest,
1476 TestPendingActivationsShouldBeForcedAfterLostOutputSurface) {
1477 SchedulerSettings settings;
1478 settings.impl_side_painting = true;
1479 StateMachine state(settings);
1480 SET_UP_STATE(state)
1482 state.SetCommitState(
1483 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
1485 // Cause a lost context.
1486 state.DidLoseOutputSurface();
1488 state.NotifyBeginMainFrameStarted();
1489 state.NotifyReadyToCommit();
1490 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1492 EXPECT_TRUE(state.PendingActivationsShouldBeForced());
1493 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1495 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1496 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1499 TEST(SchedulerStateMachineTest, TestNoBeginMainFrameWhenInvisible) {
1500 SchedulerSettings default_scheduler_settings;
1501 StateMachine state(default_scheduler_settings);
1502 state.SetCanStart();
1503 state.UpdateState(state.NextAction());
1504 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1505 state.SetVisible(false);
1506 state.SetNeedsCommit();
1507 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1510 TEST(SchedulerStateMachineTest, TestFinishCommitWhenCommitInProgress) {
1511 SchedulerSettings default_scheduler_settings;
1512 StateMachine state(default_scheduler_settings);
1513 state.SetCanStart();
1514 state.UpdateState(state.NextAction());
1515 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1516 state.SetVisible(false);
1517 state.SetCommitState(
1518 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
1519 state.SetNeedsCommit();
1521 state.NotifyBeginMainFrameStarted();
1522 state.NotifyReadyToCommit();
1523 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
1524 state.UpdateState(state.NextAction());
1526 EXPECT_TRUE(state.active_tree_needs_first_draw());
1527 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1530 TEST(SchedulerStateMachineTest, TestInitialActionsWhenContextLost) {
1531 SchedulerSettings default_scheduler_settings;
1532 StateMachine state(default_scheduler_settings);
1533 SET_UP_STATE(state)
1534 state.SetNeedsCommit();
1535 state.DidLoseOutputSurface();
1537 // When we are visible, we normally want to begin output surface creation
1538 // as soon as possible.
1539 EXPECT_ACTION_UPDATE_STATE(
1540 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1542 state.DidCreateAndInitializeOutputSurface();
1543 EXPECT_EQ(state.output_surface_state(),
1544 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT);
1546 // We should not send a BeginMainFrame when we are invisible, even if we've
1547 // lost the output surface and are trying to get the first commit, since the
1548 // main thread will just abort anyway.
1549 state.SetVisible(false);
1550 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1553 TEST(SchedulerStateMachineTest, ReportIfNotDrawing) {
1554 SchedulerSettings default_scheduler_settings;
1555 StateMachine state(default_scheduler_settings);
1556 SET_UP_STATE(state)
1557 EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
1559 state.SetCanDraw(false);
1560 state.SetVisible(true);
1561 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1563 state.SetCanDraw(true);
1564 state.SetVisible(false);
1565 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1567 state.SetCanDraw(false);
1568 state.SetVisible(false);
1569 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1571 state.SetCanDraw(true);
1572 state.SetVisible(true);
1573 EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
1576 TEST(SchedulerStateMachineTest,
1577 TestTriggerDeadlineImmediatelyAfterAbortedCommit) {
1578 SchedulerSettings settings;
1579 settings.impl_side_painting = true;
1580 StateMachine state(settings);
1581 SET_UP_STATE(state)
1583 // This test mirrors what happens during the first frame of a scroll gesture.
1584 // First we get the input event and a BeginFrame.
1585 state.OnBeginImplFrame();
1587 // As a response the compositor requests a redraw and a commit to tell the
1588 // main thread about the new scroll offset.
1589 state.SetNeedsRedraw(true);
1590 state.SetNeedsCommit();
1592 // We should start the commit normally.
1593 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1594 EXPECT_ACTION_UPDATE_STATE(
1595 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1596 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1598 // Since only the scroll offset changed, the main thread will abort the
1599 // commit.
1600 state.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES);
1602 // Since the commit was aborted, we should draw right away instead of waiting
1603 // for the deadline.
1604 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1607 void FinishPreviousCommitAndDrawWithoutExitingDeadline(
1608 StateMachine* state_ptr) {
1609 // Gross, but allows us to use macros below.
1610 StateMachine& state = *state_ptr;
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);
1620 state.OnBeginImplFrame();
1621 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1622 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1624 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1625 state.OnBeginImplFrameDeadline();
1626 EXPECT_ACTION_UPDATE_STATE(
1627 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1628 state.DidSwapBuffers();
1631 TEST(SchedulerStateMachineTest, TestImplLatencyTakesPriority) {
1632 SchedulerSettings settings;
1633 settings.impl_side_painting = true;
1634 StateMachine state(settings);
1635 SET_UP_STATE(state)
1637 // This test ensures that impl-draws are prioritized over main thread updates
1638 // in prefer impl latency mode.
1639 state.SetNeedsRedraw(true);
1640 state.SetNeedsCommit();
1641 state.OnBeginImplFrame();
1642 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1643 EXPECT_ACTION_UPDATE_STATE(
1644 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1645 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1647 // Verify the deadline is not triggered early until we enter
1648 // prefer impl latency mode.
1649 EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1650 state.SetImplLatencyTakesPriority(true);
1651 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1653 // Trigger the deadline.
1654 state.OnBeginImplFrameDeadline();
1655 EXPECT_ACTION_UPDATE_STATE(
1656 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1657 state.DidSwapBuffers();
1658 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1659 state.DidSwapBuffersComplete();
1661 // Request a new commit and finish the previous one.
1662 state.SetNeedsCommit();
1663 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state);
1664 EXPECT_ACTION_UPDATE_STATE(
1665 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1666 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1667 state.DidSwapBuffersComplete();
1668 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1670 // Finish the previous commit and draw it.
1671 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state);
1672 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1674 // Verify we do not send another BeginMainFrame if was are swap throttled
1675 // and did not just swap.
1676 state.SetNeedsCommit();
1677 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1678 state.OnBeginImplFrame();
1679 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1680 EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1681 state.OnBeginImplFrameDeadline();
1682 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1685 TEST(SchedulerStateMachineTest,
1686 TestTriggerDeadlineImmediatelyOnLostOutputSurface) {
1687 SchedulerSettings default_scheduler_settings;
1688 StateMachine state(default_scheduler_settings);
1689 SET_UP_STATE(state)
1691 state.SetNeedsCommit();
1693 state.OnBeginImplFrame();
1694 EXPECT_ACTION_UPDATE_STATE(
1695 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1696 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1697 EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1699 state.DidLoseOutputSurface();
1700 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1701 // The deadline should be triggered immediately when output surface is lost.
1702 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1705 TEST(SchedulerStateMachineTest, TestSetNeedsAnimate) {
1706 SchedulerSettings settings;
1707 settings.impl_side_painting = true;
1708 StateMachine state(settings);
1709 SET_UP_STATE(state)
1711 // Test requesting an animation that, when run, causes us to draw.
1712 state.SetNeedsAnimate();
1713 EXPECT_TRUE(state.BeginFrameNeeded());
1714 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1716 state.OnBeginImplFrame();
1717 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1719 state.OnBeginImplFrameDeadlinePending();
1720 state.OnBeginImplFrameDeadline();
1721 EXPECT_ACTION_UPDATE_STATE(
1722 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1725 TEST(SchedulerStateMachineTest, TestAnimateBeforeCommit) {
1726 SchedulerSettings settings;
1727 settings.impl_side_painting = true;
1728 StateMachine state(settings);
1729 SET_UP_STATE(state)
1731 // Check that animations are updated before we start a commit.
1732 state.SetNeedsAnimate();
1733 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1734 state.SetNeedsCommit();
1735 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1736 EXPECT_TRUE(state.BeginFrameNeeded());
1738 state.OnBeginImplFrame();
1739 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1740 EXPECT_ACTION_UPDATE_STATE(
1741 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1743 state.OnBeginImplFrameDeadlinePending();
1744 state.OnBeginImplFrameDeadline();
1745 EXPECT_ACTION_UPDATE_STATE(
1746 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1749 TEST(SchedulerStateMachineTest, TestAnimateAfterCommitBeforeDraw) {
1750 SchedulerSettings settings;
1751 settings.impl_side_painting = true;
1752 StateMachine state(settings);
1753 SET_UP_STATE(state)
1755 // Check that animations are updated before we start a commit.
1756 state.SetNeedsAnimate();
1757 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1758 state.SetNeedsCommit();
1759 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1760 EXPECT_TRUE(state.BeginFrameNeeded());
1762 state.OnBeginImplFrame();
1763 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1764 EXPECT_ACTION_UPDATE_STATE(
1765 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1767 state.NotifyBeginMainFrameStarted();
1768 state.NotifyReadyToCommit();
1769 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1771 state.OnBeginImplFrameDeadlinePending();
1772 state.OnBeginImplFrameDeadline();
1773 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1774 EXPECT_ACTION_UPDATE_STATE(
1775 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1778 TEST(SchedulerStateMachineTest, TestSetNeedsAnimateAfterAnimate) {
1779 SchedulerSettings settings;
1780 settings.impl_side_painting = true;
1781 StateMachine state(settings);
1782 SET_UP_STATE(state)
1784 // Test requesting an animation after we have already animated during this
1785 // frame.
1786 state.SetNeedsRedraw(true);
1787 EXPECT_TRUE(state.BeginFrameNeeded());
1788 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1790 state.OnBeginImplFrame();
1791 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1793 state.SetNeedsAnimate();
1794 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1796 state.OnBeginImplFrameDeadline();
1797 EXPECT_ACTION_UPDATE_STATE(
1798 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1801 TEST(SchedulerStateMachineTest, TestForwardBeginFramesToChildren) {
1802 SchedulerSettings settings;
1803 StateMachine state(settings);
1804 SET_UP_STATE(state)
1806 EXPECT_FALSE(state.BeginFrameNeeded());
1807 state.SetChildrenNeedBeginFrames(true);
1808 EXPECT_TRUE(state.BeginFrameNeeded());
1811 TEST(SchedulerStateMachineTest, TestDeferCommit) {
1812 SchedulerSettings settings;
1813 StateMachine state(settings);
1814 SET_UP_STATE(state)
1816 state.SetDeferCommits(true);
1818 state.SetNeedsCommit();
1819 EXPECT_TRUE(state.BeginFrameNeeded());
1820 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1822 state.OnBeginImplFrame();
1823 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1825 state.OnBeginImplFrameDeadline();
1826 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1828 state.SetDeferCommits(false);
1829 state.OnBeginImplFrame();
1830 EXPECT_ACTION_UPDATE_STATE(
1831 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1834 } // namespace
1835 } // namespace cc