| OLD | NEW |
| 1 // Copyright 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/scheduler/scheduler_state_machine.h" | 5 #include "cc/scheduler/scheduler_state_machine.h" |
| 6 | 6 |
| 7 #include "base/format_macros.h" | 7 #include "base/format_macros.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
| 10 | 10 |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 return true; | 216 return true; |
| 217 } | 217 } |
| 218 | 218 |
| 219 // If we've lost the output surface or draw is suspended, we want to be able | 219 // If we've lost the output surface or draw is suspended, we want to be able |
| 220 // to abort a draw and make forward progress to unblock the main thread. | 220 // to abort a draw and make forward progress to unblock the main thread. |
| 221 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE || | 221 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE || |
| 222 DrawSuspendedUntilCommit()) { | 222 DrawSuspendedUntilCommit()) { |
| 223 return !active_tree_has_been_drawn_ && | 223 return !active_tree_has_been_drawn_ && |
| 224 (commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW || | 224 (commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW || |
| 225 commit_state_ == COMMIT_STATE_WAITING_FOR_ACTIVATION || | 225 commit_state_ == COMMIT_STATE_WAITING_FOR_ACTIVATION || |
| 226 commit_state_ == COMMIT_STATE_WAITING_FOR_ACTIVATION_AND_FRAME_IN_PR
OGRESS || |
| 226 (output_surface_state_ != OUTPUT_SURFACE_ACTIVE && | 227 (output_surface_state_ != OUTPUT_SURFACE_ACTIVE && |
| 227 !active_tree_is_null_)); | 228 !active_tree_is_null_)); |
| 228 } | 229 } |
| 229 | 230 |
| 230 // Except for the cases above, do not draw outside of the BeginFrame deadline. | 231 // Except for the cases above, do not draw outside of the BeginFrame deadline. |
| 231 if (begin_frame_state_ != BEGIN_FRAME_STATE_INSIDE_DEADLINE) | 232 if (begin_frame_state_ != BEGIN_FRAME_STATE_INSIDE_DEADLINE) |
| 232 return false; | 233 return false; |
| 233 | 234 |
| 234 // Only handle forced redraws due to timeouts on the regular deadline. | 235 // Only handle forced redraws due to timeouts on the regular deadline. |
| 235 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) { | 236 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 if (!BeginFrameNeededToDrawByImplThread()) | 300 if (!BeginFrameNeededToDrawByImplThread()) |
| 300 return true; | 301 return true; |
| 301 return false; | 302 return false; |
| 302 } | 303 } |
| 303 | 304 |
| 304 bool SchedulerStateMachine::ShouldSendBeginFrameToMainThread() const { | 305 bool SchedulerStateMachine::ShouldSendBeginFrameToMainThread() const { |
| 305 if (HasSentBeginFrameToMainThreadThisFrame()) | 306 if (HasSentBeginFrameToMainThreadThisFrame()) |
| 306 return false; | 307 return false; |
| 307 | 308 |
| 308 // Only send BeginFrame to the main thread when idle. | 309 // Only send BeginFrame to the main thread when idle. |
| 309 if (commit_state_ != COMMIT_STATE_IDLE) | 310 if (commit_state_ != COMMIT_STATE_IDLE && |
| 311 commit_state_ != COMMIT_STATE_WAITING_FOR_ACTIVATION) |
| 310 return false; | 312 return false; |
| 311 | 313 |
| 312 // We can't accept a commit if we have a pending tree. | 314 // We can't accept a commit if we have a pending tree. |
| 313 if (has_pending_tree_) | 315 //if (has_pending_tree_) |
| 314 return false; | 316 // return false; |
| 315 | 317 |
| 316 // We want to handle readback commits ASAP. | 318 // We want to handle readback commits ASAP. |
| 317 if (readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED) | 319 if (readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED) |
| 318 return !CommitPending(); | 320 return !CommitPending(); |
| 319 | 321 |
| 320 // We want to start the first commit after we get a new output surface | 322 // We want to start the first commit after we get a new output surface |
| 321 // immediately. | 323 // immediately. |
| 322 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT | 324 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT |
| 323 && needs_commit_) | 325 && needs_commit_) |
| 324 return true; | 326 return true; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 if (ShouldDraw()) { | 376 if (ShouldDraw()) { |
| 375 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE || | 377 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE || |
| 376 DrawSuspendedUntilCommit()) | 378 DrawSuspendedUntilCommit()) |
| 377 return ACTION_DRAW_AND_SWAP_ABORT; | 379 return ACTION_DRAW_AND_SWAP_ABORT; |
| 378 else | 380 else |
| 379 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE; | 381 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE; |
| 380 } | 382 } |
| 381 return ACTION_NONE; | 383 return ACTION_NONE; |
| 382 | 384 |
| 383 case COMMIT_STATE_FRAME_IN_PROGRESS: | 385 case COMMIT_STATE_FRAME_IN_PROGRESS: |
| 386 case COMMIT_STATE_WAITING_FOR_ACTIVATION_AND_FRAME_IN_PROGRESS: |
| 384 if (ShouldUpdateVisibleTiles()) | 387 if (ShouldUpdateVisibleTiles()) |
| 385 return ACTION_UPDATE_VISIBLE_TILES; | 388 return ACTION_UPDATE_VISIBLE_TILES; |
| 386 if (ShouldActivatePendingTree()) | 389 if (ShouldActivatePendingTree()) |
| 387 return ACTION_ACTIVATE_PENDING_TREE; | 390 return ACTION_ACTIVATE_PENDING_TREE; |
| 388 if (ShouldDraw()) { | 391 if (ShouldDraw()) { |
| 389 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE || | 392 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE || |
| 390 DrawSuspendedUntilCommit()) | 393 DrawSuspendedUntilCommit()) |
| 391 return ACTION_DRAW_AND_SWAP_ABORT; | 394 return ACTION_DRAW_AND_SWAP_ABORT; |
| 392 else | 395 else |
| 393 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE; | 396 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE; |
| 394 } | 397 } |
| 395 return ACTION_NONE; | 398 return ACTION_NONE; |
| 396 | 399 |
| 397 case COMMIT_STATE_READY_TO_COMMIT: | 400 case COMMIT_STATE_READY_TO_COMMIT: |
| 398 return ACTION_COMMIT; | 401 return ACTION_COMMIT; |
| 399 | 402 |
| 400 case COMMIT_STATE_WAITING_FOR_ACTIVATION: { | 403 case COMMIT_STATE_WAITING_FOR_ACTIVATION: { |
| 404 if (ShouldSendBeginFrameToMainThread()) |
| 405 return ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD; |
| 401 if (ShouldUpdateVisibleTiles()) | 406 if (ShouldUpdateVisibleTiles()) |
| 402 return ACTION_UPDATE_VISIBLE_TILES; | 407 return ACTION_UPDATE_VISIBLE_TILES; |
| 403 if (ShouldActivatePendingTree()) | 408 if (ShouldActivatePendingTree()) |
| 404 return ACTION_ACTIVATE_PENDING_TREE; | 409 return ACTION_ACTIVATE_PENDING_TREE; |
| 405 if (ShouldDraw()) { | 410 if (ShouldDraw()) { |
| 406 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE || | 411 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE || |
| 407 DrawSuspendedUntilCommit()) | 412 DrawSuspendedUntilCommit()) |
| 408 return ACTION_DRAW_AND_SWAP_ABORT; | 413 return ACTION_DRAW_AND_SWAP_ABORT; |
| 409 else | 414 else |
| 410 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE; | 415 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 last_draw_attempt_count_update_visible_tiles_was_called_ = | 450 last_draw_attempt_count_update_visible_tiles_was_called_ = |
| 446 draw_attempt_count_; | 451 draw_attempt_count_; |
| 447 return; | 452 return; |
| 448 | 453 |
| 449 case ACTION_ACTIVATE_PENDING_TREE: | 454 case ACTION_ACTIVATE_PENDING_TREE: |
| 450 last_draw_attempt_count_tree_activation_attempted_ = | 455 last_draw_attempt_count_tree_activation_attempted_ = |
| 451 draw_attempt_count_; | 456 draw_attempt_count_; |
| 452 return; | 457 return; |
| 453 | 458 |
| 454 case ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD: | 459 case ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD: |
| 455 DCHECK(!has_pending_tree_); | 460 //DCHECK(!has_pending_tree_); |
| 456 DCHECK(visible_ || | 461 DCHECK(visible_ || |
| 457 readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED || | 462 readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED || |
| 458 forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT || | 463 forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT || |
| 459 output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT); | 464 output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT); |
| 460 commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS; | 465 if (commit_state_ == COMMIT_STATE_WAITING_FOR_ACTIVATION) |
| 466 commit_state_ = COMMIT_STATE_WAITING_FOR_ACTIVATION_AND_FRAME_IN_PROGRES
S; |
| 467 else |
| 468 commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS; |
| 461 needs_commit_ = false; | 469 needs_commit_ = false; |
| 462 if (readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED) | 470 if (readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED) |
| 463 readback_state_ = READBACK_STATE_FORCED_COMMIT_PENDING; | 471 readback_state_ = READBACK_STATE_FORCED_COMMIT_PENDING; |
| 464 last_begin_frame_count_begin_frame_sent_to_main_thread_ = | 472 last_begin_frame_count_begin_frame_sent_to_main_thread_ = |
| 465 begin_frame_count_; | 473 begin_frame_count_; |
| 466 return; | 474 return; |
| 467 | 475 |
| 468 case ACTION_COMMIT: | 476 case ACTION_COMMIT: |
| 469 HandleCommitInternal(false); | 477 HandleCommitInternal(false); |
| 470 return; | 478 return; |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 } else { | 633 } else { |
| 626 consecutive_failed_draws_ = 0; | 634 consecutive_failed_draws_ = 0; |
| 627 } | 635 } |
| 628 } | 636 } |
| 629 | 637 |
| 630 void SchedulerStateMachine::SetNeedsCommit() { needs_commit_ = true; } | 638 void SchedulerStateMachine::SetNeedsCommit() { needs_commit_ = true; } |
| 631 | 639 |
| 632 void SchedulerStateMachine::SetNeedsForcedCommitForReadback() { | 640 void SchedulerStateMachine::SetNeedsForcedCommitForReadback() { |
| 633 DCHECK(readback_state_ == READBACK_STATE_IDLE || | 641 DCHECK(readback_state_ == READBACK_STATE_IDLE || |
| 634 readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_PENDING); | 642 readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_PENDING); |
| 635 if (commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS) | 643 if (commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS || |
| 644 commit_state_ == COMMIT_STATE_WAITING_FOR_ACTIVATION_AND_FRAME_IN_PROGRESS
) |
| 636 readback_state_ = READBACK_STATE_FORCED_COMMIT_PENDING; | 645 readback_state_ = READBACK_STATE_FORCED_COMMIT_PENDING; |
| 637 else | 646 else |
| 638 readback_state_ = READBACK_STATE_FORCED_COMMIT_REQUESTED; | 647 readback_state_ = READBACK_STATE_FORCED_COMMIT_REQUESTED; |
| 639 } | 648 } |
| 640 | 649 |
| 641 void SchedulerStateMachine::FinishCommit() { | 650 void SchedulerStateMachine::FinishCommit() { |
| 642 DCHECK(commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS || | 651 DCHECK(commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS || |
| 652 commit_state_ == COMMIT_STATE_WAITING_FOR_ACTIVATION_AND_FRAME_IN_PROGR
ESS || |
| 643 readback_state_ == READBACK_STATE_FORCED_COMMIT_PENDING) | 653 readback_state_ == READBACK_STATE_FORCED_COMMIT_PENDING) |
| 644 << ToString(); | 654 << ToString(); |
| 645 commit_state_ = COMMIT_STATE_READY_TO_COMMIT; | 655 commit_state_ = COMMIT_STATE_READY_TO_COMMIT; |
| 646 } | 656 } |
| 647 | 657 |
| 648 void SchedulerStateMachine::BeginFrameAbortedByMainThread(bool did_handle) { | 658 void SchedulerStateMachine::BeginFrameAbortedByMainThread(bool did_handle) { |
| 649 DCHECK_EQ(commit_state_, COMMIT_STATE_FRAME_IN_PROGRESS); | 659 DCHECK(commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS || |
| 660 commit_state_ == COMMIT_STATE_WAITING_FOR_ACTIVATION_AND_FRAME_IN_PROGR
ESS); |
| 650 if (readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED) { | 661 if (readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED) { |
| 651 readback_state_ = READBACK_STATE_IDLE; | 662 readback_state_ = READBACK_STATE_IDLE; |
| 652 } else if (did_handle) { | 663 } else if (did_handle) { |
| 653 HandleCommitInternal(true); | 664 HandleCommitInternal(true); |
| 654 } else { | 665 } else { |
| 655 commit_state_ = COMMIT_STATE_IDLE; | 666 commit_state_ = COMMIT_STATE_IDLE; |
| 656 SetNeedsCommit(); | 667 SetNeedsCommit(); |
| 657 } | 668 } |
| 658 } | 669 } |
| 659 | 670 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 681 needs_redraw_ = true; | 692 needs_redraw_ = true; |
| 682 | 693 |
| 683 if (draw_if_possible_failed_) { | 694 if (draw_if_possible_failed_) { |
| 684 last_begin_frame_count_swap_performed_ = -1; | 695 last_begin_frame_count_swap_performed_ = -1; |
| 685 last_draw_attempt_count_draw_was_called_ = -1; | 696 last_draw_attempt_count_draw_was_called_ = -1; |
| 686 } | 697 } |
| 687 | 698 |
| 688 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION) | 699 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION) |
| 689 output_surface_state_ = OUTPUT_SURFACE_ACTIVE; | 700 output_surface_state_ = OUTPUT_SURFACE_ACTIVE; |
| 690 | 701 |
| 691 DCHECK_EQ(COMMIT_STATE_WAITING_FOR_ACTIVATION, commit_state_); | 702 DCHECK(commit_state_ == COMMIT_STATE_WAITING_FOR_ACTIVATION || |
| 703 commit_state_ == COMMIT_STATE_WAITING_FOR_ACTIVATION_AND_FRAME_IN_PRO
GRESS); |
| 692 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION) { | 704 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION) { |
| 693 commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW; | 705 commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW; |
| 694 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_DRAW; | 706 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_DRAW; |
| 695 } else if (readback_state_ == READBACK_STATE_WAITING_FOR_ACTIVATION) { | 707 } else if (readback_state_ == READBACK_STATE_WAITING_FOR_ACTIVATION) { |
| 696 commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW; | 708 commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW; |
| 697 readback_state_ = READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK; | 709 readback_state_ = READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK; |
| 698 } else { | 710 } else { |
| 699 commit_state_ = COMMIT_STATE_IDLE; | 711 if (commit_state_ == COMMIT_STATE_WAITING_FOR_ACTIVATION_AND_FRAME_IN_PROG
RESS) |
| 712 commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS; |
| 713 else |
| 714 commit_state_ = COMMIT_STATE_IDLE; |
| 700 if (readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_ACTIVATING) | 715 if (readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_ACTIVATING) |
| 701 readback_state_ = READBACK_STATE_IDLE; | 716 readback_state_ = READBACK_STATE_IDLE; |
| 702 } | 717 } |
| 703 } else if (!has_pending_tree_ && has_pending_tree) { | 718 } else if (!has_pending_tree_ && has_pending_tree) { |
| 704 // There is a new pending tree. | 719 // There is a new pending tree. |
| 705 pending_tree_is_ready_for_activation_ = false; | 720 pending_tree_is_ready_for_activation_ = false; |
| 706 } | 721 } |
| 707 | 722 |
| 708 has_pending_tree_ = has_pending_tree; | 723 has_pending_tree_ = has_pending_tree; |
| 709 } | 724 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 724 return output_surface_state_ != OUTPUT_SURFACE_LOST && | 739 return output_surface_state_ != OUTPUT_SURFACE_LOST && |
| 725 output_surface_state_ != OUTPUT_SURFACE_CREATING; | 740 output_surface_state_ != OUTPUT_SURFACE_CREATING; |
| 726 } | 741 } |
| 727 | 742 |
| 728 void SchedulerStateMachine::SetMaximumNumberOfFailedDrawsBeforeDrawIsForced( | 743 void SchedulerStateMachine::SetMaximumNumberOfFailedDrawsBeforeDrawIsForced( |
| 729 int num_draws) { | 744 int num_draws) { |
| 730 maximum_number_of_failed_draws_before_draw_is_forced_ = num_draws; | 745 maximum_number_of_failed_draws_before_draw_is_forced_ = num_draws; |
| 731 } | 746 } |
| 732 | 747 |
| 733 } // namespace cc | 748 } // namespace cc |
| OLD | NEW |