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/debug/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 #define EXPECT_ACTION_UPDATE_STATE(action) \
13 EXPECT_EQ(action, state.NextAction()) << state.AsValue()->ToString(); \
14 if (action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE || \
15 action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED) { \
16 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE, \
17 state.begin_impl_frame_state()) \
18 << state.AsValue()->ToString(); \
20 state.UpdateState(action); \
21 if (action == SchedulerStateMachine::ACTION_NONE) { \
22 if (state.begin_impl_frame_state() == \
23 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) \
24 state.OnBeginImplFrameDeadlinePending(); \
25 if (state.begin_impl_frame_state() == \
26 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) \
27 state.OnBeginImplFrameIdle(); \
34 const SchedulerStateMachine::BeginImplFrameState all_begin_impl_frame_states
[] =
35 {SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
,
36 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
37 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
,
38 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
, };
40 const SchedulerStateMachine::CommitState all_commit_states
[] = {
41 SchedulerStateMachine::COMMIT_STATE_IDLE
,
42 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
43 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED
,
44 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
45 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION
,
46 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
};
48 // Exposes the protected state fields of the SchedulerStateMachine for testing
49 class StateMachine
: public SchedulerStateMachine
{
51 explicit StateMachine(const SchedulerSettings
& scheduler_settings
)
52 : SchedulerStateMachine(scheduler_settings
) {}
54 void CreateAndInitializeOutputSurfaceWithActivatedCommit() {
55 DidCreateAndInitializeOutputSurface();
56 output_surface_state_
= OUTPUT_SURFACE_ACTIVE
;
59 void SetCommitState(CommitState cs
) { commit_state_
= cs
; }
60 CommitState
CommitState() const { return commit_state_
; }
62 ForcedRedrawOnTimeoutState
ForcedRedrawState() const {
63 return forced_redraw_state_
;
66 void SetBeginImplFrameState(BeginImplFrameState bifs
) {
67 begin_impl_frame_state_
= bifs
;
70 BeginImplFrameState
begin_impl_frame_state() const {
71 return begin_impl_frame_state_
;
74 OutputSurfaceState
output_surface_state() const {
75 return output_surface_state_
;
78 bool NeedsCommit() const { return needs_commit_
; }
80 void SetNeedsRedraw(bool b
) { needs_redraw_
= b
; }
82 void SetNeedsForcedRedrawForTimeout(bool b
) {
83 forced_redraw_state_
= FORCED_REDRAW_STATE_WAITING_FOR_COMMIT
;
84 active_tree_needs_first_draw_
= true;
86 bool NeedsForcedRedrawForTimeout() const {
87 return forced_redraw_state_
!= FORCED_REDRAW_STATE_IDLE
;
90 void SetActiveTreeNeedsFirstDraw(bool needs_first_draw
) {
91 active_tree_needs_first_draw_
= needs_first_draw
;
94 bool CanDraw() const { return can_draw_
; }
95 bool Visible() const { return visible_
; }
97 bool PendingActivationsShouldBeForced() const {
98 return SchedulerStateMachine::PendingActivationsShouldBeForced();
101 void SetHasPendingTree(bool has_pending_tree
) {
102 has_pending_tree_
= has_pending_tree
;
106 TEST(SchedulerStateMachineTest
, TestNextActionBeginsMainFrameIfNeeded
) {
107 SchedulerSettings default_scheduler_settings
;
109 // If no commit needed, do nothing.
111 StateMachine
state(default_scheduler_settings
);
113 EXPECT_ACTION_UPDATE_STATE(
114 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
)
115 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
116 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
117 state
.SetNeedsRedraw(false);
118 state
.SetVisible(true);
120 EXPECT_FALSE(state
.BeginFrameNeeded());
122 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
123 EXPECT_FALSE(state
.BeginFrameNeeded());
124 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
126 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
127 state
.OnBeginImplFrameDeadline();
130 // If commit requested but can_start is still false, do nothing.
132 StateMachine
state(default_scheduler_settings
);
133 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
134 state
.SetNeedsRedraw(false);
135 state
.SetVisible(true);
136 state
.SetNeedsCommit();
138 EXPECT_FALSE(state
.BeginFrameNeeded());
140 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
141 EXPECT_FALSE(state
.BeginFrameNeeded());
142 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
143 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
144 state
.OnBeginImplFrameDeadline();
147 // If commit requested, begin a main frame.
149 StateMachine
state(default_scheduler_settings
);
150 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
152 state
.UpdateState(state
.NextAction());
153 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
154 state
.SetNeedsRedraw(false);
155 state
.SetVisible(true);
156 state
.SetNeedsCommit();
158 EXPECT_TRUE(state
.BeginFrameNeeded());
160 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
161 EXPECT_ACTION_UPDATE_STATE(
162 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
165 // Begin the frame, make sure needs_commit and commit_state update correctly.
167 StateMachine
state(default_scheduler_settings
);
169 state
.UpdateState(state
.NextAction());
170 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
171 state
.SetVisible(true);
172 state
.UpdateState(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
173 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
174 state
.CommitState());
175 EXPECT_FALSE(state
.NeedsCommit());
179 // Explicitly test main_frame_before_draw_enabled = false
180 TEST(SchedulerStateMachineTest
, MainFrameBeforeDrawDisabled
) {
181 SchedulerSettings scheduler_settings
;
182 scheduler_settings
.impl_side_painting
= true;
183 scheduler_settings
.main_frame_before_draw_enabled
= false;
184 StateMachine
state(scheduler_settings
);
185 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
187 state
.UpdateState(state
.NextAction());
188 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
189 state
.SetNeedsRedraw(false);
190 state
.SetVisible(true);
191 state
.SetCanDraw(true);
192 state
.SetNeedsCommit();
194 EXPECT_TRUE(state
.BeginFrameNeeded());
196 // Commit to the pending tree.
197 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
198 EXPECT_ACTION_UPDATE_STATE(
199 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
200 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
201 state
.NotifyBeginMainFrameStarted();
202 state
.NotifyReadyToCommit();
203 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
204 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
205 EXPECT_EQ(state
.CommitState(),
206 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
);
208 state
.OnBeginImplFrameDeadline();
209 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
210 EXPECT_EQ(state
.CommitState(),
211 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
);
213 // Verify that the next commit doesn't start until the previous
214 // commit has been drawn.
215 state
.SetNeedsCommit();
216 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
217 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
219 // Make sure that a draw of the active tree doesn't spuriously advance
220 // the commit state and unblock the next commit.
221 state
.SetNeedsRedraw(true);
222 state
.OnBeginImplFrameDeadline();
223 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
224 EXPECT_ACTION_UPDATE_STATE(
225 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
226 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
227 EXPECT_EQ(state
.CommitState(),
228 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
);
229 EXPECT_TRUE(state
.has_pending_tree());
231 // Verify NotifyReadyToActivate unblocks activation, draw, and
232 // commit in that order.
233 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
235 state
.NotifyReadyToActivate();
236 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
237 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
238 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
239 EXPECT_EQ(state
.CommitState(),
240 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
);
242 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
243 state
.OnBeginImplFrameDeadline();
244 EXPECT_ACTION_UPDATE_STATE(
245 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
246 state
.DidSwapBuffers();
247 state
.DidSwapBuffersComplete();
248 EXPECT_EQ(state
.CommitState(), SchedulerStateMachine::COMMIT_STATE_IDLE
);
249 EXPECT_ACTION_UPDATE_STATE(
250 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
251 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
252 EXPECT_EQ(state
.CommitState(),
253 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
255 state
.NotifyBeginMainFrameStarted();
256 state
.NotifyReadyToCommit();
257 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
258 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
259 EXPECT_EQ(state
.CommitState(),
260 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
);
263 // Explicitly test main_frame_before_activation_enabled = true
264 TEST(SchedulerStateMachineTest
, MainFrameBeforeActivationEnabled
) {
265 SchedulerSettings scheduler_settings
;
266 scheduler_settings
.impl_side_painting
= true;
267 scheduler_settings
.main_frame_before_activation_enabled
= true;
268 StateMachine
state(scheduler_settings
);
269 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
271 state
.UpdateState(state
.NextAction());
272 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
273 state
.SetNeedsRedraw(false);
274 state
.SetVisible(true);
275 state
.SetCanDraw(true);
276 state
.SetNeedsCommit();
278 EXPECT_TRUE(state
.BeginFrameNeeded());
280 // Commit to the pending tree.
281 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
282 EXPECT_ACTION_UPDATE_STATE(
283 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
284 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
286 state
.NotifyBeginMainFrameStarted();
287 state
.NotifyReadyToCommit();
288 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
289 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
290 EXPECT_EQ(state
.CommitState(), SchedulerStateMachine::COMMIT_STATE_IDLE
);
292 state
.OnBeginImplFrameDeadline();
293 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
295 // Verify that the next commit starts while there is still a pending tree.
296 state
.SetNeedsCommit();
297 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
298 EXPECT_ACTION_UPDATE_STATE(
299 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
300 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
302 // Verify the pending commit doesn't overwrite the pending
303 // tree until the pending tree has been activated.
304 state
.NotifyBeginMainFrameStarted();
305 state
.NotifyReadyToCommit();
306 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
308 // Verify NotifyReadyToActivate unblocks activation, draw, and
309 // commit in that order.
310 state
.NotifyReadyToActivate();
311 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
312 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
314 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
315 state
.OnBeginImplFrameDeadline();
316 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
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_COMMIT
);
322 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
323 EXPECT_EQ(state
.CommitState(), SchedulerStateMachine::COMMIT_STATE_IDLE
);
326 TEST(SchedulerStateMachineTest
,
327 TestFailedDrawForAnimationCheckerboardSetsNeedsCommitAndDoesNotDrawAgain
) {
328 SchedulerSettings default_scheduler_settings
;
329 StateMachine
state(default_scheduler_settings
);
331 state
.UpdateState(state
.NextAction());
332 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
333 state
.SetVisible(true);
334 state
.SetCanDraw(true);
335 state
.SetNeedsRedraw(true);
336 EXPECT_TRUE(state
.RedrawPending());
337 EXPECT_TRUE(state
.BeginFrameNeeded());
338 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
339 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
340 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
341 state
.OnBeginImplFrameDeadline();
343 // We're drawing now.
344 EXPECT_ACTION_UPDATE_STATE(
345 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
346 state
.DidSwapBuffers();
347 state
.DidSwapBuffersComplete();
348 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
350 EXPECT_FALSE(state
.RedrawPending());
351 EXPECT_FALSE(state
.CommitPending());
353 // Failing the draw makes us require a commit.
354 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
355 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
356 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
357 EXPECT_ACTION_UPDATE_STATE(
358 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
359 EXPECT_TRUE(state
.RedrawPending());
360 EXPECT_TRUE(state
.CommitPending());
363 TEST(SchedulerStateMachineTest
, TestFailedDrawForMissingHighResNeedsCommit
) {
364 SchedulerSettings default_scheduler_settings
;
365 StateMachine
state(default_scheduler_settings
);
367 state
.UpdateState(state
.NextAction());
368 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
369 state
.SetVisible(true);
370 state
.SetCanDraw(true);
371 state
.SetNeedsRedraw(true);
372 EXPECT_TRUE(state
.RedrawPending());
373 EXPECT_TRUE(state
.BeginFrameNeeded());
375 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
376 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
377 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
378 state
.OnBeginImplFrameDeadline();
379 EXPECT_ACTION_UPDATE_STATE(
380 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
381 state
.DidSwapBuffers();
382 state
.DidSwapBuffersComplete();
383 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
384 EXPECT_FALSE(state
.RedrawPending());
385 EXPECT_FALSE(state
.CommitPending());
387 // Missing high res content requires a commit (but not a redraw)
388 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
);
389 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
390 EXPECT_ACTION_UPDATE_STATE(
391 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
392 EXPECT_FALSE(state
.RedrawPending());
393 EXPECT_TRUE(state
.CommitPending());
396 TEST(SchedulerStateMachineTest
,
397 TestsetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw
) {
398 SchedulerSettings default_scheduler_settings
;
399 StateMachine
state(default_scheduler_settings
);
401 state
.UpdateState(state
.NextAction());
402 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
404 state
.SetVisible(true);
405 state
.SetCanDraw(true);
406 state
.SetNeedsRedraw(true);
407 EXPECT_TRUE(state
.RedrawPending());
408 EXPECT_TRUE(state
.BeginFrameNeeded());
409 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
410 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
411 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
412 state
.OnBeginImplFrameDeadline();
414 // We're drawing now.
415 EXPECT_ACTION_UPDATE_STATE(
416 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
417 state
.DidSwapBuffers();
418 state
.DidSwapBuffersComplete();
419 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
420 EXPECT_FALSE(state
.RedrawPending());
421 EXPECT_FALSE(state
.CommitPending());
423 // While still in the same BeginMainFrame callback on the main thread,
424 // set needs redraw again. This should not redraw.
425 state
.SetNeedsRedraw(true);
426 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
428 // Failing the draw for animation checkerboards makes us require a commit.
429 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
430 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
431 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
432 EXPECT_ACTION_UPDATE_STATE(
433 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
434 EXPECT_TRUE(state
.RedrawPending());
437 void TestFailedDrawsEventuallyForceDrawAfterNextCommit(
438 bool main_frame_before_draw_enabled
) {
439 SchedulerSettings scheduler_settings
;
440 scheduler_settings
.main_frame_before_draw_enabled
=
441 main_frame_before_draw_enabled
;
442 scheduler_settings
.maximum_number_of_failed_draws_before_draw_is_forced_
= 1;
443 StateMachine
state(scheduler_settings
);
445 state
.UpdateState(state
.NextAction());
446 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
447 state
.SetVisible(true);
448 state
.SetCanDraw(true);
451 state
.SetNeedsCommit();
452 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
453 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
454 EXPECT_ACTION_UPDATE_STATE(
455 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
456 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
457 EXPECT_TRUE(state
.CommitPending());
459 // Then initiate a draw.
460 state
.SetNeedsRedraw(true);
461 state
.OnBeginImplFrameDeadline();
462 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
463 EXPECT_ACTION_UPDATE_STATE(
464 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
467 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
468 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
469 EXPECT_TRUE(state
.BeginFrameNeeded());
470 EXPECT_TRUE(state
.RedrawPending());
471 // But the commit is ongoing.
472 EXPECT_TRUE(state
.CommitPending());
474 // Finish the commit. Note, we should not yet be forcing a draw, but should
475 // continue the commit as usual.
476 state
.NotifyBeginMainFrameStarted();
477 state
.NotifyReadyToCommit();
478 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
479 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
480 EXPECT_TRUE(state
.RedrawPending());
482 // The redraw should be forced at the end of the next BeginImplFrame.
483 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
484 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
485 if (main_frame_before_draw_enabled
) {
486 EXPECT_ACTION_UPDATE_STATE(
487 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
489 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
490 state
.OnBeginImplFrameDeadline();
491 EXPECT_ACTION_UPDATE_STATE(
492 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED
);
493 state
.DidSwapBuffers();
494 state
.DidSwapBuffersComplete();
497 TEST(SchedulerStateMachineTest
,
498 TestFailedDrawsEventuallyForceDrawAfterNextCommit
) {
499 bool main_frame_before_draw_enabled
= false;
500 TestFailedDrawsEventuallyForceDrawAfterNextCommit(
501 main_frame_before_draw_enabled
);
504 TEST(SchedulerStateMachineTest
,
505 TestFailedDrawsEventuallyForceDrawAfterNextCommit_CommitBeforeDraw
) {
506 bool main_frame_before_draw_enabled
= true;
507 TestFailedDrawsEventuallyForceDrawAfterNextCommit(
508 main_frame_before_draw_enabled
);
511 TEST(SchedulerStateMachineTest
, TestFailedDrawsDoNotRestartForcedDraw
) {
512 SchedulerSettings scheduler_settings
;
514 scheduler_settings
.maximum_number_of_failed_draws_before_draw_is_forced_
=
516 scheduler_settings
.impl_side_painting
= true;
517 StateMachine
state(scheduler_settings
);
519 state
.UpdateState(state
.NextAction());
520 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
521 state
.SetVisible(true);
522 state
.SetCanDraw(true);
525 state
.SetNeedsCommit();
526 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
527 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
528 EXPECT_ACTION_UPDATE_STATE(
529 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
530 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
531 EXPECT_TRUE(state
.CommitPending());
533 // Then initiate a draw.
534 state
.SetNeedsRedraw(true);
535 state
.OnBeginImplFrameDeadline();
536 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
537 EXPECT_ACTION_UPDATE_STATE(
538 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
540 // Fail the draw enough times to force a redraw,
541 // then once more for good measure.
542 for (int i
= 0; i
< draw_limit
+ 1; ++i
)
543 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
544 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
545 EXPECT_TRUE(state
.BeginFrameNeeded());
546 EXPECT_TRUE(state
.RedrawPending());
547 // But the commit is ongoing.
548 EXPECT_TRUE(state
.CommitPending());
549 EXPECT_TRUE(state
.ForcedRedrawState() ==
550 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_COMMIT
);
552 state
.NotifyBeginMainFrameStarted();
553 state
.NotifyReadyToCommit();
554 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
555 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
556 EXPECT_TRUE(state
.RedrawPending());
557 EXPECT_FALSE(state
.CommitPending());
559 // Now force redraw should be in waiting for activation
560 EXPECT_TRUE(state
.ForcedRedrawState() ==
561 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
);
563 // After failing additional draws, we should still be in a forced
564 // redraw, but not back in WAITING_FOR_COMMIT.
565 for (int i
= 0; i
< draw_limit
+ 1; ++i
)
566 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
567 EXPECT_TRUE(state
.RedrawPending());
568 EXPECT_TRUE(state
.ForcedRedrawState() ==
569 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
);
572 TEST(SchedulerStateMachineTest
, TestFailedDrawIsRetriedInNextBeginImplFrame
) {
573 SchedulerSettings default_scheduler_settings
;
574 StateMachine
state(default_scheduler_settings
);
576 state
.UpdateState(state
.NextAction());
577 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
578 state
.SetVisible(true);
579 state
.SetCanDraw(true);
582 state
.SetNeedsRedraw(true);
583 EXPECT_TRUE(state
.BeginFrameNeeded());
584 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
585 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
586 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
587 state
.OnBeginImplFrameDeadline();
588 EXPECT_TRUE(state
.RedrawPending());
589 EXPECT_ACTION_UPDATE_STATE(
590 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
592 // Failing the draw for animation checkerboards makes us require a commit.
593 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
594 EXPECT_ACTION_UPDATE_STATE(
595 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
596 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
597 EXPECT_TRUE(state
.RedrawPending());
599 // We should not be trying to draw again now, but we have a commit pending.
600 EXPECT_TRUE(state
.BeginFrameNeeded());
601 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
602 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
603 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
605 // We should try to draw again at the end of the next BeginImplFrame on
607 state
.OnBeginImplFrameDeadline();
608 EXPECT_ACTION_UPDATE_STATE(
609 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
610 state
.DidSwapBuffers();
611 state
.DidSwapBuffersComplete();
612 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
615 TEST(SchedulerStateMachineTest
, TestDoestDrawTwiceInSameFrame
) {
616 SchedulerSettings default_scheduler_settings
;
617 StateMachine
state(default_scheduler_settings
);
619 state
.UpdateState(state
.NextAction());
620 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
621 state
.SetVisible(true);
622 state
.SetCanDraw(true);
623 state
.SetNeedsRedraw(true);
625 // Draw the first frame.
626 EXPECT_TRUE(state
.BeginFrameNeeded());
627 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
628 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
629 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
631 state
.OnBeginImplFrameDeadline();
632 EXPECT_ACTION_UPDATE_STATE(
633 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
634 state
.DidSwapBuffers();
635 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
636 state
.DidSwapBuffersComplete();
637 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
639 // Before the next BeginImplFrame, set needs redraw again.
640 // This should not redraw until the next BeginImplFrame.
641 state
.SetNeedsRedraw(true);
642 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
644 // Move to another frame. This should now draw.
645 EXPECT_TRUE(state
.BeginFrameNeeded());
646 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
648 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
649 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
651 state
.OnBeginImplFrameDeadline();
652 EXPECT_ACTION_UPDATE_STATE(
653 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
654 state
.DidSwapBuffers();
655 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
656 state
.DidSwapBuffersComplete();
657 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
659 // We just swapped, so we should proactively request another BeginImplFrame.
660 EXPECT_TRUE(state
.BeginFrameNeeded());
663 TEST(SchedulerStateMachineTest
, TestNextActionDrawsOnBeginImplFrame
) {
664 SchedulerSettings default_scheduler_settings
;
666 // When not in BeginImplFrame deadline, or in BeginImplFrame deadline
667 // but not visible, don't draw.
668 size_t num_commit_states
=
669 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
670 size_t num_begin_impl_frame_states
=
671 sizeof(all_begin_impl_frame_states
) /
672 sizeof(SchedulerStateMachine::BeginImplFrameState
);
673 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
674 for (size_t j
= 0; j
< num_begin_impl_frame_states
; ++j
) {
675 StateMachine
state(default_scheduler_settings
);
677 state
.UpdateState(state
.NextAction());
678 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
679 state
.SetCommitState(all_commit_states
[i
]);
680 state
.SetBeginImplFrameState(all_begin_impl_frame_states
[j
]);
682 (all_begin_impl_frame_states
[j
] !=
683 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
684 state
.SetVisible(visible
);
686 // Case 1: needs_commit=false
687 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
690 // Case 2: needs_commit=true
691 state
.SetNeedsCommit();
692 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
694 << state
.AsValue()->ToString();
698 // When in BeginImplFrame deadline we should always draw for SetNeedsRedraw
699 // except if we're ready to commit, in which case we expect a commit first.
700 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
701 StateMachine
state(default_scheduler_settings
);
703 state
.UpdateState(state
.NextAction());
704 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
705 state
.SetCanDraw(true);
706 state
.SetCommitState(all_commit_states
[i
]);
707 state
.SetBeginImplFrameState(
708 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
710 state
.SetNeedsRedraw(true);
711 state
.SetVisible(true);
713 SchedulerStateMachine::Action expected_action
;
714 if (all_commit_states
[i
] ==
715 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
) {
716 expected_action
= SchedulerStateMachine::ACTION_COMMIT
;
718 expected_action
= SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
;
719 EXPECT_EQ(state
.NextAction(), SchedulerStateMachine::ACTION_ANIMATE
)
720 << state
.AsValue()->ToString();
721 state
.UpdateState(state
.NextAction());
724 // Case 1: needs_commit=false.
725 EXPECT_EQ(state
.NextAction(), expected_action
)
726 << state
.AsValue()->ToString();
728 // Case 2: needs_commit=true.
729 state
.SetNeedsCommit();
730 EXPECT_EQ(state
.NextAction(), expected_action
)
731 << state
.AsValue()->ToString();
735 TEST(SchedulerStateMachineTest
, TestNoCommitStatesRedrawWhenInvisible
) {
736 SchedulerSettings default_scheduler_settings
;
738 size_t num_commit_states
=
739 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
740 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
741 // There shouldn't be any drawing regardless of BeginImplFrame.
742 for (size_t j
= 0; j
< 2; ++j
) {
743 StateMachine
state(default_scheduler_settings
);
745 state
.UpdateState(state
.NextAction());
746 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
747 state
.SetCommitState(all_commit_states
[i
]);
748 state
.SetVisible(false);
749 state
.SetNeedsRedraw(true);
751 state
.SetBeginImplFrameState(
752 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
755 // Case 1: needs_commit=false.
756 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
759 // Case 2: needs_commit=true.
760 state
.SetNeedsCommit();
761 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
763 << state
.AsValue()->ToString();
768 TEST(SchedulerStateMachineTest
, TestCanRedraw_StopsDraw
) {
769 SchedulerSettings default_scheduler_settings
;
771 size_t num_commit_states
=
772 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
773 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
774 // There shouldn't be any drawing regardless of BeginImplFrame.
775 for (size_t j
= 0; j
< 2; ++j
) {
776 StateMachine
state(default_scheduler_settings
);
778 state
.UpdateState(state
.NextAction());
779 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
780 state
.SetCommitState(all_commit_states
[i
]);
781 state
.SetVisible(false);
782 state
.SetNeedsRedraw(true);
784 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
786 state
.SetCanDraw(false);
787 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
793 TEST(SchedulerStateMachineTest
,
794 TestCanRedrawWithWaitingForFirstDrawMakesProgress
) {
795 SchedulerSettings default_scheduler_settings
;
796 StateMachine
state(default_scheduler_settings
);
798 state
.UpdateState(state
.NextAction());
799 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
801 state
.SetActiveTreeNeedsFirstDraw(true);
802 state
.SetNeedsCommit();
803 state
.SetNeedsRedraw(true);
804 state
.SetVisible(true);
805 state
.SetCanDraw(false);
806 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
807 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
808 EXPECT_ACTION_UPDATE_STATE(
809 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
810 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
811 state
.NotifyBeginMainFrameStarted();
812 state
.NotifyReadyToCommit();
813 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
814 state
.OnBeginImplFrameDeadline();
815 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
816 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
819 void TestSetNeedsCommitIsNotLost(bool main_frame_before_draw_enabled
) {
820 SchedulerSettings scheduler_settings
;
821 scheduler_settings
.main_frame_before_draw_enabled
=
822 main_frame_before_draw_enabled
;
823 StateMachine
state(scheduler_settings
);
825 state
.UpdateState(state
.NextAction());
826 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
827 state
.SetNeedsCommit();
828 state
.SetVisible(true);
829 state
.SetCanDraw(true);
831 EXPECT_TRUE(state
.BeginFrameNeeded());
834 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
835 EXPECT_ACTION_UPDATE_STATE(
836 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
837 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
838 state
.CommitState());
840 // Now, while the frame is in progress, set another commit.
841 state
.SetNeedsCommit();
842 EXPECT_TRUE(state
.NeedsCommit());
844 // Let the frame finish.
845 state
.NotifyBeginMainFrameStarted();
846 state
.NotifyReadyToCommit();
847 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
848 state
.CommitState());
850 // Expect to commit regardless of BeginImplFrame state.
851 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
852 state
.begin_impl_frame_state());
853 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
855 state
.OnBeginImplFrameDeadlinePending();
856 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
,
857 state
.begin_impl_frame_state());
858 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
860 state
.OnBeginImplFrameDeadline();
861 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
,
862 state
.begin_impl_frame_state());
863 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
865 state
.OnBeginImplFrameIdle();
866 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
,
867 state
.begin_impl_frame_state());
868 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
870 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
871 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
872 state
.begin_impl_frame_state());
873 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
875 // Finish the commit, then make sure we start the next commit immediately
876 // and draw on the next BeginImplFrame.
877 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
878 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
879 if (main_frame_before_draw_enabled
) {
880 EXPECT_ACTION_UPDATE_STATE(
881 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
883 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
885 state
.OnBeginImplFrameDeadline();
887 EXPECT_TRUE(state
.active_tree_needs_first_draw());
888 EXPECT_ACTION_UPDATE_STATE(
889 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
890 state
.DidSwapBuffers();
891 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
892 state
.DidSwapBuffersComplete();
893 if (!main_frame_before_draw_enabled
) {
894 EXPECT_ACTION_UPDATE_STATE(
895 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
897 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
900 TEST(SchedulerStateMachineTest
, TestSetNeedsCommitIsNotLost
) {
901 bool main_frame_before_draw_enabled
= false;
902 TestSetNeedsCommitIsNotLost(main_frame_before_draw_enabled
);
905 TEST(SchedulerStateMachineTest
, TestSetNeedsCommitIsNotLost_CommitBeforeDraw
) {
906 bool main_frame_before_draw_enabled
= true;
907 TestSetNeedsCommitIsNotLost(main_frame_before_draw_enabled
);
910 TEST(SchedulerStateMachineTest
, TestFullCycle
) {
911 SchedulerSettings default_scheduler_settings
;
912 StateMachine
state(default_scheduler_settings
);
914 state
.UpdateState(state
.NextAction());
915 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
916 state
.SetVisible(true);
917 state
.SetCanDraw(true);
919 // Start clean and set commit.
920 state
.SetNeedsCommit();
923 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
924 EXPECT_ACTION_UPDATE_STATE(
925 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
926 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
927 state
.CommitState());
928 EXPECT_FALSE(state
.NeedsCommit());
929 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
931 // Tell the scheduler the frame finished.
932 state
.NotifyBeginMainFrameStarted();
933 state
.NotifyReadyToCommit();
934 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
935 state
.CommitState());
938 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
939 EXPECT_TRUE(state
.active_tree_needs_first_draw());
940 EXPECT_TRUE(state
.needs_redraw());
942 // Expect to do nothing until BeginImplFrame deadline
943 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
945 // At BeginImplFrame deadline, draw.
946 state
.OnBeginImplFrameDeadline();
947 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
948 EXPECT_ACTION_UPDATE_STATE(
949 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
950 state
.DidSwapBuffers();
951 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
952 state
.DidSwapBuffersComplete();
954 // Should be synchronized, no draw needed, no action needed.
955 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
956 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
957 EXPECT_FALSE(state
.needs_redraw());
960 TEST(SchedulerStateMachineTest
, TestFullCycleWithCommitRequestInbetween
) {
961 SchedulerSettings default_scheduler_settings
;
962 StateMachine
state(default_scheduler_settings
);
964 state
.UpdateState(state
.NextAction());
965 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
966 state
.SetVisible(true);
967 state
.SetCanDraw(true);
969 // Start clean and set commit.
970 state
.SetNeedsCommit();
973 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
974 EXPECT_ACTION_UPDATE_STATE(
975 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
976 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
977 state
.CommitState());
978 EXPECT_FALSE(state
.NeedsCommit());
979 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
981 // Request another commit while the commit is in flight.
982 state
.SetNeedsCommit();
983 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
985 // Tell the scheduler the frame finished.
986 state
.NotifyBeginMainFrameStarted();
987 state
.NotifyReadyToCommit();
988 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
989 state
.CommitState());
992 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
993 EXPECT_TRUE(state
.active_tree_needs_first_draw());
994 EXPECT_TRUE(state
.needs_redraw());
996 // Expect to do nothing until BeginImplFrame deadline.
997 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
999 // At BeginImplFrame deadline, draw.
1000 state
.OnBeginImplFrameDeadline();
1001 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1002 EXPECT_ACTION_UPDATE_STATE(
1003 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1004 state
.DidSwapBuffers();
1005 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
1006 state
.DidSwapBuffersComplete();
1008 // Should be synchronized, no draw needed, no action needed.
1009 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1010 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1011 EXPECT_FALSE(state
.needs_redraw());
1013 // Next BeginImplFrame should initiate second commit.
1014 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1015 EXPECT_ACTION_UPDATE_STATE(
1016 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1019 TEST(SchedulerStateMachineTest
, TestRequestCommitInvisible
) {
1020 SchedulerSettings default_scheduler_settings
;
1021 StateMachine
state(default_scheduler_settings
);
1022 state
.SetCanStart();
1023 state
.UpdateState(state
.NextAction());
1024 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1025 state
.SetNeedsCommit();
1026 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1029 TEST(SchedulerStateMachineTest
, TestGoesInvisibleBeforeFinishCommit
) {
1030 SchedulerSettings default_scheduler_settings
;
1031 StateMachine
state(default_scheduler_settings
);
1032 state
.SetCanStart();
1033 state
.UpdateState(state
.NextAction());
1034 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1035 state
.SetVisible(true);
1036 state
.SetCanDraw(true);
1038 // Start clean and set commit.
1039 state
.SetNeedsCommit();
1041 // Begin the frame while visible.
1042 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1043 EXPECT_ACTION_UPDATE_STATE(
1044 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1045 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1046 state
.CommitState());
1047 EXPECT_FALSE(state
.NeedsCommit());
1048 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1050 // Become invisible and abort BeginMainFrame.
1051 state
.SetVisible(false);
1052 state
.BeginMainFrameAborted(false);
1054 // We should now be back in the idle state as if we never started the frame.
1055 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1056 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1058 // We shouldn't do anything on the BeginImplFrame deadline.
1059 state
.OnBeginImplFrameDeadline();
1060 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1062 // Become visible again.
1063 state
.SetVisible(true);
1065 // Although we have aborted on this frame and haven't cancelled the commit
1066 // (i.e. need another), don't send another BeginMainFrame yet.
1067 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1068 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1069 EXPECT_TRUE(state
.NeedsCommit());
1071 // Start a new frame.
1072 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1073 EXPECT_ACTION_UPDATE_STATE(
1074 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1076 // We should be starting the commit now.
1077 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1078 state
.CommitState());
1079 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1082 TEST(SchedulerStateMachineTest
, AbortBeginMainFrameAndCancelCommit
) {
1083 SchedulerSettings default_scheduler_settings
;
1084 StateMachine
state(default_scheduler_settings
);
1085 state
.SetCanStart();
1086 state
.UpdateState(state
.NextAction());
1087 state
.DidCreateAndInitializeOutputSurface();
1088 state
.SetVisible(true);
1089 state
.SetCanDraw(true);
1091 // Get into a begin frame / commit state.
1092 state
.SetNeedsCommit();
1094 EXPECT_ACTION_UPDATE_STATE(
1095 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1096 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1097 state
.CommitState());
1098 EXPECT_FALSE(state
.NeedsCommit());
1099 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1101 // Abort the commit, cancelling future commits.
1102 state
.BeginMainFrameAborted(true);
1104 // Verify that another commit doesn't start on the same frame.
1105 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1106 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1107 EXPECT_FALSE(state
.NeedsCommit());
1109 // Start a new frame; draw because this is the first frame since output
1111 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1112 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1113 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1114 state
.OnBeginImplFrameDeadline();
1115 EXPECT_ACTION_UPDATE_STATE(
1116 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1117 state
.DidSwapBuffers();
1118 state
.DidSwapBuffersComplete();
1120 // Verify another commit doesn't start on another frame either.
1121 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1122 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1123 EXPECT_FALSE(state
.NeedsCommit());
1125 // Verify another commit can start if requested, though.
1126 state
.SetNeedsCommit();
1127 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1128 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
,
1129 state
.NextAction());
1132 TEST(SchedulerStateMachineTest
,
1133 AbortBeginMainFrameAndCancelCommitWhenInvisible
) {
1134 SchedulerSettings default_scheduler_settings
;
1135 StateMachine
state(default_scheduler_settings
);
1136 state
.SetCanStart();
1137 state
.UpdateState(state
.NextAction());
1138 state
.DidCreateAndInitializeOutputSurface();
1139 state
.SetVisible(true);
1140 state
.SetCanDraw(true);
1142 // Get into a begin frame / commit state.
1143 state
.SetNeedsCommit();
1145 EXPECT_ACTION_UPDATE_STATE(
1146 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1147 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1148 state
.CommitState());
1149 EXPECT_FALSE(state
.NeedsCommit());
1150 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1152 // Become invisible and abort BeginMainFrame.
1153 state
.SetVisible(false);
1154 state
.BeginMainFrameAborted(true);
1156 // Verify that another commit doesn't start on the same frame.
1157 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1158 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1159 EXPECT_FALSE(state
.NeedsCommit());
1161 // Become visible and start a new frame.
1162 state
.SetVisible(true);
1163 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1164 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1165 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1167 // Draw because this is the first frame since output surface init'd.
1168 state
.OnBeginImplFrameDeadline();
1169 EXPECT_ACTION_UPDATE_STATE(
1170 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1171 state
.DidSwapBuffers();
1172 state
.DidSwapBuffersComplete();
1174 // Verify another commit doesn't start on another frame either.
1175 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1176 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1177 EXPECT_FALSE(state
.NeedsCommit());
1179 // Verify another commit can start if requested, though.
1180 state
.SetNeedsCommit();
1181 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1182 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
,
1183 state
.NextAction());
1186 TEST(SchedulerStateMachineTest
,
1187 AbortBeginMainFrameAndRequestCommitWhenInvisible
) {
1188 SchedulerSettings default_scheduler_settings
;
1189 StateMachine
state(default_scheduler_settings
);
1190 state
.SetCanStart();
1191 state
.UpdateState(state
.NextAction());
1192 state
.DidCreateAndInitializeOutputSurface();
1193 state
.SetVisible(true);
1194 state
.SetCanDraw(true);
1196 // Get into a begin frame / commit state.
1197 state
.SetNeedsCommit();
1199 EXPECT_ACTION_UPDATE_STATE(
1200 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1201 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1202 state
.CommitState());
1203 EXPECT_FALSE(state
.NeedsCommit());
1204 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1206 // Become invisible and abort BeginMainFrame.
1207 state
.SetVisible(false);
1208 state
.BeginMainFrameAborted(true);
1210 // Verify that another commit doesn't start on the same frame.
1211 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1212 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1213 EXPECT_FALSE(state
.NeedsCommit());
1215 // Asking for a commit while not visible won't make it happen.
1216 state
.SetNeedsCommit();
1217 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1218 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1219 EXPECT_TRUE(state
.NeedsCommit());
1221 // Become visible but nothing happens until the next frame.
1222 state
.SetVisible(true);
1223 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1224 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1225 EXPECT_TRUE(state
.NeedsCommit());
1227 // We should get that commit when we begin the next frame.
1228 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1229 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1230 EXPECT_ACTION_UPDATE_STATE(
1231 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1234 TEST(SchedulerStateMachineTest
,
1235 AbortBeginMainFrameAndRequestCommitAndBeginImplFrameWhenInvisible
) {
1236 SchedulerSettings default_scheduler_settings
;
1237 StateMachine
state(default_scheduler_settings
);
1238 state
.SetCanStart();
1239 state
.UpdateState(state
.NextAction());
1240 state
.DidCreateAndInitializeOutputSurface();
1241 state
.SetVisible(true);
1242 state
.SetCanDraw(true);
1244 // Get into a begin frame / commit state.
1245 state
.SetNeedsCommit();
1247 EXPECT_ACTION_UPDATE_STATE(
1248 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1249 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1250 state
.CommitState());
1251 EXPECT_FALSE(state
.NeedsCommit());
1252 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1254 // Become invisible and abort BeginMainFrame.
1255 state
.SetVisible(false);
1256 state
.BeginMainFrameAborted(true);
1258 // Asking for a commit while not visible won't make it happen.
1259 state
.SetNeedsCommit();
1260 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1261 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1262 EXPECT_TRUE(state
.NeedsCommit());
1264 // Begin a frame when not visible, the scheduler animates but does not commit.
1265 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1266 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1267 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1268 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1269 EXPECT_TRUE(state
.NeedsCommit());
1271 // Become visible and the requested commit happens immediately.
1272 state
.SetVisible(true);
1273 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1274 EXPECT_ACTION_UPDATE_STATE(
1275 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1278 TEST(SchedulerStateMachineTest
, TestFirstContextCreation
) {
1279 SchedulerSettings default_scheduler_settings
;
1280 StateMachine
state(default_scheduler_settings
);
1281 state
.SetCanStart();
1282 state
.SetVisible(true);
1283 state
.SetCanDraw(true);
1285 EXPECT_ACTION_UPDATE_STATE(
1286 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1287 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1288 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1290 // Check that the first init does not SetNeedsCommit.
1291 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1292 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1293 state
.OnBeginImplFrameDeadline();
1294 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1296 // Check that a needs commit initiates a BeginMainFrame.
1297 state
.SetNeedsCommit();
1298 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1299 EXPECT_ACTION_UPDATE_STATE(
1300 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1303 TEST(SchedulerStateMachineTest
, TestContextLostWhenCompletelyIdle
) {
1304 SchedulerSettings default_scheduler_settings
;
1305 StateMachine
state(default_scheduler_settings
);
1306 state
.SetCanStart();
1307 state
.UpdateState(state
.NextAction());
1308 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1310 state
.SetVisible(true);
1311 state
.SetCanDraw(true);
1313 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1314 state
.NextAction());
1315 state
.DidLoseOutputSurface();
1317 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1318 state
.NextAction());
1319 state
.UpdateState(state
.NextAction());
1321 // Once context recreation begins, nothing should happen.
1322 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1324 // Recreate the context.
1325 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1327 // When the context is recreated, we should begin a commit.
1328 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1329 EXPECT_ACTION_UPDATE_STATE(
1330 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1333 TEST(SchedulerStateMachineTest
,
1334 TestContextLostWhenIdleAndCommitRequestedWhileRecreating
) {
1335 SchedulerSettings default_scheduler_settings
;
1336 StateMachine
state(default_scheduler_settings
);
1337 state
.SetCanStart();
1338 state
.UpdateState(state
.NextAction());
1339 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1340 state
.SetVisible(true);
1341 state
.SetCanDraw(true);
1343 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1344 state
.NextAction());
1345 state
.DidLoseOutputSurface();
1347 EXPECT_ACTION_UPDATE_STATE(
1348 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1349 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1351 // Once context recreation begins, nothing should happen.
1352 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1353 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1354 state
.OnBeginImplFrameDeadline();
1355 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1357 // While context is recreating, commits shouldn't begin.
1358 state
.SetNeedsCommit();
1359 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1360 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1361 state
.OnBeginImplFrameDeadline();
1362 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1364 // Recreate the context
1365 state
.DidCreateAndInitializeOutputSurface();
1366 EXPECT_FALSE(state
.RedrawPending());
1368 // When the context is recreated, we should begin a commit
1369 EXPECT_ACTION_UPDATE_STATE(
1370 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1371 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1372 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1373 state
.CommitState());
1375 state
.NotifyBeginMainFrameStarted();
1376 state
.NotifyReadyToCommit();
1377 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1378 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1379 // Finishing the first commit after initializing an output surface should
1380 // automatically cause a redraw.
1381 EXPECT_TRUE(state
.RedrawPending());
1383 // Once the context is recreated, whether we draw should be based on
1385 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1386 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1387 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1388 state
.OnBeginImplFrameDeadline();
1389 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
1390 state
.NextAction());
1391 state
.SetCanDraw(false);
1392 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
,
1393 state
.NextAction());
1394 state
.SetCanDraw(true);
1395 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
1396 state
.NextAction());
1399 TEST(SchedulerStateMachineTest
, TestContextLostWhileCommitInProgress
) {
1400 SchedulerSettings scheduler_settings
;
1401 StateMachine
state(scheduler_settings
);
1402 state
.SetCanStart();
1403 state
.UpdateState(state
.NextAction());
1404 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1405 state
.SetVisible(true);
1406 state
.SetCanDraw(true);
1408 // Get a commit in flight.
1409 state
.SetNeedsCommit();
1411 // Set damage and expect a draw.
1412 state
.SetNeedsRedraw(true);
1413 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1414 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1415 EXPECT_ACTION_UPDATE_STATE(
1416 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1417 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1418 state
.OnBeginImplFrameDeadline();
1419 EXPECT_ACTION_UPDATE_STATE(
1420 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1421 state
.DidSwapBuffers();
1422 state
.DidSwapBuffersComplete();
1423 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1425 // Cause a lost context while the BeginMainFrame is in flight.
1426 state
.DidLoseOutputSurface();
1428 // Ask for another draw. Expect nothing happens.
1429 state
.SetNeedsRedraw(true);
1430 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1432 // Finish the frame, and commit.
1433 state
.NotifyBeginMainFrameStarted();
1434 state
.NotifyReadyToCommit();
1435 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1437 // We will abort the draw when the output surface is lost if we are
1438 // waiting for the first draw to unblock the main thread.
1439 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1440 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1442 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1443 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
,
1444 state
.begin_impl_frame_state());
1445 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1446 state
.NextAction());
1448 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1449 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
1450 state
.begin_impl_frame_state());
1451 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1453 state
.OnBeginImplFrameDeadlinePending();
1454 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
,
1455 state
.begin_impl_frame_state());
1456 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1458 state
.OnBeginImplFrameDeadline();
1459 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
,
1460 state
.begin_impl_frame_state());
1461 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1464 TEST(SchedulerStateMachineTest
,
1465 TestContextLostWhileCommitInProgressAndAnotherCommitRequested
) {
1466 SchedulerSettings scheduler_settings
;
1467 StateMachine
state(scheduler_settings
);
1468 state
.SetCanStart();
1469 state
.UpdateState(state
.NextAction());
1470 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1471 state
.SetVisible(true);
1472 state
.SetCanDraw(true);
1474 // Get a commit in flight.
1475 state
.SetNeedsCommit();
1476 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1478 // Set damage and expect a draw.
1479 state
.SetNeedsRedraw(true);
1480 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1481 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1482 EXPECT_ACTION_UPDATE_STATE(
1483 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1484 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1485 state
.OnBeginImplFrameDeadline();
1486 EXPECT_ACTION_UPDATE_STATE(
1487 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1488 state
.DidSwapBuffers();
1489 state
.DidSwapBuffersComplete();
1490 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1492 // Cause a lost context while the BeginMainFrame is in flight.
1493 state
.DidLoseOutputSurface();
1495 // Ask for another draw and also set needs commit. Expect nothing happens.
1496 state
.SetNeedsRedraw(true);
1497 state
.SetNeedsCommit();
1498 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1500 // Finish the frame, and commit.
1501 state
.NotifyBeginMainFrameStarted();
1502 state
.NotifyReadyToCommit();
1503 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1504 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1506 // Because the output surface is missing, we expect the draw to abort.
1507 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1509 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1510 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
,
1511 state
.begin_impl_frame_state());
1512 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1513 state
.NextAction());
1515 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1516 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
1517 state
.begin_impl_frame_state());
1518 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1520 state
.OnBeginImplFrameDeadlinePending();
1521 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
,
1522 state
.begin_impl_frame_state());
1523 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1525 state
.OnBeginImplFrameDeadline();
1526 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
,
1527 state
.begin_impl_frame_state());
1528 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1530 state
.OnBeginImplFrameIdle();
1531 EXPECT_ACTION_UPDATE_STATE(
1532 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1534 // After we get a new output surface, the commit flow should start.
1535 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1536 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1537 EXPECT_ACTION_UPDATE_STATE(
1538 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1539 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1540 state
.NotifyBeginMainFrameStarted();
1541 state
.NotifyReadyToCommit();
1542 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1543 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1544 state
.OnBeginImplFrameDeadline();
1545 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1546 EXPECT_ACTION_UPDATE_STATE(
1547 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1548 state
.DidSwapBuffers();
1549 state
.DidSwapBuffersComplete();
1550 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1553 TEST(SchedulerStateMachineTest
, DontDrawBeforeCommitAfterLostOutputSurface
) {
1554 SchedulerSettings default_scheduler_settings
;
1555 StateMachine
state(default_scheduler_settings
);
1556 state
.SetCanStart();
1557 state
.UpdateState(state
.NextAction());
1558 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1559 state
.SetVisible(true);
1560 state
.SetCanDraw(true);
1562 state
.SetNeedsRedraw(true);
1564 // Cause a lost output surface, and restore it.
1565 state
.DidLoseOutputSurface();
1566 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1567 state
.NextAction());
1568 state
.UpdateState(state
.NextAction());
1569 state
.DidCreateAndInitializeOutputSurface();
1571 EXPECT_FALSE(state
.RedrawPending());
1572 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1573 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
,
1574 state
.NextAction());
1577 TEST(SchedulerStateMachineTest
,
1578 TestPendingActivationsShouldBeForcedAfterLostOutputSurface
) {
1579 SchedulerSettings settings
;
1580 settings
.impl_side_painting
= true;
1581 StateMachine
state(settings
);
1582 state
.SetCanStart();
1583 state
.UpdateState(state
.NextAction());
1584 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1585 state
.SetVisible(true);
1586 state
.SetCanDraw(true);
1588 state
.SetCommitState(
1589 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1591 // Cause a lost context.
1592 state
.DidLoseOutputSurface();
1594 state
.NotifyBeginMainFrameStarted();
1595 state
.NotifyReadyToCommit();
1596 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1598 EXPECT_TRUE(state
.PendingActivationsShouldBeForced());
1599 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1601 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1602 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1605 TEST(SchedulerStateMachineTest
, TestNoBeginMainFrameWhenInvisible
) {
1606 SchedulerSettings default_scheduler_settings
;
1607 StateMachine
state(default_scheduler_settings
);
1608 state
.SetCanStart();
1609 state
.UpdateState(state
.NextAction());
1610 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1611 state
.SetVisible(false);
1612 state
.SetNeedsCommit();
1613 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1616 TEST(SchedulerStateMachineTest
, TestFinishCommitWhenCommitInProgress
) {
1617 SchedulerSettings default_scheduler_settings
;
1618 StateMachine
state(default_scheduler_settings
);
1619 state
.SetCanStart();
1620 state
.UpdateState(state
.NextAction());
1621 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1622 state
.SetVisible(false);
1623 state
.SetCommitState(
1624 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1625 state
.SetNeedsCommit();
1627 state
.NotifyBeginMainFrameStarted();
1628 state
.NotifyReadyToCommit();
1629 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
1630 state
.UpdateState(state
.NextAction());
1632 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1633 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1636 TEST(SchedulerStateMachineTest
, TestInitialActionsWhenContextLost
) {
1637 SchedulerSettings default_scheduler_settings
;
1638 StateMachine
state(default_scheduler_settings
);
1639 state
.SetCanStart();
1640 state
.UpdateState(state
.NextAction());
1641 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1642 state
.SetVisible(true);
1643 state
.SetCanDraw(true);
1644 state
.SetNeedsCommit();
1645 state
.DidLoseOutputSurface();
1647 // When we are visible, we normally want to begin output surface creation
1648 // as soon as possible.
1649 EXPECT_ACTION_UPDATE_STATE(
1650 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1652 state
.DidCreateAndInitializeOutputSurface();
1653 EXPECT_EQ(state
.output_surface_state(),
1654 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT
);
1656 // We should not send a BeginMainFrame when we are invisible, even if we've
1657 // lost the output surface and are trying to get the first commit, since the
1658 // main thread will just abort anyway.
1659 state
.SetVisible(false);
1660 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction())
1661 << state
.AsValue()->ToString();
1664 TEST(SchedulerStateMachineTest
, ReportIfNotDrawing
) {
1665 SchedulerSettings default_scheduler_settings
;
1666 StateMachine
state(default_scheduler_settings
);
1667 state
.SetCanStart();
1668 state
.UpdateState(state
.NextAction());
1669 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1671 state
.SetCanDraw(true);
1672 state
.SetVisible(true);
1673 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1675 state
.SetCanDraw(false);
1676 state
.SetVisible(true);
1677 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1679 state
.SetCanDraw(true);
1680 state
.SetVisible(false);
1681 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1683 state
.SetCanDraw(false);
1684 state
.SetVisible(false);
1685 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1687 state
.SetCanDraw(true);
1688 state
.SetVisible(true);
1689 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1692 TEST(SchedulerStateMachineTest
, TestTriggerDeadlineEarlyAfterAbortedCommit
) {
1693 SchedulerSettings settings
;
1694 settings
.impl_side_painting
= true;
1695 StateMachine
state(settings
);
1696 state
.SetCanStart();
1697 state
.UpdateState(state
.NextAction());
1698 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1699 state
.SetVisible(true);
1700 state
.SetCanDraw(true);
1702 // This test mirrors what happens during the first frame of a scroll gesture.
1703 // First we get the input event and a BeginFrame.
1704 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1706 // As a response the compositor requests a redraw and a commit to tell the
1707 // main thread about the new scroll offset.
1708 state
.SetNeedsRedraw(true);
1709 state
.SetNeedsCommit();
1711 // We should start the commit normally.
1712 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1713 EXPECT_ACTION_UPDATE_STATE(
1714 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1715 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1717 // Since only the scroll offset changed, the main thread will abort the
1719 state
.BeginMainFrameAborted(true);
1721 // Since the commit was aborted, we should draw right away instead of waiting
1722 // for the deadline.
1723 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1726 void FinishPreviousCommitAndDrawWithoutExitingDeadline(
1727 StateMachine
* state_ptr
) {
1728 // Gross, but allows us to use macros below.
1729 StateMachine
& state
= *state_ptr
;
1731 state
.NotifyBeginMainFrameStarted();
1732 state
.NotifyReadyToCommit();
1733 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1734 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1735 state
.NotifyReadyToActivate();
1736 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1737 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1739 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1740 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1741 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1743 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1744 state
.OnBeginImplFrameDeadline();
1745 EXPECT_ACTION_UPDATE_STATE(
1746 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1747 state
.DidSwapBuffers();
1750 TEST(SchedulerStateMachineTest
, TestImplLatencyTakesPriority
) {
1751 SchedulerSettings settings
;
1752 settings
.impl_side_painting
= true;
1753 StateMachine
state(settings
);
1754 state
.SetCanStart();
1755 state
.UpdateState(state
.NextAction());
1756 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1757 state
.SetVisible(true);
1758 state
.SetCanDraw(true);
1760 // This test ensures that impl-draws are prioritized over main thread updates
1761 // in prefer impl latency mode.
1762 state
.SetNeedsRedraw(true);
1763 state
.SetNeedsCommit();
1764 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1765 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1766 EXPECT_ACTION_UPDATE_STATE(
1767 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1768 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1770 // Verify the deadline is not triggered early until we enter
1771 // prefer impl latency mode.
1772 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1773 state
.SetImplLatencyTakesPriority(true);
1774 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1776 // Trigger the deadline.
1777 state
.OnBeginImplFrameDeadline();
1778 EXPECT_ACTION_UPDATE_STATE(
1779 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1780 state
.DidSwapBuffers();
1781 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1782 state
.DidSwapBuffersComplete();
1784 // Request a new commit and finish the previous one.
1785 state
.SetNeedsCommit();
1786 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state
);
1787 EXPECT_ACTION_UPDATE_STATE(
1788 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1789 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1790 state
.DidSwapBuffersComplete();
1791 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1793 // Finish the previous commit and draw it.
1794 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state
);
1795 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1797 // Verify we do not send another BeginMainFrame if was are swap throttled
1798 // and did not just swap.
1799 state
.SetNeedsCommit();
1800 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1801 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1802 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1803 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1804 state
.OnBeginImplFrameDeadline();
1805 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1808 TEST(SchedulerStateMachineTest
, TestTriggerDeadlineEarlyOnLostOutputSurface
) {
1809 SchedulerSettings default_scheduler_settings
;
1810 StateMachine
state(default_scheduler_settings
);
1811 state
.SetCanStart();
1812 state
.UpdateState(state
.NextAction());
1813 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1814 state
.SetVisible(true);
1815 state
.SetCanDraw(true);
1817 state
.SetNeedsCommit();
1819 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1820 EXPECT_ACTION_UPDATE_STATE(
1821 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1822 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1823 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1825 state
.DidLoseOutputSurface();
1826 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1827 // The deadline should be triggered immediately when output surface is lost.
1828 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1831 TEST(SchedulerStateMachineTest
, TestSetNeedsAnimate
) {
1832 SchedulerSettings settings
;
1833 settings
.impl_side_painting
= true;
1834 StateMachine
state(settings
);
1835 state
.SetCanStart();
1836 state
.UpdateState(state
.NextAction());
1837 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1838 state
.SetVisible(true);
1839 state
.SetCanDraw(true);
1841 // Test requesting an animation that, when run, causes us to draw.
1842 state
.SetNeedsAnimate();
1843 EXPECT_TRUE(state
.BeginFrameNeeded());
1844 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1846 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1847 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1849 state
.OnBeginImplFrameDeadlinePending();
1850 state
.OnBeginImplFrameDeadline();
1851 EXPECT_ACTION_UPDATE_STATE(
1852 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1855 TEST(SchedulerStateMachineTest
, TestAnimateBeforeCommit
) {
1856 SchedulerSettings settings
;
1857 settings
.impl_side_painting
= true;
1858 StateMachine
state(settings
);
1859 state
.SetCanStart();
1860 state
.UpdateState(state
.NextAction());
1861 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1862 state
.SetVisible(true);
1863 state
.SetCanDraw(true);
1865 // Check that animations are updated before we start a commit.
1866 state
.SetNeedsAnimate();
1867 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1868 state
.SetNeedsCommit();
1869 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1870 EXPECT_TRUE(state
.BeginFrameNeeded());
1872 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1873 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1874 EXPECT_ACTION_UPDATE_STATE(
1875 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1877 state
.OnBeginImplFrameDeadlinePending();
1878 state
.OnBeginImplFrameDeadline();
1879 EXPECT_ACTION_UPDATE_STATE(
1880 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1883 TEST(SchedulerStateMachineTest
, TestSetNeedsAnimateAfterAnimate
) {
1884 SchedulerSettings settings
;
1885 settings
.impl_side_painting
= true;
1886 StateMachine
state(settings
);
1887 state
.SetCanStart();
1888 state
.UpdateState(state
.NextAction());
1889 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1890 state
.SetVisible(true);
1891 state
.SetCanDraw(true);
1893 // Test requesting an animation after we have already animated during this
1895 state
.SetNeedsRedraw(true);
1896 EXPECT_TRUE(state
.BeginFrameNeeded());
1897 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1899 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1900 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1902 state
.SetNeedsAnimate();
1903 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1905 state
.OnBeginImplFrameDeadline();
1906 EXPECT_ACTION_UPDATE_STATE(
1907 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);