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 bool NeedsCommit() const { return needs_commit_
; }
109 void SetNeedsRedraw(bool b
) { needs_redraw_
= b
; }
111 void SetNeedsForcedRedrawForTimeout(bool b
) {
112 forced_redraw_state_
= FORCED_REDRAW_STATE_WAITING_FOR_COMMIT
;
113 active_tree_needs_first_draw_
= true;
115 bool NeedsForcedRedrawForTimeout() const {
116 return forced_redraw_state_
!= FORCED_REDRAW_STATE_IDLE
;
119 void SetActiveTreeNeedsFirstDraw(bool needs_first_draw
) {
120 active_tree_needs_first_draw_
= needs_first_draw
;
123 bool CanDraw() const { return can_draw_
; }
124 bool Visible() const { return visible_
; }
126 bool PendingActivationsShouldBeForced() const {
127 return SchedulerStateMachine::PendingActivationsShouldBeForced();
130 void SetHasPendingTree(bool has_pending_tree
) {
131 has_pending_tree_
= has_pending_tree
;
134 using SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately
;
137 TEST(SchedulerStateMachineTest
, TestNextActionBeginsMainFrameIfNeeded
) {
138 SchedulerSettings default_scheduler_settings
;
140 // If no commit needed, do nothing.
142 StateMachine
state(default_scheduler_settings
);
144 EXPECT_ACTION_UPDATE_STATE(
145 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
)
146 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
147 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
148 state
.SetNeedsRedraw(false);
149 state
.SetVisible(true);
151 EXPECT_FALSE(state
.BeginFrameNeeded());
153 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
154 EXPECT_FALSE(state
.BeginFrameNeeded());
155 state
.OnBeginImplFrame(
156 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
158 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
159 state
.OnBeginImplFrameDeadline();
162 // If commit requested but can_start is still false, do nothing.
164 StateMachine
state(default_scheduler_settings
);
165 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
166 state
.SetNeedsRedraw(false);
167 state
.SetVisible(true);
168 state
.SetNeedsCommit();
170 EXPECT_FALSE(state
.BeginFrameNeeded());
172 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
173 EXPECT_FALSE(state
.BeginFrameNeeded());
174 state
.OnBeginImplFrame(
175 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
176 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
177 state
.OnBeginImplFrameDeadline();
180 // If commit requested, begin a main frame.
182 StateMachine
state(default_scheduler_settings
);
183 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
185 state
.UpdateState(state
.NextAction());
186 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
187 state
.SetNeedsRedraw(false);
188 state
.SetVisible(true);
189 state
.SetNeedsCommit();
191 EXPECT_TRUE(state
.BeginFrameNeeded());
193 state
.OnBeginImplFrame(
194 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
195 EXPECT_ACTION_UPDATE_STATE(
196 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
199 // Begin the frame, make sure needs_commit and commit_state update correctly.
201 StateMachine
state(default_scheduler_settings
);
203 state
.UpdateState(state
.NextAction());
204 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
205 state
.SetVisible(true);
206 state
.UpdateState(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
208 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
209 EXPECT_FALSE(state
.NeedsCommit());
213 // Explicitly test main_frame_before_activation_enabled = true
214 TEST(SchedulerStateMachineTest
, MainFrameBeforeActivationEnabled
) {
215 SchedulerSettings scheduler_settings
;
216 scheduler_settings
.impl_side_painting
= true;
217 scheduler_settings
.main_frame_before_activation_enabled
= true;
218 StateMachine
state(scheduler_settings
);
219 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
221 state
.SetNeedsRedraw(false);
222 state
.SetNeedsCommit();
224 EXPECT_TRUE(state
.BeginFrameNeeded());
226 // Commit to the pending tree.
227 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
228 EXPECT_ACTION_UPDATE_STATE(
229 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
230 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
232 state
.NotifyBeginMainFrameStarted();
233 state
.NotifyReadyToCommit();
234 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
235 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
236 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
238 state
.OnBeginImplFrameDeadline();
239 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
241 // Verify that the next commit starts while there is still a pending tree.
242 state
.SetNeedsCommit();
243 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
244 EXPECT_ACTION_UPDATE_STATE(
245 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
246 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
248 // Verify the pending commit doesn't overwrite the pending
249 // tree until the pending tree has been activated.
250 state
.NotifyBeginMainFrameStarted();
251 state
.NotifyReadyToCommit();
252 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
254 // Verify NotifyReadyToActivate unblocks activation, draw, and
255 // commit in that order.
256 state
.NotifyReadyToActivate();
257 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
258 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
260 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
261 state
.OnBeginImplFrameDeadline();
262 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
263 EXPECT_ACTION_UPDATE_STATE(
264 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
265 state
.DidSwapBuffers();
266 state
.DidSwapBuffersComplete();
267 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
268 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
269 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
272 TEST(SchedulerStateMachineTest
,
273 TestFailedDrawForAnimationCheckerboardSetsNeedsCommitAndDoesNotDrawAgain
) {
274 SchedulerSettings default_scheduler_settings
;
275 StateMachine
state(default_scheduler_settings
);
277 state
.SetNeedsRedraw(true);
278 EXPECT_TRUE(state
.RedrawPending());
279 EXPECT_TRUE(state
.BeginFrameNeeded());
280 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
281 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
282 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
283 state
.OnBeginImplFrameDeadline();
285 // We're drawing now.
286 EXPECT_ACTION_UPDATE_STATE(
287 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
288 state
.DidSwapBuffers();
289 state
.DidSwapBuffersComplete();
290 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
292 EXPECT_FALSE(state
.RedrawPending());
293 EXPECT_FALSE(state
.CommitPending());
295 // Failing the draw makes us require a commit.
296 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
297 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
298 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
299 EXPECT_ACTION_UPDATE_STATE(
300 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
301 EXPECT_TRUE(state
.RedrawPending());
302 EXPECT_TRUE(state
.CommitPending());
305 TEST(SchedulerStateMachineTest
, TestFailedDrawForMissingHighResNeedsCommit
) {
306 SchedulerSettings default_scheduler_settings
;
307 StateMachine
state(default_scheduler_settings
);
309 state
.SetNeedsRedraw(true);
310 EXPECT_TRUE(state
.RedrawPending());
311 EXPECT_TRUE(state
.BeginFrameNeeded());
313 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
314 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
315 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
316 state
.OnBeginImplFrameDeadline();
317 EXPECT_ACTION_UPDATE_STATE(
318 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
319 state
.DidSwapBuffers();
320 state
.DidSwapBuffersComplete();
321 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
322 EXPECT_FALSE(state
.RedrawPending());
323 EXPECT_FALSE(state
.CommitPending());
325 // Missing high res content requires a commit (but not a redraw)
326 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
);
327 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
328 EXPECT_ACTION_UPDATE_STATE(
329 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
330 EXPECT_FALSE(state
.RedrawPending());
331 EXPECT_TRUE(state
.CommitPending());
334 TEST(SchedulerStateMachineTest
,
335 TestsetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw
) {
336 SchedulerSettings default_scheduler_settings
;
337 StateMachine
state(default_scheduler_settings
);
339 state
.SetNeedsRedraw(true);
340 EXPECT_TRUE(state
.RedrawPending());
341 EXPECT_TRUE(state
.BeginFrameNeeded());
342 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
343 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
344 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
345 state
.OnBeginImplFrameDeadline();
347 // We're drawing now.
348 EXPECT_ACTION_UPDATE_STATE(
349 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
350 state
.DidSwapBuffers();
351 state
.DidSwapBuffersComplete();
352 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
353 EXPECT_FALSE(state
.RedrawPending());
354 EXPECT_FALSE(state
.CommitPending());
356 // While still in the same BeginMainFrame callback on the main thread,
357 // set needs redraw again. This should not redraw.
358 state
.SetNeedsRedraw(true);
359 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
361 // Failing the draw for animation checkerboards makes us require a commit.
362 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
363 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
364 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
365 EXPECT_ACTION_UPDATE_STATE(
366 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
367 EXPECT_TRUE(state
.RedrawPending());
370 TEST(SchedulerStateMachineTest
,
371 TestFailedDrawsEventuallyForceDrawAfterNextCommit
) {
372 SchedulerSettings scheduler_settings
;
373 scheduler_settings
.maximum_number_of_failed_draws_before_draw_is_forced_
= 1;
374 StateMachine
state(scheduler_settings
);
378 state
.SetNeedsCommit();
379 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
380 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
381 EXPECT_ACTION_UPDATE_STATE(
382 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
383 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
384 EXPECT_TRUE(state
.CommitPending());
386 // Then initiate a draw.
387 state
.SetNeedsRedraw(true);
388 state
.OnBeginImplFrameDeadline();
389 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
390 EXPECT_ACTION_UPDATE_STATE(
391 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
394 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
395 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
396 EXPECT_TRUE(state
.BeginFrameNeeded());
397 EXPECT_TRUE(state
.RedrawPending());
398 // But the commit is ongoing.
399 EXPECT_TRUE(state
.CommitPending());
401 // Finish the commit. Note, we should not yet be forcing a draw, but should
402 // continue the commit as usual.
403 state
.NotifyBeginMainFrameStarted();
404 state
.NotifyReadyToCommit();
405 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
406 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
407 EXPECT_TRUE(state
.RedrawPending());
409 // The redraw should be forced at the end of the next BeginImplFrame.
410 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
411 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
412 EXPECT_ACTION_UPDATE_STATE(
413 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
414 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
415 state
.OnBeginImplFrameDeadline();
416 EXPECT_ACTION_UPDATE_STATE(
417 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED
);
418 state
.DidSwapBuffers();
419 state
.DidSwapBuffersComplete();
422 TEST(SchedulerStateMachineTest
, TestFailedDrawsDoNotRestartForcedDraw
) {
423 SchedulerSettings scheduler_settings
;
425 scheduler_settings
.maximum_number_of_failed_draws_before_draw_is_forced_
=
427 scheduler_settings
.impl_side_painting
= true;
428 StateMachine
state(scheduler_settings
);
432 state
.SetNeedsCommit();
433 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
434 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
435 EXPECT_ACTION_UPDATE_STATE(
436 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
437 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
438 EXPECT_TRUE(state
.CommitPending());
440 // Then initiate a draw.
441 state
.SetNeedsRedraw(true);
442 state
.OnBeginImplFrameDeadline();
443 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
444 EXPECT_ACTION_UPDATE_STATE(
445 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
447 // Fail the draw enough times to force a redraw,
448 // then once more for good measure.
449 for (int i
= 0; i
< draw_limit
+ 1; ++i
)
450 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
451 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
452 EXPECT_TRUE(state
.BeginFrameNeeded());
453 EXPECT_TRUE(state
.RedrawPending());
454 // But the commit is ongoing.
455 EXPECT_TRUE(state
.CommitPending());
456 EXPECT_TRUE(state
.ForcedRedrawState() ==
457 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_COMMIT
);
459 state
.NotifyBeginMainFrameStarted();
460 state
.NotifyReadyToCommit();
461 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
462 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
463 EXPECT_TRUE(state
.RedrawPending());
464 EXPECT_FALSE(state
.CommitPending());
466 // Now force redraw should be in waiting for activation
467 EXPECT_TRUE(state
.ForcedRedrawState() ==
468 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
);
470 // After failing additional draws, we should still be in a forced
471 // redraw, but not back in WAITING_FOR_COMMIT.
472 for (int i
= 0; i
< draw_limit
+ 1; ++i
)
473 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
474 EXPECT_TRUE(state
.RedrawPending());
475 EXPECT_TRUE(state
.ForcedRedrawState() ==
476 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
);
479 TEST(SchedulerStateMachineTest
, TestFailedDrawIsRetriedInNextBeginImplFrame
) {
480 SchedulerSettings default_scheduler_settings
;
481 StateMachine
state(default_scheduler_settings
);
485 state
.SetNeedsRedraw(true);
486 EXPECT_TRUE(state
.BeginFrameNeeded());
487 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
488 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
489 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
490 state
.OnBeginImplFrameDeadline();
491 EXPECT_TRUE(state
.RedrawPending());
492 EXPECT_ACTION_UPDATE_STATE(
493 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
495 // Failing the draw for animation checkerboards makes us require a commit.
496 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
497 EXPECT_ACTION_UPDATE_STATE(
498 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
499 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
500 EXPECT_TRUE(state
.RedrawPending());
502 // We should not be trying to draw again now, but we have a commit pending.
503 EXPECT_TRUE(state
.BeginFrameNeeded());
504 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
505 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
506 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
508 // We should try to draw again at the end of the next BeginImplFrame on
510 state
.OnBeginImplFrameDeadline();
511 EXPECT_ACTION_UPDATE_STATE(
512 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
513 state
.DidSwapBuffers();
514 state
.DidSwapBuffersComplete();
515 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
518 TEST(SchedulerStateMachineTest
, TestDoestDrawTwiceInSameFrame
) {
519 SchedulerSettings default_scheduler_settings
;
520 StateMachine
state(default_scheduler_settings
);
522 state
.SetNeedsRedraw(true);
524 // Draw the first frame.
525 EXPECT_TRUE(state
.BeginFrameNeeded());
526 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
527 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
528 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
530 state
.OnBeginImplFrameDeadline();
531 EXPECT_ACTION_UPDATE_STATE(
532 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
533 state
.DidSwapBuffers();
534 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
535 state
.DidSwapBuffersComplete();
536 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
538 // Before the next BeginImplFrame, set needs redraw again.
539 // This should not redraw until the next BeginImplFrame.
540 state
.SetNeedsRedraw(true);
541 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
543 // Move to another frame. This should now draw.
544 EXPECT_TRUE(state
.BeginFrameNeeded());
545 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
547 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
548 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
550 state
.OnBeginImplFrameDeadline();
551 EXPECT_ACTION_UPDATE_STATE(
552 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
553 state
.DidSwapBuffers();
554 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
555 state
.DidSwapBuffersComplete();
556 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
558 // We just swapped, so we should proactively request another BeginImplFrame.
559 EXPECT_TRUE(state
.BeginFrameNeeded());
562 TEST(SchedulerStateMachineTest
, TestNextActionDrawsOnBeginImplFrame
) {
563 SchedulerSettings default_scheduler_settings
;
565 // When not in BeginImplFrame deadline, or in BeginImplFrame deadline
566 // but not visible, don't draw.
567 size_t num_commit_states
=
568 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
569 size_t num_begin_impl_frame_states
=
570 sizeof(all_begin_impl_frame_states
) /
571 sizeof(SchedulerStateMachine::BeginImplFrameState
);
572 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
573 for (size_t j
= 0; j
< num_begin_impl_frame_states
; ++j
) {
574 StateMachine
state(default_scheduler_settings
);
576 state
.UpdateState(state
.NextAction());
577 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
578 state
.SetCommitState(all_commit_states
[i
]);
579 state
.SetBeginImplFrameState(all_begin_impl_frame_states
[j
]);
581 (all_begin_impl_frame_states
[j
] !=
582 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
583 state
.SetVisible(visible
);
585 // Case 1: needs_commit=false
586 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
589 // Case 2: needs_commit=true
590 state
.SetNeedsCommit();
591 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
593 << state
.AsValue()->ToString();
597 // When in BeginImplFrame deadline we should always draw for SetNeedsRedraw
598 // except if we're ready to commit, in which case we expect a commit first.
599 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
600 StateMachine
state(default_scheduler_settings
);
602 state
.UpdateState(state
.NextAction());
603 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
604 state
.SetCanDraw(true);
605 state
.SetCommitState(all_commit_states
[i
]);
606 state
.SetBeginImplFrameState(
607 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
609 state
.SetNeedsRedraw(true);
610 state
.SetVisible(true);
612 SchedulerStateMachine::Action expected_action
;
613 if (all_commit_states
[i
] ==
614 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
) {
615 expected_action
= SchedulerStateMachine::ACTION_COMMIT
;
617 expected_action
= SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
;
618 EXPECT_ACTION(SchedulerStateMachine::ACTION_ANIMATE
);
619 state
.UpdateState(state
.NextAction());
622 // Case 1: needs_commit=false.
623 EXPECT_ACTION(expected_action
);
625 // Case 2: needs_commit=true.
626 state
.SetNeedsCommit();
627 EXPECT_ACTION(expected_action
);
631 TEST(SchedulerStateMachineTest
, TestNoCommitStatesRedrawWhenInvisible
) {
632 SchedulerSettings default_scheduler_settings
;
634 size_t num_commit_states
=
635 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
636 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
637 // There shouldn't be any drawing regardless of BeginImplFrame.
638 for (size_t j
= 0; j
< 2; ++j
) {
639 StateMachine
state(default_scheduler_settings
);
641 state
.UpdateState(state
.NextAction());
642 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
643 state
.SetCommitState(all_commit_states
[i
]);
644 state
.SetVisible(false);
645 state
.SetNeedsRedraw(true);
647 state
.SetBeginImplFrameState(
648 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
651 // Case 1: needs_commit=false.
652 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
655 // Case 2: needs_commit=true.
656 state
.SetNeedsCommit();
657 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
659 << state
.AsValue()->ToString();
664 TEST(SchedulerStateMachineTest
, TestCanRedraw_StopsDraw
) {
665 SchedulerSettings default_scheduler_settings
;
667 size_t num_commit_states
=
668 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
669 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
670 // There shouldn't be any drawing regardless of BeginImplFrame.
671 for (size_t j
= 0; j
< 2; ++j
) {
672 StateMachine
state(default_scheduler_settings
);
674 state
.UpdateState(state
.NextAction());
675 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
676 state
.SetCommitState(all_commit_states
[i
]);
677 state
.SetVisible(false);
678 state
.SetNeedsRedraw(true);
680 state
.OnBeginImplFrame(
681 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
683 state
.SetCanDraw(false);
684 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
690 TEST(SchedulerStateMachineTest
,
691 TestCanRedrawWithWaitingForFirstDrawMakesProgress
) {
692 SchedulerSettings default_scheduler_settings
;
693 StateMachine
state(default_scheduler_settings
);
695 state
.UpdateState(state
.NextAction());
696 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
698 state
.SetActiveTreeNeedsFirstDraw(true);
699 state
.SetNeedsCommit();
700 state
.SetNeedsRedraw(true);
701 state
.SetVisible(true);
702 state
.SetCanDraw(false);
703 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
704 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
705 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
706 EXPECT_ACTION_UPDATE_STATE(
707 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
708 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
709 state
.NotifyBeginMainFrameStarted();
710 state
.NotifyReadyToCommit();
711 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
712 state
.OnBeginImplFrameDeadline();
713 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
714 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
715 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
718 TEST(SchedulerStateMachineTest
, TestSetNeedsCommitIsNotLost
) {
719 SchedulerSettings scheduler_settings
;
720 StateMachine
state(scheduler_settings
);
722 state
.SetNeedsCommit();
724 EXPECT_TRUE(state
.BeginFrameNeeded());
727 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
728 EXPECT_ACTION_UPDATE_STATE(
729 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
731 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
733 // Now, while the frame is in progress, set another commit.
734 state
.SetNeedsCommit();
735 EXPECT_TRUE(state
.NeedsCommit());
737 // Let the frame finish.
738 state
.NotifyBeginMainFrameStarted();
739 state
.NotifyReadyToCommit();
740 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
);
742 // Expect to commit regardless of BeginImplFrame state.
743 EXPECT_IMPL_FRAME_STATE(
744 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
745 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
747 state
.OnBeginImplFrameDeadlinePending();
748 EXPECT_IMPL_FRAME_STATE(
749 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
);
750 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
752 state
.OnBeginImplFrameDeadline();
753 EXPECT_IMPL_FRAME_STATE(
754 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
755 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
757 state
.OnBeginImplFrameIdle();
758 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
759 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
761 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
762 EXPECT_IMPL_FRAME_STATE(
763 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
764 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
766 // Finish the commit, then make sure we start the next commit immediately
767 // and draw on the next BeginImplFrame.
768 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
769 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
770 EXPECT_ACTION_UPDATE_STATE(
771 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
772 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
774 state
.OnBeginImplFrameDeadline();
776 EXPECT_TRUE(state
.active_tree_needs_first_draw());
777 EXPECT_ACTION_UPDATE_STATE(
778 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
779 state
.DidSwapBuffers();
780 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
781 state
.DidSwapBuffersComplete();
782 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
785 TEST(SchedulerStateMachineTest
, TestFullCycle
) {
786 SchedulerSettings default_scheduler_settings
;
787 StateMachine
state(default_scheduler_settings
);
790 // Start clean and set commit.
791 state
.SetNeedsCommit();
794 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
795 EXPECT_ACTION_UPDATE_STATE(
796 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
798 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
799 EXPECT_FALSE(state
.NeedsCommit());
800 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
802 // Tell the scheduler the frame finished.
803 state
.NotifyBeginMainFrameStarted();
804 state
.NotifyReadyToCommit();
805 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
);
808 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
809 EXPECT_TRUE(state
.active_tree_needs_first_draw());
810 EXPECT_TRUE(state
.needs_redraw());
812 // Expect to do nothing until BeginImplFrame deadline
813 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
815 // At BeginImplFrame deadline, draw.
816 state
.OnBeginImplFrameDeadline();
817 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
818 EXPECT_ACTION_UPDATE_STATE(
819 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
820 state
.DidSwapBuffers();
821 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
822 state
.DidSwapBuffersComplete();
824 // Should be synchronized, no draw needed, no action needed.
825 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
826 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
827 EXPECT_FALSE(state
.needs_redraw());
830 TEST(SchedulerStateMachineTest
, TestFullCycleWithMainThreadLowLatencyMode
) {
831 SchedulerSettings scheduler_settings
;
832 scheduler_settings
.main_thread_should_always_be_low_latency
= true;
833 StateMachine
state(scheduler_settings
);
836 // Start clean and set commit.
837 state
.SetNeedsCommit();
840 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
841 EXPECT_ACTION_UPDATE_STATE(
842 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
844 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
845 EXPECT_FALSE(state
.NeedsCommit());
846 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
848 // Tell the scheduler the frame finished.
849 state
.NotifyBeginMainFrameStarted();
850 state
.NotifyReadyToCommit();
851 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
);
854 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
855 EXPECT_TRUE(state
.active_tree_needs_first_draw());
856 EXPECT_TRUE(state
.needs_redraw());
858 // Now commit should wait for draw.
859 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW
);
861 // Swap throttled. Do not draw.
862 state
.DidSwapBuffers();
863 state
.OnBeginImplFrameDeadline();
864 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
865 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
866 state
.DidSwapBuffersComplete();
868 // Haven't draw since last commit, do not begin new main frame.
869 state
.SetNeedsCommit();
870 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
871 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
872 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
874 // At BeginImplFrame deadline, draw.
875 state
.OnBeginImplFrameDeadline();
876 EXPECT_ACTION_UPDATE_STATE(
877 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
878 state
.DidSwapBuffers();
879 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
880 state
.DidSwapBuffersComplete();
882 // Now will be able to start main frame.
883 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
884 EXPECT_FALSE(state
.needs_redraw());
885 EXPECT_ACTION_UPDATE_STATE(
886 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
889 TEST(SchedulerStateMachineTest
,
890 TestFullCycleWithMainThreadLowLatencyMode_ImplSidePaint
) {
891 SchedulerSettings scheduler_settings
;
892 scheduler_settings
.main_thread_should_always_be_low_latency
= true;
893 scheduler_settings
.impl_side_painting
= true;
894 StateMachine
state(scheduler_settings
);
897 // Start clean and set commit.
898 state
.SetNeedsCommit();
901 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
902 EXPECT_ACTION_UPDATE_STATE(
903 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
905 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
906 EXPECT_FALSE(state
.NeedsCommit());
907 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
909 // Tell the scheduler the frame finished.
910 state
.NotifyBeginMainFrameStarted();
911 state
.NotifyReadyToCommit();
912 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
);
915 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
917 // Now commit should wait for activation.
919 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION
);
921 // No activation yet, so this commit is not drawn yet. Force to draw this
922 // frame, and still block BeginMainFrame.
923 state
.SetNeedsRedraw(true);
924 state
.SetNeedsCommit();
925 state
.OnBeginImplFrameDeadline();
926 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
927 EXPECT_ACTION_UPDATE_STATE(
928 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
929 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
931 // Cannot BeginMainFrame yet since last commit is not yet activated and drawn.
932 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
934 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION
);
935 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
937 // Now activate sync tree.
938 state
.NotifyReadyToActivate();
939 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
940 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
941 EXPECT_TRUE(state
.active_tree_needs_first_draw());
942 EXPECT_TRUE(state
.needs_redraw());
943 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW
);
945 // Swap throttled. Do not draw.
946 state
.DidSwapBuffers();
947 state
.OnBeginImplFrameDeadline();
948 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
949 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
950 state
.DidSwapBuffersComplete();
952 // Haven't draw since last commit, do not begin new main frame.
953 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
954 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
955 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
957 // At BeginImplFrame deadline, draw. This draws unblocks BeginMainFrame.
958 state
.OnBeginImplFrameDeadline();
959 EXPECT_ACTION_UPDATE_STATE(
960 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
961 state
.DidSwapBuffers();
962 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
963 state
.DidSwapBuffersComplete();
965 // Now will be able to start main frame.
966 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
967 EXPECT_FALSE(state
.needs_redraw());
968 EXPECT_ACTION_UPDATE_STATE(
969 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
972 TEST(SchedulerStateMachineTest
, TestFullCycleWithCommitRequestInbetween
) {
973 SchedulerSettings default_scheduler_settings
;
974 StateMachine
state(default_scheduler_settings
);
977 // Start clean and set commit.
978 state
.SetNeedsCommit();
981 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
982 EXPECT_ACTION_UPDATE_STATE(
983 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
985 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
986 EXPECT_FALSE(state
.NeedsCommit());
987 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
989 // Request another commit while the commit is in flight.
990 state
.SetNeedsCommit();
991 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
993 // Tell the scheduler the frame finished.
994 state
.NotifyBeginMainFrameStarted();
995 state
.NotifyReadyToCommit();
996 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
);
999 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1000 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1001 EXPECT_TRUE(state
.needs_redraw());
1003 // Expect to do nothing until BeginImplFrame deadline.
1004 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1006 // At BeginImplFrame deadline, draw.
1007 state
.OnBeginImplFrameDeadline();
1008 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1009 EXPECT_ACTION_UPDATE_STATE(
1010 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1011 state
.DidSwapBuffers();
1012 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
1013 state
.DidSwapBuffersComplete();
1015 // Should be synchronized, no draw needed, no action needed.
1016 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1017 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1018 EXPECT_FALSE(state
.needs_redraw());
1020 // Next BeginImplFrame should initiate second commit.
1021 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1022 EXPECT_ACTION_UPDATE_STATE(
1023 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1026 TEST(SchedulerStateMachineTest
, TestRequestCommitInvisible
) {
1027 SchedulerSettings default_scheduler_settings
;
1028 StateMachine
state(default_scheduler_settings
);
1029 state
.SetCanStart();
1030 state
.UpdateState(state
.NextAction());
1031 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1032 state
.SetNeedsCommit();
1033 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1036 // See ThreadProxy::BeginMainFrame "EarlyOut_NotVisible" /
1037 // "EarlyOut_OutputSurfaceLost" cases.
1038 TEST(SchedulerStateMachineTest
, TestAbortBeginMainFrameBecauseInvisible
) {
1039 SchedulerSettings default_scheduler_settings
;
1040 StateMachine
state(default_scheduler_settings
);
1043 // Start clean and set commit.
1044 state
.SetNeedsCommit();
1046 // Begin the frame while visible.
1047 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1048 EXPECT_ACTION_UPDATE_STATE(
1049 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1050 EXPECT_COMMIT_STATE(
1051 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1052 EXPECT_FALSE(state
.NeedsCommit());
1053 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1055 // Become invisible and abort BeginMainFrame.
1056 state
.SetVisible(false);
1057 state
.BeginMainFrameAborted(CommitEarlyOutReason::ABORTED_NOT_VISIBLE
);
1059 // NeedsCommit should now be true again because we never actually did a
1061 EXPECT_TRUE(state
.NeedsCommit());
1063 // We should now be back in the idle state as if we never started the frame.
1064 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1065 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1067 // We shouldn't do anything on the BeginImplFrame deadline.
1068 state
.OnBeginImplFrameDeadline();
1069 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1071 // Become visible again.
1072 state
.SetVisible(true);
1074 // Although we have aborted on this frame and haven't cancelled the commit
1075 // (i.e. need another), don't send another BeginMainFrame yet.
1076 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1077 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1078 EXPECT_TRUE(state
.NeedsCommit());
1080 // Start a new frame.
1081 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1082 EXPECT_ACTION_UPDATE_STATE(
1083 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1085 // We should be starting the commit now.
1086 EXPECT_COMMIT_STATE(
1087 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1088 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1091 // See ThreadProxy::BeginMainFrame "EarlyOut_NoUpdates" case.
1092 TEST(SchedulerStateMachineTest
, TestAbortBeginMainFrameBecauseCommitNotNeeded
) {
1093 SchedulerSettings default_scheduler_settings
;
1094 StateMachine
state(default_scheduler_settings
);
1095 state
.SetCanStart();
1096 state
.UpdateState(state
.NextAction());
1097 state
.DidCreateAndInitializeOutputSurface();
1098 state
.SetVisible(true);
1099 state
.SetCanDraw(true);
1101 // Get into a begin frame / commit state.
1102 state
.SetNeedsCommit();
1103 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
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(SchedulerStateMachine::ACTION_NONE
);
1111 // Abort the commit, true means that the BeginMainFrame was sent but there
1112 // was no work to do on the main thread.
1113 state
.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES
);
1115 // NeedsCommit should now be false because the commit was actually handled.
1116 EXPECT_FALSE(state
.NeedsCommit());
1118 // Even though the commit was aborted, we still expect to draw the new frame.
1119 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1120 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1121 state
.OnBeginImplFrameDeadline();
1122 EXPECT_ACTION_UPDATE_STATE(
1123 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1124 state
.DidSwapBuffers();
1125 state
.DidSwapBuffersComplete();
1126 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1128 // Verify another commit doesn't start on another frame either.
1129 EXPECT_FALSE(state
.NeedsCommit());
1130 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1132 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1133 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1134 state
.OnBeginImplFrameDeadline();
1135 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1137 // Verify another commit can start if requested, though.
1138 state
.SetNeedsCommit();
1139 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1140 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1141 EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1144 TEST(SchedulerStateMachineTest
, TestFirstContextCreation
) {
1145 SchedulerSettings default_scheduler_settings
;
1146 StateMachine
state(default_scheduler_settings
);
1147 state
.SetCanStart();
1148 state
.SetVisible(true);
1149 state
.SetCanDraw(true);
1151 EXPECT_ACTION_UPDATE_STATE(
1152 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1153 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1154 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1156 // Check that the first init does not SetNeedsCommit.
1157 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1158 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1159 state
.OnBeginImplFrameDeadline();
1160 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1162 // Check that a needs commit initiates a BeginMainFrame.
1163 state
.SetNeedsCommit();
1164 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1165 EXPECT_ACTION_UPDATE_STATE(
1166 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1169 TEST(SchedulerStateMachineTest
, TestContextLostWhenCompletelyIdle
) {
1170 SchedulerSettings default_scheduler_settings
;
1171 StateMachine
state(default_scheduler_settings
);
1174 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1175 state
.NextAction());
1176 state
.DidLoseOutputSurface();
1178 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1179 state
.UpdateState(state
.NextAction());
1181 // Once context recreation begins, nothing should happen.
1182 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1184 // Recreate the context.
1185 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1187 // When the context is recreated, we should begin a commit.
1188 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1189 EXPECT_ACTION_UPDATE_STATE(
1190 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1193 TEST(SchedulerStateMachineTest
,
1194 TestContextLostWhenIdleAndCommitRequestedWhileRecreating
) {
1195 SchedulerSettings default_scheduler_settings
;
1196 // We use impl side painting because it's the more complicated version.
1197 default_scheduler_settings
.impl_side_painting
= true;
1198 StateMachine
state(default_scheduler_settings
);
1201 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1202 state
.NextAction());
1203 state
.DidLoseOutputSurface();
1204 EXPECT_EQ(state
.output_surface_state(),
1205 SchedulerStateMachine::OUTPUT_SURFACE_LOST
);
1207 EXPECT_ACTION_UPDATE_STATE(
1208 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1209 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1211 // Once context recreation begins, nothing should happen.
1212 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1213 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1214 state
.OnBeginImplFrameDeadline();
1215 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1217 // While context is recreating, commits shouldn't begin.
1218 state
.SetNeedsCommit();
1219 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1220 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1221 state
.OnBeginImplFrameDeadline();
1222 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1224 // Recreate the context
1225 state
.DidCreateAndInitializeOutputSurface();
1226 EXPECT_EQ(state
.output_surface_state(),
1227 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT
);
1228 EXPECT_FALSE(state
.RedrawPending());
1230 // When the context is recreated, we wait until the next BeginImplFrame
1232 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1234 // When the BeginFrame comes in we should begin a commit
1235 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1236 EXPECT_ACTION_UPDATE_STATE(
1237 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1238 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1239 EXPECT_COMMIT_STATE(
1240 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1242 // Until that commit finishes, we shouldn't be drawing or animate.
1243 state
.OnBeginImplFrameDeadline();
1244 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1246 // Finish the commit, which should make the surface active.
1247 state
.NotifyBeginMainFrameStarted();
1248 state
.NotifyReadyToCommit();
1249 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1250 EXPECT_EQ(state
.output_surface_state(),
1251 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION
);
1252 state
.NotifyReadyToActivate();
1253 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1254 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1255 EXPECT_EQ(state
.output_surface_state(),
1256 SchedulerStateMachine::OUTPUT_SURFACE_ACTIVE
);
1258 // Finishing the first commit after initializing an output surface should
1259 // automatically cause a redraw.
1260 EXPECT_TRUE(state
.RedrawPending());
1261 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1262 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1263 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1264 state
.OnBeginImplFrameDeadline();
1265 EXPECT_ACTION_UPDATE_STATE(
1266 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1267 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1268 EXPECT_FALSE(state
.RedrawPending());
1270 // Next frame as no work to do.
1271 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1272 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1273 state
.OnBeginImplFrameDeadline();
1274 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1276 // Once the context is recreated, whether we draw should be based on
1277 // SetCanDraw if waiting on first draw after activate.
1278 state
.SetNeedsRedraw(true);
1279 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1280 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1281 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1282 state
.OnBeginImplFrameDeadline();
1283 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1284 state
.SetCanDraw(false);
1285 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1286 state
.SetCanDraw(true);
1287 EXPECT_ACTION_UPDATE_STATE(
1288 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1289 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1291 // Once the context is recreated, whether we draw should be based on
1292 // SetCanDraw if waiting on first draw after activate.
1293 state
.SetNeedsRedraw(true);
1294 state
.SetNeedsCommit();
1295 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1296 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1297 EXPECT_ACTION_UPDATE_STATE(
1298 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1299 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1300 // Activate so we need the first draw
1301 state
.NotifyBeginMainFrameStarted();
1302 state
.NotifyReadyToCommit();
1303 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1304 state
.NotifyReadyToActivate();
1305 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1306 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1307 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1308 EXPECT_TRUE(state
.needs_redraw());
1310 state
.OnBeginImplFrameDeadline();
1311 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1312 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1313 state
.SetCanDraw(false);
1314 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1315 state
.SetCanDraw(true);
1316 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1319 TEST(SchedulerStateMachineTest
, TestContextLostWhileCommitInProgress
) {
1320 SchedulerSettings scheduler_settings
;
1321 StateMachine
state(scheduler_settings
);
1324 // Get a commit in flight.
1325 state
.SetNeedsCommit();
1327 // Set damage and expect a draw.
1328 state
.SetNeedsRedraw(true);
1329 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1330 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1331 EXPECT_ACTION_UPDATE_STATE(
1332 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1333 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1334 state
.OnBeginImplFrameDeadline();
1335 EXPECT_ACTION_UPDATE_STATE(
1336 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1337 state
.DidSwapBuffers();
1338 state
.DidSwapBuffersComplete();
1339 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1341 // Cause a lost context while the BeginMainFrame is in flight.
1342 state
.DidLoseOutputSurface();
1344 // Ask for another draw. Expect nothing happens.
1345 state
.SetNeedsRedraw(true);
1346 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1348 // Finish the frame, and commit.
1349 state
.NotifyBeginMainFrameStarted();
1350 state
.NotifyReadyToCommit();
1351 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1353 // We will abort the draw when the output surface is lost if we are
1354 // waiting for the first draw to unblock the main thread.
1355 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1356 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1358 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1359 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
1360 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1362 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1363 EXPECT_IMPL_FRAME_STATE(
1364 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
1365 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1367 state
.OnBeginImplFrameDeadlinePending();
1368 EXPECT_IMPL_FRAME_STATE(
1369 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
);
1370 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1372 state
.OnBeginImplFrameDeadline();
1373 EXPECT_IMPL_FRAME_STATE(
1374 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
1375 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1378 TEST(SchedulerStateMachineTest
,
1379 TestContextLostWhileCommitInProgressAndAnotherCommitRequested
) {
1380 SchedulerSettings scheduler_settings
;
1381 StateMachine
state(scheduler_settings
);
1384 // Get a commit in flight.
1385 state
.SetNeedsCommit();
1386 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1388 // Set damage and expect a draw.
1389 state
.SetNeedsRedraw(true);
1390 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1391 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1392 EXPECT_ACTION_UPDATE_STATE(
1393 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1394 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1395 state
.OnBeginImplFrameDeadline();
1396 EXPECT_ACTION_UPDATE_STATE(
1397 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1398 state
.DidSwapBuffers();
1399 state
.DidSwapBuffersComplete();
1400 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1402 // Cause a lost context while the BeginMainFrame is in flight.
1403 state
.DidLoseOutputSurface();
1405 // Ask for another draw and also set needs commit. Expect nothing happens.
1406 state
.SetNeedsRedraw(true);
1407 state
.SetNeedsCommit();
1408 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1410 // Finish the frame, and commit.
1411 state
.NotifyBeginMainFrameStarted();
1412 state
.NotifyReadyToCommit();
1413 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1414 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1416 // Because the output surface is missing, we expect the draw to abort.
1417 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1419 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1420 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
1421 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1423 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1424 EXPECT_IMPL_FRAME_STATE(
1425 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
1426 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1428 state
.OnBeginImplFrameDeadlinePending();
1429 EXPECT_IMPL_FRAME_STATE(
1430 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
);
1431 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1433 state
.OnBeginImplFrameDeadline();
1434 EXPECT_IMPL_FRAME_STATE(
1435 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
1436 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1438 state
.OnBeginImplFrameIdle();
1439 EXPECT_ACTION_UPDATE_STATE(
1440 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1442 // After we get a new output surface, the commit flow should start.
1443 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1444 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1445 EXPECT_ACTION_UPDATE_STATE(
1446 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1447 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1448 state
.NotifyBeginMainFrameStarted();
1449 state
.NotifyReadyToCommit();
1450 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1451 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1452 state
.OnBeginImplFrameDeadline();
1453 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1454 EXPECT_ACTION_UPDATE_STATE(
1455 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1456 state
.DidSwapBuffers();
1457 state
.DidSwapBuffersComplete();
1458 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1461 TEST(SchedulerStateMachineTest
, DontDrawBeforeCommitAfterLostOutputSurface
) {
1462 SchedulerSettings default_scheduler_settings
;
1463 StateMachine
state(default_scheduler_settings
);
1466 state
.SetNeedsRedraw(true);
1468 // Cause a lost output surface, and restore it.
1469 state
.DidLoseOutputSurface();
1470 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1471 state
.UpdateState(state
.NextAction());
1472 state
.DidCreateAndInitializeOutputSurface();
1474 EXPECT_FALSE(state
.RedrawPending());
1475 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1476 EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1479 TEST(SchedulerStateMachineTest
,
1480 TestPendingActivationsShouldBeForcedAfterLostOutputSurface
) {
1481 SchedulerSettings settings
;
1482 settings
.impl_side_painting
= true;
1483 StateMachine
state(settings
);
1486 state
.SetCommitState(
1487 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1489 // Cause a lost context.
1490 state
.DidLoseOutputSurface();
1492 state
.NotifyBeginMainFrameStarted();
1493 state
.NotifyReadyToCommit();
1494 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1496 EXPECT_TRUE(state
.PendingActivationsShouldBeForced());
1497 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1499 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1500 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1503 TEST(SchedulerStateMachineTest
, TestNoBeginMainFrameWhenInvisible
) {
1504 SchedulerSettings default_scheduler_settings
;
1505 StateMachine
state(default_scheduler_settings
);
1506 state
.SetCanStart();
1507 state
.UpdateState(state
.NextAction());
1508 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1509 state
.SetVisible(false);
1510 state
.SetNeedsCommit();
1511 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1514 TEST(SchedulerStateMachineTest
, TestFinishCommitWhenCommitInProgress
) {
1515 SchedulerSettings default_scheduler_settings
;
1516 StateMachine
state(default_scheduler_settings
);
1517 state
.SetCanStart();
1518 state
.UpdateState(state
.NextAction());
1519 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1520 state
.SetVisible(false);
1521 state
.SetCommitState(
1522 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1523 state
.SetNeedsCommit();
1525 state
.NotifyBeginMainFrameStarted();
1526 state
.NotifyReadyToCommit();
1527 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
1528 state
.UpdateState(state
.NextAction());
1530 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1531 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1534 TEST(SchedulerStateMachineTest
, TestInitialActionsWhenContextLost
) {
1535 SchedulerSettings default_scheduler_settings
;
1536 StateMachine
state(default_scheduler_settings
);
1538 state
.SetNeedsCommit();
1539 state
.DidLoseOutputSurface();
1541 // When we are visible, we normally want to begin output surface creation
1542 // as soon as possible.
1543 EXPECT_ACTION_UPDATE_STATE(
1544 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1546 state
.DidCreateAndInitializeOutputSurface();
1547 EXPECT_EQ(state
.output_surface_state(),
1548 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT
);
1550 // We should not send a BeginMainFrame when we are invisible, even if we've
1551 // lost the output surface and are trying to get the first commit, since the
1552 // main thread will just abort anyway.
1553 state
.SetVisible(false);
1554 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1557 TEST(SchedulerStateMachineTest
, ReportIfNotDrawing
) {
1558 SchedulerSettings default_scheduler_settings
;
1559 StateMachine
state(default_scheduler_settings
);
1561 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1563 state
.SetCanDraw(false);
1564 state
.SetVisible(true);
1565 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1567 state
.SetCanDraw(true);
1568 state
.SetVisible(false);
1569 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1571 state
.SetCanDraw(false);
1572 state
.SetVisible(false);
1573 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1575 state
.SetCanDraw(true);
1576 state
.SetVisible(true);
1577 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1580 TEST(SchedulerStateMachineTest
,
1581 TestTriggerDeadlineImmediatelyAfterAbortedCommit
) {
1582 SchedulerSettings settings
;
1583 settings
.impl_side_painting
= true;
1584 StateMachine
state(settings
);
1587 // This test mirrors what happens during the first frame of a scroll gesture.
1588 // First we get the input event and a BeginFrame.
1589 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1591 // As a response the compositor requests a redraw and a commit to tell the
1592 // main thread about the new scroll offset.
1593 state
.SetNeedsRedraw(true);
1594 state
.SetNeedsCommit();
1596 // We should start the commit normally.
1597 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1598 EXPECT_ACTION_UPDATE_STATE(
1599 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1600 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1602 // Since only the scroll offset changed, the main thread will abort the
1604 state
.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES
);
1606 // Since the commit was aborted, we should draw right away instead of waiting
1607 // for the deadline.
1608 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1611 void FinishPreviousCommitAndDrawWithoutExitingDeadline(
1612 StateMachine
* state_ptr
) {
1613 // Gross, but allows us to use macros below.
1614 StateMachine
& state
= *state_ptr
;
1616 state
.NotifyBeginMainFrameStarted();
1617 state
.NotifyReadyToCommit();
1618 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1619 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1620 state
.NotifyReadyToActivate();
1621 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1622 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1624 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1625 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1626 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1628 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1629 state
.OnBeginImplFrameDeadline();
1630 EXPECT_ACTION_UPDATE_STATE(
1631 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1632 state
.DidSwapBuffers();
1635 TEST(SchedulerStateMachineTest
, TestImplLatencyTakesPriority
) {
1636 SchedulerSettings settings
;
1637 settings
.impl_side_painting
= true;
1638 StateMachine
state(settings
);
1641 // This test ensures that impl-draws are prioritized over main thread updates
1642 // in prefer impl latency mode.
1643 state
.SetNeedsRedraw(true);
1644 state
.SetNeedsCommit();
1645 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1646 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1647 EXPECT_ACTION_UPDATE_STATE(
1648 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1649 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1651 // Verify the deadline is not triggered early until we enter
1652 // prefer impl latency mode.
1653 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1654 state
.SetImplLatencyTakesPriority(true);
1655 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1657 // Trigger the deadline.
1658 state
.OnBeginImplFrameDeadline();
1659 EXPECT_ACTION_UPDATE_STATE(
1660 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1661 state
.DidSwapBuffers();
1662 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1663 state
.DidSwapBuffersComplete();
1665 // Request a new commit and finish the previous one.
1666 state
.SetNeedsCommit();
1667 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state
);
1668 EXPECT_ACTION_UPDATE_STATE(
1669 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1670 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1671 state
.DidSwapBuffersComplete();
1672 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1674 // Finish the previous commit and draw it.
1675 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state
);
1676 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1678 // Verify we do not send another BeginMainFrame if was are swap throttled
1679 // and did not just swap.
1680 state
.SetNeedsCommit();
1681 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1682 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1683 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1684 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1685 state
.OnBeginImplFrameDeadline();
1686 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1689 TEST(SchedulerStateMachineTest
,
1690 TestTriggerDeadlineImmediatelyOnLostOutputSurface
) {
1691 SchedulerSettings default_scheduler_settings
;
1692 StateMachine
state(default_scheduler_settings
);
1695 state
.SetNeedsCommit();
1697 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1698 EXPECT_ACTION_UPDATE_STATE(
1699 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1700 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1701 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1703 state
.DidLoseOutputSurface();
1704 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1705 // The deadline should be triggered immediately when output surface is lost.
1706 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1709 TEST(SchedulerStateMachineTest
, TestSetNeedsAnimate
) {
1710 SchedulerSettings settings
;
1711 settings
.impl_side_painting
= true;
1712 StateMachine
state(settings
);
1715 // Test requesting an animation that, when run, causes us to draw.
1716 state
.SetNeedsAnimate();
1717 EXPECT_TRUE(state
.BeginFrameNeeded());
1718 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1720 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1721 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1723 state
.OnBeginImplFrameDeadlinePending();
1724 state
.OnBeginImplFrameDeadline();
1725 EXPECT_ACTION_UPDATE_STATE(
1726 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1729 TEST(SchedulerStateMachineTest
, TestAnimateBeforeCommit
) {
1730 SchedulerSettings settings
;
1731 settings
.impl_side_painting
= true;
1732 StateMachine
state(settings
);
1735 // Check that animations are updated before we start a commit.
1736 state
.SetNeedsAnimate();
1737 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1738 state
.SetNeedsCommit();
1739 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1740 EXPECT_TRUE(state
.BeginFrameNeeded());
1742 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1743 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1744 EXPECT_ACTION_UPDATE_STATE(
1745 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1747 state
.OnBeginImplFrameDeadlinePending();
1748 state
.OnBeginImplFrameDeadline();
1749 EXPECT_ACTION_UPDATE_STATE(
1750 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1753 TEST(SchedulerStateMachineTest
, TestAnimateAfterCommitBeforeDraw
) {
1754 SchedulerSettings settings
;
1755 settings
.impl_side_painting
= true;
1756 StateMachine
state(settings
);
1759 // Check that animations are updated before we start a commit.
1760 state
.SetNeedsAnimate();
1761 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1762 state
.SetNeedsCommit();
1763 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1764 EXPECT_TRUE(state
.BeginFrameNeeded());
1766 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1767 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1768 EXPECT_ACTION_UPDATE_STATE(
1769 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1771 state
.NotifyBeginMainFrameStarted();
1772 state
.NotifyReadyToCommit();
1773 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1775 state
.OnBeginImplFrameDeadlinePending();
1776 state
.OnBeginImplFrameDeadline();
1777 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1778 EXPECT_ACTION_UPDATE_STATE(
1779 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1782 TEST(SchedulerStateMachineTest
, TestSetNeedsAnimateAfterAnimate
) {
1783 SchedulerSettings settings
;
1784 settings
.impl_side_painting
= true;
1785 StateMachine
state(settings
);
1788 // Test requesting an animation after we have already animated during this
1790 state
.SetNeedsRedraw(true);
1791 EXPECT_TRUE(state
.BeginFrameNeeded());
1792 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1794 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1795 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1797 state
.SetNeedsAnimate();
1798 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1800 state
.OnBeginImplFrameDeadline();
1801 EXPECT_ACTION_UPDATE_STATE(
1802 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1805 TEST(SchedulerStateMachineTest
, TestForwardBeginFramesToChildren
) {
1806 SchedulerSettings settings
;
1807 settings
.forward_begin_frames_to_children
= true;
1808 StateMachine
state(settings
);
1811 EXPECT_FALSE(state
.BeginFrameNeeded());
1812 state
.SetChildrenNeedBeginFrames(true);
1813 EXPECT_TRUE(state
.BeginFrameNeeded());
1816 TEST(SchedulerStateMachineTest
, TestDeferCommit
) {
1817 SchedulerSettings settings
;
1818 StateMachine
state(settings
);
1821 state
.SetDeferCommits(true);
1823 state
.SetNeedsCommit();
1824 EXPECT_TRUE(state
.BeginFrameNeeded());
1825 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1827 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1828 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1830 state
.OnBeginImplFrameDeadline();
1831 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1833 state
.SetDeferCommits(false);
1834 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1835 EXPECT_ACTION_UPDATE_STATE(
1836 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);