[Enhanced Bookmark] Change "Bookmark Bar" to "Bookmark bar" on Android
[chromium-blink-merge.git] / cc / scheduler / scheduler_state_machine_unittest.cc
blob4c2c267a5a493ebbbe734017265f2af8b8f7325b
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;
135 using SchedulerStateMachine::ProactiveBeginFrameWanted;
136 using SchedulerStateMachine::UpdateStateOnCommit;
139 TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) {
140 SchedulerSettings default_scheduler_settings;
142 // If no commit needed, do nothing.
144 StateMachine state(default_scheduler_settings);
145 state.SetCanStart();
146 EXPECT_ACTION_UPDATE_STATE(
147 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION)
148 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
149 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
150 state.SetNeedsRedraw(false);
151 state.SetVisible(true);
153 EXPECT_FALSE(state.BeginFrameNeeded());
155 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
156 EXPECT_FALSE(state.BeginFrameNeeded());
157 state.OnBeginImplFrame();
159 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
160 state.OnBeginImplFrameDeadline();
163 // If commit requested but can_start is still false, do nothing.
165 StateMachine state(default_scheduler_settings);
166 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
167 state.SetNeedsRedraw(false);
168 state.SetVisible(true);
169 state.SetNeedsCommit();
171 EXPECT_FALSE(state.BeginFrameNeeded());
173 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
174 EXPECT_FALSE(state.BeginFrameNeeded());
175 state.OnBeginImplFrame();
176 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
177 state.OnBeginImplFrameDeadline();
180 // If commit requested, begin a main frame.
182 StateMachine state(default_scheduler_settings);
183 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
184 state.SetCanStart();
185 state.UpdateState(state.NextAction());
186 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
187 state.SetNeedsRedraw(false);
188 state.SetVisible(true);
189 state.SetNeedsCommit();
191 EXPECT_TRUE(state.BeginFrameNeeded());
193 state.OnBeginImplFrame();
194 EXPECT_ACTION_UPDATE_STATE(
195 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
198 // Begin the frame, make sure needs_commit and commit_state update correctly.
200 StateMachine state(default_scheduler_settings);
201 state.SetCanStart();
202 state.UpdateState(state.NextAction());
203 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
204 state.SetVisible(true);
205 state.UpdateState(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
206 EXPECT_COMMIT_STATE(
207 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
208 EXPECT_FALSE(state.NeedsCommit());
212 // Explicitly test main_frame_before_activation_enabled = true
213 TEST(SchedulerStateMachineTest, MainFrameBeforeActivationEnabled) {
214 SchedulerSettings scheduler_settings;
215 scheduler_settings.impl_side_painting = true;
216 scheduler_settings.main_frame_before_activation_enabled = true;
217 StateMachine state(scheduler_settings);
218 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
219 SET_UP_STATE(state)
220 state.SetNeedsRedraw(false);
221 state.SetNeedsCommit();
223 EXPECT_TRUE(state.BeginFrameNeeded());
225 // Commit to the pending tree.
226 state.OnBeginImplFrame();
227 EXPECT_ACTION_UPDATE_STATE(
228 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
229 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
231 state.NotifyBeginMainFrameStarted();
232 state.NotifyReadyToCommit();
233 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
234 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
235 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
237 state.OnBeginImplFrameDeadline();
238 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
240 // Verify that the next commit starts while there is still a pending tree.
241 state.SetNeedsCommit();
242 state.OnBeginImplFrame();
243 EXPECT_ACTION_UPDATE_STATE(
244 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
245 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
247 // Verify the pending commit doesn't overwrite the pending
248 // tree until the pending tree has been activated.
249 state.NotifyBeginMainFrameStarted();
250 state.NotifyReadyToCommit();
251 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
253 // Verify NotifyReadyToActivate unblocks activation, draw, and
254 // commit in that order.
255 state.NotifyReadyToActivate();
256 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
257 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
259 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
260 state.OnBeginImplFrameDeadline();
261 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
262 EXPECT_ACTION_UPDATE_STATE(
263 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
264 state.DidSwapBuffers();
265 state.DidSwapBuffersComplete();
266 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
267 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
268 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
271 TEST(SchedulerStateMachineTest,
272 TestFailedDrawForAnimationCheckerboardSetsNeedsCommitAndDoesNotDrawAgain) {
273 SchedulerSettings default_scheduler_settings;
274 StateMachine state(default_scheduler_settings);
275 SET_UP_STATE(state)
276 state.SetNeedsRedraw(true);
277 EXPECT_TRUE(state.RedrawPending());
278 EXPECT_TRUE(state.BeginFrameNeeded());
279 state.OnBeginImplFrame();
280 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
281 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
282 state.OnBeginImplFrameDeadline();
284 // We're drawing now.
285 EXPECT_ACTION_UPDATE_STATE(
286 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
287 state.DidSwapBuffers();
288 state.DidSwapBuffersComplete();
289 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
291 EXPECT_FALSE(state.RedrawPending());
292 EXPECT_FALSE(state.CommitPending());
294 // Failing the draw makes us require a commit.
295 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
296 state.OnBeginImplFrame();
297 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
298 EXPECT_ACTION_UPDATE_STATE(
299 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
300 EXPECT_TRUE(state.RedrawPending());
301 EXPECT_TRUE(state.CommitPending());
304 TEST(SchedulerStateMachineTest, TestFailedDrawForMissingHighResNeedsCommit) {
305 SchedulerSettings default_scheduler_settings;
306 StateMachine state(default_scheduler_settings);
307 SET_UP_STATE(state)
308 state.SetNeedsRedraw(true);
309 EXPECT_TRUE(state.RedrawPending());
310 EXPECT_TRUE(state.BeginFrameNeeded());
312 state.OnBeginImplFrame();
313 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
314 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
315 state.OnBeginImplFrameDeadline();
316 EXPECT_ACTION_UPDATE_STATE(
317 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
318 state.DidSwapBuffers();
319 state.DidSwapBuffersComplete();
320 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
321 EXPECT_FALSE(state.RedrawPending());
322 EXPECT_FALSE(state.CommitPending());
324 // Missing high res content requires a commit (but not a redraw)
325 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT);
326 state.OnBeginImplFrame();
327 EXPECT_ACTION_UPDATE_STATE(
328 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
329 EXPECT_FALSE(state.RedrawPending());
330 EXPECT_TRUE(state.CommitPending());
333 TEST(SchedulerStateMachineTest,
334 TestsetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw) {
335 SchedulerSettings default_scheduler_settings;
336 StateMachine state(default_scheduler_settings);
337 SET_UP_STATE(state)
338 state.SetNeedsRedraw(true);
339 EXPECT_TRUE(state.RedrawPending());
340 EXPECT_TRUE(state.BeginFrameNeeded());
341 state.OnBeginImplFrame();
342 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
343 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
344 state.OnBeginImplFrameDeadline();
346 // We're drawing now.
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_FALSE(state.RedrawPending());
353 EXPECT_FALSE(state.CommitPending());
355 // While still in the same BeginMainFrame callback on the main thread,
356 // set needs redraw again. This should not redraw.
357 state.SetNeedsRedraw(true);
358 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
360 // Failing the draw for animation checkerboards makes us require a commit.
361 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
362 state.OnBeginImplFrame();
363 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
364 EXPECT_ACTION_UPDATE_STATE(
365 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
366 EXPECT_TRUE(state.RedrawPending());
369 TEST(SchedulerStateMachineTest,
370 TestFailedDrawsEventuallyForceDrawAfterNextCommit) {
371 SchedulerSettings scheduler_settings;
372 scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ = 1;
373 StateMachine state(scheduler_settings);
374 SET_UP_STATE(state)
376 // Start a commit.
377 state.SetNeedsCommit();
378 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
379 state.OnBeginImplFrame();
380 EXPECT_ACTION_UPDATE_STATE(
381 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
382 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
383 EXPECT_TRUE(state.CommitPending());
385 // Then initiate a draw.
386 state.SetNeedsRedraw(true);
387 state.OnBeginImplFrameDeadline();
388 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
389 EXPECT_ACTION_UPDATE_STATE(
390 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
392 // Fail the draw.
393 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
394 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
395 EXPECT_TRUE(state.BeginFrameNeeded());
396 EXPECT_TRUE(state.RedrawPending());
397 // But the commit is ongoing.
398 EXPECT_TRUE(state.CommitPending());
400 // Finish the commit. Note, we should not yet be forcing a draw, but should
401 // continue the commit as usual.
402 state.NotifyBeginMainFrameStarted();
403 state.NotifyReadyToCommit();
404 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
405 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
406 EXPECT_TRUE(state.RedrawPending());
408 // The redraw should be forced at the end of the next BeginImplFrame.
409 state.OnBeginImplFrame();
410 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
411 EXPECT_ACTION_UPDATE_STATE(
412 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
413 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
414 state.OnBeginImplFrameDeadline();
415 EXPECT_ACTION_UPDATE_STATE(
416 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED);
417 state.DidSwapBuffers();
418 state.DidSwapBuffersComplete();
421 TEST(SchedulerStateMachineTest, TestFailedDrawsDoNotRestartForcedDraw) {
422 SchedulerSettings scheduler_settings;
423 int draw_limit = 1;
424 scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ =
425 draw_limit;
426 scheduler_settings.impl_side_painting = true;
427 StateMachine state(scheduler_settings);
428 SET_UP_STATE(state)
430 // Start a commit.
431 state.SetNeedsCommit();
432 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
433 state.OnBeginImplFrame();
434 EXPECT_ACTION_UPDATE_STATE(
435 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
436 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
437 EXPECT_TRUE(state.CommitPending());
439 // Then initiate a draw.
440 state.SetNeedsRedraw(true);
441 state.OnBeginImplFrameDeadline();
442 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
443 EXPECT_ACTION_UPDATE_STATE(
444 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
446 // Fail the draw enough times to force a redraw,
447 // then once more for good measure.
448 for (int i = 0; i < draw_limit + 1; ++i)
449 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
450 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
451 EXPECT_TRUE(state.BeginFrameNeeded());
452 EXPECT_TRUE(state.RedrawPending());
453 // But the commit is ongoing.
454 EXPECT_TRUE(state.CommitPending());
455 EXPECT_TRUE(state.ForcedRedrawState() ==
456 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_COMMIT);
458 state.NotifyBeginMainFrameStarted();
459 state.NotifyReadyToCommit();
460 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
461 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
462 EXPECT_TRUE(state.RedrawPending());
463 EXPECT_FALSE(state.CommitPending());
465 // Now force redraw should be in waiting for activation
466 EXPECT_TRUE(state.ForcedRedrawState() ==
467 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION);
469 // After failing additional draws, we should still be in a forced
470 // redraw, but not back in WAITING_FOR_COMMIT.
471 for (int i = 0; i < draw_limit + 1; ++i)
472 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
473 EXPECT_TRUE(state.RedrawPending());
474 EXPECT_TRUE(state.ForcedRedrawState() ==
475 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION);
478 TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedInNextBeginImplFrame) {
479 SchedulerSettings default_scheduler_settings;
480 StateMachine state(default_scheduler_settings);
481 SET_UP_STATE(state)
483 // Start a draw.
484 state.SetNeedsRedraw(true);
485 EXPECT_TRUE(state.BeginFrameNeeded());
486 state.OnBeginImplFrame();
487 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
488 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
489 state.OnBeginImplFrameDeadline();
490 EXPECT_TRUE(state.RedrawPending());
491 EXPECT_ACTION_UPDATE_STATE(
492 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
494 // Failing the draw for animation checkerboards makes us require a commit.
495 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
496 EXPECT_ACTION_UPDATE_STATE(
497 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
498 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
499 EXPECT_TRUE(state.RedrawPending());
501 // We should not be trying to draw again now, but we have a commit pending.
502 EXPECT_TRUE(state.BeginFrameNeeded());
503 state.OnBeginImplFrame();
504 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
505 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
507 // We should try to draw again at the end of the next BeginImplFrame on
508 // the impl thread.
509 state.OnBeginImplFrameDeadline();
510 EXPECT_ACTION_UPDATE_STATE(
511 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
512 state.DidSwapBuffers();
513 state.DidSwapBuffersComplete();
514 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
517 TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) {
518 SchedulerSettings default_scheduler_settings;
519 StateMachine state(default_scheduler_settings);
520 SET_UP_STATE(state)
521 state.SetNeedsRedraw(true);
523 // Draw the first frame.
524 EXPECT_TRUE(state.BeginFrameNeeded());
525 state.OnBeginImplFrame();
526 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
527 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
529 state.OnBeginImplFrameDeadline();
530 EXPECT_ACTION_UPDATE_STATE(
531 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
532 state.DidSwapBuffers();
533 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
534 state.DidSwapBuffersComplete();
535 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
537 // Before the next BeginImplFrame, set needs redraw again.
538 // This should not redraw until the next BeginImplFrame.
539 state.SetNeedsRedraw(true);
540 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
542 // Move to another frame. This should now draw.
543 EXPECT_TRUE(state.BeginFrameNeeded());
544 state.OnBeginImplFrame();
546 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
547 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
549 state.OnBeginImplFrameDeadline();
550 EXPECT_ACTION_UPDATE_STATE(
551 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
552 state.DidSwapBuffers();
553 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
554 state.DidSwapBuffersComplete();
555 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
557 // We just swapped, so we should proactively request another BeginImplFrame.
558 EXPECT_TRUE(state.BeginFrameNeeded());
561 TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) {
562 SchedulerSettings default_scheduler_settings;
564 // When not in BeginImplFrame deadline, or in BeginImplFrame deadline
565 // but not visible, don't draw.
566 size_t num_commit_states =
567 sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState);
568 size_t num_begin_impl_frame_states =
569 sizeof(all_begin_impl_frame_states) /
570 sizeof(SchedulerStateMachine::BeginImplFrameState);
571 for (size_t i = 0; i < num_commit_states; ++i) {
572 for (size_t j = 0; j < num_begin_impl_frame_states; ++j) {
573 StateMachine state(default_scheduler_settings);
574 state.SetCanStart();
575 state.UpdateState(state.NextAction());
576 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
577 state.SetCommitState(all_commit_states[i]);
578 state.SetBeginImplFrameState(all_begin_impl_frame_states[j]);
579 bool visible =
580 (all_begin_impl_frame_states[j] !=
581 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
582 state.SetVisible(visible);
584 // Case 1: needs_commit=false
585 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
586 state.NextAction());
588 // Case 2: needs_commit=true
589 state.SetNeedsCommit();
590 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
591 state.NextAction())
592 << state.AsValue()->ToString();
596 // When in BeginImplFrame deadline we should always draw for SetNeedsRedraw
597 // except if we're ready to commit, in which case we expect a commit first.
598 for (size_t i = 0; i < num_commit_states; ++i) {
599 StateMachine state(default_scheduler_settings);
600 state.SetCanStart();
601 state.UpdateState(state.NextAction());
602 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
603 state.SetCanDraw(true);
604 state.SetCommitState(all_commit_states[i]);
605 state.SetBeginImplFrameState(
606 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
608 state.SetNeedsRedraw(true);
609 state.SetVisible(true);
611 SchedulerStateMachine::Action expected_action;
612 if (all_commit_states[i] ==
613 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT) {
614 expected_action = SchedulerStateMachine::ACTION_COMMIT;
615 } else {
616 expected_action = SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
617 EXPECT_ACTION(SchedulerStateMachine::ACTION_ANIMATE);
618 state.UpdateState(state.NextAction());
621 // Case 1: needs_commit=false.
622 EXPECT_ACTION(expected_action);
624 // Case 2: needs_commit=true.
625 state.SetNeedsCommit();
626 EXPECT_ACTION(expected_action);
630 TEST(SchedulerStateMachineTest, TestNoCommitStatesRedrawWhenInvisible) {
631 SchedulerSettings default_scheduler_settings;
633 size_t num_commit_states =
634 sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState);
635 for (size_t i = 0; i < num_commit_states; ++i) {
636 // There shouldn't be any drawing regardless of BeginImplFrame.
637 for (size_t j = 0; j < 2; ++j) {
638 StateMachine state(default_scheduler_settings);
639 state.SetCanStart();
640 state.UpdateState(state.NextAction());
641 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
642 state.SetCommitState(all_commit_states[i]);
643 state.SetVisible(false);
644 state.SetNeedsRedraw(true);
645 if (j == 1) {
646 state.SetBeginImplFrameState(
647 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
650 // Case 1: needs_commit=false.
651 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
652 state.NextAction());
654 // Case 2: needs_commit=true.
655 state.SetNeedsCommit();
656 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
657 state.NextAction())
658 << state.AsValue()->ToString();
663 TEST(SchedulerStateMachineTest, TestCanRedraw_StopsDraw) {
664 SchedulerSettings default_scheduler_settings;
666 size_t num_commit_states =
667 sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState);
668 for (size_t i = 0; i < num_commit_states; ++i) {
669 // There shouldn't be any drawing regardless of BeginImplFrame.
670 for (size_t j = 0; j < 2; ++j) {
671 StateMachine state(default_scheduler_settings);
672 state.SetCanStart();
673 state.UpdateState(state.NextAction());
674 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
675 state.SetCommitState(all_commit_states[i]);
676 state.SetVisible(false);
677 state.SetNeedsRedraw(true);
678 if (j == 1)
679 state.OnBeginImplFrame();
681 state.SetCanDraw(false);
682 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
683 state.NextAction());
688 TEST(SchedulerStateMachineTest,
689 TestCanRedrawWithWaitingForFirstDrawMakesProgress) {
690 SchedulerSettings default_scheduler_settings;
691 StateMachine state(default_scheduler_settings);
692 state.SetCanStart();
693 state.UpdateState(state.NextAction());
694 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
696 state.SetActiveTreeNeedsFirstDraw(true);
697 state.SetNeedsCommit();
698 state.SetNeedsRedraw(true);
699 state.SetVisible(true);
700 state.SetCanDraw(false);
701 state.OnBeginImplFrame();
702 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
703 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
704 EXPECT_ACTION_UPDATE_STATE(
705 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
706 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
707 state.NotifyBeginMainFrameStarted();
708 state.NotifyReadyToCommit();
709 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
710 state.OnBeginImplFrameDeadline();
711 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
712 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
713 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
716 TEST(SchedulerStateMachineTest, TestSetNeedsCommitIsNotLost) {
717 SchedulerSettings scheduler_settings;
718 StateMachine state(scheduler_settings);
719 SET_UP_STATE(state)
720 state.SetNeedsCommit();
722 EXPECT_TRUE(state.BeginFrameNeeded());
724 // Begin the frame.
725 state.OnBeginImplFrame();
726 EXPECT_ACTION_UPDATE_STATE(
727 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
728 EXPECT_COMMIT_STATE(
729 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
731 // Now, while the frame is in progress, set another commit.
732 state.SetNeedsCommit();
733 EXPECT_TRUE(state.NeedsCommit());
735 // Let the frame finish.
736 state.NotifyBeginMainFrameStarted();
737 state.NotifyReadyToCommit();
738 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
740 // Expect to commit regardless of BeginImplFrame state.
741 EXPECT_IMPL_FRAME_STATE(
742 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING);
743 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
745 state.OnBeginImplFrameDeadlinePending();
746 EXPECT_IMPL_FRAME_STATE(
747 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME);
748 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
750 state.OnBeginImplFrameDeadline();
751 EXPECT_IMPL_FRAME_STATE(
752 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
753 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
755 state.OnBeginImplFrameIdle();
756 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
757 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
759 state.OnBeginImplFrame();
760 EXPECT_IMPL_FRAME_STATE(
761 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING);
762 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
764 // Finish the commit, then make sure we start the next commit immediately
765 // and draw on the next BeginImplFrame.
766 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
767 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
768 EXPECT_ACTION_UPDATE_STATE(
769 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
770 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
772 state.OnBeginImplFrameDeadline();
774 EXPECT_TRUE(state.active_tree_needs_first_draw());
775 EXPECT_ACTION_UPDATE_STATE(
776 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
777 state.DidSwapBuffers();
778 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
779 state.DidSwapBuffersComplete();
780 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
783 TEST(SchedulerStateMachineTest, TestFullCycle) {
784 SchedulerSettings default_scheduler_settings;
785 StateMachine state(default_scheduler_settings);
786 SET_UP_STATE(state)
788 // Start clean and set commit.
789 state.SetNeedsCommit();
791 // Begin the frame.
792 state.OnBeginImplFrame();
793 EXPECT_ACTION_UPDATE_STATE(
794 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
795 EXPECT_COMMIT_STATE(
796 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
797 EXPECT_FALSE(state.NeedsCommit());
798 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
800 // Tell the scheduler the frame finished.
801 state.NotifyBeginMainFrameStarted();
802 state.NotifyReadyToCommit();
803 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
805 // Commit.
806 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
807 EXPECT_TRUE(state.active_tree_needs_first_draw());
808 EXPECT_TRUE(state.needs_redraw());
810 // Expect to do nothing until BeginImplFrame deadline
811 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
813 // At BeginImplFrame deadline, draw.
814 state.OnBeginImplFrameDeadline();
815 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
816 EXPECT_ACTION_UPDATE_STATE(
817 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
818 state.DidSwapBuffers();
819 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
820 state.DidSwapBuffersComplete();
822 // Should be synchronized, no draw needed, no action needed.
823 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
824 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
825 EXPECT_FALSE(state.needs_redraw());
828 TEST(SchedulerStateMachineTest, TestFullCycleWithMainThreadLowLatencyMode) {
829 SchedulerSettings scheduler_settings;
830 scheduler_settings.main_thread_should_always_be_low_latency = true;
831 StateMachine state(scheduler_settings);
832 SET_UP_STATE(state)
834 // Start clean and set commit.
835 state.SetNeedsCommit();
837 // Begin the frame.
838 state.OnBeginImplFrame();
839 EXPECT_ACTION_UPDATE_STATE(
840 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
841 EXPECT_COMMIT_STATE(
842 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
843 EXPECT_FALSE(state.NeedsCommit());
844 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
846 // Tell the scheduler the frame finished.
847 state.NotifyBeginMainFrameStarted();
848 state.NotifyReadyToCommit();
849 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
851 // Commit.
852 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
853 EXPECT_TRUE(state.active_tree_needs_first_draw());
854 EXPECT_TRUE(state.needs_redraw());
856 // Now commit should wait for draw.
857 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW);
859 // Swap throttled. Do not draw.
860 state.DidSwapBuffers();
861 state.OnBeginImplFrameDeadline();
862 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
863 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
864 state.DidSwapBuffersComplete();
866 // Haven't draw since last commit, do not begin new main frame.
867 state.SetNeedsCommit();
868 state.OnBeginImplFrame();
869 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
870 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
872 // At BeginImplFrame deadline, draw.
873 state.OnBeginImplFrameDeadline();
874 EXPECT_ACTION_UPDATE_STATE(
875 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
876 state.DidSwapBuffers();
877 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
878 state.DidSwapBuffersComplete();
880 // Now will be able to start main frame.
881 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
882 EXPECT_FALSE(state.needs_redraw());
883 EXPECT_ACTION_UPDATE_STATE(
884 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
887 TEST(SchedulerStateMachineTest,
888 TestFullCycleWithMainThreadLowLatencyMode_ImplSidePaint) {
889 SchedulerSettings scheduler_settings;
890 scheduler_settings.main_thread_should_always_be_low_latency = true;
891 scheduler_settings.impl_side_painting = true;
892 StateMachine state(scheduler_settings);
893 SET_UP_STATE(state)
895 // Start clean and set commit.
896 state.SetNeedsCommit();
898 // Begin the frame.
899 state.OnBeginImplFrame();
900 EXPECT_ACTION_UPDATE_STATE(
901 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
902 EXPECT_COMMIT_STATE(
903 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
904 EXPECT_FALSE(state.NeedsCommit());
905 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
907 // Tell the scheduler the frame finished.
908 state.NotifyBeginMainFrameStarted();
909 state.NotifyReadyToCommit();
910 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
912 // Commit.
913 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
915 // Now commit should wait for activation.
916 EXPECT_COMMIT_STATE(
917 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION);
919 // No activation yet, so this commit is not drawn yet. Force to draw this
920 // frame, and still block BeginMainFrame.
921 state.SetNeedsRedraw(true);
922 state.SetNeedsCommit();
923 state.OnBeginImplFrameDeadline();
924 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
925 EXPECT_ACTION_UPDATE_STATE(
926 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
927 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
929 // Cannot BeginMainFrame yet since last commit is not yet activated and drawn.
930 state.OnBeginImplFrame();
931 EXPECT_COMMIT_STATE(
932 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION);
933 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
935 // Now activate sync tree.
936 state.NotifyReadyToActivate();
937 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
938 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
939 EXPECT_TRUE(state.active_tree_needs_first_draw());
940 EXPECT_TRUE(state.needs_redraw());
941 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW);
943 // Swap throttled. Do not draw.
944 state.DidSwapBuffers();
945 state.OnBeginImplFrameDeadline();
946 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
947 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
948 state.DidSwapBuffersComplete();
950 // Haven't draw since last commit, do not begin new main frame.
951 state.OnBeginImplFrame();
952 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
953 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
955 // At BeginImplFrame deadline, draw. This draws unblocks BeginMainFrame.
956 state.OnBeginImplFrameDeadline();
957 EXPECT_ACTION_UPDATE_STATE(
958 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
959 state.DidSwapBuffers();
960 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
961 state.DidSwapBuffersComplete();
963 // Now will be able to start main frame.
964 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
965 EXPECT_FALSE(state.needs_redraw());
966 EXPECT_ACTION_UPDATE_STATE(
967 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
970 TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween) {
971 SchedulerSettings default_scheduler_settings;
972 StateMachine state(default_scheduler_settings);
973 SET_UP_STATE(state)
975 // Start clean and set commit.
976 state.SetNeedsCommit();
978 // Begin the frame.
979 state.OnBeginImplFrame();
980 EXPECT_ACTION_UPDATE_STATE(
981 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
982 EXPECT_COMMIT_STATE(
983 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
984 EXPECT_FALSE(state.NeedsCommit());
985 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
987 // Request another commit while the commit is in flight.
988 state.SetNeedsCommit();
989 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
991 // Tell the scheduler the frame finished.
992 state.NotifyBeginMainFrameStarted();
993 state.NotifyReadyToCommit();
994 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
996 // First commit.
997 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
998 EXPECT_TRUE(state.active_tree_needs_first_draw());
999 EXPECT_TRUE(state.needs_redraw());
1001 // Expect to do nothing until BeginImplFrame deadline.
1002 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1004 // At BeginImplFrame deadline, draw.
1005 state.OnBeginImplFrameDeadline();
1006 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1007 EXPECT_ACTION_UPDATE_STATE(
1008 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1009 state.DidSwapBuffers();
1010 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
1011 state.DidSwapBuffersComplete();
1013 // Should be synchronized, no draw needed, no action needed.
1014 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1015 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
1016 EXPECT_FALSE(state.needs_redraw());
1018 // Next BeginImplFrame should initiate second commit.
1019 state.OnBeginImplFrame();
1020 EXPECT_ACTION_UPDATE_STATE(
1021 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1024 TEST(SchedulerStateMachineTest, TestRequestCommitInvisible) {
1025 SchedulerSettings default_scheduler_settings;
1026 StateMachine state(default_scheduler_settings);
1027 state.SetCanStart();
1028 state.UpdateState(state.NextAction());
1029 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1030 state.SetNeedsCommit();
1031 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1034 // See ThreadProxy::BeginMainFrame "EarlyOut_NotVisible" /
1035 // "EarlyOut_OutputSurfaceLost" cases.
1036 TEST(SchedulerStateMachineTest, TestAbortBeginMainFrameBecauseInvisible) {
1037 SchedulerSettings default_scheduler_settings;
1038 StateMachine state(default_scheduler_settings);
1039 SET_UP_STATE(state)
1041 // Start clean and set commit.
1042 state.SetNeedsCommit();
1044 // Begin the frame while visible.
1045 state.OnBeginImplFrame();
1046 EXPECT_ACTION_UPDATE_STATE(
1047 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1048 EXPECT_COMMIT_STATE(
1049 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
1050 EXPECT_FALSE(state.NeedsCommit());
1051 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1053 // Become invisible and abort BeginMainFrame.
1054 state.SetVisible(false);
1055 state.BeginMainFrameAborted(CommitEarlyOutReason::ABORTED_NOT_VISIBLE);
1057 // NeedsCommit should now be true again because we never actually did a
1058 // commit.
1059 EXPECT_TRUE(state.NeedsCommit());
1061 // We should now be back in the idle state as if we never started the frame.
1062 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
1063 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1065 // We shouldn't do anything on the BeginImplFrame deadline.
1066 state.OnBeginImplFrameDeadline();
1067 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1069 // Become visible again.
1070 state.SetVisible(true);
1072 // Although we have aborted on this frame and haven't cancelled the commit
1073 // (i.e. need another), don't send another BeginMainFrame yet.
1074 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
1075 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1076 EXPECT_TRUE(state.NeedsCommit());
1078 // Start a new frame.
1079 state.OnBeginImplFrame();
1080 EXPECT_ACTION_UPDATE_STATE(
1081 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1083 // We should be starting the commit now.
1084 EXPECT_COMMIT_STATE(
1085 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
1086 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1089 // See ThreadProxy::BeginMainFrame "EarlyOut_NoUpdates" case.
1090 TEST(SchedulerStateMachineTest, TestAbortBeginMainFrameBecauseCommitNotNeeded) {
1091 SchedulerSettings default_scheduler_settings;
1092 StateMachine state(default_scheduler_settings);
1093 state.SetCanStart();
1094 state.UpdateState(state.NextAction());
1095 state.DidCreateAndInitializeOutputSurface();
1096 state.SetVisible(true);
1097 state.SetCanDraw(true);
1099 // Get into a begin frame / commit state.
1100 state.SetNeedsCommit();
1101 state.OnBeginImplFrame();
1102 EXPECT_ACTION_UPDATE_STATE(
1103 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1104 EXPECT_COMMIT_STATE(
1105 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
1106 EXPECT_FALSE(state.NeedsCommit());
1107 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1109 // Abort the commit, true means that the BeginMainFrame was sent but there
1110 // was no work to do on the main thread.
1111 state.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES);
1113 // NeedsCommit should now be false because the commit was actually handled.
1114 EXPECT_FALSE(state.NeedsCommit());
1116 // Even though the commit was aborted, we still expect to draw the new frame.
1117 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1118 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1119 state.OnBeginImplFrameDeadline();
1120 EXPECT_ACTION_UPDATE_STATE(
1121 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1122 state.DidSwapBuffers();
1123 state.DidSwapBuffersComplete();
1124 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1126 // Verify another commit doesn't start on another frame either.
1127 EXPECT_FALSE(state.NeedsCommit());
1128 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
1130 state.OnBeginImplFrame();
1131 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1132 state.OnBeginImplFrameDeadline();
1133 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1135 // Verify another commit can start if requested, though.
1136 state.SetNeedsCommit();
1137 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
1138 state.OnBeginImplFrame();
1139 EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1142 TEST(SchedulerStateMachineTest, TestFirstContextCreation) {
1143 SchedulerSettings default_scheduler_settings;
1144 StateMachine state(default_scheduler_settings);
1145 state.SetCanStart();
1146 state.SetVisible(true);
1147 state.SetCanDraw(true);
1149 EXPECT_ACTION_UPDATE_STATE(
1150 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1151 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1152 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1154 // Check that the first init does not SetNeedsCommit.
1155 state.OnBeginImplFrame();
1156 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1157 state.OnBeginImplFrameDeadline();
1158 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1160 // Check that a needs commit initiates a BeginMainFrame.
1161 state.SetNeedsCommit();
1162 state.OnBeginImplFrame();
1163 EXPECT_ACTION_UPDATE_STATE(
1164 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1167 TEST(SchedulerStateMachineTest, TestContextLostWhenCompletelyIdle) {
1168 SchedulerSettings default_scheduler_settings;
1169 StateMachine state(default_scheduler_settings);
1170 SET_UP_STATE(state)
1172 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1173 state.NextAction());
1174 state.DidLoseOutputSurface();
1176 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1177 state.UpdateState(state.NextAction());
1179 // Once context recreation begins, nothing should happen.
1180 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1182 // Recreate the context.
1183 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1185 // When the context is recreated, we should begin a commit.
1186 state.OnBeginImplFrame();
1187 EXPECT_ACTION_UPDATE_STATE(
1188 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1191 TEST(SchedulerStateMachineTest,
1192 TestContextLostWhenIdleAndCommitRequestedWhileRecreating) {
1193 SchedulerSettings default_scheduler_settings;
1194 // We use impl side painting because it's the more complicated version.
1195 default_scheduler_settings.impl_side_painting = true;
1196 StateMachine state(default_scheduler_settings);
1197 SET_UP_STATE(state)
1199 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1200 state.NextAction());
1201 state.DidLoseOutputSurface();
1202 EXPECT_EQ(state.output_surface_state(),
1203 SchedulerStateMachine::OUTPUT_SURFACE_LOST);
1205 EXPECT_ACTION_UPDATE_STATE(
1206 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1207 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1209 // Once context recreation begins, nothing should happen.
1210 state.OnBeginImplFrame();
1211 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1212 state.OnBeginImplFrameDeadline();
1213 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1215 // While context is recreating, commits shouldn't begin.
1216 state.SetNeedsCommit();
1217 state.OnBeginImplFrame();
1218 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1219 state.OnBeginImplFrameDeadline();
1220 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1222 // Recreate the context
1223 state.DidCreateAndInitializeOutputSurface();
1224 EXPECT_EQ(state.output_surface_state(),
1225 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT);
1226 EXPECT_FALSE(state.RedrawPending());
1228 // When the context is recreated, we wait until the next BeginImplFrame
1229 // before starting.
1230 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1232 // When the BeginFrame comes in we should begin a commit
1233 state.OnBeginImplFrame();
1234 EXPECT_ACTION_UPDATE_STATE(
1235 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1236 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1237 EXPECT_COMMIT_STATE(
1238 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
1240 // Until that commit finishes, we shouldn't be drawing or animate.
1241 state.OnBeginImplFrameDeadline();
1242 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1244 // Finish the commit, which should make the surface active.
1245 state.NotifyBeginMainFrameStarted();
1246 state.NotifyReadyToCommit();
1247 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1248 EXPECT_EQ(state.output_surface_state(),
1249 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION);
1250 state.NotifyReadyToActivate();
1251 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1252 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1253 EXPECT_EQ(state.output_surface_state(),
1254 SchedulerStateMachine::OUTPUT_SURFACE_ACTIVE);
1256 // Finishing the first commit after initializing an output surface should
1257 // automatically cause a redraw.
1258 EXPECT_TRUE(state.RedrawPending());
1259 state.OnBeginImplFrame();
1260 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1261 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1262 state.OnBeginImplFrameDeadline();
1263 EXPECT_ACTION_UPDATE_STATE(
1264 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1265 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1266 EXPECT_FALSE(state.RedrawPending());
1268 // Next frame as no work to do.
1269 state.OnBeginImplFrame();
1270 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1271 state.OnBeginImplFrameDeadline();
1272 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1274 // Once the context is recreated, whether we draw should be based on
1275 // SetCanDraw if waiting on first draw after activate.
1276 state.SetNeedsRedraw(true);
1277 state.OnBeginImplFrame();
1278 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1279 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1280 state.OnBeginImplFrameDeadline();
1281 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1282 state.SetCanDraw(false);
1283 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1284 state.SetCanDraw(true);
1285 EXPECT_ACTION_UPDATE_STATE(
1286 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1287 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1289 // Once the context is recreated, whether we draw should be based on
1290 // SetCanDraw if waiting on first draw after activate.
1291 state.SetNeedsRedraw(true);
1292 state.SetNeedsCommit();
1293 state.OnBeginImplFrame();
1294 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1295 EXPECT_ACTION_UPDATE_STATE(
1296 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1297 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1298 // Activate so we need the first draw
1299 state.NotifyBeginMainFrameStarted();
1300 state.NotifyReadyToCommit();
1301 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1302 state.NotifyReadyToActivate();
1303 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1304 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1305 EXPECT_TRUE(state.active_tree_needs_first_draw());
1306 EXPECT_TRUE(state.needs_redraw());
1308 state.OnBeginImplFrameDeadline();
1309 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1310 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1311 state.SetCanDraw(false);
1312 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1313 state.SetCanDraw(true);
1314 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1317 TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) {
1318 SchedulerSettings scheduler_settings;
1319 StateMachine state(scheduler_settings);
1320 SET_UP_STATE(state)
1322 // Get a commit in flight.
1323 state.SetNeedsCommit();
1325 // Set damage and expect a draw.
1326 state.SetNeedsRedraw(true);
1327 state.OnBeginImplFrame();
1328 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1329 EXPECT_ACTION_UPDATE_STATE(
1330 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1331 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1332 state.OnBeginImplFrameDeadline();
1333 EXPECT_ACTION_UPDATE_STATE(
1334 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1335 state.DidSwapBuffers();
1336 state.DidSwapBuffersComplete();
1337 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1339 // Cause a lost context while the BeginMainFrame is in flight.
1340 state.DidLoseOutputSurface();
1342 // Ask for another draw. Expect nothing happens.
1343 state.SetNeedsRedraw(true);
1344 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1346 // Finish the frame, and commit.
1347 state.NotifyBeginMainFrameStarted();
1348 state.NotifyReadyToCommit();
1349 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1351 // We will abort the draw when the output surface is lost if we are
1352 // waiting for the first draw to unblock the main thread.
1353 EXPECT_TRUE(state.active_tree_needs_first_draw());
1354 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1356 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1357 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
1358 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1360 state.OnBeginImplFrame();
1361 EXPECT_IMPL_FRAME_STATE(
1362 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING);
1363 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1365 state.OnBeginImplFrameDeadlinePending();
1366 EXPECT_IMPL_FRAME_STATE(
1367 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME);
1368 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1370 state.OnBeginImplFrameDeadline();
1371 EXPECT_IMPL_FRAME_STATE(
1372 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
1373 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1376 TEST(SchedulerStateMachineTest,
1377 TestContextLostWhileCommitInProgressAndAnotherCommitRequested) {
1378 SchedulerSettings scheduler_settings;
1379 StateMachine state(scheduler_settings);
1380 SET_UP_STATE(state)
1382 // Get a commit in flight.
1383 state.SetNeedsCommit();
1384 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1386 // Set damage and expect a draw.
1387 state.SetNeedsRedraw(true);
1388 state.OnBeginImplFrame();
1389 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1390 EXPECT_ACTION_UPDATE_STATE(
1391 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1392 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1393 state.OnBeginImplFrameDeadline();
1394 EXPECT_ACTION_UPDATE_STATE(
1395 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1396 state.DidSwapBuffers();
1397 state.DidSwapBuffersComplete();
1398 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1400 // Cause a lost context while the BeginMainFrame is in flight.
1401 state.DidLoseOutputSurface();
1403 // Ask for another draw and also set needs commit. Expect nothing happens.
1404 state.SetNeedsRedraw(true);
1405 state.SetNeedsCommit();
1406 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1408 // Finish the frame, and commit.
1409 state.NotifyBeginMainFrameStarted();
1410 state.NotifyReadyToCommit();
1411 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1412 EXPECT_TRUE(state.active_tree_needs_first_draw());
1414 // Because the output surface is missing, we expect the draw to abort.
1415 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1417 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1418 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
1419 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1421 state.OnBeginImplFrame();
1422 EXPECT_IMPL_FRAME_STATE(
1423 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING);
1424 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1426 state.OnBeginImplFrameDeadlinePending();
1427 EXPECT_IMPL_FRAME_STATE(
1428 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME);
1429 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1431 state.OnBeginImplFrameDeadline();
1432 EXPECT_IMPL_FRAME_STATE(
1433 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
1434 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1436 state.OnBeginImplFrameIdle();
1437 EXPECT_ACTION_UPDATE_STATE(
1438 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1440 // After we get a new output surface, the commit flow should start.
1441 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1442 state.OnBeginImplFrame();
1443 EXPECT_ACTION_UPDATE_STATE(
1444 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1445 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1446 state.NotifyBeginMainFrameStarted();
1447 state.NotifyReadyToCommit();
1448 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1449 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1450 state.OnBeginImplFrameDeadline();
1451 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1452 EXPECT_ACTION_UPDATE_STATE(
1453 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1454 state.DidSwapBuffers();
1455 state.DidSwapBuffersComplete();
1456 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1459 TEST(SchedulerStateMachineTest, DontDrawBeforeCommitAfterLostOutputSurface) {
1460 SchedulerSettings default_scheduler_settings;
1461 StateMachine state(default_scheduler_settings);
1462 SET_UP_STATE(state)
1464 state.SetNeedsRedraw(true);
1466 // Cause a lost output surface, and restore it.
1467 state.DidLoseOutputSurface();
1468 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1469 state.UpdateState(state.NextAction());
1470 state.DidCreateAndInitializeOutputSurface();
1472 EXPECT_FALSE(state.RedrawPending());
1473 state.OnBeginImplFrame();
1474 EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1477 TEST(SchedulerStateMachineTest,
1478 TestPendingActivationsShouldBeForcedAfterLostOutputSurface) {
1479 SchedulerSettings settings;
1480 settings.impl_side_painting = true;
1481 StateMachine state(settings);
1482 SET_UP_STATE(state)
1484 state.SetCommitState(
1485 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
1487 // Cause a lost context.
1488 state.DidLoseOutputSurface();
1490 state.NotifyBeginMainFrameStarted();
1491 state.NotifyReadyToCommit();
1492 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1494 EXPECT_TRUE(state.PendingActivationsShouldBeForced());
1495 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1497 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1498 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1501 TEST(SchedulerStateMachineTest, TestNoBeginMainFrameWhenInvisible) {
1502 SchedulerSettings default_scheduler_settings;
1503 StateMachine state(default_scheduler_settings);
1504 state.SetCanStart();
1505 state.UpdateState(state.NextAction());
1506 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1507 state.SetVisible(false);
1508 state.SetNeedsCommit();
1509 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1512 TEST(SchedulerStateMachineTest, TestFinishCommitWhenCommitInProgress) {
1513 SchedulerSettings default_scheduler_settings;
1514 StateMachine state(default_scheduler_settings);
1515 state.SetCanStart();
1516 state.UpdateState(state.NextAction());
1517 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1518 state.SetVisible(false);
1519 state.SetCommitState(
1520 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
1521 state.SetNeedsCommit();
1523 state.NotifyBeginMainFrameStarted();
1524 state.NotifyReadyToCommit();
1525 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
1526 state.UpdateState(state.NextAction());
1528 EXPECT_TRUE(state.active_tree_needs_first_draw());
1529 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1532 TEST(SchedulerStateMachineTest, TestInitialActionsWhenContextLost) {
1533 SchedulerSettings default_scheduler_settings;
1534 StateMachine state(default_scheduler_settings);
1535 SET_UP_STATE(state)
1536 state.SetNeedsCommit();
1537 state.DidLoseOutputSurface();
1539 // When we are visible, we normally want to begin output surface creation
1540 // as soon as possible.
1541 EXPECT_ACTION_UPDATE_STATE(
1542 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1544 state.DidCreateAndInitializeOutputSurface();
1545 EXPECT_EQ(state.output_surface_state(),
1546 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT);
1548 // We should not send a BeginMainFrame when we are invisible, even if we've
1549 // lost the output surface and are trying to get the first commit, since the
1550 // main thread will just abort anyway.
1551 state.SetVisible(false);
1552 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
1555 TEST(SchedulerStateMachineTest, ReportIfNotDrawing) {
1556 SchedulerSettings default_scheduler_settings;
1557 StateMachine state(default_scheduler_settings);
1558 SET_UP_STATE(state)
1559 EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
1561 state.SetCanDraw(false);
1562 state.SetVisible(true);
1563 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1565 state.SetCanDraw(true);
1566 state.SetVisible(false);
1567 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1569 state.SetCanDraw(false);
1570 state.SetVisible(false);
1571 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1573 state.SetCanDraw(true);
1574 state.SetVisible(true);
1575 EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
1578 TEST(SchedulerStateMachineTest,
1579 TestTriggerDeadlineImmediatelyAfterAbortedCommit) {
1580 SchedulerSettings settings;
1581 settings.impl_side_painting = true;
1582 StateMachine state(settings);
1583 SET_UP_STATE(state)
1585 // This test mirrors what happens during the first frame of a scroll gesture.
1586 // First we get the input event and a BeginFrame.
1587 state.OnBeginImplFrame();
1589 // As a response the compositor requests a redraw and a commit to tell the
1590 // main thread about the new scroll offset.
1591 state.SetNeedsRedraw(true);
1592 state.SetNeedsCommit();
1594 // We should start the commit normally.
1595 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1596 EXPECT_ACTION_UPDATE_STATE(
1597 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1598 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1600 // Since only the scroll offset changed, the main thread will abort the
1601 // commit.
1602 state.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES);
1604 // Since the commit was aborted, we should draw right away instead of waiting
1605 // for the deadline.
1606 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1609 void FinishPreviousCommitAndDrawWithoutExitingDeadline(
1610 StateMachine* state_ptr) {
1611 // Gross, but allows us to use macros below.
1612 StateMachine& state = *state_ptr;
1614 state.NotifyBeginMainFrameStarted();
1615 state.NotifyReadyToCommit();
1616 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1617 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1618 state.NotifyReadyToActivate();
1619 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1620 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1622 state.OnBeginImplFrame();
1623 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1624 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1626 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1627 state.OnBeginImplFrameDeadline();
1628 EXPECT_ACTION_UPDATE_STATE(
1629 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1630 state.DidSwapBuffers();
1633 TEST(SchedulerStateMachineTest, TestImplLatencyTakesPriority) {
1634 SchedulerSettings settings;
1635 settings.impl_side_painting = true;
1636 StateMachine state(settings);
1637 SET_UP_STATE(state)
1639 // This test ensures that impl-draws are prioritized over main thread updates
1640 // in prefer impl latency mode.
1641 state.SetNeedsRedraw(true);
1642 state.SetNeedsCommit();
1643 state.OnBeginImplFrame();
1644 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1645 EXPECT_ACTION_UPDATE_STATE(
1646 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1647 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1649 // Verify the deadline is not triggered early until we enter
1650 // prefer impl latency mode.
1651 EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1652 state.SetImplLatencyTakesPriority(true);
1653 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1655 // Trigger the deadline.
1656 state.OnBeginImplFrameDeadline();
1657 EXPECT_ACTION_UPDATE_STATE(
1658 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1659 state.DidSwapBuffers();
1660 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1661 state.DidSwapBuffersComplete();
1663 // Request a new commit and finish the previous one.
1664 state.SetNeedsCommit();
1665 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state);
1666 EXPECT_ACTION_UPDATE_STATE(
1667 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1668 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1669 state.DidSwapBuffersComplete();
1670 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1672 // Finish the previous commit and draw it.
1673 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state);
1674 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1676 // Verify we do not send another BeginMainFrame if was are swap throttled
1677 // and did not just swap.
1678 state.SetNeedsCommit();
1679 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1680 state.OnBeginImplFrame();
1681 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1682 EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1683 state.OnBeginImplFrameDeadline();
1684 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1687 TEST(SchedulerStateMachineTest,
1688 TestTriggerDeadlineImmediatelyOnLostOutputSurface) {
1689 SchedulerSettings default_scheduler_settings;
1690 StateMachine state(default_scheduler_settings);
1691 SET_UP_STATE(state)
1693 state.SetNeedsCommit();
1695 state.OnBeginImplFrame();
1696 EXPECT_ACTION_UPDATE_STATE(
1697 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1698 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1699 EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1701 state.DidLoseOutputSurface();
1702 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1703 // The deadline should be triggered immediately when output surface is lost.
1704 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
1707 TEST(SchedulerStateMachineTest, TestSetNeedsAnimate) {
1708 SchedulerSettings settings;
1709 settings.impl_side_painting = true;
1710 StateMachine state(settings);
1711 SET_UP_STATE(state)
1713 // Test requesting an animation that, when run, causes us to draw.
1714 state.SetNeedsAnimate();
1715 EXPECT_TRUE(state.BeginFrameNeeded());
1716 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1718 state.OnBeginImplFrame();
1719 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1721 state.OnBeginImplFrameDeadlinePending();
1722 state.OnBeginImplFrameDeadline();
1723 EXPECT_ACTION_UPDATE_STATE(
1724 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1727 TEST(SchedulerStateMachineTest, TestAnimateBeforeCommit) {
1728 SchedulerSettings settings;
1729 settings.impl_side_painting = true;
1730 StateMachine state(settings);
1731 SET_UP_STATE(state)
1733 // Check that animations are updated before we start a commit.
1734 state.SetNeedsAnimate();
1735 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1736 state.SetNeedsCommit();
1737 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1738 EXPECT_TRUE(state.BeginFrameNeeded());
1740 state.OnBeginImplFrame();
1741 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1742 EXPECT_ACTION_UPDATE_STATE(
1743 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1745 state.OnBeginImplFrameDeadlinePending();
1746 state.OnBeginImplFrameDeadline();
1747 EXPECT_ACTION_UPDATE_STATE(
1748 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1751 TEST(SchedulerStateMachineTest, TestAnimateAfterCommitBeforeDraw) {
1752 SchedulerSettings settings;
1753 settings.impl_side_painting = true;
1754 StateMachine state(settings);
1755 SET_UP_STATE(state)
1757 // Check that animations are updated before we start a commit.
1758 state.SetNeedsAnimate();
1759 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1760 state.SetNeedsCommit();
1761 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1762 EXPECT_TRUE(state.BeginFrameNeeded());
1764 state.OnBeginImplFrame();
1765 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1766 EXPECT_ACTION_UPDATE_STATE(
1767 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1769 state.NotifyBeginMainFrameStarted();
1770 state.NotifyReadyToCommit();
1771 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1773 state.OnBeginImplFrameDeadlinePending();
1774 state.OnBeginImplFrameDeadline();
1775 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1776 EXPECT_ACTION_UPDATE_STATE(
1777 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1780 TEST(SchedulerStateMachineTest, TestSetNeedsAnimateAfterAnimate) {
1781 SchedulerSettings settings;
1782 settings.impl_side_painting = true;
1783 StateMachine state(settings);
1784 SET_UP_STATE(state)
1786 // Test requesting an animation after we have already animated during this
1787 // frame.
1788 state.SetNeedsRedraw(true);
1789 EXPECT_TRUE(state.BeginFrameNeeded());
1790 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1792 state.OnBeginImplFrame();
1793 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1795 state.SetNeedsAnimate();
1796 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1798 state.OnBeginImplFrameDeadline();
1799 EXPECT_ACTION_UPDATE_STATE(
1800 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1803 TEST(SchedulerStateMachineTest, TestForwardBeginFramesToChildren) {
1804 SchedulerSettings settings;
1805 StateMachine state(settings);
1806 SET_UP_STATE(state)
1808 EXPECT_FALSE(state.BeginFrameNeeded());
1809 state.SetChildrenNeedBeginFrames(true);
1810 EXPECT_TRUE(state.BeginFrameNeeded());
1813 TEST(SchedulerStateMachineTest, TestDeferCommit) {
1814 SchedulerSettings settings;
1815 StateMachine state(settings);
1816 SET_UP_STATE(state)
1818 state.SetDeferCommits(true);
1820 state.SetNeedsCommit();
1821 EXPECT_TRUE(state.BeginFrameNeeded());
1822 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1824 state.OnBeginImplFrame();
1825 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1827 state.OnBeginImplFrameDeadline();
1828 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1830 state.SetDeferCommits(false);
1831 state.OnBeginImplFrame();
1832 EXPECT_ACTION_UPDATE_STATE(
1833 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1836 TEST(SchedulerStateMachineTest, EarlyOutCommitWantsProactiveBeginFrame) {
1837 SchedulerSettings settings;
1838 StateMachine state(settings);
1839 SET_UP_STATE(state);
1841 EXPECT_FALSE(state.ProactiveBeginFrameWanted());
1842 bool commit_has_no_updates = true;
1843 state.UpdateStateOnCommit(commit_has_no_updates);
1844 EXPECT_TRUE(state.ProactiveBeginFrameWanted());
1845 state.OnBeginImplFrame();
1846 EXPECT_FALSE(state.ProactiveBeginFrameWanted());
1849 } // namespace
1850 } // namespace cc