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 // Background tick for animations.
175 state
.SetVisible(false);
176 state
.SetNeedsRedraw(false);
177 state
.SetNeedsAnimateForTest(true);
178 EXPECT_TRUE(state
.BeginFrameNeeded());
180 // Proactively request BeginFrames when commit is pending.
181 state
.SetVisible(true);
182 state
.SetNeedsRedraw(false);
183 state
.SetNeedsAnimateForTest(false);
184 state
.SetNeedsCommitForTest(true);
185 EXPECT_TRUE(state
.BeginFrameNeeded());
187 // Don't request BeginFrames when commit is pending if
188 // we are currently deferring commits.
189 state
.SetVisible(true);
190 state
.SetNeedsRedraw(false);
191 state
.SetNeedsAnimateForTest(false);
192 state
.SetNeedsCommitForTest(true);
193 state
.SetDeferCommits(true);
194 EXPECT_FALSE(state
.BeginFrameNeeded());
197 TEST(SchedulerStateMachineTest
, TestNextActionBeginsMainFrameIfNeeded
) {
198 SchedulerSettings default_scheduler_settings
;
200 // If no commit needed, do nothing.
202 StateMachine
state(default_scheduler_settings
);
204 EXPECT_ACTION_UPDATE_STATE(
205 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
)
206 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
207 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
208 state
.SetNeedsRedraw(false);
209 state
.SetVisible(true);
211 EXPECT_FALSE(state
.BeginFrameNeeded());
213 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
214 EXPECT_FALSE(state
.BeginFrameNeeded());
215 state
.OnBeginImplFrame();
217 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
218 state
.OnBeginImplFrameDeadline();
221 // If commit requested but can_start is still false, do nothing.
223 StateMachine
state(default_scheduler_settings
);
224 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
225 state
.SetNeedsRedraw(false);
226 state
.SetVisible(true);
227 state
.SetNeedsCommit();
229 EXPECT_FALSE(state
.BeginFrameNeeded());
231 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
232 EXPECT_FALSE(state
.BeginFrameNeeded());
233 state
.OnBeginImplFrame();
234 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
235 state
.OnBeginImplFrameDeadline();
238 // If commit requested, begin a main frame.
240 StateMachine
state(default_scheduler_settings
);
241 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
243 state
.UpdateState(state
.NextAction());
244 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
245 state
.SetNeedsRedraw(false);
246 state
.SetVisible(true);
247 state
.SetNeedsCommit();
249 EXPECT_TRUE(state
.BeginFrameNeeded());
251 state
.OnBeginImplFrame();
252 EXPECT_ACTION_UPDATE_STATE(
253 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
256 // Begin the frame, make sure needs_commit and commit_state update correctly.
258 StateMachine
state(default_scheduler_settings
);
260 state
.UpdateState(state
.NextAction());
261 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
262 state
.SetVisible(true);
263 state
.UpdateState(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
265 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
266 EXPECT_FALSE(state
.NeedsCommit());
270 // Explicitly test main_frame_before_activation_enabled = true
271 TEST(SchedulerStateMachineTest
, MainFrameBeforeActivationEnabled
) {
272 SchedulerSettings scheduler_settings
;
273 scheduler_settings
.impl_side_painting
= true;
274 scheduler_settings
.main_frame_before_activation_enabled
= true;
275 StateMachine
state(scheduler_settings
);
276 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
278 state
.SetNeedsRedraw(false);
279 state
.SetNeedsCommit();
281 EXPECT_TRUE(state
.BeginFrameNeeded());
283 // Commit to the pending tree.
284 state
.OnBeginImplFrame();
285 EXPECT_ACTION_UPDATE_STATE(
286 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
287 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
289 state
.NotifyBeginMainFrameStarted();
290 state
.NotifyReadyToCommit();
291 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
292 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
293 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
295 state
.OnBeginImplFrameDeadline();
296 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
298 // Verify that the next commit starts while there is still a pending tree.
299 state
.SetNeedsCommit();
300 state
.OnBeginImplFrame();
301 EXPECT_ACTION_UPDATE_STATE(
302 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
303 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
305 // Verify the pending commit doesn't overwrite the pending
306 // tree until the pending tree has been activated.
307 state
.NotifyBeginMainFrameStarted();
308 state
.NotifyReadyToCommit();
309 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
311 // Verify NotifyReadyToActivate unblocks activation, draw, and
312 // commit in that order.
313 state
.NotifyReadyToActivate();
314 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
315 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
317 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
318 state
.OnBeginImplFrameDeadline();
319 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
320 EXPECT_ACTION_UPDATE_STATE(
321 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
322 state
.DidSwapBuffers();
323 state
.DidSwapBuffersComplete();
324 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
325 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
326 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
329 TEST(SchedulerStateMachineTest
,
330 TestFailedDrawForAnimationCheckerboardSetsNeedsCommitAndDoesNotDrawAgain
) {
331 SchedulerSettings default_scheduler_settings
;
332 StateMachine
state(default_scheduler_settings
);
334 state
.SetNeedsRedraw(true);
335 EXPECT_TRUE(state
.RedrawPending());
336 EXPECT_TRUE(state
.BeginFrameNeeded());
337 state
.OnBeginImplFrame();
338 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
339 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
340 state
.OnBeginImplFrameDeadline();
342 // We're drawing now.
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_NONE
);
349 EXPECT_FALSE(state
.RedrawPending());
350 EXPECT_FALSE(state
.CommitPending());
352 // Failing the draw makes us require a commit.
353 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
354 state
.OnBeginImplFrame();
355 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
356 EXPECT_ACTION_UPDATE_STATE(
357 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
358 EXPECT_TRUE(state
.RedrawPending());
359 EXPECT_TRUE(state
.CommitPending());
362 TEST(SchedulerStateMachineTest
, TestFailedDrawForMissingHighResNeedsCommit
) {
363 SchedulerSettings default_scheduler_settings
;
364 StateMachine
state(default_scheduler_settings
);
366 state
.SetNeedsRedraw(true);
367 EXPECT_TRUE(state
.RedrawPending());
368 EXPECT_TRUE(state
.BeginFrameNeeded());
370 state
.OnBeginImplFrame();
371 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
372 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
373 state
.OnBeginImplFrameDeadline();
374 EXPECT_ACTION_UPDATE_STATE(
375 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
376 state
.DidSwapBuffers();
377 state
.DidSwapBuffersComplete();
378 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
379 EXPECT_FALSE(state
.RedrawPending());
380 EXPECT_FALSE(state
.CommitPending());
382 // Missing high res content requires a commit (but not a redraw)
383 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
);
384 state
.OnBeginImplFrame();
385 EXPECT_ACTION_UPDATE_STATE(
386 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
387 EXPECT_FALSE(state
.RedrawPending());
388 EXPECT_TRUE(state
.CommitPending());
391 TEST(SchedulerStateMachineTest
,
392 TestsetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw
) {
393 SchedulerSettings default_scheduler_settings
;
394 StateMachine
state(default_scheduler_settings
);
396 state
.SetNeedsRedraw(true);
397 EXPECT_TRUE(state
.RedrawPending());
398 EXPECT_TRUE(state
.BeginFrameNeeded());
399 state
.OnBeginImplFrame();
400 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
401 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
402 state
.OnBeginImplFrameDeadline();
404 // We're drawing now.
405 EXPECT_ACTION_UPDATE_STATE(
406 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
407 state
.DidSwapBuffers();
408 state
.DidSwapBuffersComplete();
409 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
410 EXPECT_FALSE(state
.RedrawPending());
411 EXPECT_FALSE(state
.CommitPending());
413 // While still in the same BeginMainFrame callback on the main thread,
414 // set needs redraw again. This should not redraw.
415 state
.SetNeedsRedraw(true);
416 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
418 // Failing the draw for animation checkerboards makes us require a commit.
419 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
420 state
.OnBeginImplFrame();
421 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
422 EXPECT_ACTION_UPDATE_STATE(
423 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
424 EXPECT_TRUE(state
.RedrawPending());
427 TEST(SchedulerStateMachineTest
,
428 TestFailedDrawsEventuallyForceDrawAfterNextCommit
) {
429 SchedulerSettings scheduler_settings
;
430 scheduler_settings
.maximum_number_of_failed_draws_before_draw_is_forced_
= 1;
431 StateMachine
state(scheduler_settings
);
435 state
.SetNeedsCommit();
436 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
437 state
.OnBeginImplFrame();
438 EXPECT_ACTION_UPDATE_STATE(
439 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
440 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
441 EXPECT_TRUE(state
.CommitPending());
443 // Then initiate a draw.
444 state
.SetNeedsRedraw(true);
445 state
.OnBeginImplFrameDeadline();
446 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
447 EXPECT_ACTION_UPDATE_STATE(
448 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
451 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
452 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
453 EXPECT_TRUE(state
.BeginFrameNeeded());
454 EXPECT_TRUE(state
.RedrawPending());
455 // But the commit is ongoing.
456 EXPECT_TRUE(state
.CommitPending());
458 // Finish the commit. Note, we should not yet be forcing a draw, but should
459 // continue the commit as usual.
460 state
.NotifyBeginMainFrameStarted();
461 state
.NotifyReadyToCommit();
462 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
463 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
464 EXPECT_TRUE(state
.RedrawPending());
466 // The redraw should be forced at the end of the next BeginImplFrame.
467 state
.OnBeginImplFrame();
468 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
469 EXPECT_ACTION_UPDATE_STATE(
470 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
471 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
472 state
.OnBeginImplFrameDeadline();
473 EXPECT_ACTION_UPDATE_STATE(
474 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED
);
475 state
.DidSwapBuffers();
476 state
.DidSwapBuffersComplete();
479 TEST(SchedulerStateMachineTest
, TestFailedDrawsDoNotRestartForcedDraw
) {
480 SchedulerSettings scheduler_settings
;
482 scheduler_settings
.maximum_number_of_failed_draws_before_draw_is_forced_
=
484 scheduler_settings
.impl_side_painting
= true;
485 StateMachine
state(scheduler_settings
);
489 state
.SetNeedsCommit();
490 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
491 state
.OnBeginImplFrame();
492 EXPECT_ACTION_UPDATE_STATE(
493 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
494 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
495 EXPECT_TRUE(state
.CommitPending());
497 // Then initiate a draw.
498 state
.SetNeedsRedraw(true);
499 state
.OnBeginImplFrameDeadline();
500 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
501 EXPECT_ACTION_UPDATE_STATE(
502 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
504 // Fail the draw enough times to force a redraw,
505 // then once more for good measure.
506 for (int i
= 0; i
< draw_limit
+ 1; ++i
)
507 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
508 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
509 EXPECT_TRUE(state
.BeginFrameNeeded());
510 EXPECT_TRUE(state
.RedrawPending());
511 // But the commit is ongoing.
512 EXPECT_TRUE(state
.CommitPending());
513 EXPECT_TRUE(state
.ForcedRedrawState() ==
514 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_COMMIT
);
516 state
.NotifyBeginMainFrameStarted();
517 state
.NotifyReadyToCommit();
518 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
519 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
520 EXPECT_TRUE(state
.RedrawPending());
521 EXPECT_FALSE(state
.CommitPending());
523 // Now force redraw should be in waiting for activation
524 EXPECT_TRUE(state
.ForcedRedrawState() ==
525 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
);
527 // After failing additional draws, we should still be in a forced
528 // redraw, but not back in WAITING_FOR_COMMIT.
529 for (int i
= 0; i
< draw_limit
+ 1; ++i
)
530 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
531 EXPECT_TRUE(state
.RedrawPending());
532 EXPECT_TRUE(state
.ForcedRedrawState() ==
533 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
);
536 TEST(SchedulerStateMachineTest
, TestFailedDrawIsRetriedInNextBeginImplFrame
) {
537 SchedulerSettings default_scheduler_settings
;
538 StateMachine
state(default_scheduler_settings
);
542 state
.SetNeedsRedraw(true);
543 EXPECT_TRUE(state
.BeginFrameNeeded());
544 state
.OnBeginImplFrame();
545 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
546 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
547 state
.OnBeginImplFrameDeadline();
548 EXPECT_TRUE(state
.RedrawPending());
549 EXPECT_ACTION_UPDATE_STATE(
550 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
552 // Failing the draw for animation checkerboards makes us require a commit.
553 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
554 EXPECT_ACTION_UPDATE_STATE(
555 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
556 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
557 EXPECT_TRUE(state
.RedrawPending());
559 // We should not be trying to draw again now, but we have a commit pending.
560 EXPECT_TRUE(state
.BeginFrameNeeded());
561 state
.OnBeginImplFrame();
562 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
563 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
565 // We should try to draw again at the end of the next BeginImplFrame on
567 state
.OnBeginImplFrameDeadline();
568 EXPECT_ACTION_UPDATE_STATE(
569 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
570 state
.DidSwapBuffers();
571 state
.DidSwapBuffersComplete();
572 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
575 TEST(SchedulerStateMachineTest
, TestDoestDrawTwiceInSameFrame
) {
576 SchedulerSettings default_scheduler_settings
;
577 StateMachine
state(default_scheduler_settings
);
579 state
.SetNeedsRedraw(true);
581 // Draw the first frame.
582 EXPECT_TRUE(state
.BeginFrameNeeded());
583 state
.OnBeginImplFrame();
584 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
585 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
587 state
.OnBeginImplFrameDeadline();
588 EXPECT_ACTION_UPDATE_STATE(
589 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
590 state
.DidSwapBuffers();
591 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
592 state
.DidSwapBuffersComplete();
593 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
595 // Before the next BeginImplFrame, set needs redraw again.
596 // This should not redraw until the next BeginImplFrame.
597 state
.SetNeedsRedraw(true);
598 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
600 // Move to another frame. This should now draw.
601 EXPECT_TRUE(state
.BeginFrameNeeded());
602 state
.OnBeginImplFrame();
604 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
605 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
607 state
.OnBeginImplFrameDeadline();
608 EXPECT_ACTION_UPDATE_STATE(
609 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
610 state
.DidSwapBuffers();
611 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
612 state
.DidSwapBuffersComplete();
613 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
615 // We just swapped, so we should proactively request another BeginImplFrame.
616 EXPECT_TRUE(state
.BeginFrameNeeded());
619 TEST(SchedulerStateMachineTest
, TestNextActionDrawsOnBeginImplFrame
) {
620 SchedulerSettings default_scheduler_settings
;
622 // When not in BeginImplFrame deadline, or in BeginImplFrame deadline
623 // but not visible, don't draw.
624 size_t num_commit_states
=
625 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
626 size_t num_begin_impl_frame_states
=
627 sizeof(all_begin_impl_frame_states
) /
628 sizeof(SchedulerStateMachine::BeginImplFrameState
);
629 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
630 for (size_t j
= 0; j
< num_begin_impl_frame_states
; ++j
) {
631 StateMachine
state(default_scheduler_settings
);
633 state
.UpdateState(state
.NextAction());
634 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
635 state
.SetCommitState(all_commit_states
[i
]);
636 state
.SetBeginImplFrameState(all_begin_impl_frame_states
[j
]);
638 (all_begin_impl_frame_states
[j
] !=
639 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
640 state
.SetVisible(visible
);
642 // Case 1: needs_commit=false
643 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
646 // Case 2: needs_commit=true
647 state
.SetNeedsCommit();
648 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
650 << state
.AsValue()->ToString();
654 // When in BeginImplFrame deadline we should always draw for SetNeedsRedraw
655 // except if we're ready to commit, in which case we expect a commit first.
656 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
657 StateMachine
state(default_scheduler_settings
);
659 state
.UpdateState(state
.NextAction());
660 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
661 state
.SetCanDraw(true);
662 state
.SetCommitState(all_commit_states
[i
]);
663 state
.SetBeginImplFrameState(
664 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
666 state
.SetNeedsRedraw(true);
667 state
.SetVisible(true);
669 SchedulerStateMachine::Action expected_action
;
670 if (all_commit_states
[i
] ==
671 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
) {
672 expected_action
= SchedulerStateMachine::ACTION_COMMIT
;
674 expected_action
= SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
;
675 EXPECT_ACTION(SchedulerStateMachine::ACTION_ANIMATE
);
676 state
.UpdateState(state
.NextAction());
679 // Case 1: needs_commit=false.
680 EXPECT_ACTION(expected_action
);
682 // Case 2: needs_commit=true.
683 state
.SetNeedsCommit();
684 EXPECT_ACTION(expected_action
);
688 TEST(SchedulerStateMachineTest
, TestNoCommitStatesRedrawWhenInvisible
) {
689 SchedulerSettings default_scheduler_settings
;
691 size_t num_commit_states
=
692 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
693 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
694 // There shouldn't be any drawing regardless of BeginImplFrame.
695 for (size_t j
= 0; j
< 2; ++j
) {
696 StateMachine
state(default_scheduler_settings
);
698 state
.UpdateState(state
.NextAction());
699 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
700 state
.SetCommitState(all_commit_states
[i
]);
701 state
.SetVisible(false);
702 state
.SetNeedsRedraw(true);
704 state
.SetBeginImplFrameState(
705 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
708 // Case 1: needs_commit=false.
709 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
712 // Case 2: needs_commit=true.
713 state
.SetNeedsCommit();
714 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
716 << state
.AsValue()->ToString();
721 TEST(SchedulerStateMachineTest
, TestCanRedraw_StopsDraw
) {
722 SchedulerSettings default_scheduler_settings
;
724 size_t num_commit_states
=
725 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
726 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
727 // There shouldn't be any drawing regardless of BeginImplFrame.
728 for (size_t j
= 0; j
< 2; ++j
) {
729 StateMachine
state(default_scheduler_settings
);
731 state
.UpdateState(state
.NextAction());
732 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
733 state
.SetCommitState(all_commit_states
[i
]);
734 state
.SetVisible(false);
735 state
.SetNeedsRedraw(true);
737 state
.OnBeginImplFrame();
739 state
.SetCanDraw(false);
740 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
746 TEST(SchedulerStateMachineTest
,
747 TestCanRedrawWithWaitingForFirstDrawMakesProgress
) {
748 SchedulerSettings default_scheduler_settings
;
749 StateMachine
state(default_scheduler_settings
);
751 state
.UpdateState(state
.NextAction());
752 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
754 state
.SetActiveTreeNeedsFirstDraw(true);
755 state
.SetNeedsCommit();
756 state
.SetNeedsRedraw(true);
757 state
.SetVisible(true);
758 state
.SetCanDraw(false);
759 state
.OnBeginImplFrame();
760 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
761 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
762 EXPECT_ACTION_UPDATE_STATE(
763 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
764 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
765 state
.NotifyBeginMainFrameStarted();
766 state
.NotifyReadyToCommit();
767 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
768 state
.OnBeginImplFrameDeadline();
769 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
770 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
771 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
774 TEST(SchedulerStateMachineTest
, TestSetNeedsCommitIsNotLost
) {
775 SchedulerSettings scheduler_settings
;
776 StateMachine
state(scheduler_settings
);
778 state
.SetNeedsCommit();
780 EXPECT_TRUE(state
.BeginFrameNeeded());
783 state
.OnBeginImplFrame();
784 EXPECT_ACTION_UPDATE_STATE(
785 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
787 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
789 // Now, while the frame is in progress, set another commit.
790 state
.SetNeedsCommit();
791 EXPECT_TRUE(state
.NeedsCommit());
793 // Let the frame finish.
794 state
.NotifyBeginMainFrameStarted();
795 state
.NotifyReadyToCommit();
796 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
);
798 // Expect to commit regardless of BeginImplFrame state.
799 EXPECT_IMPL_FRAME_STATE(
800 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
801 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
803 state
.OnBeginImplFrameDeadlinePending();
804 EXPECT_IMPL_FRAME_STATE(
805 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
);
806 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
808 state
.OnBeginImplFrameDeadline();
809 EXPECT_IMPL_FRAME_STATE(
810 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
811 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
813 state
.OnBeginImplFrameIdle();
814 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
815 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
817 state
.OnBeginImplFrame();
818 EXPECT_IMPL_FRAME_STATE(
819 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
820 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
822 // Finish the commit, then make sure we start the next commit immediately
823 // and draw on the next BeginImplFrame.
824 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
825 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
826 EXPECT_ACTION_UPDATE_STATE(
827 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
828 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
830 state
.OnBeginImplFrameDeadline();
832 EXPECT_TRUE(state
.active_tree_needs_first_draw());
833 EXPECT_ACTION_UPDATE_STATE(
834 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
835 state
.DidSwapBuffers();
836 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
837 state
.DidSwapBuffersComplete();
838 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
841 TEST(SchedulerStateMachineTest
, TestFullCycle
) {
842 SchedulerSettings default_scheduler_settings
;
843 StateMachine
state(default_scheduler_settings
);
846 // Start clean and set commit.
847 state
.SetNeedsCommit();
850 state
.OnBeginImplFrame();
851 EXPECT_ACTION_UPDATE_STATE(
852 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
854 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
855 EXPECT_FALSE(state
.NeedsCommit());
856 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
858 // Tell the scheduler the frame finished.
859 state
.NotifyBeginMainFrameStarted();
860 state
.NotifyReadyToCommit();
861 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
);
864 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
865 EXPECT_TRUE(state
.active_tree_needs_first_draw());
866 EXPECT_TRUE(state
.needs_redraw());
868 // Expect to do nothing until BeginImplFrame deadline
869 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
871 // At BeginImplFrame deadline, draw.
872 state
.OnBeginImplFrameDeadline();
873 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
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 // Should be synchronized, no draw needed, no action needed.
881 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
882 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
883 EXPECT_FALSE(state
.needs_redraw());
886 TEST(SchedulerStateMachineTest
, TestFullCycleWithMainThreadLowLatencyMode
) {
887 SchedulerSettings scheduler_settings
;
888 scheduler_settings
.main_thread_should_always_be_low_latency
= true;
889 StateMachine
state(scheduler_settings
);
892 // Start clean and set commit.
893 state
.SetNeedsCommit();
896 state
.OnBeginImplFrame();
897 EXPECT_ACTION_UPDATE_STATE(
898 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
900 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
901 EXPECT_FALSE(state
.NeedsCommit());
902 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
904 // Tell the scheduler the frame finished.
905 state
.NotifyBeginMainFrameStarted();
906 state
.NotifyReadyToCommit();
907 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
);
910 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
911 EXPECT_TRUE(state
.active_tree_needs_first_draw());
912 EXPECT_TRUE(state
.needs_redraw());
914 // Now commit should wait for draw.
915 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW
);
917 // Swap throttled. Do not draw.
918 state
.DidSwapBuffers();
919 state
.OnBeginImplFrameDeadline();
920 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
921 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
922 state
.DidSwapBuffersComplete();
924 // Haven't draw since last commit, do not begin new main frame.
925 state
.SetNeedsCommit();
926 state
.OnBeginImplFrame();
927 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
928 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
930 // At BeginImplFrame deadline, draw.
931 state
.OnBeginImplFrameDeadline();
932 EXPECT_ACTION_UPDATE_STATE(
933 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
934 state
.DidSwapBuffers();
935 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
936 state
.DidSwapBuffersComplete();
938 // Now will be able to start main frame.
939 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
940 EXPECT_FALSE(state
.needs_redraw());
941 EXPECT_ACTION_UPDATE_STATE(
942 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
945 TEST(SchedulerStateMachineTest
,
946 TestFullCycleWithMainThreadLowLatencyMode_ImplSidePaint
) {
947 SchedulerSettings scheduler_settings
;
948 scheduler_settings
.main_thread_should_always_be_low_latency
= true;
949 scheduler_settings
.impl_side_painting
= true;
950 StateMachine
state(scheduler_settings
);
953 // Start clean and set commit.
954 state
.SetNeedsCommit();
957 state
.OnBeginImplFrame();
958 EXPECT_ACTION_UPDATE_STATE(
959 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
961 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
962 EXPECT_FALSE(state
.NeedsCommit());
963 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
965 // Tell the scheduler the frame finished.
966 state
.NotifyBeginMainFrameStarted();
967 state
.NotifyReadyToCommit();
968 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
);
971 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
973 // Now commit should wait for activation.
975 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION
);
977 // No activation yet, so this commit is not drawn yet. Force to draw this
978 // frame, and still block BeginMainFrame.
979 state
.SetNeedsRedraw(true);
980 state
.SetNeedsCommit();
981 state
.OnBeginImplFrameDeadline();
982 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
983 EXPECT_ACTION_UPDATE_STATE(
984 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
985 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
987 // Cannot BeginMainFrame yet since last commit is not yet activated and drawn.
988 state
.OnBeginImplFrame();
990 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION
);
991 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
993 // Now activate sync tree.
994 state
.NotifyReadyToActivate();
995 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
996 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
997 EXPECT_TRUE(state
.active_tree_needs_first_draw());
998 EXPECT_TRUE(state
.needs_redraw());
999 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW
);
1001 // Swap throttled. Do not draw.
1002 state
.DidSwapBuffers();
1003 state
.OnBeginImplFrameDeadline();
1004 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1005 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1006 state
.DidSwapBuffersComplete();
1008 // Haven't draw since last commit, do not begin new main frame.
1009 state
.OnBeginImplFrame();
1010 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1011 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1013 // At BeginImplFrame deadline, draw. This draws unblocks BeginMainFrame.
1014 state
.OnBeginImplFrameDeadline();
1015 EXPECT_ACTION_UPDATE_STATE(
1016 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1017 state
.DidSwapBuffers();
1018 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
1019 state
.DidSwapBuffersComplete();
1021 // Now will be able to start main frame.
1022 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1023 EXPECT_FALSE(state
.needs_redraw());
1024 EXPECT_ACTION_UPDATE_STATE(
1025 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1028 TEST(SchedulerStateMachineTest
, TestFullCycleWithCommitRequestInbetween
) {
1029 SchedulerSettings default_scheduler_settings
;
1030 StateMachine
state(default_scheduler_settings
);
1033 // Start clean and set commit.
1034 state
.SetNeedsCommit();
1037 state
.OnBeginImplFrame();
1038 EXPECT_ACTION_UPDATE_STATE(
1039 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1040 EXPECT_COMMIT_STATE(
1041 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1042 EXPECT_FALSE(state
.NeedsCommit());
1043 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1045 // Request another commit while the commit is in flight.
1046 state
.SetNeedsCommit();
1047 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1049 // Tell the scheduler the frame finished.
1050 state
.NotifyBeginMainFrameStarted();
1051 state
.NotifyReadyToCommit();
1052 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
);
1055 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1056 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1057 EXPECT_TRUE(state
.needs_redraw());
1059 // Expect to do nothing until BeginImplFrame deadline.
1060 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1062 // At BeginImplFrame deadline, draw.
1063 state
.OnBeginImplFrameDeadline();
1064 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1065 EXPECT_ACTION_UPDATE_STATE(
1066 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1067 state
.DidSwapBuffers();
1068 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
1069 state
.DidSwapBuffersComplete();
1071 // Should be synchronized, no draw needed, no action needed.
1072 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1073 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1074 EXPECT_FALSE(state
.needs_redraw());
1076 // Next BeginImplFrame should initiate second commit.
1077 state
.OnBeginImplFrame();
1078 EXPECT_ACTION_UPDATE_STATE(
1079 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1082 TEST(SchedulerStateMachineTest
, TestRequestCommitInvisible
) {
1083 SchedulerSettings default_scheduler_settings
;
1084 StateMachine
state(default_scheduler_settings
);
1085 state
.SetCanStart();
1086 state
.UpdateState(state
.NextAction());
1087 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1088 state
.SetNeedsCommit();
1089 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1092 // See ThreadProxy::BeginMainFrame "EarlyOut_NotVisible" /
1093 // "EarlyOut_OutputSurfaceLost" cases.
1094 TEST(SchedulerStateMachineTest
, TestAbortBeginMainFrameBecauseInvisible
) {
1095 SchedulerSettings default_scheduler_settings
;
1096 StateMachine
state(default_scheduler_settings
);
1099 // Start clean and set commit.
1100 state
.SetNeedsCommit();
1102 // Begin the frame while visible.
1103 state
.OnBeginImplFrame();
1104 EXPECT_ACTION_UPDATE_STATE(
1105 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1106 EXPECT_COMMIT_STATE(
1107 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1108 EXPECT_FALSE(state
.NeedsCommit());
1109 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1111 // Become invisible and abort BeginMainFrame.
1112 state
.SetVisible(false);
1113 state
.BeginMainFrameAborted(CommitEarlyOutReason::ABORTED_NOT_VISIBLE
);
1115 // NeedsCommit should now be true again because we never actually did a
1117 EXPECT_TRUE(state
.NeedsCommit());
1119 // We should now be back in the idle state as if we never started the frame.
1120 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1121 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1123 // We shouldn't do anything on the BeginImplFrame deadline.
1124 state
.OnBeginImplFrameDeadline();
1125 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1127 // Become visible again.
1128 state
.SetVisible(true);
1130 // Although we have aborted on this frame and haven't cancelled the commit
1131 // (i.e. need another), don't send another BeginMainFrame yet.
1132 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1133 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1134 EXPECT_TRUE(state
.NeedsCommit());
1136 // Start a new frame.
1137 state
.OnBeginImplFrame();
1138 EXPECT_ACTION_UPDATE_STATE(
1139 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1141 // We should be starting the commit now.
1142 EXPECT_COMMIT_STATE(
1143 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1144 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1147 // See ThreadProxy::BeginMainFrame "EarlyOut_NoUpdates" case.
1148 TEST(SchedulerStateMachineTest
, TestAbortBeginMainFrameBecauseCommitNotNeeded
) {
1149 SchedulerSettings default_scheduler_settings
;
1150 StateMachine
state(default_scheduler_settings
);
1151 state
.SetCanStart();
1152 state
.UpdateState(state
.NextAction());
1153 state
.DidCreateAndInitializeOutputSurface();
1154 state
.SetVisible(true);
1155 state
.SetCanDraw(true);
1157 // Get into a begin frame / commit state.
1158 state
.SetNeedsCommit();
1159 state
.OnBeginImplFrame();
1160 EXPECT_ACTION_UPDATE_STATE(
1161 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1162 EXPECT_COMMIT_STATE(
1163 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1164 EXPECT_FALSE(state
.NeedsCommit());
1165 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1167 // Abort the commit, true means that the BeginMainFrame was sent but there
1168 // was no work to do on the main thread.
1169 state
.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES
);
1171 // NeedsCommit should now be false because the commit was actually handled.
1172 EXPECT_FALSE(state
.NeedsCommit());
1174 // Even though the commit was aborted, we still expect to draw the new frame.
1175 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1176 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1177 state
.OnBeginImplFrameDeadline();
1178 EXPECT_ACTION_UPDATE_STATE(
1179 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1180 state
.DidSwapBuffers();
1181 state
.DidSwapBuffersComplete();
1182 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1184 // Verify another commit doesn't start on another frame either.
1185 EXPECT_FALSE(state
.NeedsCommit());
1186 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1188 state
.OnBeginImplFrame();
1189 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1190 state
.OnBeginImplFrameDeadline();
1191 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1193 // Verify another commit can start if requested, though.
1194 state
.SetNeedsCommit();
1195 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1196 state
.OnBeginImplFrame();
1197 EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1200 TEST(SchedulerStateMachineTest
, TestFirstContextCreation
) {
1201 SchedulerSettings default_scheduler_settings
;
1202 StateMachine
state(default_scheduler_settings
);
1203 state
.SetCanStart();
1204 state
.SetVisible(true);
1205 state
.SetCanDraw(true);
1207 EXPECT_ACTION_UPDATE_STATE(
1208 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1209 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1210 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1212 // Check that the first init does not SetNeedsCommit.
1213 state
.OnBeginImplFrame();
1214 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1215 state
.OnBeginImplFrameDeadline();
1216 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1218 // Check that a needs commit initiates a BeginMainFrame.
1219 state
.SetNeedsCommit();
1220 state
.OnBeginImplFrame();
1221 EXPECT_ACTION_UPDATE_STATE(
1222 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1225 TEST(SchedulerStateMachineTest
, TestContextLostWhenCompletelyIdle
) {
1226 SchedulerSettings default_scheduler_settings
;
1227 StateMachine
state(default_scheduler_settings
);
1230 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1231 state
.NextAction());
1232 state
.DidLoseOutputSurface();
1234 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1235 state
.UpdateState(state
.NextAction());
1237 // Once context recreation begins, nothing should happen.
1238 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1240 // Recreate the context.
1241 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1243 // When the context is recreated, we should begin a commit.
1244 state
.OnBeginImplFrame();
1245 EXPECT_ACTION_UPDATE_STATE(
1246 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1249 TEST(SchedulerStateMachineTest
,
1250 TestContextLostWhenIdleAndCommitRequestedWhileRecreating
) {
1251 SchedulerSettings default_scheduler_settings
;
1252 // We use impl side painting because it's the more complicated version.
1253 default_scheduler_settings
.impl_side_painting
= true;
1254 StateMachine
state(default_scheduler_settings
);
1257 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1258 state
.NextAction());
1259 state
.DidLoseOutputSurface();
1260 EXPECT_EQ(state
.output_surface_state(),
1261 SchedulerStateMachine::OUTPUT_SURFACE_LOST
);
1263 EXPECT_ACTION_UPDATE_STATE(
1264 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1265 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1267 // Once context recreation begins, nothing should happen.
1268 state
.OnBeginImplFrame();
1269 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1270 state
.OnBeginImplFrameDeadline();
1271 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1273 // While context is recreating, commits shouldn't begin.
1274 state
.SetNeedsCommit();
1275 state
.OnBeginImplFrame();
1276 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1277 state
.OnBeginImplFrameDeadline();
1278 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1280 // Recreate the context
1281 state
.DidCreateAndInitializeOutputSurface();
1282 EXPECT_EQ(state
.output_surface_state(),
1283 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT
);
1284 EXPECT_FALSE(state
.RedrawPending());
1286 // When the context is recreated, we wait until the next BeginImplFrame
1288 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1290 // When the BeginFrame comes in we should begin a commit
1291 state
.OnBeginImplFrame();
1292 EXPECT_ACTION_UPDATE_STATE(
1293 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1294 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1295 EXPECT_COMMIT_STATE(
1296 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1298 // Until that commit finishes, we shouldn't be drawing or animate.
1299 state
.OnBeginImplFrameDeadline();
1300 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1302 // Finish the commit, which should make the surface active.
1303 state
.NotifyBeginMainFrameStarted();
1304 state
.NotifyReadyToCommit();
1305 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1306 EXPECT_EQ(state
.output_surface_state(),
1307 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION
);
1308 state
.NotifyReadyToActivate();
1309 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1310 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1311 EXPECT_EQ(state
.output_surface_state(),
1312 SchedulerStateMachine::OUTPUT_SURFACE_ACTIVE
);
1314 // Finishing the first commit after initializing an output surface should
1315 // automatically cause a redraw.
1316 EXPECT_TRUE(state
.RedrawPending());
1317 state
.OnBeginImplFrame();
1318 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1319 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1320 state
.OnBeginImplFrameDeadline();
1321 EXPECT_ACTION_UPDATE_STATE(
1322 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1323 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1324 EXPECT_FALSE(state
.RedrawPending());
1326 // Next frame as no work to do.
1327 state
.OnBeginImplFrame();
1328 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1329 state
.OnBeginImplFrameDeadline();
1330 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1332 // Once the context is recreated, whether we draw should be based on
1333 // SetCanDraw if waiting on first draw after activate.
1334 state
.SetNeedsRedraw(true);
1335 state
.OnBeginImplFrame();
1336 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1337 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1338 state
.OnBeginImplFrameDeadline();
1339 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1340 state
.SetCanDraw(false);
1341 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1342 state
.SetCanDraw(true);
1343 EXPECT_ACTION_UPDATE_STATE(
1344 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1345 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1347 // Once the context is recreated, whether we draw should be based on
1348 // SetCanDraw if waiting on first draw after activate.
1349 state
.SetNeedsRedraw(true);
1350 state
.SetNeedsCommit();
1351 state
.OnBeginImplFrame();
1352 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1353 EXPECT_ACTION_UPDATE_STATE(
1354 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1355 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1356 // Activate so we need the first draw
1357 state
.NotifyBeginMainFrameStarted();
1358 state
.NotifyReadyToCommit();
1359 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1360 state
.NotifyReadyToActivate();
1361 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1362 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1363 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1364 EXPECT_TRUE(state
.needs_redraw());
1366 state
.OnBeginImplFrameDeadline();
1367 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1368 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1369 state
.SetCanDraw(false);
1370 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1371 state
.SetCanDraw(true);
1372 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1375 TEST(SchedulerStateMachineTest
, TestContextLostWhileCommitInProgress
) {
1376 SchedulerSettings scheduler_settings
;
1377 StateMachine
state(scheduler_settings
);
1380 // Get a commit in flight.
1381 state
.SetNeedsCommit();
1383 // Set damage and expect a draw.
1384 state
.SetNeedsRedraw(true);
1385 state
.OnBeginImplFrame();
1386 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1387 EXPECT_ACTION_UPDATE_STATE(
1388 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1389 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1390 state
.OnBeginImplFrameDeadline();
1391 EXPECT_ACTION_UPDATE_STATE(
1392 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1393 state
.DidSwapBuffers();
1394 state
.DidSwapBuffersComplete();
1395 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1397 // Cause a lost context while the BeginMainFrame is in flight.
1398 state
.DidLoseOutputSurface();
1400 // Ask for another draw. Expect nothing happens.
1401 state
.SetNeedsRedraw(true);
1402 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1404 // Finish the frame, and commit.
1405 state
.NotifyBeginMainFrameStarted();
1406 state
.NotifyReadyToCommit();
1407 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1409 // We will abort the draw when the output surface is lost if we are
1410 // waiting for the first draw to unblock the main thread.
1411 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1412 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1414 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1415 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
1416 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1418 state
.OnBeginImplFrame();
1419 EXPECT_IMPL_FRAME_STATE(
1420 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
1421 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1423 state
.OnBeginImplFrameDeadlinePending();
1424 EXPECT_IMPL_FRAME_STATE(
1425 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
);
1426 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1428 state
.OnBeginImplFrameDeadline();
1429 EXPECT_IMPL_FRAME_STATE(
1430 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
1431 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1434 TEST(SchedulerStateMachineTest
,
1435 TestContextLostWhileCommitInProgressAndAnotherCommitRequested
) {
1436 SchedulerSettings scheduler_settings
;
1437 StateMachine
state(scheduler_settings
);
1440 // Get a commit in flight.
1441 state
.SetNeedsCommit();
1442 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1444 // Set damage and expect a draw.
1445 state
.SetNeedsRedraw(true);
1446 state
.OnBeginImplFrame();
1447 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1448 EXPECT_ACTION_UPDATE_STATE(
1449 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1450 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1451 state
.OnBeginImplFrameDeadline();
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
);
1458 // Cause a lost context while the BeginMainFrame is in flight.
1459 state
.DidLoseOutputSurface();
1461 // Ask for another draw and also set needs commit. Expect nothing happens.
1462 state
.SetNeedsRedraw(true);
1463 state
.SetNeedsCommit();
1464 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1466 // Finish the frame, and commit.
1467 state
.NotifyBeginMainFrameStarted();
1468 state
.NotifyReadyToCommit();
1469 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1470 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1472 // Because the output surface is missing, we expect the draw to abort.
1473 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1475 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1476 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
1477 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1479 state
.OnBeginImplFrame();
1480 EXPECT_IMPL_FRAME_STATE(
1481 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
1482 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1484 state
.OnBeginImplFrameDeadlinePending();
1485 EXPECT_IMPL_FRAME_STATE(
1486 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
);
1487 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1489 state
.OnBeginImplFrameDeadline();
1490 EXPECT_IMPL_FRAME_STATE(
1491 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
1492 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1494 state
.OnBeginImplFrameIdle();
1495 EXPECT_ACTION_UPDATE_STATE(
1496 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1498 // After we get a new output surface, the commit flow should start.
1499 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1500 state
.OnBeginImplFrame();
1501 EXPECT_ACTION_UPDATE_STATE(
1502 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1503 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1504 state
.NotifyBeginMainFrameStarted();
1505 state
.NotifyReadyToCommit();
1506 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1507 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1508 state
.OnBeginImplFrameDeadline();
1509 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1510 EXPECT_ACTION_UPDATE_STATE(
1511 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1512 state
.DidSwapBuffers();
1513 state
.DidSwapBuffersComplete();
1514 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1517 TEST(SchedulerStateMachineTest
, DontDrawBeforeCommitAfterLostOutputSurface
) {
1518 SchedulerSettings default_scheduler_settings
;
1519 StateMachine
state(default_scheduler_settings
);
1522 state
.SetNeedsRedraw(true);
1524 // Cause a lost output surface, and restore it.
1525 state
.DidLoseOutputSurface();
1526 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1527 state
.UpdateState(state
.NextAction());
1528 state
.DidCreateAndInitializeOutputSurface();
1530 EXPECT_FALSE(state
.RedrawPending());
1531 state
.OnBeginImplFrame();
1532 EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1535 TEST(SchedulerStateMachineTest
,
1536 TestPendingActivationsShouldBeForcedAfterLostOutputSurface
) {
1537 SchedulerSettings settings
;
1538 settings
.impl_side_painting
= true;
1539 StateMachine
state(settings
);
1542 state
.SetCommitState(
1543 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1545 // Cause a lost context.
1546 state
.DidLoseOutputSurface();
1548 state
.NotifyBeginMainFrameStarted();
1549 state
.NotifyReadyToCommit();
1550 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1552 EXPECT_TRUE(state
.PendingActivationsShouldBeForced());
1553 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1555 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1556 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1559 TEST(SchedulerStateMachineTest
, TestNoBeginMainFrameWhenInvisible
) {
1560 SchedulerSettings default_scheduler_settings
;
1561 StateMachine
state(default_scheduler_settings
);
1562 state
.SetCanStart();
1563 state
.UpdateState(state
.NextAction());
1564 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1565 state
.SetVisible(false);
1566 state
.SetNeedsCommit();
1567 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1570 TEST(SchedulerStateMachineTest
, TestFinishCommitWhenCommitInProgress
) {
1571 SchedulerSettings default_scheduler_settings
;
1572 StateMachine
state(default_scheduler_settings
);
1573 state
.SetCanStart();
1574 state
.UpdateState(state
.NextAction());
1575 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1576 state
.SetVisible(false);
1577 state
.SetCommitState(
1578 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1579 state
.SetNeedsCommit();
1581 state
.NotifyBeginMainFrameStarted();
1582 state
.NotifyReadyToCommit();
1583 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
1584 state
.UpdateState(state
.NextAction());
1586 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1587 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1590 TEST(SchedulerStateMachineTest
, TestInitialActionsWhenContextLost
) {
1591 SchedulerSettings default_scheduler_settings
;
1592 StateMachine
state(default_scheduler_settings
);
1594 state
.SetNeedsCommit();
1595 state
.DidLoseOutputSurface();
1597 // When we are visible, we normally want to begin output surface creation
1598 // as soon as possible.
1599 EXPECT_ACTION_UPDATE_STATE(
1600 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1602 state
.DidCreateAndInitializeOutputSurface();
1603 EXPECT_EQ(state
.output_surface_state(),
1604 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT
);
1606 // We should not send a BeginMainFrame when we are invisible, even if we've
1607 // lost the output surface and are trying to get the first commit, since the
1608 // main thread will just abort anyway.
1609 state
.SetVisible(false);
1610 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1613 TEST(SchedulerStateMachineTest
, ReportIfNotDrawing
) {
1614 SchedulerSettings default_scheduler_settings
;
1615 StateMachine
state(default_scheduler_settings
);
1617 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1619 state
.SetCanDraw(false);
1620 state
.SetVisible(true);
1621 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1623 state
.SetCanDraw(true);
1624 state
.SetVisible(false);
1625 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1627 state
.SetCanDraw(false);
1628 state
.SetVisible(false);
1629 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1631 state
.SetCanDraw(true);
1632 state
.SetVisible(true);
1633 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1636 TEST(SchedulerStateMachineTest
,
1637 TestTriggerDeadlineImmediatelyAfterAbortedCommit
) {
1638 SchedulerSettings settings
;
1639 settings
.impl_side_painting
= true;
1640 StateMachine
state(settings
);
1643 // This test mirrors what happens during the first frame of a scroll gesture.
1644 // First we get the input event and a BeginFrame.
1645 state
.OnBeginImplFrame();
1647 // As a response the compositor requests a redraw and a commit to tell the
1648 // main thread about the new scroll offset.
1649 state
.SetNeedsRedraw(true);
1650 state
.SetNeedsCommit();
1652 // We should start the commit normally.
1653 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1654 EXPECT_ACTION_UPDATE_STATE(
1655 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1656 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1658 // Since only the scroll offset changed, the main thread will abort the
1660 state
.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES
);
1662 // Since the commit was aborted, we should draw right away instead of waiting
1663 // for the deadline.
1664 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1667 void FinishPreviousCommitAndDrawWithoutExitingDeadline(
1668 StateMachine
* state_ptr
) {
1669 // Gross, but allows us to use macros below.
1670 StateMachine
& state
= *state_ptr
;
1672 state
.NotifyBeginMainFrameStarted();
1673 state
.NotifyReadyToCommit();
1674 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1675 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1676 state
.NotifyReadyToActivate();
1677 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1678 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1680 state
.OnBeginImplFrame();
1681 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1682 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1684 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1685 state
.OnBeginImplFrameDeadline();
1686 EXPECT_ACTION_UPDATE_STATE(
1687 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1688 state
.DidSwapBuffers();
1691 TEST(SchedulerStateMachineTest
, TestImplLatencyTakesPriority
) {
1692 SchedulerSettings settings
;
1693 settings
.impl_side_painting
= true;
1694 StateMachine
state(settings
);
1697 // This test ensures that impl-draws are prioritized over main thread updates
1698 // in prefer impl latency mode.
1699 state
.SetNeedsRedraw(true);
1700 state
.SetNeedsCommit();
1701 state
.OnBeginImplFrame();
1702 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1703 EXPECT_ACTION_UPDATE_STATE(
1704 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1705 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1707 // Verify the deadline is not triggered early until we enter
1708 // prefer impl latency mode.
1709 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1710 state
.SetImplLatencyTakesPriority(true);
1711 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1713 // Trigger the deadline.
1714 state
.OnBeginImplFrameDeadline();
1715 EXPECT_ACTION_UPDATE_STATE(
1716 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1717 state
.DidSwapBuffers();
1718 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1719 state
.DidSwapBuffersComplete();
1721 // Request a new commit and finish the previous one.
1722 state
.SetNeedsCommit();
1723 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state
);
1724 EXPECT_ACTION_UPDATE_STATE(
1725 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1726 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1727 state
.DidSwapBuffersComplete();
1728 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1730 // Finish the previous commit and draw it.
1731 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state
);
1732 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1734 // Verify we do not send another BeginMainFrame if was are swap throttled
1735 // and did not just swap.
1736 state
.SetNeedsCommit();
1737 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1738 state
.OnBeginImplFrame();
1739 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1740 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1741 state
.OnBeginImplFrameDeadline();
1742 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1745 TEST(SchedulerStateMachineTest
,
1746 TestTriggerDeadlineImmediatelyOnLostOutputSurface
) {
1747 SchedulerSettings default_scheduler_settings
;
1748 StateMachine
state(default_scheduler_settings
);
1751 state
.SetNeedsCommit();
1753 state
.OnBeginImplFrame();
1754 EXPECT_ACTION_UPDATE_STATE(
1755 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1756 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1757 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1759 state
.DidLoseOutputSurface();
1760 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1761 // The deadline should be triggered immediately when output surface is lost.
1762 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1765 TEST(SchedulerStateMachineTest
, TestSetNeedsAnimate
) {
1766 SchedulerSettings settings
;
1767 settings
.impl_side_painting
= true;
1768 StateMachine
state(settings
);
1771 // Test requesting an animation that, when run, causes us to draw.
1772 state
.SetNeedsAnimate();
1773 EXPECT_TRUE(state
.BeginFrameNeeded());
1774 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1776 state
.OnBeginImplFrame();
1777 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1779 state
.OnBeginImplFrameDeadlinePending();
1780 state
.OnBeginImplFrameDeadline();
1781 EXPECT_ACTION_UPDATE_STATE(
1782 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1785 TEST(SchedulerStateMachineTest
, TestAnimateBeforeCommit
) {
1786 SchedulerSettings settings
;
1787 settings
.impl_side_painting
= true;
1788 StateMachine
state(settings
);
1791 // Check that animations are updated before we start a commit.
1792 state
.SetNeedsAnimate();
1793 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1794 state
.SetNeedsCommit();
1795 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1796 EXPECT_TRUE(state
.BeginFrameNeeded());
1798 state
.OnBeginImplFrame();
1799 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1800 EXPECT_ACTION_UPDATE_STATE(
1801 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1803 state
.OnBeginImplFrameDeadlinePending();
1804 state
.OnBeginImplFrameDeadline();
1805 EXPECT_ACTION_UPDATE_STATE(
1806 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1809 TEST(SchedulerStateMachineTest
, TestAnimateAfterCommitBeforeDraw
) {
1810 SchedulerSettings settings
;
1811 settings
.impl_side_painting
= true;
1812 StateMachine
state(settings
);
1815 // Check that animations are updated before we start a commit.
1816 state
.SetNeedsAnimate();
1817 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1818 state
.SetNeedsCommit();
1819 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1820 EXPECT_TRUE(state
.BeginFrameNeeded());
1822 state
.OnBeginImplFrame();
1823 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1824 EXPECT_ACTION_UPDATE_STATE(
1825 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1827 state
.NotifyBeginMainFrameStarted();
1828 state
.NotifyReadyToCommit();
1829 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1831 state
.OnBeginImplFrameDeadlinePending();
1832 state
.OnBeginImplFrameDeadline();
1833 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1834 EXPECT_ACTION_UPDATE_STATE(
1835 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1838 TEST(SchedulerStateMachineTest
, TestSetNeedsAnimateAfterAnimate
) {
1839 SchedulerSettings settings
;
1840 settings
.impl_side_painting
= true;
1841 StateMachine
state(settings
);
1844 // Test requesting an animation after we have already animated during this
1846 state
.SetNeedsRedraw(true);
1847 EXPECT_TRUE(state
.BeginFrameNeeded());
1848 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1850 state
.OnBeginImplFrame();
1851 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1853 state
.SetNeedsAnimate();
1854 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1856 state
.OnBeginImplFrameDeadline();
1857 EXPECT_ACTION_UPDATE_STATE(
1858 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1861 TEST(SchedulerStateMachineTest
, TestForwardBeginFramesToChildren
) {
1862 SchedulerSettings settings
;
1863 StateMachine
state(settings
);
1866 EXPECT_FALSE(state
.BeginFrameNeeded());
1867 state
.SetChildrenNeedBeginFrames(true);
1868 EXPECT_TRUE(state
.BeginFrameNeeded());
1871 TEST(SchedulerStateMachineTest
, TestDeferCommit
) {
1872 SchedulerSettings settings
;
1873 StateMachine
state(settings
);
1876 state
.SetDeferCommits(true);
1878 state
.SetNeedsCommit();
1879 EXPECT_FALSE(state
.BeginFrameNeeded());
1880 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1882 state
.OnBeginImplFrame();
1883 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1885 state
.OnBeginImplFrameDeadline();
1886 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1888 state
.SetDeferCommits(false);
1889 state
.OnBeginImplFrame();
1890 EXPECT_ACTION_UPDATE_STATE(
1891 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1894 TEST(SchedulerStateMachineTest
, EarlyOutCommitWantsProactiveBeginFrame
) {
1895 SchedulerSettings settings
;
1896 StateMachine
state(settings
);
1897 SET_UP_STATE(state
);
1899 EXPECT_FALSE(state
.ProactiveBeginFrameWanted());
1900 bool commit_has_no_updates
= true;
1901 state
.UpdateStateOnCommit(commit_has_no_updates
);
1902 EXPECT_TRUE(state
.ProactiveBeginFrameWanted());
1903 state
.OnBeginImplFrame();
1904 EXPECT_FALSE(state
.ProactiveBeginFrameWanted());