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