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 // 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(); \
56 const SchedulerStateMachine::BeginImplFrameState all_begin_impl_frame_states
[] =
57 {SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
,
58 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
59 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
,
60 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
, };
62 const SchedulerStateMachine::CommitState all_commit_states
[] = {
63 SchedulerStateMachine::COMMIT_STATE_IDLE
,
64 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
65 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED
,
66 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
67 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION
,
68 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW
};
70 // Exposes the protected state fields of the SchedulerStateMachine for testing
71 class StateMachine
: public SchedulerStateMachine
{
73 explicit StateMachine(const SchedulerSettings
& scheduler_settings
)
74 : SchedulerStateMachine(scheduler_settings
) {}
76 void CreateAndInitializeOutputSurfaceWithActivatedCommit() {
77 DidCreateAndInitializeOutputSurface();
78 output_surface_state_
= OUTPUT_SURFACE_ACTIVE
;
81 void SetCommitState(CommitState cs
) { commit_state_
= cs
; }
82 CommitState
CommitState() const { return commit_state_
; }
84 ForcedRedrawOnTimeoutState
ForcedRedrawState() const {
85 return forced_redraw_state_
;
88 void SetBeginImplFrameState(BeginImplFrameState bifs
) {
89 begin_impl_frame_state_
= bifs
;
92 BeginImplFrameState
begin_impl_frame_state() const {
93 return begin_impl_frame_state_
;
96 OutputSurfaceState
output_surface_state() const {
97 return output_surface_state_
;
100 bool NeedsCommit() const { return needs_commit_
; }
102 void SetNeedsRedraw(bool b
) { needs_redraw_
= b
; }
104 void SetNeedsForcedRedrawForTimeout(bool b
) {
105 forced_redraw_state_
= FORCED_REDRAW_STATE_WAITING_FOR_COMMIT
;
106 active_tree_needs_first_draw_
= true;
108 bool NeedsForcedRedrawForTimeout() const {
109 return forced_redraw_state_
!= FORCED_REDRAW_STATE_IDLE
;
112 void SetActiveTreeNeedsFirstDraw(bool needs_first_draw
) {
113 active_tree_needs_first_draw_
= needs_first_draw
;
116 bool CanDraw() const { return can_draw_
; }
117 bool Visible() const { return visible_
; }
119 bool PendingActivationsShouldBeForced() const {
120 return SchedulerStateMachine::PendingActivationsShouldBeForced();
123 void SetHasPendingTree(bool has_pending_tree
) {
124 has_pending_tree_
= has_pending_tree
;
127 using SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately
;
130 TEST(SchedulerStateMachineTest
, TestNextActionBeginsMainFrameIfNeeded
) {
131 SchedulerSettings default_scheduler_settings
;
133 // If no commit needed, do nothing.
135 StateMachine
state(default_scheduler_settings
);
137 EXPECT_ACTION_UPDATE_STATE(
138 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
)
139 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
140 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
141 state
.SetNeedsRedraw(false);
142 state
.SetVisible(true);
144 EXPECT_FALSE(state
.BeginFrameNeeded());
146 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
147 EXPECT_FALSE(state
.BeginFrameNeeded());
148 state
.OnBeginImplFrame(
149 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
151 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
152 state
.OnBeginImplFrameDeadline();
155 // If commit requested but can_start is still false, do nothing.
157 StateMachine
state(default_scheduler_settings
);
158 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
159 state
.SetNeedsRedraw(false);
160 state
.SetVisible(true);
161 state
.SetNeedsCommit();
163 EXPECT_FALSE(state
.BeginFrameNeeded());
165 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
166 EXPECT_FALSE(state
.BeginFrameNeeded());
167 state
.OnBeginImplFrame(
168 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
169 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
170 state
.OnBeginImplFrameDeadline();
173 // If commit requested, begin a main frame.
175 StateMachine
state(default_scheduler_settings
);
176 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
178 state
.UpdateState(state
.NextAction());
179 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
180 state
.SetNeedsRedraw(false);
181 state
.SetVisible(true);
182 state
.SetNeedsCommit();
184 EXPECT_TRUE(state
.BeginFrameNeeded());
186 state
.OnBeginImplFrame(
187 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
188 EXPECT_ACTION_UPDATE_STATE(
189 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
192 // Begin the frame, make sure needs_commit and commit_state update correctly.
194 StateMachine
state(default_scheduler_settings
);
196 state
.UpdateState(state
.NextAction());
197 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
198 state
.SetVisible(true);
199 state
.UpdateState(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
201 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
202 EXPECT_FALSE(state
.NeedsCommit());
206 // Explicitly test main_frame_before_activation_enabled = true
207 TEST(SchedulerStateMachineTest
, MainFrameBeforeActivationEnabled
) {
208 SchedulerSettings scheduler_settings
;
209 scheduler_settings
.impl_side_painting
= true;
210 scheduler_settings
.main_frame_before_activation_enabled
= true;
211 StateMachine
state(scheduler_settings
);
212 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
214 state
.UpdateState(state
.NextAction());
215 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
216 state
.SetNeedsRedraw(false);
217 state
.SetVisible(true);
218 state
.SetCanDraw(true);
219 state
.SetNeedsCommit();
221 EXPECT_TRUE(state
.BeginFrameNeeded());
223 // Commit to the pending tree.
224 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
225 EXPECT_ACTION_UPDATE_STATE(
226 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
227 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
229 state
.NotifyBeginMainFrameStarted();
230 state
.NotifyReadyToCommit();
231 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
232 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
233 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
235 state
.OnBeginImplFrameDeadline();
236 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
238 // Verify that the next commit starts while there is still a pending tree.
239 state
.SetNeedsCommit();
240 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
241 EXPECT_ACTION_UPDATE_STATE(
242 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
243 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
245 // Verify the pending commit doesn't overwrite the pending
246 // tree until the pending tree has been activated.
247 state
.NotifyBeginMainFrameStarted();
248 state
.NotifyReadyToCommit();
249 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
251 // Verify NotifyReadyToActivate unblocks activation, draw, and
252 // commit in that order.
253 state
.NotifyReadyToActivate();
254 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
255 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
257 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
258 state
.OnBeginImplFrameDeadline();
259 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
260 EXPECT_ACTION_UPDATE_STATE(
261 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
262 state
.DidSwapBuffers();
263 state
.DidSwapBuffersComplete();
264 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
265 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
266 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
269 TEST(SchedulerStateMachineTest
,
270 TestFailedDrawForAnimationCheckerboardSetsNeedsCommitAndDoesNotDrawAgain
) {
271 SchedulerSettings default_scheduler_settings
;
272 StateMachine
state(default_scheduler_settings
);
274 state
.UpdateState(state
.NextAction());
275 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
276 state
.SetVisible(true);
277 state
.SetCanDraw(true);
278 state
.SetNeedsRedraw(true);
279 EXPECT_TRUE(state
.RedrawPending());
280 EXPECT_TRUE(state
.BeginFrameNeeded());
281 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
282 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
283 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
284 state
.OnBeginImplFrameDeadline();
286 // We're drawing now.
287 EXPECT_ACTION_UPDATE_STATE(
288 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
289 state
.DidSwapBuffers();
290 state
.DidSwapBuffersComplete();
291 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
293 EXPECT_FALSE(state
.RedrawPending());
294 EXPECT_FALSE(state
.CommitPending());
296 // Failing the draw makes us require a commit.
297 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
298 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
299 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
300 EXPECT_ACTION_UPDATE_STATE(
301 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
302 EXPECT_TRUE(state
.RedrawPending());
303 EXPECT_TRUE(state
.CommitPending());
306 TEST(SchedulerStateMachineTest
, TestFailedDrawForMissingHighResNeedsCommit
) {
307 SchedulerSettings default_scheduler_settings
;
308 StateMachine
state(default_scheduler_settings
);
310 state
.UpdateState(state
.NextAction());
311 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
312 state
.SetVisible(true);
313 state
.SetCanDraw(true);
314 state
.SetNeedsRedraw(true);
315 EXPECT_TRUE(state
.RedrawPending());
316 EXPECT_TRUE(state
.BeginFrameNeeded());
318 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
319 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
320 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
321 state
.OnBeginImplFrameDeadline();
322 EXPECT_ACTION_UPDATE_STATE(
323 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
324 state
.DidSwapBuffers();
325 state
.DidSwapBuffersComplete();
326 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
327 EXPECT_FALSE(state
.RedrawPending());
328 EXPECT_FALSE(state
.CommitPending());
330 // Missing high res content requires a commit (but not a redraw)
331 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
);
332 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
333 EXPECT_ACTION_UPDATE_STATE(
334 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
335 EXPECT_FALSE(state
.RedrawPending());
336 EXPECT_TRUE(state
.CommitPending());
339 TEST(SchedulerStateMachineTest
,
340 TestsetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw
) {
341 SchedulerSettings default_scheduler_settings
;
342 StateMachine
state(default_scheduler_settings
);
344 state
.UpdateState(state
.NextAction());
345 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
347 state
.SetVisible(true);
348 state
.SetCanDraw(true);
349 state
.SetNeedsRedraw(true);
350 EXPECT_TRUE(state
.RedrawPending());
351 EXPECT_TRUE(state
.BeginFrameNeeded());
352 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
353 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
354 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
355 state
.OnBeginImplFrameDeadline();
357 // We're drawing now.
358 EXPECT_ACTION_UPDATE_STATE(
359 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
360 state
.DidSwapBuffers();
361 state
.DidSwapBuffersComplete();
362 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
363 EXPECT_FALSE(state
.RedrawPending());
364 EXPECT_FALSE(state
.CommitPending());
366 // While still in the same BeginMainFrame callback on the main thread,
367 // set needs redraw again. This should not redraw.
368 state
.SetNeedsRedraw(true);
369 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
371 // Failing the draw for animation checkerboards makes us require a commit.
372 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
373 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
374 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
375 EXPECT_ACTION_UPDATE_STATE(
376 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
377 EXPECT_TRUE(state
.RedrawPending());
380 TEST(SchedulerStateMachineTest
,
381 TestFailedDrawsEventuallyForceDrawAfterNextCommit
) {
382 SchedulerSettings scheduler_settings
;
383 scheduler_settings
.maximum_number_of_failed_draws_before_draw_is_forced_
= 1;
384 StateMachine
state(scheduler_settings
);
386 state
.UpdateState(state
.NextAction());
387 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
388 state
.SetVisible(true);
389 state
.SetCanDraw(true);
392 state
.SetNeedsCommit();
393 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
394 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
395 EXPECT_ACTION_UPDATE_STATE(
396 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
397 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
398 EXPECT_TRUE(state
.CommitPending());
400 // Then initiate a draw.
401 state
.SetNeedsRedraw(true);
402 state
.OnBeginImplFrameDeadline();
403 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
404 EXPECT_ACTION_UPDATE_STATE(
405 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
408 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
409 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
410 EXPECT_TRUE(state
.BeginFrameNeeded());
411 EXPECT_TRUE(state
.RedrawPending());
412 // But the commit is ongoing.
413 EXPECT_TRUE(state
.CommitPending());
415 // Finish the commit. Note, we should not yet be forcing a draw, but should
416 // continue the commit as usual.
417 state
.NotifyBeginMainFrameStarted();
418 state
.NotifyReadyToCommit();
419 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
420 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
421 EXPECT_TRUE(state
.RedrawPending());
423 // The redraw should be forced at the end of the next BeginImplFrame.
424 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
425 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
426 EXPECT_ACTION_UPDATE_STATE(
427 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
428 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
429 state
.OnBeginImplFrameDeadline();
430 EXPECT_ACTION_UPDATE_STATE(
431 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED
);
432 state
.DidSwapBuffers();
433 state
.DidSwapBuffersComplete();
436 TEST(SchedulerStateMachineTest
, TestFailedDrawsDoNotRestartForcedDraw
) {
437 SchedulerSettings scheduler_settings
;
439 scheduler_settings
.maximum_number_of_failed_draws_before_draw_is_forced_
=
441 scheduler_settings
.impl_side_painting
= true;
442 StateMachine
state(scheduler_settings
);
444 state
.UpdateState(state
.NextAction());
445 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
446 state
.SetVisible(true);
447 state
.SetCanDraw(true);
450 state
.SetNeedsCommit();
451 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
452 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
453 EXPECT_ACTION_UPDATE_STATE(
454 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
455 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
456 EXPECT_TRUE(state
.CommitPending());
458 // Then initiate a draw.
459 state
.SetNeedsRedraw(true);
460 state
.OnBeginImplFrameDeadline();
461 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
462 EXPECT_ACTION_UPDATE_STATE(
463 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
465 // Fail the draw enough times to force a redraw,
466 // then once more for good measure.
467 for (int i
= 0; i
< draw_limit
+ 1; ++i
)
468 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
469 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
470 EXPECT_TRUE(state
.BeginFrameNeeded());
471 EXPECT_TRUE(state
.RedrawPending());
472 // But the commit is ongoing.
473 EXPECT_TRUE(state
.CommitPending());
474 EXPECT_TRUE(state
.ForcedRedrawState() ==
475 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_COMMIT
);
477 state
.NotifyBeginMainFrameStarted();
478 state
.NotifyReadyToCommit();
479 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
480 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
481 EXPECT_TRUE(state
.RedrawPending());
482 EXPECT_FALSE(state
.CommitPending());
484 // Now force redraw should be in waiting for activation
485 EXPECT_TRUE(state
.ForcedRedrawState() ==
486 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
);
488 // After failing additional draws, we should still be in a forced
489 // redraw, but not back in WAITING_FOR_COMMIT.
490 for (int i
= 0; i
< draw_limit
+ 1; ++i
)
491 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
492 EXPECT_TRUE(state
.RedrawPending());
493 EXPECT_TRUE(state
.ForcedRedrawState() ==
494 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
);
497 TEST(SchedulerStateMachineTest
, TestFailedDrawIsRetriedInNextBeginImplFrame
) {
498 SchedulerSettings default_scheduler_settings
;
499 StateMachine
state(default_scheduler_settings
);
501 state
.UpdateState(state
.NextAction());
502 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
503 state
.SetVisible(true);
504 state
.SetCanDraw(true);
507 state
.SetNeedsRedraw(true);
508 EXPECT_TRUE(state
.BeginFrameNeeded());
509 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
510 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
511 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
512 state
.OnBeginImplFrameDeadline();
513 EXPECT_TRUE(state
.RedrawPending());
514 EXPECT_ACTION_UPDATE_STATE(
515 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
517 // Failing the draw for animation checkerboards makes us require a commit.
518 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
519 EXPECT_ACTION_UPDATE_STATE(
520 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
521 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
522 EXPECT_TRUE(state
.RedrawPending());
524 // We should not be trying to draw again now, but we have a commit pending.
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 // We should try to draw again at the end of the next BeginImplFrame on
532 state
.OnBeginImplFrameDeadline();
533 EXPECT_ACTION_UPDATE_STATE(
534 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
535 state
.DidSwapBuffers();
536 state
.DidSwapBuffersComplete();
537 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
540 TEST(SchedulerStateMachineTest
, TestDoestDrawTwiceInSameFrame
) {
541 SchedulerSettings default_scheduler_settings
;
542 StateMachine
state(default_scheduler_settings
);
544 state
.UpdateState(state
.NextAction());
545 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
546 state
.SetVisible(true);
547 state
.SetCanDraw(true);
548 state
.SetNeedsRedraw(true);
550 // Draw the first frame.
551 EXPECT_TRUE(state
.BeginFrameNeeded());
552 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
553 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
554 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
556 state
.OnBeginImplFrameDeadline();
557 EXPECT_ACTION_UPDATE_STATE(
558 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
559 state
.DidSwapBuffers();
560 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
561 state
.DidSwapBuffersComplete();
562 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
564 // Before the next BeginImplFrame, set needs redraw again.
565 // This should not redraw until the next BeginImplFrame.
566 state
.SetNeedsRedraw(true);
567 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
569 // Move to another frame. This should now draw.
570 EXPECT_TRUE(state
.BeginFrameNeeded());
571 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
573 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
574 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
576 state
.OnBeginImplFrameDeadline();
577 EXPECT_ACTION_UPDATE_STATE(
578 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
579 state
.DidSwapBuffers();
580 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
581 state
.DidSwapBuffersComplete();
582 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
584 // We just swapped, so we should proactively request another BeginImplFrame.
585 EXPECT_TRUE(state
.BeginFrameNeeded());
588 TEST(SchedulerStateMachineTest
, TestNextActionDrawsOnBeginImplFrame
) {
589 SchedulerSettings default_scheduler_settings
;
591 // When not in BeginImplFrame deadline, or in BeginImplFrame deadline
592 // but not visible, don't draw.
593 size_t num_commit_states
=
594 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
595 size_t num_begin_impl_frame_states
=
596 sizeof(all_begin_impl_frame_states
) /
597 sizeof(SchedulerStateMachine::BeginImplFrameState
);
598 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
599 for (size_t j
= 0; j
< num_begin_impl_frame_states
; ++j
) {
600 StateMachine
state(default_scheduler_settings
);
602 state
.UpdateState(state
.NextAction());
603 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
604 state
.SetCommitState(all_commit_states
[i
]);
605 state
.SetBeginImplFrameState(all_begin_impl_frame_states
[j
]);
607 (all_begin_impl_frame_states
[j
] !=
608 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
609 state
.SetVisible(visible
);
611 // Case 1: needs_commit=false
612 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
615 // Case 2: needs_commit=true
616 state
.SetNeedsCommit();
617 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
619 << state
.AsValue()->ToString();
623 // When in BeginImplFrame deadline we should always draw for SetNeedsRedraw
624 // except if we're ready to commit, in which case we expect a commit first.
625 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
626 StateMachine
state(default_scheduler_settings
);
628 state
.UpdateState(state
.NextAction());
629 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
630 state
.SetCanDraw(true);
631 state
.SetCommitState(all_commit_states
[i
]);
632 state
.SetBeginImplFrameState(
633 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
635 state
.SetNeedsRedraw(true);
636 state
.SetVisible(true);
638 SchedulerStateMachine::Action expected_action
;
639 if (all_commit_states
[i
] ==
640 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
) {
641 expected_action
= SchedulerStateMachine::ACTION_COMMIT
;
643 expected_action
= SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
;
644 EXPECT_ACTION(SchedulerStateMachine::ACTION_ANIMATE
);
645 state
.UpdateState(state
.NextAction());
648 // Case 1: needs_commit=false.
649 EXPECT_ACTION(expected_action
);
651 // Case 2: needs_commit=true.
652 state
.SetNeedsCommit();
653 EXPECT_ACTION(expected_action
);
657 TEST(SchedulerStateMachineTest
, TestNoCommitStatesRedrawWhenInvisible
) {
658 SchedulerSettings default_scheduler_settings
;
660 size_t num_commit_states
=
661 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
662 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
663 // There shouldn't be any drawing regardless of BeginImplFrame.
664 for (size_t j
= 0; j
< 2; ++j
) {
665 StateMachine
state(default_scheduler_settings
);
667 state
.UpdateState(state
.NextAction());
668 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
669 state
.SetCommitState(all_commit_states
[i
]);
670 state
.SetVisible(false);
671 state
.SetNeedsRedraw(true);
673 state
.SetBeginImplFrameState(
674 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
677 // Case 1: needs_commit=false.
678 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
681 // Case 2: needs_commit=true.
682 state
.SetNeedsCommit();
683 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
685 << state
.AsValue()->ToString();
690 TEST(SchedulerStateMachineTest
, TestCanRedraw_StopsDraw
) {
691 SchedulerSettings default_scheduler_settings
;
693 size_t num_commit_states
=
694 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
695 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
696 // There shouldn't be any drawing regardless of BeginImplFrame.
697 for (size_t j
= 0; j
< 2; ++j
) {
698 StateMachine
state(default_scheduler_settings
);
700 state
.UpdateState(state
.NextAction());
701 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
702 state
.SetCommitState(all_commit_states
[i
]);
703 state
.SetVisible(false);
704 state
.SetNeedsRedraw(true);
706 state
.OnBeginImplFrame(
707 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
709 state
.SetCanDraw(false);
710 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
716 TEST(SchedulerStateMachineTest
,
717 TestCanRedrawWithWaitingForFirstDrawMakesProgress
) {
718 SchedulerSettings default_scheduler_settings
;
719 StateMachine
state(default_scheduler_settings
);
721 state
.UpdateState(state
.NextAction());
722 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
724 state
.SetActiveTreeNeedsFirstDraw(true);
725 state
.SetNeedsCommit();
726 state
.SetNeedsRedraw(true);
727 state
.SetVisible(true);
728 state
.SetCanDraw(false);
729 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
730 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
731 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
732 EXPECT_ACTION_UPDATE_STATE(
733 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
734 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
735 state
.NotifyBeginMainFrameStarted();
736 state
.NotifyReadyToCommit();
737 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
738 state
.OnBeginImplFrameDeadline();
739 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
740 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
741 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
744 TEST(SchedulerStateMachineTest
, TestSetNeedsCommitIsNotLost
) {
745 SchedulerSettings scheduler_settings
;
746 StateMachine
state(scheduler_settings
);
748 state
.UpdateState(state
.NextAction());
749 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
750 state
.SetNeedsCommit();
751 state
.SetVisible(true);
752 state
.SetCanDraw(true);
754 EXPECT_TRUE(state
.BeginFrameNeeded());
757 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
758 EXPECT_ACTION_UPDATE_STATE(
759 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
761 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
763 // Now, while the frame is in progress, set another commit.
764 state
.SetNeedsCommit();
765 EXPECT_TRUE(state
.NeedsCommit());
767 // Let the frame finish.
768 state
.NotifyBeginMainFrameStarted();
769 state
.NotifyReadyToCommit();
770 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
);
772 // Expect to commit regardless of BeginImplFrame state.
773 EXPECT_IMPL_FRAME_STATE(
774 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
775 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
777 state
.OnBeginImplFrameDeadlinePending();
778 EXPECT_IMPL_FRAME_STATE(
779 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
);
780 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
782 state
.OnBeginImplFrameDeadline();
783 EXPECT_IMPL_FRAME_STATE(
784 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
785 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
787 state
.OnBeginImplFrameIdle();
788 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
789 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
791 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
792 EXPECT_IMPL_FRAME_STATE(
793 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
794 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
796 // Finish the commit, then make sure we start the next commit immediately
797 // and draw on the next BeginImplFrame.
798 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
799 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
800 EXPECT_ACTION_UPDATE_STATE(
801 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
802 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
804 state
.OnBeginImplFrameDeadline();
806 EXPECT_TRUE(state
.active_tree_needs_first_draw());
807 EXPECT_ACTION_UPDATE_STATE(
808 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
809 state
.DidSwapBuffers();
810 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
811 state
.DidSwapBuffersComplete();
812 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
815 TEST(SchedulerStateMachineTest
, TestFullCycle
) {
816 SchedulerSettings default_scheduler_settings
;
817 StateMachine
state(default_scheduler_settings
);
819 state
.UpdateState(state
.NextAction());
820 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
821 state
.SetVisible(true);
822 state
.SetCanDraw(true);
824 // Start clean and set commit.
825 state
.SetNeedsCommit();
828 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
829 EXPECT_ACTION_UPDATE_STATE(
830 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
832 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
833 EXPECT_FALSE(state
.NeedsCommit());
834 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
836 // Tell the scheduler the frame finished.
837 state
.NotifyBeginMainFrameStarted();
838 state
.NotifyReadyToCommit();
839 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
);
842 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
843 EXPECT_TRUE(state
.active_tree_needs_first_draw());
844 EXPECT_TRUE(state
.needs_redraw());
846 // Expect to do nothing until BeginImplFrame deadline
847 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
849 // At BeginImplFrame deadline, draw.
850 state
.OnBeginImplFrameDeadline();
851 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
852 EXPECT_ACTION_UPDATE_STATE(
853 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
854 state
.DidSwapBuffers();
855 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
856 state
.DidSwapBuffersComplete();
858 // Should be synchronized, no draw needed, no action needed.
859 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
860 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
861 EXPECT_FALSE(state
.needs_redraw());
864 TEST(SchedulerStateMachineTest
, TestFullCycleWithMainThreadLowLatencyMode
) {
865 SchedulerSettings scheduler_settings
;
866 scheduler_settings
.main_thread_should_always_be_low_latency
= true;
867 StateMachine
state(scheduler_settings
);
869 state
.UpdateState(state
.NextAction());
870 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
871 state
.SetVisible(true);
872 state
.SetCanDraw(true);
874 // Start clean and set commit.
875 state
.SetNeedsCommit();
878 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
879 EXPECT_ACTION_UPDATE_STATE(
880 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
882 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
883 EXPECT_FALSE(state
.NeedsCommit());
884 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
886 // Tell the scheduler the frame finished.
887 state
.NotifyBeginMainFrameStarted();
888 state
.NotifyReadyToCommit();
889 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
);
892 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
893 EXPECT_TRUE(state
.active_tree_needs_first_draw());
894 EXPECT_TRUE(state
.needs_redraw());
896 // Now commit should wait for draw.
897 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW
);
899 // Swap throttled. Do not draw.
900 state
.DidSwapBuffers();
901 state
.OnBeginImplFrameDeadline();
902 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
903 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
904 state
.DidSwapBuffersComplete();
906 // Haven't draw since last commit, do not begin new main frame.
907 state
.SetNeedsCommit();
908 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
909 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
910 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
912 // At BeginImplFrame deadline, draw.
913 state
.OnBeginImplFrameDeadline();
914 EXPECT_ACTION_UPDATE_STATE(
915 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
916 state
.DidSwapBuffers();
917 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
918 state
.DidSwapBuffersComplete();
920 // Now will be able to start main frame.
921 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
922 EXPECT_FALSE(state
.needs_redraw());
923 EXPECT_ACTION_UPDATE_STATE(
924 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
927 TEST(SchedulerStateMachineTest
,
928 TestFullCycleWithMainThreadLowLatencyMode_ImplSidePaint
) {
929 SchedulerSettings scheduler_settings
;
930 scheduler_settings
.main_thread_should_always_be_low_latency
= true;
931 scheduler_settings
.impl_side_painting
= true;
932 StateMachine
state(scheduler_settings
);
934 state
.UpdateState(state
.NextAction());
935 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
936 state
.SetVisible(true);
937 state
.SetCanDraw(true);
939 // Start clean and set commit.
940 state
.SetNeedsCommit();
943 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
944 EXPECT_ACTION_UPDATE_STATE(
945 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
947 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
948 EXPECT_FALSE(state
.NeedsCommit());
949 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
951 // Tell the scheduler the frame finished.
952 state
.NotifyBeginMainFrameStarted();
953 state
.NotifyReadyToCommit();
954 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
);
957 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
959 // Now commit should wait for activation.
961 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION
);
963 // No activation yet, so this commit is not drawn yet. Force to draw this
964 // frame, and still block BeginMainFrame.
965 state
.SetNeedsRedraw(true);
966 state
.SetNeedsCommit();
967 state
.OnBeginImplFrameDeadline();
968 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
969 EXPECT_ACTION_UPDATE_STATE(
970 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
971 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
973 // Cannot BeginMainFrame yet since last commit is not yet activated and drawn.
974 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
976 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION
);
977 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
979 // Now activate sync tree.
980 state
.NotifyReadyToActivate();
981 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
982 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
983 EXPECT_TRUE(state
.active_tree_needs_first_draw());
984 EXPECT_TRUE(state
.needs_redraw());
985 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW
);
987 // Swap throttled. Do not draw.
988 state
.DidSwapBuffers();
989 state
.OnBeginImplFrameDeadline();
990 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
991 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
992 state
.DidSwapBuffersComplete();
994 // Haven't draw since last commit, do not begin new main frame.
995 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
996 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
997 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
999 // At BeginImplFrame deadline, draw. This draws unblocks BeginMainFrame.
1000 state
.OnBeginImplFrameDeadline();
1001 EXPECT_ACTION_UPDATE_STATE(
1002 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1003 state
.DidSwapBuffers();
1004 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
1005 state
.DidSwapBuffersComplete();
1007 // Now will be able to start main frame.
1008 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1009 EXPECT_FALSE(state
.needs_redraw());
1010 EXPECT_ACTION_UPDATE_STATE(
1011 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1014 TEST(SchedulerStateMachineTest
, TestFullCycleWithCommitRequestInbetween
) {
1015 SchedulerSettings default_scheduler_settings
;
1016 StateMachine
state(default_scheduler_settings
);
1017 state
.SetCanStart();
1018 state
.UpdateState(state
.NextAction());
1019 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1020 state
.SetVisible(true);
1021 state
.SetCanDraw(true);
1023 // Start clean and set commit.
1024 state
.SetNeedsCommit();
1027 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1028 EXPECT_ACTION_UPDATE_STATE(
1029 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1030 EXPECT_COMMIT_STATE(
1031 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1032 EXPECT_FALSE(state
.NeedsCommit());
1033 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1035 // Request another commit while the commit is in flight.
1036 state
.SetNeedsCommit();
1037 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1039 // Tell the scheduler the frame finished.
1040 state
.NotifyBeginMainFrameStarted();
1041 state
.NotifyReadyToCommit();
1042 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
);
1045 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1046 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1047 EXPECT_TRUE(state
.needs_redraw());
1049 // Expect to do nothing until BeginImplFrame deadline.
1050 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1052 // At BeginImplFrame deadline, draw.
1053 state
.OnBeginImplFrameDeadline();
1054 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1055 EXPECT_ACTION_UPDATE_STATE(
1056 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1057 state
.DidSwapBuffers();
1058 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
1059 state
.DidSwapBuffersComplete();
1061 // Should be synchronized, no draw needed, no action needed.
1062 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1063 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1064 EXPECT_FALSE(state
.needs_redraw());
1066 // Next BeginImplFrame should initiate second commit.
1067 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1068 EXPECT_ACTION_UPDATE_STATE(
1069 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1072 TEST(SchedulerStateMachineTest
, TestRequestCommitInvisible
) {
1073 SchedulerSettings default_scheduler_settings
;
1074 StateMachine
state(default_scheduler_settings
);
1075 state
.SetCanStart();
1076 state
.UpdateState(state
.NextAction());
1077 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1078 state
.SetNeedsCommit();
1079 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1082 // See ThreadProxy::BeginMainFrame "EarlyOut_NotVisible" /
1083 // "EarlyOut_OutputSurfaceLost" cases.
1084 TEST(SchedulerStateMachineTest
, TestAbortBeginMainFrameBecauseInvisible
) {
1085 SchedulerSettings default_scheduler_settings
;
1086 StateMachine
state(default_scheduler_settings
);
1087 state
.SetCanStart();
1088 state
.UpdateState(state
.NextAction());
1089 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1090 state
.SetVisible(true);
1091 state
.SetCanDraw(true);
1093 // Start clean and set commit.
1094 state
.SetNeedsCommit();
1096 // Begin the frame while visible.
1097 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1098 EXPECT_ACTION_UPDATE_STATE(
1099 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1100 EXPECT_COMMIT_STATE(
1101 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1102 EXPECT_FALSE(state
.NeedsCommit());
1103 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1105 // Become invisible and abort BeginMainFrame.
1106 state
.SetVisible(false);
1107 state
.BeginMainFrameAborted(CommitEarlyOutReason::ABORTED_NOT_VISIBLE
);
1109 // NeedsCommit should now be true again because we never actually did a
1111 EXPECT_TRUE(state
.NeedsCommit());
1113 // We should now be back in the idle state as if we never started the frame.
1114 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1115 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1117 // We shouldn't do anything on the BeginImplFrame deadline.
1118 state
.OnBeginImplFrameDeadline();
1119 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1121 // Become visible again.
1122 state
.SetVisible(true);
1124 // Although we have aborted on this frame and haven't cancelled the commit
1125 // (i.e. need another), don't send another BeginMainFrame yet.
1126 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1127 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1128 EXPECT_TRUE(state
.NeedsCommit());
1130 // Start a new frame.
1131 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1132 EXPECT_ACTION_UPDATE_STATE(
1133 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1135 // We should be starting the commit now.
1136 EXPECT_COMMIT_STATE(
1137 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1138 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1141 // See ThreadProxy::BeginMainFrame "EarlyOut_NoUpdates" case.
1142 TEST(SchedulerStateMachineTest
, TestAbortBeginMainFrameBecauseCommitNotNeeded
) {
1143 SchedulerSettings default_scheduler_settings
;
1144 StateMachine
state(default_scheduler_settings
);
1145 state
.SetCanStart();
1146 state
.UpdateState(state
.NextAction());
1147 state
.DidCreateAndInitializeOutputSurface();
1148 state
.SetVisible(true);
1149 state
.SetCanDraw(true);
1151 // Get into a begin frame / commit state.
1152 state
.SetNeedsCommit();
1153 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1154 EXPECT_ACTION_UPDATE_STATE(
1155 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1156 EXPECT_COMMIT_STATE(
1157 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1158 EXPECT_FALSE(state
.NeedsCommit());
1159 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1161 // Abort the commit, true means that the BeginMainFrame was sent but there
1162 // was no work to do on the main thread.
1163 state
.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES
);
1165 // NeedsCommit should now be false because the commit was actually handled.
1166 EXPECT_FALSE(state
.NeedsCommit());
1168 // Even though the commit was aborted, we still expect to draw the new frame.
1169 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1170 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1171 state
.OnBeginImplFrameDeadline();
1172 EXPECT_ACTION_UPDATE_STATE(
1173 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1174 state
.DidSwapBuffers();
1175 state
.DidSwapBuffersComplete();
1176 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1178 // Verify another commit doesn't start on another frame either.
1179 EXPECT_FALSE(state
.NeedsCommit());
1180 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1182 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1183 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1184 state
.OnBeginImplFrameDeadline();
1185 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1187 // Verify another commit can start if requested, though.
1188 state
.SetNeedsCommit();
1189 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE
);
1190 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1191 EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1194 TEST(SchedulerStateMachineTest
, TestFirstContextCreation
) {
1195 SchedulerSettings default_scheduler_settings
;
1196 StateMachine
state(default_scheduler_settings
);
1197 state
.SetCanStart();
1198 state
.SetVisible(true);
1199 state
.SetCanDraw(true);
1201 EXPECT_ACTION_UPDATE_STATE(
1202 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1203 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1204 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1206 // Check that the first init does not SetNeedsCommit.
1207 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1208 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1209 state
.OnBeginImplFrameDeadline();
1210 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1212 // Check that a needs commit initiates a BeginMainFrame.
1213 state
.SetNeedsCommit();
1214 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1215 EXPECT_ACTION_UPDATE_STATE(
1216 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1219 TEST(SchedulerStateMachineTest
, TestContextLostWhenCompletelyIdle
) {
1220 SchedulerSettings default_scheduler_settings
;
1221 StateMachine
state(default_scheduler_settings
);
1222 state
.SetCanStart();
1223 state
.UpdateState(state
.NextAction());
1224 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1226 state
.SetVisible(true);
1227 state
.SetCanDraw(true);
1229 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1230 state
.NextAction());
1231 state
.DidLoseOutputSurface();
1233 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1234 state
.UpdateState(state
.NextAction());
1236 // Once context recreation begins, nothing should happen.
1237 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1239 // Recreate the context.
1240 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1242 // When the context is recreated, we should begin a commit.
1243 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1244 EXPECT_ACTION_UPDATE_STATE(
1245 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1248 TEST(SchedulerStateMachineTest
,
1249 TestContextLostWhenIdleAndCommitRequestedWhileRecreating
) {
1250 SchedulerSettings default_scheduler_settings
;
1251 // We use impl side painting because it's the more complicated version.
1252 default_scheduler_settings
.impl_side_painting
= true;
1253 StateMachine
state(default_scheduler_settings
);
1254 state
.SetCanStart();
1255 state
.UpdateState(state
.NextAction());
1256 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1257 state
.SetVisible(true);
1258 state
.SetCanDraw(true);
1260 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1261 state
.NextAction());
1262 state
.DidLoseOutputSurface();
1263 EXPECT_EQ(state
.output_surface_state(),
1264 SchedulerStateMachine::OUTPUT_SURFACE_LOST
);
1266 EXPECT_ACTION_UPDATE_STATE(
1267 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1268 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1270 // Once context recreation begins, nothing should happen.
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 // While context is recreating, commits shouldn't begin.
1277 state
.SetNeedsCommit();
1278 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1279 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1280 state
.OnBeginImplFrameDeadline();
1281 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1283 // Recreate the context
1284 state
.DidCreateAndInitializeOutputSurface();
1285 EXPECT_EQ(state
.output_surface_state(),
1286 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT
);
1287 EXPECT_FALSE(state
.RedrawPending());
1289 // When the context is recreated, we wait until the next BeginImplFrame
1291 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1293 // When the BeginFrame comes in we should begin a commit
1294 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1295 EXPECT_ACTION_UPDATE_STATE(
1296 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1297 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1298 EXPECT_COMMIT_STATE(
1299 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1301 // Until that commit finishes, we shouldn't be drawing or animate.
1302 state
.OnBeginImplFrameDeadline();
1303 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1305 // Finish the commit, which should make the surface active.
1306 state
.NotifyBeginMainFrameStarted();
1307 state
.NotifyReadyToCommit();
1308 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1309 EXPECT_EQ(state
.output_surface_state(),
1310 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION
);
1311 state
.NotifyReadyToActivate();
1312 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1313 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1314 EXPECT_EQ(state
.output_surface_state(),
1315 SchedulerStateMachine::OUTPUT_SURFACE_ACTIVE
);
1317 // Finishing the first commit after initializing an output surface should
1318 // automatically cause a redraw.
1319 EXPECT_TRUE(state
.RedrawPending());
1320 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1321 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1322 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1323 state
.OnBeginImplFrameDeadline();
1324 EXPECT_ACTION_UPDATE_STATE(
1325 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1326 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1327 EXPECT_FALSE(state
.RedrawPending());
1329 // Next frame as no work to do.
1330 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1331 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1332 state
.OnBeginImplFrameDeadline();
1333 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1335 // Once the context is recreated, whether we draw should be based on
1336 // SetCanDraw if waiting on first draw after activate.
1337 state
.SetNeedsRedraw(true);
1338 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1339 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1340 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1341 state
.OnBeginImplFrameDeadline();
1342 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1343 state
.SetCanDraw(false);
1344 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1345 state
.SetCanDraw(true);
1346 EXPECT_ACTION_UPDATE_STATE(
1347 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1348 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1350 // Once the context is recreated, whether we draw should be based on
1351 // SetCanDraw if waiting on first draw after activate.
1352 state
.SetNeedsRedraw(true);
1353 state
.SetNeedsCommit();
1354 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1355 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1356 EXPECT_ACTION_UPDATE_STATE(
1357 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1358 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1359 // Activate so we need the first draw
1360 state
.NotifyBeginMainFrameStarted();
1361 state
.NotifyReadyToCommit();
1362 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1363 state
.NotifyReadyToActivate();
1364 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1365 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1366 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1367 EXPECT_TRUE(state
.needs_redraw());
1369 state
.OnBeginImplFrameDeadline();
1370 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1371 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1372 state
.SetCanDraw(false);
1373 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1374 state
.SetCanDraw(true);
1375 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1378 TEST(SchedulerStateMachineTest
, TestContextLostWhileCommitInProgress
) {
1379 SchedulerSettings scheduler_settings
;
1380 StateMachine
state(scheduler_settings
);
1381 state
.SetCanStart();
1382 state
.UpdateState(state
.NextAction());
1383 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1384 state
.SetVisible(true);
1385 state
.SetCanDraw(true);
1387 // Get a commit in flight.
1388 state
.SetNeedsCommit();
1390 // Set damage and expect a draw.
1391 state
.SetNeedsRedraw(true);
1392 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1393 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1394 EXPECT_ACTION_UPDATE_STATE(
1395 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1396 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1397 state
.OnBeginImplFrameDeadline();
1398 EXPECT_ACTION_UPDATE_STATE(
1399 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1400 state
.DidSwapBuffers();
1401 state
.DidSwapBuffersComplete();
1402 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1404 // Cause a lost context while the BeginMainFrame is in flight.
1405 state
.DidLoseOutputSurface();
1407 // Ask for another draw. Expect nothing happens.
1408 state
.SetNeedsRedraw(true);
1409 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1411 // Finish the frame, and commit.
1412 state
.NotifyBeginMainFrameStarted();
1413 state
.NotifyReadyToCommit();
1414 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1416 // We will abort the draw when the output surface is lost if we are
1417 // waiting for the first draw to unblock the main thread.
1418 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1419 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1421 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1422 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
1423 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1425 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1426 EXPECT_IMPL_FRAME_STATE(
1427 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
1428 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1430 state
.OnBeginImplFrameDeadlinePending();
1431 EXPECT_IMPL_FRAME_STATE(
1432 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
);
1433 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1435 state
.OnBeginImplFrameDeadline();
1436 EXPECT_IMPL_FRAME_STATE(
1437 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
1438 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1441 TEST(SchedulerStateMachineTest
,
1442 TestContextLostWhileCommitInProgressAndAnotherCommitRequested
) {
1443 SchedulerSettings scheduler_settings
;
1444 StateMachine
state(scheduler_settings
);
1445 state
.SetCanStart();
1446 state
.UpdateState(state
.NextAction());
1447 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1448 state
.SetVisible(true);
1449 state
.SetCanDraw(true);
1451 // Get a commit in flight.
1452 state
.SetNeedsCommit();
1453 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1455 // Set damage and expect a draw.
1456 state
.SetNeedsRedraw(true);
1457 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1458 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1459 EXPECT_ACTION_UPDATE_STATE(
1460 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1461 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1462 state
.OnBeginImplFrameDeadline();
1463 EXPECT_ACTION_UPDATE_STATE(
1464 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1465 state
.DidSwapBuffers();
1466 state
.DidSwapBuffersComplete();
1467 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1469 // Cause a lost context while the BeginMainFrame is in flight.
1470 state
.DidLoseOutputSurface();
1472 // Ask for another draw and also set needs commit. Expect nothing happens.
1473 state
.SetNeedsRedraw(true);
1474 state
.SetNeedsCommit();
1475 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1477 // Finish the frame, and commit.
1478 state
.NotifyBeginMainFrameStarted();
1479 state
.NotifyReadyToCommit();
1480 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1481 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1483 // Because the output surface is missing, we expect the draw to abort.
1484 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1486 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1487 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
);
1488 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1490 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1491 EXPECT_IMPL_FRAME_STATE(
1492 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
);
1493 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1495 state
.OnBeginImplFrameDeadlinePending();
1496 EXPECT_IMPL_FRAME_STATE(
1497 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
);
1498 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1500 state
.OnBeginImplFrameDeadline();
1501 EXPECT_IMPL_FRAME_STATE(
1502 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
1503 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1505 state
.OnBeginImplFrameIdle();
1506 EXPECT_ACTION_UPDATE_STATE(
1507 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1509 // After we get a new output surface, the commit flow should start.
1510 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1511 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1512 EXPECT_ACTION_UPDATE_STATE(
1513 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1514 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1515 state
.NotifyBeginMainFrameStarted();
1516 state
.NotifyReadyToCommit();
1517 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1518 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1519 state
.OnBeginImplFrameDeadline();
1520 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1521 EXPECT_ACTION_UPDATE_STATE(
1522 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1523 state
.DidSwapBuffers();
1524 state
.DidSwapBuffersComplete();
1525 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1528 TEST(SchedulerStateMachineTest
, DontDrawBeforeCommitAfterLostOutputSurface
) {
1529 SchedulerSettings default_scheduler_settings
;
1530 StateMachine
state(default_scheduler_settings
);
1531 state
.SetCanStart();
1532 state
.UpdateState(state
.NextAction());
1533 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1534 state
.SetVisible(true);
1535 state
.SetCanDraw(true);
1537 state
.SetNeedsRedraw(true);
1539 // Cause a lost output surface, and restore it.
1540 state
.DidLoseOutputSurface();
1541 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1542 state
.UpdateState(state
.NextAction());
1543 state
.DidCreateAndInitializeOutputSurface();
1545 EXPECT_FALSE(state
.RedrawPending());
1546 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1547 EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1550 TEST(SchedulerStateMachineTest
,
1551 TestPendingActivationsShouldBeForcedAfterLostOutputSurface
) {
1552 SchedulerSettings settings
;
1553 settings
.impl_side_painting
= true;
1554 StateMachine
state(settings
);
1555 state
.SetCanStart();
1556 state
.UpdateState(state
.NextAction());
1557 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1558 state
.SetVisible(true);
1559 state
.SetCanDraw(true);
1561 state
.SetCommitState(
1562 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1564 // Cause a lost context.
1565 state
.DidLoseOutputSurface();
1567 state
.NotifyBeginMainFrameStarted();
1568 state
.NotifyReadyToCommit();
1569 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1571 EXPECT_TRUE(state
.PendingActivationsShouldBeForced());
1572 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1574 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1575 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1578 TEST(SchedulerStateMachineTest
, TestNoBeginMainFrameWhenInvisible
) {
1579 SchedulerSettings default_scheduler_settings
;
1580 StateMachine
state(default_scheduler_settings
);
1581 state
.SetCanStart();
1582 state
.UpdateState(state
.NextAction());
1583 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1584 state
.SetVisible(false);
1585 state
.SetNeedsCommit();
1586 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1589 TEST(SchedulerStateMachineTest
, TestFinishCommitWhenCommitInProgress
) {
1590 SchedulerSettings default_scheduler_settings
;
1591 StateMachine
state(default_scheduler_settings
);
1592 state
.SetCanStart();
1593 state
.UpdateState(state
.NextAction());
1594 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1595 state
.SetVisible(false);
1596 state
.SetCommitState(
1597 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1598 state
.SetNeedsCommit();
1600 state
.NotifyBeginMainFrameStarted();
1601 state
.NotifyReadyToCommit();
1602 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT
);
1603 state
.UpdateState(state
.NextAction());
1605 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1606 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1609 TEST(SchedulerStateMachineTest
, TestInitialActionsWhenContextLost
) {
1610 SchedulerSettings default_scheduler_settings
;
1611 StateMachine
state(default_scheduler_settings
);
1612 state
.SetCanStart();
1613 state
.UpdateState(state
.NextAction());
1614 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1615 state
.SetVisible(true);
1616 state
.SetCanDraw(true);
1617 state
.SetNeedsCommit();
1618 state
.DidLoseOutputSurface();
1620 // When we are visible, we normally want to begin output surface creation
1621 // as soon as possible.
1622 EXPECT_ACTION_UPDATE_STATE(
1623 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1625 state
.DidCreateAndInitializeOutputSurface();
1626 EXPECT_EQ(state
.output_surface_state(),
1627 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT
);
1629 // We should not send a BeginMainFrame when we are invisible, even if we've
1630 // lost the output surface and are trying to get the first commit, since the
1631 // main thread will just abort anyway.
1632 state
.SetVisible(false);
1633 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE
);
1636 TEST(SchedulerStateMachineTest
, ReportIfNotDrawing
) {
1637 SchedulerSettings default_scheduler_settings
;
1638 StateMachine
state(default_scheduler_settings
);
1639 state
.SetCanStart();
1640 state
.UpdateState(state
.NextAction());
1641 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1643 state
.SetCanDraw(true);
1644 state
.SetVisible(true);
1645 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1647 state
.SetCanDraw(false);
1648 state
.SetVisible(true);
1649 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1651 state
.SetCanDraw(true);
1652 state
.SetVisible(false);
1653 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1655 state
.SetCanDraw(false);
1656 state
.SetVisible(false);
1657 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1659 state
.SetCanDraw(true);
1660 state
.SetVisible(true);
1661 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1664 TEST(SchedulerStateMachineTest
,
1665 TestTriggerDeadlineImmediatelyAfterAbortedCommit
) {
1666 SchedulerSettings settings
;
1667 settings
.impl_side_painting
= true;
1668 StateMachine
state(settings
);
1669 state
.SetCanStart();
1670 state
.UpdateState(state
.NextAction());
1671 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1672 state
.SetVisible(true);
1673 state
.SetCanDraw(true);
1675 // This test mirrors what happens during the first frame of a scroll gesture.
1676 // First we get the input event and a BeginFrame.
1677 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1679 // As a response the compositor requests a redraw and a commit to tell the
1680 // main thread about the new scroll offset.
1681 state
.SetNeedsRedraw(true);
1682 state
.SetNeedsCommit();
1684 // We should start the commit normally.
1685 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1686 EXPECT_ACTION_UPDATE_STATE(
1687 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1688 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1690 // Since only the scroll offset changed, the main thread will abort the
1692 state
.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES
);
1694 // Since the commit was aborted, we should draw right away instead of waiting
1695 // for the deadline.
1696 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1699 void FinishPreviousCommitAndDrawWithoutExitingDeadline(
1700 StateMachine
* state_ptr
) {
1701 // Gross, but allows us to use macros below.
1702 StateMachine
& state
= *state_ptr
;
1704 state
.NotifyBeginMainFrameStarted();
1705 state
.NotifyReadyToCommit();
1706 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1707 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1708 state
.NotifyReadyToActivate();
1709 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1710 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1712 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1713 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1714 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1716 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1717 state
.OnBeginImplFrameDeadline();
1718 EXPECT_ACTION_UPDATE_STATE(
1719 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1720 state
.DidSwapBuffers();
1723 TEST(SchedulerStateMachineTest
, TestImplLatencyTakesPriority
) {
1724 SchedulerSettings settings
;
1725 settings
.impl_side_painting
= true;
1726 StateMachine
state(settings
);
1727 state
.SetCanStart();
1728 state
.UpdateState(state
.NextAction());
1729 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1730 state
.SetVisible(true);
1731 state
.SetCanDraw(true);
1733 // This test ensures that impl-draws are prioritized over main thread updates
1734 // in prefer impl latency mode.
1735 state
.SetNeedsRedraw(true);
1736 state
.SetNeedsCommit();
1737 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1738 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1739 EXPECT_ACTION_UPDATE_STATE(
1740 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1741 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1743 // Verify the deadline is not triggered early until we enter
1744 // prefer impl latency mode.
1745 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1746 state
.SetImplLatencyTakesPriority(true);
1747 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1749 // Trigger the deadline.
1750 state
.OnBeginImplFrameDeadline();
1751 EXPECT_ACTION_UPDATE_STATE(
1752 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1753 state
.DidSwapBuffers();
1754 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1755 state
.DidSwapBuffersComplete();
1757 // Request a new commit and finish the previous one.
1758 state
.SetNeedsCommit();
1759 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state
);
1760 EXPECT_ACTION_UPDATE_STATE(
1761 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1762 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1763 state
.DidSwapBuffersComplete();
1764 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1766 // Finish the previous commit and draw it.
1767 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state
);
1768 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1770 // Verify we do not send another BeginMainFrame if was are swap throttled
1771 // and did not just swap.
1772 state
.SetNeedsCommit();
1773 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1774 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1775 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1776 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1777 state
.OnBeginImplFrameDeadline();
1778 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1781 TEST(SchedulerStateMachineTest
,
1782 TestTriggerDeadlineImmediatelyOnLostOutputSurface
) {
1783 SchedulerSettings default_scheduler_settings
;
1784 StateMachine
state(default_scheduler_settings
);
1785 state
.SetCanStart();
1786 state
.UpdateState(state
.NextAction());
1787 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1788 state
.SetVisible(true);
1789 state
.SetCanDraw(true);
1791 state
.SetNeedsCommit();
1793 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1794 EXPECT_ACTION_UPDATE_STATE(
1795 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1796 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1797 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1799 state
.DidLoseOutputSurface();
1800 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1801 // The deadline should be triggered immediately when output surface is lost.
1802 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineImmediately());
1805 TEST(SchedulerStateMachineTest
, TestSetNeedsAnimate
) {
1806 SchedulerSettings settings
;
1807 settings
.impl_side_painting
= true;
1808 StateMachine
state(settings
);
1809 state
.SetCanStart();
1810 state
.UpdateState(state
.NextAction());
1811 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1812 state
.SetVisible(true);
1813 state
.SetCanDraw(true);
1815 // Test requesting an animation that, when run, causes us to draw.
1816 state
.SetNeedsAnimate();
1817 EXPECT_TRUE(state
.BeginFrameNeeded());
1818 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1820 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1821 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1823 state
.OnBeginImplFrameDeadlinePending();
1824 state
.OnBeginImplFrameDeadline();
1825 EXPECT_ACTION_UPDATE_STATE(
1826 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1829 TEST(SchedulerStateMachineTest
, TestAnimateBeforeCommit
) {
1830 SchedulerSettings settings
;
1831 settings
.impl_side_painting
= true;
1832 StateMachine
state(settings
);
1833 state
.SetCanStart();
1834 state
.UpdateState(state
.NextAction());
1835 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1836 state
.SetVisible(true);
1837 state
.SetCanDraw(true);
1839 // Check that animations are updated before we start a commit.
1840 state
.SetNeedsAnimate();
1841 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1842 state
.SetNeedsCommit();
1843 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1844 EXPECT_TRUE(state
.BeginFrameNeeded());
1846 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1847 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1848 EXPECT_ACTION_UPDATE_STATE(
1849 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1851 state
.OnBeginImplFrameDeadlinePending();
1852 state
.OnBeginImplFrameDeadline();
1853 EXPECT_ACTION_UPDATE_STATE(
1854 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1857 TEST(SchedulerStateMachineTest
, TestAnimateAfterCommitBeforeDraw
) {
1858 SchedulerSettings settings
;
1859 settings
.impl_side_painting
= true;
1860 StateMachine
state(settings
);
1861 state
.SetCanStart();
1862 state
.UpdateState(state
.NextAction());
1863 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1864 state
.SetVisible(true);
1865 state
.SetCanDraw(true);
1867 // Check that animations are updated before we start a commit.
1868 state
.SetNeedsAnimate();
1869 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1870 state
.SetNeedsCommit();
1871 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1872 EXPECT_TRUE(state
.BeginFrameNeeded());
1874 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1875 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1876 EXPECT_ACTION_UPDATE_STATE(
1877 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1879 state
.NotifyBeginMainFrameStarted();
1880 state
.NotifyReadyToCommit();
1881 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1883 state
.OnBeginImplFrameDeadlinePending();
1884 state
.OnBeginImplFrameDeadline();
1885 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1886 EXPECT_ACTION_UPDATE_STATE(
1887 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1890 TEST(SchedulerStateMachineTest
, TestSetNeedsAnimateAfterAnimate
) {
1891 SchedulerSettings settings
;
1892 settings
.impl_side_painting
= true;
1893 StateMachine
state(settings
);
1894 state
.SetCanStart();
1895 state
.UpdateState(state
.NextAction());
1896 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1897 state
.SetVisible(true);
1898 state
.SetCanDraw(true);
1900 // Test requesting an animation after we have already animated during this
1902 state
.SetNeedsRedraw(true);
1903 EXPECT_TRUE(state
.BeginFrameNeeded());
1904 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1906 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
));
1907 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1909 state
.SetNeedsAnimate();
1910 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1912 state
.OnBeginImplFrameDeadline();
1913 EXPECT_ACTION_UPDATE_STATE(
1914 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1917 TEST(SchedulerStateMachineTest
, TestForwardBeginFramesToChildren
) {
1918 SchedulerSettings settings
;
1919 settings
.forward_begin_frames_to_children
= true;
1920 StateMachine
state(settings
);
1921 state
.SetCanStart();
1922 state
.UpdateState(state
.NextAction());
1923 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1924 state
.SetVisible(true);
1925 state
.SetCanDraw(true);
1927 EXPECT_FALSE(state
.BeginFrameNeeded());
1928 state
.SetChildrenNeedBeginFrames(true);
1929 EXPECT_TRUE(state
.BeginFrameNeeded());