Delete chrome.mediaGalleriesPrivate because the functionality unique to it has since...
[chromium-blink-merge.git] / cc / scheduler / scheduler_state_machine_unittest.cc
blob1f377b5a1ca182404c3ca15aa90f604b024b96aa
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.
13 // Without:
14 // Value of: actual() Actual: 7
15 // Expected: expected() Which is: 0
16 // With:
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); \
41 } \
42 state.UpdateState(action); \
43 if (action == SchedulerStateMachine::ACTION_NONE) { \
44 if (state.begin_impl_frame_state() == \
45 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) \
46 state.OnBeginImplFrameDeadlinePending(); \
47 if (state.begin_impl_frame_state() == \
48 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) \
49 state.OnBeginImplFrameIdle(); \
52 namespace cc {
54 namespace {
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 {
72 public:
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);
136 state.SetCanStart();
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);
177 state.SetCanStart();
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);
195 state.SetCanStart();
196 state.UpdateState(state.NextAction());
197 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
198 state.SetVisible(true);
199 state.UpdateState(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
200 EXPECT_COMMIT_STATE(
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);
213 state.SetCanStart();
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);
273 state.SetCanStart();
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);
309 state.SetCanStart();
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);
343 state.SetCanStart();
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);
385 state.SetCanStart();
386 state.UpdateState(state.NextAction());
387 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
388 state.SetVisible(true);
389 state.SetCanDraw(true);
391 // Start a commit.
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);
407 // Fail the draw.
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;
438 int draw_limit = 1;
439 scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ =
440 draw_limit;
441 scheduler_settings.impl_side_painting = true;
442 StateMachine state(scheduler_settings);
443 state.SetCanStart();
444 state.UpdateState(state.NextAction());
445 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
446 state.SetVisible(true);
447 state.SetCanDraw(true);
449 // Start a commit.
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);
500 state.SetCanStart();
501 state.UpdateState(state.NextAction());
502 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
503 state.SetVisible(true);
504 state.SetCanDraw(true);
506 // Start a draw.
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
531 // the impl thread.
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);
543 state.SetCanStart();
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);
601 state.SetCanStart();
602 state.UpdateState(state.NextAction());
603 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
604 state.SetCommitState(all_commit_states[i]);
605 state.SetBeginImplFrameState(all_begin_impl_frame_states[j]);
606 bool visible =
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,
613 state.NextAction());
615 // Case 2: needs_commit=true
616 state.SetNeedsCommit();
617 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
618 state.NextAction())
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);
627 state.SetCanStart();
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;
642 } else {
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);
666 state.SetCanStart();
667 state.UpdateState(state.NextAction());
668 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
669 state.SetCommitState(all_commit_states[i]);
670 state.SetVisible(false);
671 state.SetNeedsRedraw(true);
672 if (j == 1) {
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,
679 state.NextAction());
681 // Case 2: needs_commit=true.
682 state.SetNeedsCommit();
683 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
684 state.NextAction())
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);
699 state.SetCanStart();
700 state.UpdateState(state.NextAction());
701 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
702 state.SetCommitState(all_commit_states[i]);
703 state.SetVisible(false);
704 state.SetNeedsRedraw(true);
705 if (j == 1)
706 state.OnBeginImplFrame(
707 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
709 state.SetCanDraw(false);
710 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
711 state.NextAction());
716 TEST(SchedulerStateMachineTest,
717 TestCanRedrawWithWaitingForFirstDrawMakesProgress) {
718 SchedulerSettings default_scheduler_settings;
719 StateMachine state(default_scheduler_settings);
720 state.SetCanStart();
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);
747 state.SetCanStart();
748 state.UpdateState(state.NextAction());
749 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
750 state.SetNeedsCommit();
751 state.SetVisible(true);
752 state.SetCanDraw(true);
754 EXPECT_TRUE(state.BeginFrameNeeded());
756 // Begin the frame.
757 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
758 EXPECT_ACTION_UPDATE_STATE(
759 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
760 EXPECT_COMMIT_STATE(
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);
818 state.SetCanStart();
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();
827 // Begin the frame.
828 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
829 EXPECT_ACTION_UPDATE_STATE(
830 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
831 EXPECT_COMMIT_STATE(
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);
841 // 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);
868 state.SetCanStart();
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();
877 // Begin the frame.
878 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
879 EXPECT_ACTION_UPDATE_STATE(
880 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
881 EXPECT_COMMIT_STATE(
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);
891 // 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);
933 state.SetCanStart();
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();
942 // Begin the frame.
943 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
944 EXPECT_ACTION_UPDATE_STATE(
945 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
946 EXPECT_COMMIT_STATE(
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);
956 // Commit.
957 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
959 // Now commit should wait for activation.
960 EXPECT_COMMIT_STATE(
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));
975 EXPECT_COMMIT_STATE(
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();
1026 // Begin the frame.
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);
1044 // First 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
1110 // commit.
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
1290 // before starting.
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
1691 // commit.
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
1901 // frame.
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());
1932 } // namespace
1933 } // namespace cc