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 "cc/scheduler/scheduler.h" 8 #include "testing/gtest/include/gtest/gtest.h" 9 10 namespace cc { 11 12 namespace { 13 14 const SchedulerStateMachine::CommitState all_commit_states[] = { 15 SchedulerStateMachine::COMMIT_STATE_IDLE, 16 SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, 17 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, 18 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW 19 }; 20 21 // Exposes the protected state fields of the SchedulerStateMachine for testing 22 class StateMachine : public SchedulerStateMachine { 23 public: 24 explicit StateMachine(const SchedulerSettings& scheduler_settings) 25 : SchedulerStateMachine(scheduler_settings) {} 26 void SetCommitState(CommitState cs) { commit_state_ = cs; } 27 CommitState CommitState() const { return commit_state_; } 28 29 bool NeedsCommit() const { return needs_commit_; } 30 31 void SetNeedsRedraw(bool b) { needs_redraw_ = b; } 32 bool NeedsRedraw() const { return needs_redraw_; } 33 34 void SetNeedsForcedRedraw(bool b) { needs_forced_redraw_ = b; } 35 bool NeedsForcedRedraw() const { return needs_forced_redraw_; } 36 37 bool CanDraw() const { return can_draw_; } 38 bool Visible() const { return visible_; } 39 }; 40 41 TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) { 42 SchedulerSettings default_scheduler_settings; 43 44 // If no commit needed, do nothing. 45 { 46 StateMachine state(default_scheduler_settings); 47 state.SetCanStart(); 48 state.UpdateState(state.NextAction()); 49 state.DidCreateAndInitializeOutputSurface(); 50 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE); 51 state.SetNeedsRedraw(false); 52 state.SetVisible(true); 53 54 EXPECT_FALSE(state.BeginFrameNeededToDrawByImplThread()); 55 56 state.DidLeaveBeginFrame(); 57 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 58 EXPECT_FALSE(state.BeginFrameNeededToDrawByImplThread()); 59 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 60 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 61 } 62 63 // If commit requested but can_start is still false, do nothing. 64 { 65 StateMachine state(default_scheduler_settings); 66 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE); 67 state.SetNeedsRedraw(false); 68 state.SetVisible(true); 69 70 EXPECT_FALSE(state.BeginFrameNeededToDrawByImplThread()); 71 72 state.DidLeaveBeginFrame(); 73 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 74 EXPECT_FALSE(state.BeginFrameNeededToDrawByImplThread()); 75 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 76 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 77 } 78 79 // If commit requested, begin a main frame. 80 { 81 StateMachine state(default_scheduler_settings); 82 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE); 83 state.SetCanStart(); 84 state.SetNeedsRedraw(false); 85 state.SetVisible(true); 86 EXPECT_FALSE(state.BeginFrameNeededToDrawByImplThread()); 87 } 88 89 // Begin the frame, make sure needs_commit and commit_state update correctly. 90 { 91 StateMachine state(default_scheduler_settings); 92 state.SetCanStart(); 93 state.UpdateState(state.NextAction()); 94 state.DidCreateAndInitializeOutputSurface(); 95 state.SetVisible(true); 96 state.UpdateState( 97 SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD); 98 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, 99 state.CommitState()); 100 EXPECT_FALSE(state.NeedsCommit()); 101 EXPECT_FALSE(state.BeginFrameNeededToDrawByImplThread()); 102 } 103 } 104 105 TEST(SchedulerStateMachineTest, TestSetForcedRedrawDoesNotSetsNormalRedraw) { 106 SchedulerSettings default_scheduler_settings; 107 SchedulerStateMachine state(default_scheduler_settings); 108 state.SetCanDraw(true); 109 state.SetNeedsForcedRedraw(); 110 EXPECT_FALSE(state.RedrawPending()); 111 EXPECT_TRUE(state.BeginFrameNeededToDrawByImplThread()); 112 } 113 114 TEST(SchedulerStateMachineTest, 115 TestFailedDrawSetsNeedsCommitAndDoesNotDrawAgain) { 116 SchedulerSettings default_scheduler_settings; 117 SchedulerStateMachine state(default_scheduler_settings); 118 state.SetCanStart(); 119 state.UpdateState(state.NextAction()); 120 state.DidCreateAndInitializeOutputSurface(); 121 state.SetVisible(true); 122 state.SetCanDraw(true); 123 state.SetNeedsRedraw(); 124 EXPECT_TRUE(state.RedrawPending()); 125 EXPECT_TRUE(state.BeginFrameNeededToDrawByImplThread()); 126 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 127 128 // We're drawing now. 129 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); 130 state.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); 131 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 132 EXPECT_FALSE(state.RedrawPending()); 133 EXPECT_FALSE(state.CommitPending()); 134 135 // Failing the draw makes us require a commit. 136 state.DidDrawIfPossibleCompleted(false); 137 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 138 state.NextAction()); 139 state.UpdateState( 140 SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD); 141 EXPECT_TRUE(state.RedrawPending()); 142 EXPECT_TRUE(state.CommitPending()); 143 } 144 145 TEST(SchedulerStateMachineTest, 146 TestsetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw) { 147 SchedulerSettings default_scheduler_settings; 148 SchedulerStateMachine state(default_scheduler_settings); 149 state.SetCanStart(); 150 state.UpdateState(state.NextAction()); 151 state.DidCreateAndInitializeOutputSurface(); 152 153 state.SetVisible(true); 154 state.SetCanDraw(true); 155 state.SetNeedsRedraw(); 156 EXPECT_TRUE(state.RedrawPending()); 157 EXPECT_TRUE(state.BeginFrameNeededToDrawByImplThread()); 158 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 159 160 // We're drawing now. 161 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); 162 state.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); 163 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 164 EXPECT_FALSE(state.RedrawPending()); 165 EXPECT_FALSE(state.CommitPending()); 166 167 // While still in the same begin frame callback on the main thread, 168 // set needs redraw again. This should not redraw. 169 state.SetNeedsRedraw(); 170 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 171 172 // Failing the draw makes us require a commit. 173 state.DidDrawIfPossibleCompleted(false); 174 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 175 state.NextAction()); 176 EXPECT_TRUE(state.RedrawPending()); 177 } 178 179 TEST(SchedulerStateMachineTest, 180 TestCommitAfterFailedDrawAllowsDrawInSameFrame) { 181 SchedulerSettings default_scheduler_settings; 182 SchedulerStateMachine state(default_scheduler_settings); 183 state.SetCanStart(); 184 state.UpdateState(state.NextAction()); 185 state.DidCreateAndInitializeOutputSurface(); 186 state.SetVisible(true); 187 state.SetCanDraw(true); 188 189 // Start a commit. 190 state.SetNeedsCommit(); 191 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 192 state.NextAction()); 193 state.UpdateState( 194 SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD); 195 EXPECT_TRUE(state.CommitPending()); 196 197 // Then initiate a draw. 198 state.SetNeedsRedraw(); 199 EXPECT_TRUE(state.BeginFrameNeededToDrawByImplThread()); 200 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 201 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); 202 EXPECT_TRUE(state.RedrawPending()); 203 204 // Fail the draw. 205 state.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); 206 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 207 state.DidDrawIfPossibleCompleted(false); 208 EXPECT_TRUE(state.RedrawPending()); 209 // But the commit is ongoing. 210 EXPECT_TRUE(state.CommitPending()); 211 212 // Finish the commit. 213 state.FinishCommit(); 214 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction()); 215 state.UpdateState(SchedulerStateMachine::ACTION_COMMIT); 216 EXPECT_TRUE(state.RedrawPending()); 217 218 // And we should be allowed to draw again. 219 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); 220 } 221 222 TEST(SchedulerStateMachineTest, 223 TestCommitAfterFailedAndSuccessfulDrawDoesNotAllowDrawInSameFrame) { 224 SchedulerSettings default_scheduler_settings; 225 SchedulerStateMachine state(default_scheduler_settings); 226 state.SetCanStart(); 227 state.UpdateState(state.NextAction()); 228 state.DidCreateAndInitializeOutputSurface(); 229 state.SetVisible(true); 230 state.SetCanDraw(true); 231 232 // Start a commit. 233 state.SetNeedsCommit(); 234 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 235 state.NextAction()); 236 state.UpdateState( 237 SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD); 238 EXPECT_TRUE(state.CommitPending()); 239 240 // Then initiate a draw. 241 state.SetNeedsRedraw(); 242 EXPECT_TRUE(state.BeginFrameNeededToDrawByImplThread()); 243 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 244 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); 245 EXPECT_TRUE(state.RedrawPending()); 246 247 // Fail the draw. 248 state.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); 249 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 250 state.DidDrawIfPossibleCompleted(false); 251 EXPECT_TRUE(state.RedrawPending()); 252 // But the commit is ongoing. 253 EXPECT_TRUE(state.CommitPending()); 254 255 // Force a draw. 256 state.SetNeedsForcedRedraw(); 257 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.NextAction()); 258 259 // Do the forced draw. 260 state.UpdateState(SchedulerStateMachine::ACTION_DRAW_FORCED); 261 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 262 EXPECT_FALSE(state.RedrawPending()); 263 // And the commit is still ongoing. 264 EXPECT_TRUE(state.CommitPending()); 265 266 // Finish the commit. 267 state.FinishCommit(); 268 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction()); 269 state.UpdateState(SchedulerStateMachine::ACTION_COMMIT); 270 EXPECT_TRUE(state.RedrawPending()); 271 272 // And we should not be allowed to draw again in the same frame.. 273 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 274 } 275 276 TEST(SchedulerStateMachineTest, 277 TestFailedDrawsWillEventuallyForceADrawAfterTheNextCommit) { 278 SchedulerSettings default_scheduler_settings; 279 SchedulerStateMachine state(default_scheduler_settings); 280 state.SetCanStart(); 281 state.UpdateState(state.NextAction()); 282 state.DidCreateAndInitializeOutputSurface(); 283 state.SetVisible(true); 284 state.SetCanDraw(true); 285 state.SetMaximumNumberOfFailedDrawsBeforeDrawIsForced(1); 286 287 // Start a commit. 288 state.SetNeedsCommit(); 289 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 290 state.NextAction()); 291 state.UpdateState( 292 SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD); 293 EXPECT_TRUE(state.CommitPending()); 294 295 // Then initiate a draw. 296 state.SetNeedsRedraw(); 297 EXPECT_TRUE(state.BeginFrameNeededToDrawByImplThread()); 298 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 299 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); 300 EXPECT_TRUE(state.RedrawPending()); 301 302 // Fail the draw. 303 state.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); 304 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 305 state.DidDrawIfPossibleCompleted(false); 306 EXPECT_TRUE(state.RedrawPending()); 307 // But the commit is ongoing. 308 EXPECT_TRUE(state.CommitPending()); 309 310 // Finish the commit. Note, we should not yet be forcing a draw, but should 311 // continue the commit as usual. 312 state.FinishCommit(); 313 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction()); 314 state.UpdateState(SchedulerStateMachine::ACTION_COMMIT); 315 EXPECT_TRUE(state.RedrawPending()); 316 317 // The redraw should be forced in this case. 318 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.NextAction()); 319 } 320 321 TEST(SchedulerStateMachineTest, 322 TestFailedDrawIsRetriedInNextBeginFrameForImplThread) { 323 SchedulerSettings default_scheduler_settings; 324 SchedulerStateMachine state(default_scheduler_settings); 325 state.SetCanStart(); 326 state.UpdateState(state.NextAction()); 327 state.DidCreateAndInitializeOutputSurface(); 328 state.SetVisible(true); 329 state.SetCanDraw(true); 330 331 // Start a draw. 332 state.SetNeedsRedraw(); 333 EXPECT_TRUE(state.BeginFrameNeededToDrawByImplThread()); 334 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 335 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); 336 EXPECT_TRUE(state.RedrawPending()); 337 338 // Fail the draw. 339 state.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); 340 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 341 state.DidDrawIfPossibleCompleted(false); 342 EXPECT_TRUE(state.RedrawPending()); 343 344 // We should not be trying to draw again now, but we have a commit pending. 345 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 346 state.NextAction()); 347 348 state.DidLeaveBeginFrame(); 349 EXPECT_TRUE(state.BeginFrameNeededToDrawByImplThread()); 350 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 351 352 // We should try to draw again in the next begin frame on the impl thread. 353 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); 354 } 355 356 TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) { 357 SchedulerSettings default_scheduler_settings; 358 SchedulerStateMachine state(default_scheduler_settings); 359 state.SetCanStart(); 360 state.UpdateState(state.NextAction()); 361 state.DidCreateAndInitializeOutputSurface(); 362 state.SetVisible(true); 363 state.SetCanDraw(true); 364 state.SetNeedsRedraw(); 365 EXPECT_TRUE(state.BeginFrameNeededToDrawByImplThread()); 366 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 367 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); 368 state.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); 369 370 // While still in the same begin frame for the impl thread, set needs redraw 371 // again. This should not redraw. 372 state.SetNeedsRedraw(); 373 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 374 375 // Move to another frame. This should now draw. 376 state.DidDrawIfPossibleCompleted(true); 377 state.DidLeaveBeginFrame(); 378 EXPECT_TRUE(state.BeginFrameNeededToDrawByImplThread()); 379 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 380 381 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); 382 state.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); 383 state.DidDrawIfPossibleCompleted(true); 384 EXPECT_FALSE(state.BeginFrameNeededToDrawByImplThread()); 385 } 386 387 TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginFrame) { 388 SchedulerSettings default_scheduler_settings; 389 390 // When not in BeginFrame, or in BeginFrame but not visible, 391 // don't draw. 392 size_t num_commit_states = 393 sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState); 394 for (size_t i = 0; i < num_commit_states; ++i) { 395 for (size_t j = 0; j < 2; ++j) { 396 StateMachine state(default_scheduler_settings); 397 state.SetCanStart(); 398 state.UpdateState(state.NextAction()); 399 state.DidCreateAndInitializeOutputSurface(); 400 state.SetCommitState(all_commit_states[i]); 401 bool visible = j; 402 if (!visible) { 403 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 404 state.SetVisible(false); 405 } else { 406 state.SetVisible(true); 407 } 408 409 // Case 1: needs_commit=false 410 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, 411 state.NextAction()); 412 413 // Case 2: needs_commit=true 414 state.SetNeedsCommit(); 415 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, 416 state.NextAction()); 417 } 418 } 419 420 // When in BeginFrame, or not in BeginFrame but needs_forced_dedraw 421 // set, should always draw except if you're ready to commit, in which case 422 // commit. 423 for (size_t i = 0; i < num_commit_states; ++i) { 424 for (size_t j = 0; j < 2; ++j) { 425 StateMachine state(default_scheduler_settings); 426 state.SetCanStart(); 427 state.UpdateState(state.NextAction()); 428 state.DidCreateAndInitializeOutputSurface(); 429 state.SetCanDraw(true); 430 state.SetCommitState(all_commit_states[i]); 431 bool forced_draw = j; 432 if (!forced_draw) { 433 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 434 state.SetNeedsRedraw(true); 435 state.SetVisible(true); 436 } else { 437 state.SetNeedsForcedRedraw(true); 438 } 439 440 SchedulerStateMachine::Action expected_action; 441 if (all_commit_states[i] != 442 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT) { 443 expected_action = 444 forced_draw ? SchedulerStateMachine::ACTION_DRAW_FORCED 445 : SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE; 446 } else { 447 expected_action = SchedulerStateMachine::ACTION_COMMIT; 448 } 449 450 // Case 1: needs_commit=false. 451 EXPECT_TRUE(state.BeginFrameNeededToDrawByImplThread()); 452 EXPECT_EQ(expected_action, state.NextAction()); 453 454 // Case 2: needs_commit=true. 455 state.SetNeedsCommit(); 456 EXPECT_TRUE(state.BeginFrameNeededToDrawByImplThread()); 457 EXPECT_EQ(expected_action, state.NextAction()); 458 } 459 } 460 } 461 462 TEST(SchedulerStateMachineTest, TestNoCommitStatesRedrawWhenInvisible) { 463 SchedulerSettings default_scheduler_settings; 464 465 size_t num_commit_states = 466 sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState); 467 for (size_t i = 0; i < num_commit_states; ++i) { 468 // There shouldn't be any drawing regardless of BeginFrame. 469 for (size_t j = 0; j < 2; ++j) { 470 StateMachine state(default_scheduler_settings); 471 state.SetCanStart(); 472 state.UpdateState(state.NextAction()); 473 state.DidCreateAndInitializeOutputSurface(); 474 state.SetCommitState(all_commit_states[i]); 475 state.SetVisible(false); 476 state.SetNeedsRedraw(true); 477 state.SetNeedsForcedRedraw(false); 478 if (j == 1) 479 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 480 481 // Case 1: needs_commit=false. 482 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, 483 state.NextAction()); 484 485 // Case 2: needs_commit=true. 486 state.SetNeedsCommit(); 487 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, 488 state.NextAction()); 489 } 490 } 491 } 492 493 TEST(SchedulerStateMachineTest, TestCanRedraw_StopsDraw) { 494 SchedulerSettings default_scheduler_settings; 495 496 size_t num_commit_states = 497 sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState); 498 for (size_t i = 0; i < num_commit_states; ++i) { 499 // There shouldn't be any drawing regardless of BeginFrame. 500 for (size_t j = 0; j < 2; ++j) { 501 StateMachine state(default_scheduler_settings); 502 state.SetCanStart(); 503 state.UpdateState(state.NextAction()); 504 state.DidCreateAndInitializeOutputSurface(); 505 state.SetCommitState(all_commit_states[i]); 506 state.SetVisible(false); 507 state.SetNeedsRedraw(true); 508 state.SetNeedsForcedRedraw(false); 509 if (j == 1) 510 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 511 512 state.SetCanDraw(false); 513 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, 514 state.NextAction()); 515 } 516 } 517 } 518 519 TEST(SchedulerStateMachineTest, 520 TestCanRedrawWithWaitingForFirstDrawMakesProgress) { 521 SchedulerSettings default_scheduler_settings; 522 StateMachine state(default_scheduler_settings); 523 state.SetCanStart(); 524 state.UpdateState(state.NextAction()); 525 state.DidCreateAndInitializeOutputSurface(); 526 state.SetCommitState( 527 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW); 528 state.SetNeedsCommit(); 529 state.SetNeedsRedraw(true); 530 state.SetVisible(true); 531 state.SetCanDraw(false); 532 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 533 state.NextAction()); 534 } 535 536 TEST(SchedulerStateMachineTest, TestsetNeedsCommitIsNotLost) { 537 SchedulerSettings default_scheduler_settings; 538 StateMachine state(default_scheduler_settings); 539 state.SetCanStart(); 540 state.UpdateState(state.NextAction()); 541 state.DidCreateAndInitializeOutputSurface(); 542 state.SetNeedsCommit(); 543 state.SetVisible(true); 544 state.SetCanDraw(true); 545 546 // Begin the frame. 547 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 548 state.NextAction()); 549 state.UpdateState(state.NextAction()); 550 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, 551 state.CommitState()); 552 553 // Now, while the frame is in progress, set another commit. 554 state.SetNeedsCommit(); 555 EXPECT_TRUE(state.NeedsCommit()); 556 557 // Let the frame finish. 558 state.FinishCommit(); 559 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, 560 state.CommitState()); 561 562 // Expect to commit regardless of BeginFrame state. 563 state.DidLeaveBeginFrame(); 564 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction()); 565 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 566 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction()); 567 568 // Commit and make sure we draw on next BeginFrame 569 state.UpdateState(SchedulerStateMachine::ACTION_COMMIT); 570 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); 571 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, 572 state.CommitState()); 573 state.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); 574 state.DidDrawIfPossibleCompleted(true); 575 576 // Verify that another commit will begin. 577 state.DidLeaveBeginFrame(); 578 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 579 state.NextAction()); 580 } 581 582 TEST(SchedulerStateMachineTest, TestFullCycle) { 583 SchedulerSettings default_scheduler_settings; 584 StateMachine state(default_scheduler_settings); 585 state.SetCanStart(); 586 state.UpdateState(state.NextAction()); 587 state.DidCreateAndInitializeOutputSurface(); 588 state.SetVisible(true); 589 state.SetCanDraw(true); 590 591 // Start clean and set commit. 592 state.SetNeedsCommit(); 593 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 594 state.NextAction()); 595 596 // Begin the frame. 597 state.UpdateState( 598 SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD); 599 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, 600 state.CommitState()); 601 EXPECT_FALSE(state.NeedsCommit()); 602 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 603 604 // Tell the scheduler the frame finished. 605 state.FinishCommit(); 606 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, 607 state.CommitState()); 608 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction()); 609 610 // Commit. 611 state.UpdateState(SchedulerStateMachine::ACTION_COMMIT); 612 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, 613 state.CommitState()); 614 EXPECT_TRUE(state.NeedsRedraw()); 615 616 // Expect to do nothing until BeginFrame. 617 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 618 619 // At BeginFrame, draw. 620 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 621 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); 622 state.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); 623 state.DidDrawIfPossibleCompleted(true); 624 state.DidLeaveBeginFrame(); 625 626 // Should be synchronized, no draw needed, no action needed. 627 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState()); 628 EXPECT_FALSE(state.NeedsRedraw()); 629 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 630 } 631 632 TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween) { 633 SchedulerSettings default_scheduler_settings; 634 StateMachine state(default_scheduler_settings); 635 state.SetCanStart(); 636 state.UpdateState(state.NextAction()); 637 state.DidCreateAndInitializeOutputSurface(); 638 state.SetVisible(true); 639 state.SetCanDraw(true); 640 641 // Start clean and set commit. 642 state.SetNeedsCommit(); 643 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 644 state.NextAction()); 645 646 // Begin the frame. 647 state.UpdateState( 648 SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD); 649 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, 650 state.CommitState()); 651 EXPECT_FALSE(state.NeedsCommit()); 652 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 653 654 // Request another commit while the commit is in flight. 655 state.SetNeedsCommit(); 656 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 657 658 // Tell the scheduler the frame finished. 659 state.FinishCommit(); 660 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, 661 state.CommitState()); 662 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction()); 663 664 // Commit. 665 state.UpdateState(SchedulerStateMachine::ACTION_COMMIT); 666 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, 667 state.CommitState()); 668 EXPECT_TRUE(state.NeedsRedraw()); 669 670 // Expect to do nothing until BeginFrame. 671 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 672 673 // At BeginFrame, draw. 674 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 675 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); 676 state.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); 677 state.DidDrawIfPossibleCompleted(true); 678 state.DidLeaveBeginFrame(); 679 680 // Should be synchronized, no draw needed, no action needed. 681 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState()); 682 EXPECT_FALSE(state.NeedsRedraw()); 683 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 684 state.NextAction()); 685 } 686 687 TEST(SchedulerStateMachineTest, TestRequestCommitInvisible) { 688 SchedulerSettings default_scheduler_settings; 689 StateMachine state(default_scheduler_settings); 690 state.SetCanStart(); 691 state.UpdateState(state.NextAction()); 692 state.DidCreateAndInitializeOutputSurface(); 693 state.SetNeedsCommit(); 694 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 695 } 696 697 TEST(SchedulerStateMachineTest, TestGoesInvisibleBeforeFinishCommit) { 698 SchedulerSettings default_scheduler_settings; 699 StateMachine state(default_scheduler_settings); 700 state.SetCanStart(); 701 state.UpdateState(state.NextAction()); 702 state.DidCreateAndInitializeOutputSurface(); 703 state.SetVisible(true); 704 state.SetCanDraw(true); 705 706 // Start clean and set commit. 707 state.SetNeedsCommit(); 708 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 709 state.NextAction()); 710 711 // Begin the frame while visible. 712 state.UpdateState( 713 SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD); 714 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, 715 state.CommitState()); 716 EXPECT_FALSE(state.NeedsCommit()); 717 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 718 719 // Become invisible and abort the main thread's begin frame. 720 state.SetVisible(false); 721 state.BeginFrameAbortedByMainThread(false); 722 723 // We should now be back in the idle state as if we didn't start a frame at 724 // all. 725 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState()); 726 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 727 728 // Become visible again. 729 state.SetVisible(true); 730 731 // Although we have aborted on this frame and haven't cancelled the commit 732 // (i.e. need another), don't send another begin frame yet. 733 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState()); 734 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 735 EXPECT_TRUE(state.NeedsCommit()); 736 737 // Start a new frame. 738 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 739 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 740 state.NextAction()); 741 742 // Begin the frame. 743 state.UpdateState(state.NextAction()); 744 745 // We should be starting the commit now. 746 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, 747 state.CommitState()); 748 } 749 750 TEST(SchedulerStateMachineTest, AbortBeginFrameAndCancelCommit) { 751 SchedulerSettings default_scheduler_settings; 752 StateMachine state(default_scheduler_settings); 753 state.SetCanStart(); 754 state.UpdateState(state.NextAction()); 755 state.DidCreateAndInitializeOutputSurface(); 756 state.SetVisible(true); 757 state.SetCanDraw(true); 758 759 // Get into a begin frame / commit state. 760 state.SetNeedsCommit(); 761 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 762 state.NextAction()); 763 state.UpdateState( 764 SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD); 765 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, 766 state.CommitState()); 767 EXPECT_FALSE(state.NeedsCommit()); 768 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 769 770 // Abort the commit, cancelling future commits. 771 state.BeginFrameAbortedByMainThread(true); 772 773 // Verify that another commit doesn't start on the same frame. 774 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState()); 775 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 776 EXPECT_FALSE(state.NeedsCommit()); 777 778 // Start a new frame; draw because this is the first frame since output 779 // surface init'd. 780 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 781 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); 782 state.DidLeaveBeginFrame(); 783 784 // Verify another commit doesn't start on another frame either. 785 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState()); 786 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 787 EXPECT_FALSE(state.NeedsCommit()); 788 789 // Verify another commit can start if requested, though. 790 state.SetNeedsCommit(); 791 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState()); 792 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 793 state.NextAction()); 794 } 795 796 TEST(SchedulerStateMachineTest, TestFirstContextCreation) { 797 SchedulerSettings default_scheduler_settings; 798 StateMachine state(default_scheduler_settings); 799 state.SetCanStart(); 800 state.SetVisible(true); 801 state.SetCanDraw(true); 802 803 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, 804 state.NextAction()); 805 state.UpdateState(state.NextAction()); 806 state.DidCreateAndInitializeOutputSurface(); 807 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 808 809 // Check that the first init does not SetNeedsCommit. 810 state.SetNeedsCommit(); 811 EXPECT_NE(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 812 } 813 814 TEST(SchedulerStateMachineTest, TestContextLostWhenCompletelyIdle) { 815 SchedulerSettings default_scheduler_settings; 816 StateMachine state(default_scheduler_settings); 817 state.SetCanStart(); 818 state.UpdateState(state.NextAction()); 819 state.DidCreateAndInitializeOutputSurface(); 820 821 state.SetVisible(true); 822 state.SetCanDraw(true); 823 824 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, 825 state.NextAction()); 826 state.DidLoseOutputSurface(); 827 828 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, 829 state.NextAction()); 830 state.UpdateState(state.NextAction()); 831 832 // Once context recreation begins, nothing should happen. 833 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 834 835 // Recreate the context. 836 state.DidCreateAndInitializeOutputSurface(); 837 838 // When the context is recreated, we should begin a commit. 839 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 840 state.NextAction()); 841 state.UpdateState(state.NextAction()); 842 } 843 844 TEST(SchedulerStateMachineTest, 845 TestContextLostWhenIdleAndCommitRequestedWhileRecreating) { 846 SchedulerSettings default_scheduler_settings; 847 StateMachine state(default_scheduler_settings); 848 state.SetCanStart(); 849 state.UpdateState(state.NextAction()); 850 state.DidCreateAndInitializeOutputSurface(); 851 state.SetVisible(true); 852 state.SetCanDraw(true); 853 854 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, 855 state.NextAction()); 856 state.DidLoseOutputSurface(); 857 858 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, 859 state.NextAction()); 860 state.UpdateState(state.NextAction()); 861 862 // Once context recreation begins, nothing should happen. 863 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 864 865 // While context is recreating, commits shouldn't begin. 866 state.SetNeedsCommit(); 867 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 868 869 // Recreate the context 870 state.DidCreateAndInitializeOutputSurface(); 871 EXPECT_FALSE(state.RedrawPending()); 872 873 // When the context is recreated, we should begin a commit 874 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 875 state.NextAction()); 876 state.UpdateState(state.NextAction()); 877 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, 878 state.CommitState()); 879 state.FinishCommit(); 880 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction()); 881 state.UpdateState(state.NextAction()); 882 // Finishing the first commit after initializing an output surface should 883 // automatically cause a redraw. 884 EXPECT_TRUE(state.RedrawPending()); 885 886 // Once the context is recreated, whether we draw should be based on 887 // SetCanDraw. 888 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 889 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); 890 state.SetCanDraw(false); 891 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 892 state.SetCanDraw(true); 893 state.DidLeaveBeginFrame(); 894 } 895 896 TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) { 897 SchedulerSettings default_scheduler_settings; 898 StateMachine state(default_scheduler_settings); 899 state.SetCanStart(); 900 state.UpdateState(state.NextAction()); 901 state.DidCreateAndInitializeOutputSurface(); 902 state.SetVisible(true); 903 state.SetCanDraw(true); 904 905 // Get a commit in flight. 906 state.SetNeedsCommit(); 907 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 908 state.NextAction()); 909 state.UpdateState(state.NextAction()); 910 911 // Set damage and expect a draw. 912 state.SetNeedsRedraw(true); 913 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 914 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); 915 state.UpdateState(state.NextAction()); 916 state.DidLeaveBeginFrame(); 917 918 // Cause a lost context while the begin frame is in flight 919 // for the main thread. 920 state.DidLoseOutputSurface(); 921 922 // Ask for another draw. Expect nothing happens. 923 state.SetNeedsRedraw(true); 924 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 925 926 // Finish the frame, and commit. 927 state.FinishCommit(); 928 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction()); 929 state.UpdateState(state.NextAction()); 930 931 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, 932 state.CommitState()); 933 934 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); 935 state.UpdateState(state.NextAction()); 936 937 // Expect to be told to begin context recreation, independent of 938 // BeginFrame state. 939 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 940 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, 941 state.NextAction()); 942 state.DidLeaveBeginFrame(); 943 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, 944 state.NextAction()); 945 } 946 947 TEST(SchedulerStateMachineTest, 948 TestContextLostWhileCommitInProgressAndAnotherCommitRequested) { 949 SchedulerSettings default_scheduler_settings; 950 StateMachine state(default_scheduler_settings); 951 state.SetCanStart(); 952 state.UpdateState(state.NextAction()); 953 state.DidCreateAndInitializeOutputSurface(); 954 state.SetVisible(true); 955 state.SetCanDraw(true); 956 957 // Get a commit in flight. 958 state.SetNeedsCommit(); 959 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 960 state.NextAction()); 961 state.UpdateState(state.NextAction()); 962 963 // Set damage and expect a draw. 964 state.SetNeedsRedraw(true); 965 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 966 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); 967 state.UpdateState(state.NextAction()); 968 state.DidLeaveBeginFrame(); 969 970 // Cause a lost context while the begin frame is in flight 971 // for the main thread. 972 state.DidLoseOutputSurface(); 973 974 // Ask for another draw and also set needs commit. Expect nothing happens. 975 state.SetNeedsRedraw(true); 976 state.SetNeedsCommit(); 977 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 978 979 // Finish the frame, and commit. 980 state.FinishCommit(); 981 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction()); 982 state.UpdateState(state.NextAction()); 983 984 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, 985 state.CommitState()); 986 987 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); 988 state.UpdateState(state.NextAction()); 989 990 // Expect to be told to begin context recreation, independent of 991 // BeginFrame state 992 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 993 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, 994 state.NextAction()); 995 state.DidLeaveBeginFrame(); 996 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, 997 state.NextAction()); 998 } 999 1000 TEST(SchedulerStateMachineTest, TestFinishAllRenderingWhileContextLost) { 1001 SchedulerSettings default_scheduler_settings; 1002 StateMachine state(default_scheduler_settings); 1003 state.SetCanStart(); 1004 state.UpdateState(state.NextAction()); 1005 state.DidCreateAndInitializeOutputSurface(); 1006 state.SetVisible(true); 1007 state.SetCanDraw(true); 1008 1009 // Cause a lost context lost. 1010 state.DidLoseOutputSurface(); 1011 1012 // Ask a forced redraw and verify it ocurrs. 1013 state.SetNeedsForcedRedraw(true); 1014 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 1015 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.NextAction()); 1016 state.DidLeaveBeginFrame(); 1017 1018 // Clear the forced redraw bit. 1019 state.SetNeedsForcedRedraw(false); 1020 1021 // Expect to be told to begin context recreation, independent of 1022 // BeginFrame state 1023 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, 1024 state.NextAction()); 1025 state.UpdateState(state.NextAction()); 1026 1027 // Ask a forced redraw and verify it ocurrs. 1028 state.SetNeedsForcedRedraw(true); 1029 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 1030 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.NextAction()); 1031 state.DidLeaveBeginFrame(); 1032 } 1033 1034 TEST(SchedulerStateMachineTest, DontDrawBeforeCommitAfterLostOutputSurface) { 1035 SchedulerSettings default_scheduler_settings; 1036 StateMachine state(default_scheduler_settings); 1037 state.SetCanStart(); 1038 state.UpdateState(state.NextAction()); 1039 state.DidCreateAndInitializeOutputSurface(); 1040 state.SetVisible(true); 1041 state.SetCanDraw(true); 1042 1043 state.SetNeedsRedraw(true); 1044 1045 // Cause a lost output surface, and restore it. 1046 state.DidLoseOutputSurface(); 1047 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, 1048 state.NextAction()); 1049 state.UpdateState(state.NextAction()); 1050 state.DidCreateAndInitializeOutputSurface(); 1051 1052 EXPECT_FALSE(state.RedrawPending()); 1053 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 1054 state.NextAction()); 1055 } 1056 1057 TEST(SchedulerStateMachineTest, 1058 TestSendBeginFrameToMainThreadWhenInvisibleAndForceCommit) { 1059 SchedulerSettings default_scheduler_settings; 1060 StateMachine state(default_scheduler_settings); 1061 state.SetCanStart(); 1062 state.UpdateState(state.NextAction()); 1063 state.DidCreateAndInitializeOutputSurface(); 1064 state.SetVisible(false); 1065 state.SetNeedsCommit(); 1066 state.SetNeedsForcedCommit(); 1067 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 1068 state.NextAction()); 1069 } 1070 1071 TEST(SchedulerStateMachineTest, 1072 TestSendBeginFrameToMainThreadWhenCanStartFalseAndForceCommit) { 1073 SchedulerSettings default_scheduler_settings; 1074 StateMachine state(default_scheduler_settings); 1075 state.SetVisible(true); 1076 state.SetCanDraw(true); 1077 state.SetNeedsCommit(); 1078 state.SetNeedsForcedCommit(); 1079 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 1080 state.NextAction()); 1081 } 1082 1083 TEST(SchedulerStateMachineTest, TestFinishCommitWhenCommitInProgress) { 1084 SchedulerSettings default_scheduler_settings; 1085 StateMachine state(default_scheduler_settings); 1086 state.SetCanStart(); 1087 state.UpdateState(state.NextAction()); 1088 state.DidCreateAndInitializeOutputSurface(); 1089 state.SetVisible(false); 1090 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS); 1091 state.SetNeedsCommit(); 1092 1093 state.FinishCommit(); 1094 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction()); 1095 state.UpdateState(state.NextAction()); 1096 1097 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, 1098 state.CommitState()); 1099 1100 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 1101 } 1102 1103 TEST(SchedulerStateMachineTest, TestFinishCommitWhenForcedCommitInProgress) { 1104 SchedulerSettings default_scheduler_settings; 1105 StateMachine state(default_scheduler_settings); 1106 state.SetCanStart(); 1107 state.UpdateState(state.NextAction()); 1108 state.DidCreateAndInitializeOutputSurface(); 1109 state.SetVisible(false); 1110 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS); 1111 state.SetNeedsCommit(); 1112 state.SetNeedsForcedCommit(); 1113 1114 state.FinishCommit(); 1115 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction()); 1116 state.UpdateState(state.NextAction()); 1117 1118 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW, 1119 state.CommitState()); 1120 1121 // If we are waiting for forced draw then we know a begin frame is already 1122 // in flight for the main thread. 1123 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 1124 } 1125 1126 TEST(SchedulerStateMachineTest, TestSendBeginFrameToMainThreadWhenContextLost) { 1127 SchedulerSettings default_scheduler_settings; 1128 StateMachine state(default_scheduler_settings); 1129 state.SetCanStart(); 1130 state.UpdateState(state.NextAction()); 1131 state.DidCreateAndInitializeOutputSurface(); 1132 state.SetVisible(true); 1133 state.SetCanDraw(true); 1134 state.SetNeedsCommit(); 1135 state.SetNeedsForcedCommit(); 1136 state.DidLoseOutputSurface(); 1137 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 1138 state.NextAction()); 1139 } 1140 1141 TEST(SchedulerStateMachineTest, TestImmediateFinishCommit) { 1142 SchedulerSettings default_scheduler_settings; 1143 StateMachine state(default_scheduler_settings); 1144 state.SetCanStart(); 1145 state.UpdateState(state.NextAction()); 1146 state.DidCreateAndInitializeOutputSurface(); 1147 state.SetVisible(true); 1148 state.SetCanDraw(true); 1149 1150 // Schedule a forced frame, commit it, draw it. 1151 state.SetNeedsCommit(); 1152 state.SetNeedsForcedCommit(); 1153 state.UpdateState(state.NextAction()); 1154 state.FinishCommit(); 1155 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction()); 1156 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, 1157 state.CommitState()); 1158 state.UpdateState(state.NextAction()); 1159 1160 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW, 1161 state.CommitState()); 1162 1163 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 1164 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 1165 state.SetNeedsForcedRedraw(true); 1166 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.NextAction()); 1167 state.UpdateState(state.NextAction()); 1168 state.DidDrawIfPossibleCompleted(true); 1169 state.DidLeaveBeginFrame(); 1170 1171 // Should be waiting for the normal begin frame from the main thread. 1172 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, 1173 state.CommitState()); 1174 } 1175 1176 TEST(SchedulerStateMachineTest, TestImmediateFinishCommitDuringCommit) { 1177 SchedulerSettings default_scheduler_settings; 1178 StateMachine state(default_scheduler_settings); 1179 state.SetCanStart(); 1180 state.UpdateState(state.NextAction()); 1181 state.DidCreateAndInitializeOutputSurface(); 1182 state.SetVisible(true); 1183 state.SetCanDraw(true); 1184 1185 // Start a normal commit. 1186 state.SetNeedsCommit(); 1187 state.UpdateState(state.NextAction()); 1188 1189 // Schedule a forced frame, commit it, draw it. 1190 state.SetNeedsCommit(); 1191 state.SetNeedsForcedCommit(); 1192 state.UpdateState(state.NextAction()); 1193 state.FinishCommit(); 1194 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction()); 1195 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, 1196 state.CommitState()); 1197 state.UpdateState(state.NextAction()); 1198 1199 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW, 1200 state.CommitState()); 1201 1202 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 1203 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 1204 state.SetNeedsForcedRedraw(true); 1205 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.NextAction()); 1206 state.UpdateState(state.NextAction()); 1207 state.DidDrawIfPossibleCompleted(true); 1208 state.DidLeaveBeginFrame(); 1209 1210 // Should be waiting for the normal begin frame from the main thread. 1211 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, 1212 state.CommitState()) << state.ToString(); 1213 } 1214 1215 TEST(SchedulerStateMachineTest, 1216 ImmediateBeginFrameAbortedByMainThreadWhileInvisible) { 1217 SchedulerSettings default_scheduler_settings; 1218 StateMachine state(default_scheduler_settings); 1219 state.SetCanStart(); 1220 state.UpdateState(state.NextAction()); 1221 state.DidCreateAndInitializeOutputSurface(); 1222 state.SetVisible(true); 1223 state.SetCanDraw(true); 1224 1225 state.SetNeedsCommit(); 1226 state.UpdateState(state.NextAction()); 1227 1228 state.SetNeedsCommit(); 1229 state.SetNeedsForcedCommit(); 1230 state.UpdateState(state.NextAction()); 1231 state.FinishCommit(); 1232 1233 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction()); 1234 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, 1235 state.CommitState()); 1236 state.UpdateState(state.NextAction()); 1237 1238 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW, 1239 state.CommitState()); 1240 1241 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 1242 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 1243 state.SetNeedsForcedRedraw(true); 1244 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.NextAction()); 1245 state.UpdateState(state.NextAction()); 1246 state.DidDrawIfPossibleCompleted(true); 1247 state.DidLeaveBeginFrame(); 1248 1249 // Should be waiting for the main thread's begin frame. 1250 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, 1251 state.CommitState()) << state.ToString(); 1252 1253 // Become invisible and abort the main thread's begin frame. 1254 state.SetVisible(false); 1255 state.BeginFrameAbortedByMainThread(false); 1256 1257 // Should be back in the idle state, but needing a commit. 1258 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState()); 1259 EXPECT_TRUE(state.NeedsCommit()); 1260 } 1261 1262 TEST(SchedulerStateMachineTest, ImmediateFinishCommitWhileCantDraw) { 1263 SchedulerSettings default_scheduler_settings; 1264 StateMachine state(default_scheduler_settings); 1265 state.SetCanStart(); 1266 state.UpdateState(state.NextAction()); 1267 state.DidCreateAndInitializeOutputSurface(); 1268 state.SetVisible(true); 1269 state.SetCanDraw(false); 1270 1271 state.SetNeedsCommit(); 1272 state.UpdateState(state.NextAction()); 1273 1274 state.SetNeedsCommit(); 1275 state.SetNeedsForcedCommit(); 1276 state.UpdateState(state.NextAction()); 1277 state.FinishCommit(); 1278 1279 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction()); 1280 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, 1281 state.CommitState()); 1282 state.UpdateState(state.NextAction()); 1283 1284 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW, 1285 state.CommitState()); 1286 1287 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting()); 1288 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 1289 state.SetNeedsForcedRedraw(true); 1290 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.NextAction()); 1291 state.UpdateState(state.NextAction()); 1292 state.DidDrawIfPossibleCompleted(true); 1293 state.DidLeaveBeginFrame(); 1294 } 1295 1296 TEST(SchedulerStateMachineTest, ReportIfNotDrawing) { 1297 SchedulerSettings default_scheduler_settings; 1298 SchedulerStateMachine state(default_scheduler_settings); 1299 1300 state.SetCanDraw(true); 1301 state.SetVisible(true); 1302 EXPECT_FALSE(state.DrawSuspendedUntilCommit()); 1303 1304 state.SetCanDraw(false); 1305 state.SetVisible(true); 1306 EXPECT_TRUE(state.DrawSuspendedUntilCommit()); 1307 1308 state.SetCanDraw(true); 1309 state.SetVisible(false); 1310 EXPECT_TRUE(state.DrawSuspendedUntilCommit()); 1311 1312 state.SetCanDraw(false); 1313 state.SetVisible(false); 1314 EXPECT_TRUE(state.DrawSuspendedUntilCommit()); 1315 1316 state.SetCanDraw(true); 1317 state.SetVisible(true); 1318 EXPECT_FALSE(state.DrawSuspendedUntilCommit()); 1319 } 1320 1321 TEST(SchedulerStateMachineTest, ReportIfNotDrawingFromAcquiredTextures) { 1322 SchedulerSettings default_scheduler_settings; 1323 SchedulerStateMachine state(default_scheduler_settings); 1324 state.SetCanStart(); 1325 state.UpdateState(state.NextAction()); 1326 state.DidCreateAndInitializeOutputSurface(); 1327 state.SetCanDraw(true); 1328 state.SetVisible(true); 1329 EXPECT_FALSE(state.DrawSuspendedUntilCommit()); 1330 1331 state.SetMainThreadNeedsLayerTextures(); 1332 EXPECT_EQ( 1333 SchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD, 1334 state.NextAction()); 1335 state.UpdateState(state.NextAction()); 1336 EXPECT_TRUE(state.DrawSuspendedUntilCommit()); 1337 1338 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 1339 1340 state.SetNeedsCommit(); 1341 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 1342 state.NextAction()); 1343 1344 state.UpdateState(state.NextAction()); 1345 EXPECT_TRUE(state.DrawSuspendedUntilCommit()); 1346 1347 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 1348 1349 state.FinishCommit(); 1350 EXPECT_TRUE(state.DrawSuspendedUntilCommit()); 1351 1352 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction()); 1353 1354 state.UpdateState(state.NextAction()); 1355 EXPECT_FALSE(state.DrawSuspendedUntilCommit()); 1356 } 1357 1358 TEST(SchedulerStateMachineTest, AcquireTexturesWithAbort) { 1359 SchedulerSettings default_scheduler_settings; 1360 SchedulerStateMachine state(default_scheduler_settings); 1361 state.SetCanStart(); 1362 state.UpdateState(state.NextAction()); 1363 state.DidCreateAndInitializeOutputSurface(); 1364 state.SetCanDraw(true); 1365 state.SetVisible(true); 1366 1367 state.SetMainThreadNeedsLayerTextures(); 1368 EXPECT_EQ( 1369 SchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD, 1370 state.NextAction()); 1371 state.UpdateState(state.NextAction()); 1372 EXPECT_TRUE(state.DrawSuspendedUntilCommit()); 1373 1374 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 1375 1376 state.SetNeedsCommit(); 1377 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD, 1378 state.NextAction()); 1379 state.UpdateState(state.NextAction()); 1380 EXPECT_TRUE(state.DrawSuspendedUntilCommit()); 1381 1382 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 1383 1384 state.BeginFrameAbortedByMainThread(true); 1385 1386 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction()); 1387 EXPECT_FALSE(state.DrawSuspendedUntilCommit()); 1388 } 1389 1390 } // namespace 1391 } // namespace cc 1392