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