1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/scheduler/scheduler_state_machine.h"
7 #include "base/trace_event/trace_event.h"
8 #include "cc/scheduler/scheduler.h"
9 #include "cc/test/begin_frame_args_test.h"
10 #include "testing/gtest/include/gtest/gtest.h"
12 // Macro to compare two enum values and get nice output.
14 // Value of: actual() Actual: 7
15 // Expected: expected() Which is: 0
17 // Value of: actual() Actual: "ACTION_ANIMATE"
18 // Expected: expected() Which is: "ACTION_NONE"
19 #define EXPECT_ENUM_EQ(enum_tostring, expected, actual) \
20 EXPECT_STREQ(SchedulerStateMachine::enum_tostring(expected), \
21 SchedulerStateMachine::enum_tostring(actual))
23 #define EXPECT_IMPL_FRAME_STATE(expected) \
24 EXPECT_ENUM_EQ(BeginImplFrameStateToString, expected, \
25 state.begin_impl_frame_state()) \
26 << state.AsValue()->ToString()
28 #define EXPECT_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); \
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);
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
{
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 void SetNeedsCommitForTest(bool needs_commit
) {
108 needs_commit_
= needs_commit
;
111 bool NeedsCommit() const { return needs_commit_
; }
113 void SetNeedsAnimateForTest(bool needs_animate
) {
114 needs_animate_
= needs_animate
;
117 void SetNeedsRedraw(bool needs_redraw
) { needs_redraw_
= needs_redraw
; }
119 void SetNeedsForcedRedrawForTimeout(bool b
) {
120 forced_redraw_state_
= FORCED_REDRAW_STATE_WAITING_FOR_COMMIT
;
121 active_tree_needs_first_draw_
= true;
123 bool NeedsForcedRedrawForTimeout() const {
124 return forced_redraw_state_
!= FORCED_REDRAW_STATE_IDLE
;
127 void SetActiveTreeNeedsFirstDraw(bool needs_first_draw
) {
128 active_tree_needs_first_draw_
= needs_first_draw
;
131 bool CanDraw() const { return can_draw_
; }
132 bool Visible() const { return visible_
; }
134 bool PendingActivationsShouldBeForced() const {
135 return SchedulerStateMachine::PendingActivationsShouldBeForced();
138 void SetHasPendingTree(bool has_pending_tree
) {
139 has_pending_tree_
= has_pending_tree
;
142 using SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately
;
143 using SchedulerStateMachine::ProactiveBeginFrameWanted
;
144 using SchedulerStateMachine::UpdateStateOnCommit
;
147 TEST(SchedulerStateMachineTest
, BeginFrameNeeded
) {
148 SchedulerSettings default_scheduler_settings
;
149 StateMachine
state(default_scheduler_settings
);
151 EXPECT_ACTION_UPDATE_STATE(
152 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
)
153 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
154 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
156 // Don't request BeginFrames if we are idle.
157 state
.SetVisible(true);
158 state
.SetNeedsRedraw(false);
159 state
.SetNeedsAnimateForTest(false);
160 EXPECT_FALSE(state
.BeginFrameNeeded());
162 // Request BeginFrames if we are ready to draw.
163 state
.SetVisible(true);
164 state
.SetNeedsRedraw(true);
165 state
.SetNeedsAnimateForTest(false);
166 EXPECT_TRUE(state
.BeginFrameNeeded());
168 // Don't background tick for needs_redraw.
169 state
.SetVisible(false);
170 state
.SetNeedsRedraw(true);
171 state
.SetNeedsAnimateForTest(false);
172 EXPECT_FALSE(state
.BeginFrameNeeded());
174 // Proactively request BeginFrames when commit is pending.
175 state
.SetVisible(true);
176 state
.SetNeedsRedraw(false);
177 state
.SetNeedsAnimateForTest(false);
178 state
.SetNeedsCommitForTest(true);
179 EXPECT_TRUE(state
.BeginFrameNeeded());
181 // Don't request BeginFrames when commit is pending if
182 // we are currently deferring commits.
183 state
.SetVisible(true);
184 state
.SetNeedsRedraw(false);
185 state
.SetNeedsAnimateForTest(false);
186 state
.SetNeedsCommitForTest(true);
187 state
.SetDeferCommits(true);
188 EXPECT_FALSE(state
.BeginFrameNeeded());
191 TEST(SchedulerStateMachineTest
, TestNextActionBeginsMainFrameIfNeeded
) {
192 SchedulerSettings default_scheduler_settings
;
194 // If no commit needed, do nothing.
196 StateMachine
state(default_scheduler_settings
);
198 EXPECT_ACTION_UPDATE_STATE(
199 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
)
200 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
201 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
202 state
.SetNeedsRedraw(false);
203 state
.SetVisible(true);
205 EXPECT_FALSE(state
.BeginFrameNeeded());
207 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
208 EXPECT_FALSE(state
.BeginFrameNeeded());
209 state
.OnBeginImplFrame();
211 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
212 state
.OnBeginImplFrameDeadline();
215 // If commit requested but can_start is still false, do nothing.
217 StateMachine
state(default_scheduler_settings
);
218 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
219 state
.SetNeedsRedraw(false);
220 state
.SetVisible(true);
221 state
.SetNeedsCommit();
223 EXPECT_FALSE(state
.BeginFrameNeeded());
225 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
226 EXPECT_FALSE(state
.BeginFrameNeeded());
227 state
.OnBeginImplFrame();
228 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
229 state
.OnBeginImplFrameDeadline();
232 // If commit requested, begin a main frame.
234 StateMachine
state(default_scheduler_settings
);
235 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
237 state
.UpdateState(state
.NextAction());
238 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
239 state
.SetNeedsRedraw(false);
240 state
.SetVisible(true);
241 state
.SetNeedsCommit();
243 EXPECT_TRUE(state
.BeginFrameNeeded());
245 // Expect nothing to happen until after OnBeginImplFrame.
246 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
247 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
248 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
250 state
.OnBeginImplFrame();
251 EXPECT_ACTION_UPDATE_STATE(
252 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
255 // If commit requested and can't draw, still begin a main frame.
257 StateMachine
state(default_scheduler_settings
);
258 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
260 state
.UpdateState(state
.NextAction());
261 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
262 state
.SetNeedsRedraw(false);
263 state
.SetVisible(true);
264 state
.SetNeedsCommit();
265 state
.SetCanDraw(false);
267 EXPECT_TRUE(state
.BeginFrameNeeded());
269 // Expect nothing to happen until after OnBeginImplFrame.
270 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
271 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
272 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
274 state
.OnBeginImplFrame();
275 EXPECT_ACTION_UPDATE_STATE(
276 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
279 // Begin the frame, make sure needs_commit and commit_state update correctly.
281 StateMachine
state(default_scheduler_settings
);
283 state
.UpdateState(state
.NextAction());
284 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
285 state
.SetVisible(true);
286 state
.UpdateState(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
288 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
289 EXPECT_FALSE(state
.NeedsCommit());
293 // Explicitly test main_frame_before_activation_enabled = true
294 TEST(SchedulerStateMachineTest
, MainFrameBeforeActivationEnabled
) {
295 SchedulerSettings scheduler_settings
;
296 scheduler_settings
.impl_side_painting
= true;
297 scheduler_settings
.main_frame_before_activation_enabled
= true;
298 StateMachine
state(scheduler_settings
);
299 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
301 state
.SetNeedsRedraw(false);
302 state
.SetNeedsCommit();
304 EXPECT_TRUE(state
.BeginFrameNeeded());
306 // Commit to the pending tree.
307 state
.OnBeginImplFrame();
308 EXPECT_ACTION_UPDATE_STATE(
309 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
310 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
312 state
.NotifyBeginMainFrameStarted();
313 state
.NotifyReadyToCommit();
314 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
315 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
316 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
318 state
.OnBeginImplFrameDeadline();
319 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
321 // Verify that the next commit starts while there is still a pending tree.
322 state
.SetNeedsCommit();
323 state
.OnBeginImplFrame();
324 EXPECT_ACTION_UPDATE_STATE(
325 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
326 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
328 // Verify the pending commit doesn't overwrite the pending
329 // tree until the pending tree has been activated.
330 state
.NotifyBeginMainFrameStarted();
331 state
.NotifyReadyToCommit();
332 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
334 // Verify NotifyReadyToActivate unblocks activation, draw, and
335 // commit in that order.
336 state
.NotifyReadyToActivate();
337 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
338 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
340 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
341 state
.OnBeginImplFrameDeadline();
342 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
343 EXPECT_ACTION_UPDATE_STATE(
344 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
345 state
.DidSwapBuffers();
346 state
.DidSwapBuffersComplete();
347 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
348 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
349 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
352 TEST(SchedulerStateMachineTest
,
353 TestFailedDrawForAnimationCheckerboardSetsNeedsCommitAndDoesNotDrawAgain
) {
354 SchedulerSettings default_scheduler_settings
;
355 StateMachine
state(default_scheduler_settings
);
357 state
.SetNeedsRedraw(true);
358 EXPECT_TRUE(state
.RedrawPending());
359 EXPECT_TRUE(state
.BeginFrameNeeded());
360 state
.OnBeginImplFrame();
361 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
362 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
363 state
.OnBeginImplFrameDeadline();
365 // We're drawing now.
366 EXPECT_ACTION_UPDATE_STATE(
367 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
368 state
.DidSwapBuffers();
369 state
.DidSwapBuffersComplete();
370 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
372 EXPECT_FALSE(state
.RedrawPending());
373 EXPECT_FALSE(state
.CommitPending());
375 // Failing the draw makes us require a commit.
376 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
377 state
.OnBeginImplFrame();
378 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
379 EXPECT_ACTION_UPDATE_STATE(
380 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
381 EXPECT_TRUE(state
.RedrawPending());
382 EXPECT_TRUE(state
.CommitPending());
385 TEST(SchedulerStateMachineTest
, TestFailedDrawForMissingHighResNeedsCommit
) {
386 SchedulerSettings default_scheduler_settings
;
387 StateMachine
state(default_scheduler_settings
);
389 state
.SetNeedsRedraw(true);
390 EXPECT_TRUE(state
.RedrawPending());
391 EXPECT_TRUE(state
.BeginFrameNeeded());
393 state
.OnBeginImplFrame();
394 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
395 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
396 state
.OnBeginImplFrameDeadline();
397 EXPECT_ACTION_UPDATE_STATE(
398 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
399 state
.DidSwapBuffers();
400 state
.DidSwapBuffersComplete();
401 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
402 EXPECT_FALSE(state
.RedrawPending());
403 EXPECT_FALSE(state
.CommitPending());
405 // Missing high res content requires a commit (but not a redraw)
406 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
);
407 state
.OnBeginImplFrame();
408 EXPECT_ACTION_UPDATE_STATE(
409 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
410 EXPECT_FALSE(state
.RedrawPending());
411 EXPECT_TRUE(state
.CommitPending());
414 TEST(SchedulerStateMachineTest
,
415 TestsetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw
) {
416 SchedulerSettings default_scheduler_settings
;
417 StateMachine
state(default_scheduler_settings
);
419 state
.SetNeedsRedraw(true);
420 EXPECT_TRUE(state
.RedrawPending());
421 EXPECT_TRUE(state
.BeginFrameNeeded());
422 state
.OnBeginImplFrame();
423 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
424 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
425 state
.OnBeginImplFrameDeadline();
427 // We're drawing now.
428 EXPECT_ACTION_UPDATE_STATE(
429 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
430 state
.DidSwapBuffers();
431 state
.DidSwapBuffersComplete();
432 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
433 EXPECT_FALSE(state
.RedrawPending());
434 EXPECT_FALSE(state
.CommitPending());
436 // While still in the same BeginMainFrame callback on the main thread,
437 // set needs redraw again. This should not redraw.
438 state
.SetNeedsRedraw(true);
439 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
441 // Failing the draw for animation checkerboards makes us require a commit.
442 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
443 state
.OnBeginImplFrame();
444 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
445 EXPECT_ACTION_UPDATE_STATE(
446 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
447 EXPECT_TRUE(state
.RedrawPending());
450 TEST(SchedulerStateMachineTest
,
451 TestFailedDrawsEventuallyForceDrawAfterNextCommit
) {
452 SchedulerSettings scheduler_settings
;
453 scheduler_settings
.maximum_number_of_failed_draws_before_draw_is_forced_
= 1;
454 StateMachine
state(scheduler_settings
);
458 state
.SetNeedsCommit();
459 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
460 state
.OnBeginImplFrame();
461 EXPECT_ACTION_UPDATE_STATE(
462 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
463 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
464 EXPECT_TRUE(state
.CommitPending());
466 // Then initiate a draw.
467 state
.SetNeedsRedraw(true);
468 state
.OnBeginImplFrameDeadline();
469 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
470 EXPECT_ACTION_UPDATE_STATE(
471 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
474 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
475 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
476 EXPECT_TRUE(state
.BeginFrameNeeded());
477 EXPECT_TRUE(state
.RedrawPending());
478 // But the commit is ongoing.
479 EXPECT_TRUE(state
.CommitPending());
481 // Finish the commit. Note, we should not yet be forcing a draw, but should
482 // continue the commit as usual.
483 state
.NotifyBeginMainFrameStarted();
484 state
.NotifyReadyToCommit();
485 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
486 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
487 EXPECT_TRUE(state
.RedrawPending());
489 // The redraw should be forced at the end of the next BeginImplFrame.
490 state
.OnBeginImplFrame();
491 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
492 EXPECT_ACTION_UPDATE_STATE(
493 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
494 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
495 state
.OnBeginImplFrameDeadline();
496 EXPECT_ACTION_UPDATE_STATE(
497 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED
);
498 state
.DidSwapBuffers();
499 state
.DidSwapBuffersComplete();
502 TEST(SchedulerStateMachineTest
, TestFailedDrawsDoNotRestartForcedDraw
) {
503 SchedulerSettings scheduler_settings
;
505 scheduler_settings
.maximum_number_of_failed_draws_before_draw_is_forced_
=
507 scheduler_settings
.impl_side_painting
= true;
508 StateMachine
state(scheduler_settings
);
512 state
.SetNeedsCommit();
513 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
514 state
.OnBeginImplFrame();
515 EXPECT_ACTION_UPDATE_STATE(
516 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
517 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
518 EXPECT_TRUE(state
.CommitPending());
520 // Then initiate a draw.
521 state
.SetNeedsRedraw(true);
522 state
.OnBeginImplFrameDeadline();
523 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
524 EXPECT_ACTION_UPDATE_STATE(
525 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
527 // Fail the draw enough times to force a redraw,
528 // then once more for good measure.
529 for (int i
= 0; i
< draw_limit
+ 1; ++i
)
530 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
531 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
532 EXPECT_TRUE(state
.BeginFrameNeeded());
533 EXPECT_TRUE(state
.RedrawPending());
534 // But the commit is ongoing.
535 EXPECT_TRUE(state
.CommitPending());
536 EXPECT_TRUE(state
.ForcedRedrawState() ==
537 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_COMMIT
);
539 state
.NotifyBeginMainFrameStarted();
540 state
.NotifyReadyToCommit();
541 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
542 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
543 EXPECT_TRUE(state
.RedrawPending());
544 EXPECT_FALSE(state
.CommitPending());
546 // Now force redraw should be in waiting for activation
547 EXPECT_TRUE(state
.ForcedRedrawState() ==
548 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
);
550 // After failing additional draws, we should still be in a forced
551 // redraw, but not back in WAITING_FOR_COMMIT.
552 for (int i
= 0; i
< draw_limit
+ 1; ++i
)
553 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
554 EXPECT_TRUE(state
.RedrawPending());
555 EXPECT_TRUE(state
.ForcedRedrawState() ==
556 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
);
559 TEST(SchedulerStateMachineTest
, TestFailedDrawIsRetriedInNextBeginImplFrame
) {
560 SchedulerSettings default_scheduler_settings
;
561 StateMachine
state(default_scheduler_settings
);
565 state
.SetNeedsRedraw(true);
566 EXPECT_TRUE(state
.BeginFrameNeeded());
567 state
.OnBeginImplFrame();
568 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
569 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
570 state
.OnBeginImplFrameDeadline();
571 EXPECT_TRUE(state
.RedrawPending());
572 EXPECT_ACTION_UPDATE_STATE(
573 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
575 // Failing the draw for animation checkerboards makes us require a commit.
576 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
577 EXPECT_ACTION_UPDATE_STATE(
578 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
579 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
580 EXPECT_TRUE(state
.RedrawPending());
582 // We should not be trying to draw again now, but we have a commit pending.
583 EXPECT_TRUE(state
.BeginFrameNeeded());
584 state
.OnBeginImplFrame();
585 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
586 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
588 // We should try to draw again at the end of the next BeginImplFrame on
590 state
.OnBeginImplFrameDeadline();
591 EXPECT_ACTION_UPDATE_STATE(
592 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
593 state
.DidSwapBuffers();
594 state
.DidSwapBuffersComplete();
595 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
598 TEST(SchedulerStateMachineTest
, TestDoestDrawTwiceInSameFrame
) {
599 SchedulerSettings default_scheduler_settings
;
600 StateMachine
state(default_scheduler_settings
);
602 state
.SetNeedsRedraw(true);
604 // Draw the first frame.
605 EXPECT_TRUE(state
.BeginFrameNeeded());
606 state
.OnBeginImplFrame();
607 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
608 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
610 state
.OnBeginImplFrameDeadline();
611 EXPECT_ACTION_UPDATE_STATE(
612 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
613 state
.DidSwapBuffers();
614 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
615 state
.DidSwapBuffersComplete();
616 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
618 // Before the next BeginImplFrame, set needs redraw again.
619 // This should not redraw until the next BeginImplFrame.
620 state
.SetNeedsRedraw(true);
621 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
623 // Move to another frame. This should now draw.
624 EXPECT_TRUE(state
.BeginFrameNeeded());
625 state
.OnBeginImplFrame();
627 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
628 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
630 state
.OnBeginImplFrameDeadline();
631 EXPECT_ACTION_UPDATE_STATE(
632 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
633 state
.DidSwapBuffers();
634 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
635 state
.DidSwapBuffersComplete();
636 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
638 // We just swapped, so we should proactively request another BeginImplFrame.
639 EXPECT_TRUE(state
.BeginFrameNeeded());
642 TEST(SchedulerStateMachineTest
, TestNextActionDrawsOnBeginImplFrame
) {
643 SchedulerSettings default_scheduler_settings
;
645 // When not in BeginImplFrame deadline, or in BeginImplFrame deadline
646 // but not visible, don't draw.
647 size_t num_commit_states
=
648 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
649 size_t num_begin_impl_frame_states
=
650 sizeof(all_begin_impl_frame_states
) /
651 sizeof(SchedulerStateMachine::BeginImplFrameState
);
652 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
653 for (size_t j
= 0; j
< num_begin_impl_frame_states
; ++j
) {
654 StateMachine
state(default_scheduler_settings
);
656 state
.UpdateState(state
.NextAction());
657 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
658 state
.SetCommitState(all_commit_states
[i
]);
659 state
.SetBeginImplFrameState(all_begin_impl_frame_states
[j
]);
661 (all_begin_impl_frame_states
[j
] !=
662 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
663 state
.SetVisible(visible
);
665 // Case 1: needs_commit=false
666 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
669 // Case 2: needs_commit=true
670 state
.SetNeedsCommit();
671 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
673 << state
.AsValue()->ToString();
677 // When in BeginImplFrame deadline we should always draw for SetNeedsRedraw
678 // except if we're ready to commit, in which case we expect a commit first.
679 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
680 StateMachine
state(default_scheduler_settings
);
682 state
.UpdateState(state
.NextAction());
683 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
684 state
.SetCanDraw(true);
685 state
.SetCommitState(all_commit_states
[i
]);
686 state
.SetBeginImplFrameState(
687 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
689 state
.SetNeedsRedraw(true);
690 state
.SetVisible(true);
692 SchedulerStateMachine::Action expected_action
;
693 if (all_commit_states
[i
] ==
694 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
) {
695 expected_action
= SchedulerStateMachine::ACTION_COMMIT
;
697 expected_action
= SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
;
698 EXPECT_ACTION(SchedulerStateMachine::ACTION_ANIMATE
);
699 state
.UpdateState(state
.NextAction());
702 // Case 1: needs_commit=false.
703 EXPECT_ACTION(expected_action
);
705 // Case 2: needs_commit=true.
706 state
.SetNeedsCommit();
707 EXPECT_ACTION(expected_action
);
711 TEST(SchedulerStateMachineTest
, TestNoCommitStatesRedrawWhenInvisible
) {
712 SchedulerSettings default_scheduler_settings
;
714 size_t num_commit_states
=
715 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
716 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
717 // There shouldn't be any drawing regardless of BeginImplFrame.
718 for (size_t j
= 0; j
< 2; ++j
) {
719 StateMachine
state(default_scheduler_settings
);
721 state
.UpdateState(state
.NextAction());
722 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
723 state
.SetCommitState(all_commit_states
[i
]);
724 state
.SetVisible(false);
725 state
.SetNeedsRedraw(true);
727 state
.SetBeginImplFrameState(
728 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
731 // Case 1: needs_commit=false.
732 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
735 // Case 2: needs_commit=true.
736 state
.SetNeedsCommit();
737 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
739 << state
.AsValue()->ToString();
744 TEST(SchedulerStateMachineTest
, TestCanRedraw_StopsDraw
) {
745 SchedulerSettings default_scheduler_settings
;
747 size_t num_commit_states
=
748 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
749 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
750 // There shouldn't be any drawing regardless of BeginImplFrame.
751 for (size_t j
= 0; j
< 2; ++j
) {
752 StateMachine
state(default_scheduler_settings
);
754 state
.UpdateState(state
.NextAction());
755 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
756 state
.SetCommitState(all_commit_states
[i
]);
757 state
.SetVisible(false);
758 state
.SetNeedsRedraw(true);
760 state
.OnBeginImplFrame();
762 state
.SetCanDraw(false);
763 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
769 TEST(SchedulerStateMachineTest
,
770 TestCanRedrawWithWaitingForFirstDrawMakesProgress
) {
771 SchedulerSettings default_scheduler_settings
;
772 StateMachine
state(default_scheduler_settings
);
774 state
.UpdateState(state
.NextAction());
775 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
777 state
.SetActiveTreeNeedsFirstDraw(true);
778 state
.SetNeedsCommit();
779 state
.SetNeedsRedraw(true);
780 state
.SetVisible(true);
781 state
.SetCanDraw(false);
782 state
.OnBeginImplFrame();
783 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
784 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
785 EXPECT_ACTION_UPDATE_STATE(
786 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
787 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
788 state
.NotifyBeginMainFrameStarted();
789 state
.NotifyReadyToCommit();
790 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
791 state
.OnBeginImplFrameDeadline();
792 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
793 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
794 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
797 TEST(SchedulerStateMachineTest
, TestSetNeedsCommitIsNotLost
) {
798 SchedulerSettings scheduler_settings
;
799 StateMachine
state(scheduler_settings
);
801 state
.SetNeedsCommit();
803 EXPECT_TRUE(state
.BeginFrameNeeded());
806 state
.OnBeginImplFrame();
807 EXPECT_ACTION_UPDATE_STATE(
808 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
810 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
812 // Now, while the frame is in progress, set another commit.
813 state
.SetNeedsCommit();
814 EXPECT_TRUE(state
.NeedsCommit());
816 // Let the frame finish.
817 state
.NotifyBeginMainFrameStarted();
818 state
.NotifyReadyToCommit();
819 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
);
821 // Expect to commit regardless of BeginImplFrame state.
822 EXPECT_IMPL_FRAME_STATE(
823 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
824 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
826 state
.OnBeginImplFrameDeadlinePending();
827 EXPECT_IMPL_FRAME_STATE(
828 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
);
829 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
831 state
.OnBeginImplFrameDeadline();
832 EXPECT_IMPL_FRAME_STATE(
833 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
834 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
836 state
.OnBeginImplFrameIdle();
837 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
838 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
840 state
.OnBeginImplFrame();
841 EXPECT_IMPL_FRAME_STATE(
842 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
843 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
845 // Finish the commit, then make sure we start the next commit immediately
846 // and draw on the next BeginImplFrame.
847 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
848 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
849 EXPECT_ACTION_UPDATE_STATE(
850 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
851 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
853 state
.OnBeginImplFrameDeadline();
855 EXPECT_TRUE(state
.active_tree_needs_first_draw());
856 EXPECT_ACTION_UPDATE_STATE(
857 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
858 state
.DidSwapBuffers();
859 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
860 state
.DidSwapBuffersComplete();
861 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
864 TEST(SchedulerStateMachineTest
, TestFullCycle
) {
865 SchedulerSettings default_scheduler_settings
;
866 StateMachine
state(default_scheduler_settings
);
869 // Start clean and set commit.
870 state
.SetNeedsCommit();
873 state
.OnBeginImplFrame();
874 EXPECT_ACTION_UPDATE_STATE(
875 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
877 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
878 EXPECT_FALSE(state
.NeedsCommit());
879 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
881 // Tell the scheduler the frame finished.
882 state
.NotifyBeginMainFrameStarted();
883 state
.NotifyReadyToCommit();
884 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
);
887 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
888 EXPECT_TRUE(state
.active_tree_needs_first_draw());
889 EXPECT_TRUE(state
.needs_redraw());
891 // Expect to do nothing until BeginImplFrame deadline
892 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
894 // At BeginImplFrame deadline, draw.
895 state
.OnBeginImplFrameDeadline();
896 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
897 EXPECT_ACTION_UPDATE_STATE(
898 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
899 state
.DidSwapBuffers();
900 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
901 state
.DidSwapBuffersComplete();
903 // Should be synchronized, no draw needed, no action needed.
904 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
905 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
906 EXPECT_FALSE(state
.needs_redraw());
909 TEST(SchedulerStateMachineTest
, TestFullCycleWithMainThreadLowLatencyMode
) {
910 SchedulerSettings scheduler_settings
;
911 scheduler_settings
.main_thread_should_always_be_low_latency
= true;
912 StateMachine
state(scheduler_settings
);
915 // Start clean and set commit.
916 state
.SetNeedsCommit();
919 state
.OnBeginImplFrame();
920 EXPECT_ACTION_UPDATE_STATE(
921 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
923 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
924 EXPECT_FALSE(state
.NeedsCommit());
925 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
927 // Tell the scheduler the frame finished.
928 state
.NotifyBeginMainFrameStarted();
929 state
.NotifyReadyToCommit();
930 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
);
933 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
934 EXPECT_TRUE(state
.active_tree_needs_first_draw());
935 EXPECT_TRUE(state
.needs_redraw());
937 // Now commit should wait for draw.
938 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW
);
940 // Swap throttled. Do not draw.
941 state
.DidSwapBuffers();
942 state
.OnBeginImplFrameDeadline();
943 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
944 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
945 state
.DidSwapBuffersComplete();
947 // Haven't draw since last commit, do not begin new main frame.
948 state
.SetNeedsCommit();
949 state
.OnBeginImplFrame();
950 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
951 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
953 // At BeginImplFrame deadline, draw.
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
,
969 TestFullCycleWithMainThreadLowLatencyMode_ImplSidePaint
) {
970 SchedulerSettings scheduler_settings
;
971 scheduler_settings
.main_thread_should_always_be_low_latency
= true;
972 scheduler_settings
.impl_side_painting
= true;
973 StateMachine
state(scheduler_settings
);
976 // Start clean and set commit.
977 state
.SetNeedsCommit();
980 state
.OnBeginImplFrame();
981 EXPECT_ACTION_UPDATE_STATE(
982 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
984 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
985 EXPECT_FALSE(state
.NeedsCommit());
986 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
988 // Tell the scheduler the frame finished.
989 state
.NotifyBeginMainFrameStarted();
990 state
.NotifyReadyToCommit();
991 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
);
994 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
996 // Now commit should wait for activation.
998 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION
);
1000 // No activation yet, so this commit is not drawn yet. Force to draw this
1001 // frame, and still block BeginMainFrame.
1002 state
.SetNeedsRedraw(true);
1003 state
.SetNeedsCommit();
1004 state
.OnBeginImplFrameDeadline();
1005 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1006 EXPECT_ACTION_UPDATE_STATE(
1007 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1008 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1010 // Cannot BeginMainFrame yet since last commit is not yet activated and drawn.
1011 state
.OnBeginImplFrame();
1012 EXPECT_COMMIT_STATE(
1013 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION
);
1014 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1016 // Now activate sync tree.
1017 state
.NotifyReadyToActivate();
1018 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1019 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1020 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1021 EXPECT_TRUE(state
.needs_redraw());
1022 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW
);
1024 // Swap throttled. Do not draw.
1025 state
.DidSwapBuffers();
1026 state
.OnBeginImplFrameDeadline();
1027 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1028 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1029 state
.DidSwapBuffersComplete();
1031 // Haven't draw since last commit, do not begin new main frame.
1032 state
.OnBeginImplFrame();
1033 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1034 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1036 // At BeginImplFrame deadline, draw. This draws unblocks BeginMainFrame.
1037 state
.OnBeginImplFrameDeadline();
1038 EXPECT_ACTION_UPDATE_STATE(
1039 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1040 state
.DidSwapBuffers();
1041 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
1042 state
.DidSwapBuffersComplete();
1044 // Now will be able to start main frame.
1045 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1046 EXPECT_FALSE(state
.needs_redraw());
1047 EXPECT_ACTION_UPDATE_STATE(
1048 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1051 TEST(SchedulerStateMachineTest
, TestFullCycleWithCommitRequestInbetween
) {
1052 SchedulerSettings default_scheduler_settings
;
1053 StateMachine
state(default_scheduler_settings
);
1056 // Start clean and set commit.
1057 state
.SetNeedsCommit();
1060 state
.OnBeginImplFrame();
1061 EXPECT_ACTION_UPDATE_STATE(
1062 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1063 EXPECT_COMMIT_STATE(
1064 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1065 EXPECT_FALSE(state
.NeedsCommit());
1066 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1068 // Request another commit while the commit is in flight.
1069 state
.SetNeedsCommit();
1070 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1072 // Tell the scheduler the frame finished.
1073 state
.NotifyBeginMainFrameStarted();
1074 state
.NotifyReadyToCommit();
1075 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
);
1078 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1079 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1080 EXPECT_TRUE(state
.needs_redraw());
1082 // Expect to do nothing until BeginImplFrame deadline.
1083 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1085 // At BeginImplFrame deadline, draw.
1086 state
.OnBeginImplFrameDeadline();
1087 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1088 EXPECT_ACTION_UPDATE_STATE(
1089 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1090 state
.DidSwapBuffers();
1091 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
1092 state
.DidSwapBuffersComplete();
1094 // Should be synchronized, no draw needed, no action needed.
1095 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1096 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1097 EXPECT_FALSE(state
.needs_redraw());
1099 // Next BeginImplFrame should initiate second commit.
1100 state
.OnBeginImplFrame();
1101 EXPECT_ACTION_UPDATE_STATE(
1102 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1105 TEST(SchedulerStateMachineTest
, TestRequestCommitInvisible
) {
1106 SchedulerSettings default_scheduler_settings
;
1107 StateMachine
state(default_scheduler_settings
);
1108 state
.SetCanStart();
1109 state
.UpdateState(state
.NextAction());
1110 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1111 state
.SetNeedsCommit();
1112 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1115 // See ThreadProxy::BeginMainFrame "EarlyOut_NotVisible" /
1116 // "EarlyOut_OutputSurfaceLost" cases.
1117 TEST(SchedulerStateMachineTest
, TestAbortBeginMainFrameBecauseInvisible
) {
1118 SchedulerSettings default_scheduler_settings
;
1119 StateMachine
state(default_scheduler_settings
);
1122 // Start clean and set commit.
1123 state
.SetNeedsCommit();
1125 // Begin the frame while visible.
1126 state
.OnBeginImplFrame();
1127 EXPECT_ACTION_UPDATE_STATE(
1128 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1129 EXPECT_COMMIT_STATE(
1130 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1131 EXPECT_FALSE(state
.NeedsCommit());
1132 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1134 // Become invisible and abort BeginMainFrame.
1135 state
.SetVisible(false);
1136 state
.BeginMainFrameAborted(CommitEarlyOutReason::ABORTED_NOT_VISIBLE
);
1138 // NeedsCommit should now be true again because we never actually did a
1140 EXPECT_TRUE(state
.NeedsCommit());
1142 // We should now be back in the idle state as if we never started the frame.
1143 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1144 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1146 // We shouldn't do anything on the BeginImplFrame deadline.
1147 state
.OnBeginImplFrameDeadline();
1148 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1150 // Become visible again.
1151 state
.SetVisible(true);
1153 // Although we have aborted on this frame and haven't cancelled the commit
1154 // (i.e. need another), don't send another BeginMainFrame yet.
1155 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1156 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1157 EXPECT_TRUE(state
.NeedsCommit());
1159 // Start a new frame.
1160 state
.OnBeginImplFrame();
1161 EXPECT_ACTION_UPDATE_STATE(
1162 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1164 // We should be starting the commit now.
1165 EXPECT_COMMIT_STATE(
1166 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1167 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1170 // See ThreadProxy::BeginMainFrame "EarlyOut_NoUpdates" case.
1171 TEST(SchedulerStateMachineTest
, TestAbortBeginMainFrameBecauseCommitNotNeeded
) {
1172 SchedulerSettings default_scheduler_settings
;
1173 StateMachine
state(default_scheduler_settings
);
1174 state
.SetCanStart();
1175 state
.UpdateState(state
.NextAction());
1176 state
.DidCreateAndInitializeOutputSurface();
1177 state
.SetVisible(true);
1178 state
.SetCanDraw(true);
1180 // Get into a begin frame / commit state.
1181 state
.SetNeedsCommit();
1182 state
.OnBeginImplFrame();
1183 EXPECT_ACTION_UPDATE_STATE(
1184 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1185 EXPECT_COMMIT_STATE(
1186 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1187 EXPECT_FALSE(state
.NeedsCommit());
1188 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1190 // Abort the commit, true means that the BeginMainFrame was sent but there
1191 // was no work to do on the main thread.
1192 state
.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES
);
1194 // NeedsCommit should now be false because the commit was actually handled.
1195 EXPECT_FALSE(state
.NeedsCommit());
1197 // Even though the commit was aborted, we still expect to draw the new frame.
1198 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1199 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1200 state
.OnBeginImplFrameDeadline();
1201 EXPECT_ACTION_UPDATE_STATE(
1202 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1203 state
.DidSwapBuffers();
1204 state
.DidSwapBuffersComplete();
1205 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1207 // Verify another commit doesn't start on another frame either.
1208 EXPECT_FALSE(state
.NeedsCommit());
1209 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1211 state
.OnBeginImplFrame();
1212 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1213 state
.OnBeginImplFrameDeadline();
1214 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1216 // Verify another commit can start if requested, though.
1217 state
.SetNeedsCommit();
1218 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1219 state
.OnBeginImplFrame();
1220 EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1223 TEST(SchedulerStateMachineTest
, TestFirstContextCreation
) {
1224 SchedulerSettings default_scheduler_settings
;
1225 StateMachine
state(default_scheduler_settings
);
1226 state
.SetCanStart();
1227 state
.SetVisible(true);
1228 state
.SetCanDraw(true);
1230 EXPECT_ACTION_UPDATE_STATE(
1231 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1232 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1233 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1235 // Check that the first init does not SetNeedsCommit.
1236 state
.OnBeginImplFrame();
1237 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1238 state
.OnBeginImplFrameDeadline();
1239 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1241 // Check that a needs commit initiates a BeginMainFrame.
1242 state
.SetNeedsCommit();
1243 state
.OnBeginImplFrame();
1244 EXPECT_ACTION_UPDATE_STATE(
1245 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1248 TEST(SchedulerStateMachineTest
, TestContextLostWhenCompletelyIdle
) {
1249 SchedulerSettings default_scheduler_settings
;
1250 StateMachine
state(default_scheduler_settings
);
1253 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1254 state
.NextAction());
1255 state
.DidLoseOutputSurface();
1257 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1258 state
.UpdateState(state
.NextAction());
1260 // Once context recreation begins, nothing should happen.
1261 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1263 // Recreate the context.
1264 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1266 // When the context is recreated, we should begin a commit.
1267 state
.OnBeginImplFrame();
1268 EXPECT_ACTION_UPDATE_STATE(
1269 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1272 TEST(SchedulerStateMachineTest
,
1273 TestContextLostWhenIdleAndCommitRequestedWhileRecreating
) {
1274 SchedulerSettings default_scheduler_settings
;
1275 // We use impl side painting because it's the more complicated version.
1276 default_scheduler_settings
.impl_side_painting
= true;
1277 StateMachine
state(default_scheduler_settings
);
1280 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1281 state
.NextAction());
1282 state
.DidLoseOutputSurface();
1283 EXPECT_EQ(state
.output_surface_state(),
1284 SchedulerStateMachine::OUTPUT_SURFACE_LOST
);
1286 EXPECT_ACTION_UPDATE_STATE(
1287 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1288 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1290 // Once context recreation begins, nothing should happen.
1291 state
.OnBeginImplFrame();
1292 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1293 state
.OnBeginImplFrameDeadline();
1294 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1296 // While context is recreating, commits shouldn't begin.
1297 state
.SetNeedsCommit();
1298 state
.OnBeginImplFrame();
1299 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1300 state
.OnBeginImplFrameDeadline();
1301 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1303 // Recreate the context
1304 state
.DidCreateAndInitializeOutputSurface();
1305 EXPECT_EQ(state
.output_surface_state(),
1306 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT
);
1307 EXPECT_FALSE(state
.RedrawPending());
1309 // When the context is recreated, we wait until the next BeginImplFrame
1311 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1313 // When the BeginFrame comes in we should begin a commit
1314 state
.OnBeginImplFrame();
1315 EXPECT_ACTION_UPDATE_STATE(
1316 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1317 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1318 EXPECT_COMMIT_STATE(
1319 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1321 // Until that commit finishes, we shouldn't be drawing or animate.
1322 state
.OnBeginImplFrameDeadline();
1323 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1325 // Finish the commit, which should make the surface active.
1326 state
.NotifyBeginMainFrameStarted();
1327 state
.NotifyReadyToCommit();
1328 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1329 EXPECT_EQ(state
.output_surface_state(),
1330 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION
);
1331 state
.NotifyReadyToActivate();
1332 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1333 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1334 EXPECT_EQ(state
.output_surface_state(),
1335 SchedulerStateMachine::OUTPUT_SURFACE_ACTIVE
);
1337 // Finishing the first commit after initializing an output surface should
1338 // automatically cause a redraw.
1339 EXPECT_TRUE(state
.RedrawPending());
1340 state
.OnBeginImplFrame();
1341 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1342 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1343 state
.OnBeginImplFrameDeadline();
1344 EXPECT_ACTION_UPDATE_STATE(
1345 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1346 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1347 EXPECT_FALSE(state
.RedrawPending());
1349 // Next frame as no work to do.
1350 state
.OnBeginImplFrame();
1351 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1352 state
.OnBeginImplFrameDeadline();
1353 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1355 // Once the context is recreated, whether we draw should be based on
1356 // SetCanDraw if waiting on first draw after activate.
1357 state
.SetNeedsRedraw(true);
1358 state
.OnBeginImplFrame();
1359 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1360 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1361 state
.OnBeginImplFrameDeadline();
1362 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1363 state
.SetCanDraw(false);
1364 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1365 state
.SetCanDraw(true);
1366 EXPECT_ACTION_UPDATE_STATE(
1367 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1368 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1370 // Once the context is recreated, whether we draw should be based on
1371 // SetCanDraw if waiting on first draw after activate.
1372 state
.SetNeedsRedraw(true);
1373 state
.SetNeedsCommit();
1374 state
.OnBeginImplFrame();
1375 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1376 EXPECT_ACTION_UPDATE_STATE(
1377 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1378 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1379 // Activate so we need the first draw
1380 state
.NotifyBeginMainFrameStarted();
1381 state
.NotifyReadyToCommit();
1382 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1383 state
.NotifyReadyToActivate();
1384 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1385 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1386 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1387 EXPECT_TRUE(state
.needs_redraw());
1389 state
.OnBeginImplFrameDeadline();
1390 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1391 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1392 state
.SetCanDraw(false);
1393 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1394 state
.SetCanDraw(true);
1395 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1398 TEST(SchedulerStateMachineTest
, TestContextLostWhileCommitInProgress
) {
1399 SchedulerSettings scheduler_settings
;
1400 StateMachine
state(scheduler_settings
);
1403 // Get a commit in flight.
1404 state
.SetNeedsCommit();
1406 // Set damage and expect a draw.
1407 state
.SetNeedsRedraw(true);
1408 state
.OnBeginImplFrame();
1409 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1410 EXPECT_ACTION_UPDATE_STATE(
1411 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1412 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1413 state
.OnBeginImplFrameDeadline();
1414 EXPECT_ACTION_UPDATE_STATE(
1415 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1416 state
.DidSwapBuffers();
1417 state
.DidSwapBuffersComplete();
1418 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1420 // Cause a lost context while the BeginMainFrame is in flight.
1421 state
.DidLoseOutputSurface();
1423 // Ask for another draw. Expect nothing happens.
1424 state
.SetNeedsRedraw(true);
1425 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1427 // Finish the frame, and commit.
1428 state
.NotifyBeginMainFrameStarted();
1429 state
.NotifyReadyToCommit();
1430 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1432 // We will abort the draw when the output surface is lost if we are
1433 // waiting for the first draw to unblock the main thread.
1434 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1435 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1437 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1438 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
1439 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1441 state
.OnBeginImplFrame();
1442 EXPECT_IMPL_FRAME_STATE(
1443 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
1444 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1446 state
.OnBeginImplFrameDeadlinePending();
1447 EXPECT_IMPL_FRAME_STATE(
1448 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
);
1449 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1451 state
.OnBeginImplFrameDeadline();
1452 EXPECT_IMPL_FRAME_STATE(
1453 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
1454 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1457 TEST(SchedulerStateMachineTest
,
1458 TestContextLostWhileCommitInProgressAndAnotherCommitRequested
) {
1459 SchedulerSettings scheduler_settings
;
1460 StateMachine
state(scheduler_settings
);
1463 // Get a commit in flight.
1464 state
.SetNeedsCommit();
1465 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1467 // Set damage and expect a draw.
1468 state
.SetNeedsRedraw(true);
1469 state
.OnBeginImplFrame();
1470 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1471 EXPECT_ACTION_UPDATE_STATE(
1472 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1473 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1474 state
.OnBeginImplFrameDeadline();
1475 EXPECT_ACTION_UPDATE_STATE(
1476 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1477 state
.DidSwapBuffers();
1478 state
.DidSwapBuffersComplete();
1479 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1481 // Cause a lost context while the BeginMainFrame is in flight.
1482 state
.DidLoseOutputSurface();
1484 // Ask for another draw and also set needs commit. Expect nothing happens.
1485 state
.SetNeedsRedraw(true);
1486 state
.SetNeedsCommit();
1487 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1489 // Finish the frame, and commit.
1490 state
.NotifyBeginMainFrameStarted();
1491 state
.NotifyReadyToCommit();
1492 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1493 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1495 // Because the output surface is missing, we expect the draw to abort.
1496 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1498 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1499 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
1500 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1502 state
.OnBeginImplFrame();
1503 EXPECT_IMPL_FRAME_STATE(
1504 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
1505 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1507 state
.OnBeginImplFrameDeadlinePending();
1508 EXPECT_IMPL_FRAME_STATE(
1509 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
);
1510 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1512 state
.OnBeginImplFrameDeadline();
1513 EXPECT_IMPL_FRAME_STATE(
1514 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
1515 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1517 state
.OnBeginImplFrameIdle();
1518 EXPECT_ACTION_UPDATE_STATE(
1519 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1521 // After we get a new output surface, the commit flow should start.
1522 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1523 state
.OnBeginImplFrame();
1524 EXPECT_ACTION_UPDATE_STATE(
1525 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1526 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1527 state
.NotifyBeginMainFrameStarted();
1528 state
.NotifyReadyToCommit();
1529 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1530 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1531 state
.OnBeginImplFrameDeadline();
1532 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1533 EXPECT_ACTION_UPDATE_STATE(
1534 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1535 state
.DidSwapBuffers();
1536 state
.DidSwapBuffersComplete();
1537 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1540 TEST(SchedulerStateMachineTest
, DontDrawBeforeCommitAfterLostOutputSurface
) {
1541 SchedulerSettings default_scheduler_settings
;
1542 StateMachine
state(default_scheduler_settings
);
1545 state
.SetNeedsRedraw(true);
1547 // Cause a lost output surface, and restore it.
1548 state
.DidLoseOutputSurface();
1549 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1550 state
.UpdateState(state
.NextAction());
1551 state
.DidCreateAndInitializeOutputSurface();
1553 EXPECT_FALSE(state
.RedrawPending());
1554 state
.OnBeginImplFrame();
1555 EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1558 TEST(SchedulerStateMachineTest
,
1559 TestPendingActivationsShouldBeForcedAfterLostOutputSurface
) {
1560 SchedulerSettings settings
;
1561 settings
.impl_side_painting
= true;
1562 StateMachine
state(settings
);
1565 state
.SetCommitState(
1566 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1568 // Cause a lost context.
1569 state
.DidLoseOutputSurface();
1571 state
.NotifyBeginMainFrameStarted();
1572 state
.NotifyReadyToCommit();
1573 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1575 EXPECT_TRUE(state
.PendingActivationsShouldBeForced());
1576 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1578 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1579 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1582 TEST(SchedulerStateMachineTest
, TestNoBeginFrameNeededWhenInvisible
) {
1583 SchedulerSettings default_scheduler_settings
;
1584 StateMachine
state(default_scheduler_settings
);
1585 state
.SetCanStart();
1586 state
.UpdateState(state
.NextAction());
1587 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1588 state
.SetVisible(true);
1590 EXPECT_FALSE(state
.BeginFrameNeeded());
1591 state
.SetNeedsRedraw(true);
1592 EXPECT_TRUE(state
.BeginFrameNeeded());
1594 state
.SetVisible(false);
1595 EXPECT_FALSE(state
.BeginFrameNeeded());
1597 state
.SetVisible(true);
1598 EXPECT_TRUE(state
.BeginFrameNeeded());
1601 TEST(SchedulerStateMachineTest
, TestNoBeginMainFrameWhenInvisible
) {
1602 SchedulerSettings default_scheduler_settings
;
1603 StateMachine
state(default_scheduler_settings
);
1604 state
.SetCanStart();
1605 state
.UpdateState(state
.NextAction());
1606 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1607 state
.SetVisible(false);
1608 state
.SetNeedsCommit();
1609 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1610 EXPECT_FALSE(state
.BeginFrameNeeded());
1612 // When become visible again, the needs commit should still be pending.
1613 state
.SetVisible(true);
1614 EXPECT_TRUE(state
.BeginFrameNeeded());
1615 state
.OnBeginImplFrame();
1616 EXPECT_ACTION_UPDATE_STATE(
1617 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1620 TEST(SchedulerStateMachineTest
, TestFinishCommitWhenCommitInProgress
) {
1621 SchedulerSettings default_scheduler_settings
;
1622 StateMachine
state(default_scheduler_settings
);
1623 state
.SetCanStart();
1624 state
.UpdateState(state
.NextAction());
1625 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1626 state
.SetVisible(false);
1627 state
.SetCommitState(
1628 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1629 state
.SetNeedsCommit();
1631 state
.NotifyBeginMainFrameStarted();
1632 state
.NotifyReadyToCommit();
1633 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
1634 state
.UpdateState(state
.NextAction());
1636 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1637 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1640 TEST(SchedulerStateMachineTest
, TestInitialActionsWhenContextLost
) {
1641 SchedulerSettings default_scheduler_settings
;
1642 StateMachine
state(default_scheduler_settings
);
1644 state
.SetNeedsCommit();
1645 state
.DidLoseOutputSurface();
1647 // When we are visible, we normally want to begin output surface creation
1648 // as soon as possible.
1649 EXPECT_ACTION_UPDATE_STATE(
1650 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1652 state
.DidCreateAndInitializeOutputSurface();
1653 EXPECT_EQ(state
.output_surface_state(),
1654 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT
);
1656 // We should not send a BeginMainFrame when we are invisible, even if we've
1657 // lost the output surface and are trying to get the first commit, since the
1658 // main thread will just abort anyway.
1659 state
.SetVisible(false);
1660 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1663 TEST(SchedulerStateMachineTest
, ReportIfNotDrawing
) {
1664 SchedulerSettings default_scheduler_settings
;
1665 StateMachine
state(default_scheduler_settings
);
1667 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1669 state
.SetCanDraw(false);
1670 state
.SetVisible(true);
1671 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1673 state
.SetCanDraw(true);
1674 state
.SetVisible(false);
1675 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1677 state
.SetCanDraw(false);
1678 state
.SetVisible(false);
1679 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1681 state
.SetCanDraw(true);
1682 state
.SetVisible(true);
1683 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1686 TEST(SchedulerStateMachineTest
,
1687 TestTriggerDeadlineImmediatelyAfterAbortedCommit
) {
1688 SchedulerSettings settings
;
1689 settings
.impl_side_painting
= true;
1690 StateMachine
state(settings
);
1693 // This test mirrors what happens during the first frame of a scroll gesture.
1694 // First we get the input event and a BeginFrame.
1695 state
.OnBeginImplFrame();
1697 // As a response the compositor requests a redraw and a commit to tell the
1698 // main thread about the new scroll offset.
1699 state
.SetNeedsRedraw(true);
1700 state
.SetNeedsCommit();
1702 // We should start the commit normally.
1703 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1704 EXPECT_ACTION_UPDATE_STATE(
1705 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1706 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1708 // Since only the scroll offset changed, the main thread will abort the
1710 state
.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES
);
1712 // Since the commit was aborted, we should draw right away instead of waiting
1713 // for the deadline.
1714 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1717 void FinishPreviousCommitAndDrawWithoutExitingDeadline(
1718 StateMachine
* state_ptr
) {
1719 // Gross, but allows us to use macros below.
1720 StateMachine
& state
= *state_ptr
;
1722 state
.NotifyBeginMainFrameStarted();
1723 state
.NotifyReadyToCommit();
1724 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1725 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1726 state
.NotifyReadyToActivate();
1727 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1728 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1730 state
.OnBeginImplFrame();
1731 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1732 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1734 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1735 state
.OnBeginImplFrameDeadline();
1736 EXPECT_ACTION_UPDATE_STATE(
1737 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1738 state
.DidSwapBuffers();
1741 TEST(SchedulerStateMachineTest
, TestImplLatencyTakesPriority
) {
1742 SchedulerSettings settings
;
1743 settings
.impl_side_painting
= true;
1744 StateMachine
state(settings
);
1747 // This test ensures that impl-draws are prioritized over main thread updates
1748 // in prefer impl latency mode.
1749 state
.SetNeedsRedraw(true);
1750 state
.SetNeedsCommit();
1751 state
.OnBeginImplFrame();
1752 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1753 EXPECT_ACTION_UPDATE_STATE(
1754 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1755 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1757 // Verify the deadline is not triggered early until we enter
1758 // prefer impl latency mode.
1759 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1760 state
.SetImplLatencyTakesPriority(true);
1761 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1763 // Trigger the deadline.
1764 state
.OnBeginImplFrameDeadline();
1765 EXPECT_ACTION_UPDATE_STATE(
1766 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1767 state
.DidSwapBuffers();
1768 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1769 state
.DidSwapBuffersComplete();
1771 // Request a new commit and finish the previous one.
1772 state
.SetNeedsCommit();
1773 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state
);
1774 EXPECT_ACTION_UPDATE_STATE(
1775 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1776 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1777 state
.DidSwapBuffersComplete();
1778 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1780 // Finish the previous commit and draw it.
1781 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state
);
1782 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1784 // Verify we do not send another BeginMainFrame if was are swap throttled
1785 // and did not just swap.
1786 state
.SetNeedsCommit();
1787 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1788 state
.OnBeginImplFrame();
1789 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1790 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1791 state
.OnBeginImplFrameDeadline();
1792 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1795 TEST(SchedulerStateMachineTest
,
1796 TestTriggerDeadlineImmediatelyOnLostOutputSurface
) {
1797 SchedulerSettings default_scheduler_settings
;
1798 StateMachine
state(default_scheduler_settings
);
1801 state
.SetNeedsCommit();
1803 state
.OnBeginImplFrame();
1804 EXPECT_ACTION_UPDATE_STATE(
1805 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1806 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1807 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1809 state
.DidLoseOutputSurface();
1810 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1811 // The deadline should be triggered immediately when output surface is lost.
1812 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1815 TEST(SchedulerStateMachineTest
, TestTriggerDeadlineImmediatelyWhenInvisible
) {
1816 SchedulerSettings settings
;
1817 settings
.impl_side_painting
= true;
1818 StateMachine
state(settings
);
1821 state
.SetNeedsCommit();
1823 state
.OnBeginImplFrame();
1824 EXPECT_ACTION_UPDATE_STATE(
1825 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1826 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1827 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1829 state
.SetVisible(false);
1830 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1831 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1834 TEST(SchedulerStateMachineTest
, TestSetNeedsAnimate
) {
1835 SchedulerSettings settings
;
1836 settings
.impl_side_painting
= true;
1837 StateMachine
state(settings
);
1840 // Test requesting an animation that, when run, causes us to draw.
1841 state
.SetNeedsAnimate();
1842 EXPECT_TRUE(state
.BeginFrameNeeded());
1843 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1845 state
.OnBeginImplFrame();
1846 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1848 state
.OnBeginImplFrameDeadlinePending();
1849 state
.OnBeginImplFrameDeadline();
1850 EXPECT_ACTION_UPDATE_STATE(
1851 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1854 TEST(SchedulerStateMachineTest
, TestAnimateBeforeCommit
) {
1855 SchedulerSettings settings
;
1856 settings
.impl_side_painting
= true;
1857 StateMachine
state(settings
);
1860 // Check that animations are updated before we start a commit.
1861 state
.SetNeedsAnimate();
1862 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1863 state
.SetNeedsCommit();
1864 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1865 EXPECT_TRUE(state
.BeginFrameNeeded());
1867 state
.OnBeginImplFrame();
1868 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1869 EXPECT_ACTION_UPDATE_STATE(
1870 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1872 state
.OnBeginImplFrameDeadlinePending();
1873 state
.OnBeginImplFrameDeadline();
1874 EXPECT_ACTION_UPDATE_STATE(
1875 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1878 TEST(SchedulerStateMachineTest
, TestAnimateAfterCommitBeforeDraw
) {
1879 SchedulerSettings settings
;
1880 settings
.impl_side_painting
= true;
1881 StateMachine
state(settings
);
1884 // Check that animations are updated before we start a commit.
1885 state
.SetNeedsAnimate();
1886 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1887 state
.SetNeedsCommit();
1888 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1889 EXPECT_TRUE(state
.BeginFrameNeeded());
1891 state
.OnBeginImplFrame();
1892 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1893 EXPECT_ACTION_UPDATE_STATE(
1894 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1896 state
.NotifyBeginMainFrameStarted();
1897 state
.NotifyReadyToCommit();
1898 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1900 state
.OnBeginImplFrameDeadlinePending();
1901 state
.OnBeginImplFrameDeadline();
1902 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1903 EXPECT_ACTION_UPDATE_STATE(
1904 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1907 TEST(SchedulerStateMachineTest
, TestSetNeedsAnimateAfterAnimate
) {
1908 SchedulerSettings settings
;
1909 settings
.impl_side_painting
= true;
1910 StateMachine
state(settings
);
1913 // Test requesting an animation after we have already animated during this
1915 state
.SetNeedsRedraw(true);
1916 EXPECT_TRUE(state
.BeginFrameNeeded());
1917 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1919 state
.OnBeginImplFrame();
1920 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1922 state
.SetNeedsAnimate();
1923 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1925 state
.OnBeginImplFrameDeadline();
1926 EXPECT_ACTION_UPDATE_STATE(
1927 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1930 TEST(SchedulerStateMachineTest
, TestForwardBeginFramesToChildren
) {
1931 SchedulerSettings settings
;
1932 StateMachine
state(settings
);
1935 EXPECT_FALSE(state
.BeginFrameNeeded());
1936 state
.SetChildrenNeedBeginFrames(true);
1937 EXPECT_TRUE(state
.BeginFrameNeeded());
1940 TEST(SchedulerStateMachineTest
, TestDeferCommit
) {
1941 SchedulerSettings settings
;
1942 StateMachine
state(settings
);
1945 state
.SetDeferCommits(true);
1947 state
.SetNeedsCommit();
1948 EXPECT_FALSE(state
.BeginFrameNeeded());
1949 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1951 state
.OnBeginImplFrame();
1952 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1954 state
.OnBeginImplFrameDeadline();
1955 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1957 state
.SetDeferCommits(false);
1958 state
.OnBeginImplFrame();
1959 EXPECT_ACTION_UPDATE_STATE(
1960 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1963 TEST(SchedulerStateMachineTest
, EarlyOutCommitWantsProactiveBeginFrame
) {
1964 SchedulerSettings settings
;
1965 StateMachine
state(settings
);
1966 SET_UP_STATE(state
);
1968 EXPECT_FALSE(state
.ProactiveBeginFrameWanted());
1969 bool commit_has_no_updates
= true;
1970 state
.UpdateStateOnCommit(commit_has_no_updates
);
1971 EXPECT_TRUE(state
.ProactiveBeginFrameWanted());
1972 state
.OnBeginImplFrame();
1973 EXPECT_FALSE(state
.ProactiveBeginFrameWanted());