| 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 #include "base/values.h" | 10 #include "base/values.h" |
| 11 | 11 |
| 12 namespace cc { | 12 namespace cc { |
| 13 | 13 |
| 14 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) | 14 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) |
| 15 : settings_(settings), | 15 : settings_(settings), |
| 16 output_surface_state_(OUTPUT_SURFACE_LOST), | 16 output_surface_state_(OUTPUT_SURFACE_LOST), |
| 17 commit_state_(COMMIT_STATE_IDLE), | 17 commit_state_(COMMIT_STATE_IDLE), |
| 18 texture_state_(LAYER_TEXTURE_STATE_UNLOCKED), | 18 texture_state_(LAYER_TEXTURE_STATE_UNLOCKED), |
| 19 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE), | 19 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE), |
| 20 readback_state_(READBACK_STATE_IDLE), | 20 readback_state_(READBACK_STATE_IDLE), |
| 21 commit_count_(0), | 21 commit_count_(0), |
| 22 current_frame_number_(0), | 22 current_frame_number_(0), |
| 23 last_frame_number_where_begin_frame_sent_to_main_thread_(-1), | 23 last_frame_number_where_begin_frame_sent_to_main_thread_(-1), |
| 24 last_frame_number_swap_performed_(-1), | 24 last_frame_number_swap_performed_(-1), |
| 25 last_frame_number_where_update_visible_tiles_was_called_(-1), | 25 last_frame_number_where_update_visible_tiles_was_called_(-1), |
| 26 consecutive_failed_draws_(0), | 26 consecutive_failed_draws_(0), |
| 27 needs_redraw_(false), | 27 needs_redraw_(false), |
| 28 needs_manage_tiles_(false), |
| 28 swap_used_incomplete_tile_(false), | 29 swap_used_incomplete_tile_(false), |
| 29 needs_commit_(false), | 30 needs_commit_(false), |
| 30 main_thread_needs_layer_textures_(false), | 31 main_thread_needs_layer_textures_(false), |
| 31 inside_begin_frame_(false), | 32 inside_begin_frame_(false), |
| 33 inside_poll_for_anticipated_draw_triggers_(false), |
| 32 visible_(false), | 34 visible_(false), |
| 33 can_start_(false), | 35 can_start_(false), |
| 34 can_draw_(false), | 36 can_draw_(false), |
| 35 has_pending_tree_(false), | 37 has_pending_tree_(false), |
| 36 pending_tree_is_ready_for_activation_(false), | 38 pending_tree_is_ready_for_activation_(false), |
| 37 active_tree_needs_first_draw_(false), | 39 active_tree_needs_first_draw_(false), |
| 38 draw_if_possible_failed_(false), | 40 draw_if_possible_failed_(false), |
| 39 did_create_and_initialize_first_output_surface_(false) {} | 41 did_create_and_initialize_first_output_surface_(false) {} |
| 40 | 42 |
| 41 const char* SchedulerStateMachine::OutputSurfaceStateToString( | 43 const char* SchedulerStateMachine::OutputSurfaceStateToString( |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 case ACTION_DRAW_AND_SWAP_FORCED: | 141 case ACTION_DRAW_AND_SWAP_FORCED: |
| 140 return "ACTION_DRAW_AND_SWAP_FORCED"; | 142 return "ACTION_DRAW_AND_SWAP_FORCED"; |
| 141 case ACTION_DRAW_AND_SWAP_ABORT: | 143 case ACTION_DRAW_AND_SWAP_ABORT: |
| 142 return "ACTION_DRAW_AND_SWAP_ABORT"; | 144 return "ACTION_DRAW_AND_SWAP_ABORT"; |
| 143 case ACTION_DRAW_AND_READBACK: | 145 case ACTION_DRAW_AND_READBACK: |
| 144 return "ACTION_DRAW_AND_READBACK"; | 146 return "ACTION_DRAW_AND_READBACK"; |
| 145 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION: | 147 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION: |
| 146 return "ACTION_BEGIN_OUTPUT_SURFACE_CREATION"; | 148 return "ACTION_BEGIN_OUTPUT_SURFACE_CREATION"; |
| 147 case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: | 149 case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: |
| 148 return "ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD"; | 150 return "ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD"; |
| 151 case ACTION_MANAGE_TILES: |
| 152 return "ACTION_MANAGE_TILES"; |
| 149 } | 153 } |
| 150 NOTREACHED(); | 154 NOTREACHED(); |
| 151 return "???"; | 155 return "???"; |
| 152 } | 156 } |
| 153 | 157 |
| 154 scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const { | 158 scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const { |
| 155 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); | 159 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); |
| 156 | 160 |
| 157 scoped_ptr<base::DictionaryValue> major_state(new base::DictionaryValue); | 161 scoped_ptr<base::DictionaryValue> major_state(new base::DictionaryValue); |
| 158 major_state->SetString("next_action", ActionToString(NextAction())); | 162 major_state->SetString("next_action", ActionToString(NextAction())); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 "last_frame_number_where_begin_frame_sent_to_main_thread", | 206 "last_frame_number_where_begin_frame_sent_to_main_thread", |
| 203 last_frame_number_where_begin_frame_sent_to_main_thread_); | 207 last_frame_number_where_begin_frame_sent_to_main_thread_); |
| 204 minor_state->SetInteger("last_frame_number_swap_performed_", | 208 minor_state->SetInteger("last_frame_number_swap_performed_", |
| 205 last_frame_number_swap_performed_); | 209 last_frame_number_swap_performed_); |
| 206 minor_state->SetInteger( | 210 minor_state->SetInteger( |
| 207 "last_frame_number_where_update_visible_tiles_was_called", | 211 "last_frame_number_where_update_visible_tiles_was_called", |
| 208 last_frame_number_where_update_visible_tiles_was_called_); | 212 last_frame_number_where_update_visible_tiles_was_called_); |
| 209 minor_state->SetInteger("consecutive_failed_draws", | 213 minor_state->SetInteger("consecutive_failed_draws", |
| 210 consecutive_failed_draws_); | 214 consecutive_failed_draws_); |
| 211 minor_state->SetBoolean("needs_redraw", needs_redraw_); | 215 minor_state->SetBoolean("needs_redraw", needs_redraw_); |
| 216 minor_state->SetBoolean("needs_manage_tiles", needs_manage_tiles_); |
| 212 minor_state->SetBoolean("swap_used_incomplete_tile", | 217 minor_state->SetBoolean("swap_used_incomplete_tile", |
| 213 swap_used_incomplete_tile_); | 218 swap_used_incomplete_tile_); |
| 214 minor_state->SetBoolean("needs_commit", needs_commit_); | 219 minor_state->SetBoolean("needs_commit", needs_commit_); |
| 215 minor_state->SetBoolean("main_thread_needs_layer_textures", | 220 minor_state->SetBoolean("main_thread_needs_layer_textures", |
| 216 main_thread_needs_layer_textures_); | 221 main_thread_needs_layer_textures_); |
| 217 minor_state->SetBoolean("inside_begin_frame", inside_begin_frame_); | 222 minor_state->SetBoolean("inside_begin_frame", inside_begin_frame_); |
| 218 minor_state->SetBoolean("visible", visible_); | 223 minor_state->SetBoolean("visible", visible_); |
| 219 minor_state->SetBoolean("can_start", can_start_); | 224 minor_state->SetBoolean("can_start", can_start_); |
| 220 minor_state->SetBoolean("can_draw", can_draw_); | 225 minor_state->SetBoolean("can_draw", can_draw_); |
| 221 minor_state->SetBoolean("has_pending_tree", has_pending_tree_); | 226 minor_state->SetBoolean("has_pending_tree", has_pending_tree_); |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 if (!HasInitializedOutputSurface()) | 440 if (!HasInitializedOutputSurface()) |
| 436 return false; | 441 return false; |
| 437 | 442 |
| 438 return true; | 443 return true; |
| 439 } | 444 } |
| 440 | 445 |
| 441 bool SchedulerStateMachine::ShouldCommit() const { | 446 bool SchedulerStateMachine::ShouldCommit() const { |
| 442 return commit_state_ == COMMIT_STATE_READY_TO_COMMIT; | 447 return commit_state_ == COMMIT_STATE_READY_TO_COMMIT; |
| 443 } | 448 } |
| 444 | 449 |
| 450 bool SchedulerStateMachine::ShouldManageTiles() const { |
| 451 // Limiting to once per-frame is not enough, since we only want to |
| 452 // manage tiles _after_ draws. Polling for draw triggers and |
| 453 // begin-frame are mutually exclusive, so we limit to these two cases. |
| 454 if (!inside_begin_frame_ && !inside_poll_for_anticipated_draw_triggers_) |
| 455 return false; |
| 456 return needs_manage_tiles_; |
| 457 } |
| 458 |
| 445 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { | 459 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { |
| 446 if (ShouldAcquireLayerTexturesForMainThread()) | 460 if (ShouldAcquireLayerTexturesForMainThread()) |
| 447 return ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD; | 461 return ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD; |
| 448 if (ShouldUpdateVisibleTiles()) | 462 if (ShouldUpdateVisibleTiles()) |
| 449 return ACTION_UPDATE_VISIBLE_TILES; | 463 return ACTION_UPDATE_VISIBLE_TILES; |
| 450 if (ShouldActivatePendingTree()) | 464 if (ShouldActivatePendingTree()) |
| 451 return ACTION_ACTIVATE_PENDING_TREE; | 465 return ACTION_ACTIVATE_PENDING_TREE; |
| 452 if (ShouldCommit()) | 466 if (ShouldCommit()) |
| 453 return ACTION_COMMIT; | 467 return ACTION_COMMIT; |
| 454 if (ShouldDraw()) { | 468 if (ShouldDraw()) { |
| 455 if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) | 469 if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) |
| 456 return ACTION_DRAW_AND_READBACK; | 470 return ACTION_DRAW_AND_READBACK; |
| 457 else if (PendingDrawsShouldBeAborted()) | 471 else if (PendingDrawsShouldBeAborted()) |
| 458 return ACTION_DRAW_AND_SWAP_ABORT; | 472 return ACTION_DRAW_AND_SWAP_ABORT; |
| 459 else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) | 473 else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) |
| 460 return ACTION_DRAW_AND_SWAP_FORCED; | 474 return ACTION_DRAW_AND_SWAP_FORCED; |
| 461 else | 475 else |
| 462 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE; | 476 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE; |
| 463 } | 477 } |
| 478 if (ShouldManageTiles()) |
| 479 return ACTION_MANAGE_TILES; |
| 464 if (ShouldSendBeginFrameToMainThread()) | 480 if (ShouldSendBeginFrameToMainThread()) |
| 465 return ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD; | 481 return ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD; |
| 466 if (ShouldBeginOutputSurfaceCreation()) | 482 if (ShouldBeginOutputSurfaceCreation()) |
| 467 return ACTION_BEGIN_OUTPUT_SURFACE_CREATION; | 483 return ACTION_BEGIN_OUTPUT_SURFACE_CREATION; |
| 468 return ACTION_NONE; | 484 return ACTION_NONE; |
| 469 } | 485 } |
| 470 | 486 |
| 471 void SchedulerStateMachine::CheckInvariants() { | 487 void SchedulerStateMachine::CheckInvariants() { |
| 472 // We should never try to perform a draw for readback and forced draw due to | 488 // We should never try to perform a draw for readback and forced draw due to |
| 473 // timeout simultaneously. | 489 // timeout simultaneously. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 // surface creation to avoid complicated corner cases. | 545 // surface creation to avoid complicated corner cases. |
| 530 DCHECK_EQ(commit_state_, COMMIT_STATE_IDLE); | 546 DCHECK_EQ(commit_state_, COMMIT_STATE_IDLE); |
| 531 DCHECK(!has_pending_tree_); | 547 DCHECK(!has_pending_tree_); |
| 532 DCHECK(!active_tree_needs_first_draw_); | 548 DCHECK(!active_tree_needs_first_draw_); |
| 533 return; | 549 return; |
| 534 | 550 |
| 535 case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: | 551 case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: |
| 536 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD; | 552 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD; |
| 537 main_thread_needs_layer_textures_ = false; | 553 main_thread_needs_layer_textures_ = false; |
| 538 return; | 554 return; |
| 555 |
| 556 case ACTION_MANAGE_TILES: |
| 557 UpdateStateOnManageTiles(); |
| 558 return; |
| 539 } | 559 } |
| 540 } | 560 } |
| 541 | 561 |
| 542 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { | 562 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { |
| 543 commit_count_++; | 563 commit_count_++; |
| 544 | 564 |
| 545 // If we are impl-side-painting but the commit was aborted, then we behave | 565 // If we are impl-side-painting but the commit was aborted, then we behave |
| 546 // mostly as if we are not impl-side-painting since there is no pending tree. | 566 // mostly as if we are not impl-side-painting since there is no pending tree. |
| 547 has_pending_tree_ = settings_.impl_side_painting && !commit_was_aborted; | 567 has_pending_tree_ = settings_.impl_side_painting && !commit_was_aborted; |
| 548 | 568 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED; | 690 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED; |
| 671 | 691 |
| 672 needs_redraw_ = false; | 692 needs_redraw_ = false; |
| 673 draw_if_possible_failed_ = false; | 693 draw_if_possible_failed_ = false; |
| 674 active_tree_needs_first_draw_ = false; | 694 active_tree_needs_first_draw_ = false; |
| 675 | 695 |
| 676 if (did_swap) | 696 if (did_swap) |
| 677 last_frame_number_swap_performed_ = current_frame_number_; | 697 last_frame_number_swap_performed_ = current_frame_number_; |
| 678 } | 698 } |
| 679 | 699 |
| 700 void SchedulerStateMachine::UpdateStateOnManageTiles() { |
| 701 needs_manage_tiles_ = false; |
| 702 } |
| 703 |
| 680 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() { | 704 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() { |
| 681 DCHECK(!main_thread_needs_layer_textures_); | 705 DCHECK(!main_thread_needs_layer_textures_); |
| 682 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD); | 706 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD); |
| 683 main_thread_needs_layer_textures_ = true; | 707 main_thread_needs_layer_textures_ = true; |
| 684 } | 708 } |
| 685 | 709 |
| 686 // These are the cases where we definitely (or almost definitely) have a | 710 // These are the cases where we definitely (or almost definitely) have a |
| 687 // new frame to draw and can draw. | 711 // new frame to draw and can draw. |
| 688 bool SchedulerStateMachine::BeginFrameNeededToDrawByImplThread() const { | 712 bool SchedulerStateMachine::BeginFrameNeededToDrawByImplThread() const { |
| 689 // The output surface is the provider of BeginFrames for the impl thread, | 713 // The output surface is the provider of BeginFrames for the impl thread, |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 733 // We should proactively request a BeginFrame if a commit is pending | 757 // We should proactively request a BeginFrame if a commit is pending |
| 734 // because we will want to draw if the commit completes quickly. | 758 // because we will want to draw if the commit completes quickly. |
| 735 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE) | 759 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE) |
| 736 return true; | 760 return true; |
| 737 | 761 |
| 738 // If the pending tree activates quickly, we'll want a BeginFrame soon | 762 // If the pending tree activates quickly, we'll want a BeginFrame soon |
| 739 // to draw the new active tree. | 763 // to draw the new active tree. |
| 740 if (has_pending_tree_) | 764 if (has_pending_tree_) |
| 741 return true; | 765 return true; |
| 742 | 766 |
| 767 // Changing priorities may allow us to activate (given the new priorities), |
| 768 // which may result in a new frame. |
| 769 if (needs_manage_tiles_) |
| 770 return true; |
| 771 |
| 743 return false; | 772 return false; |
| 744 } | 773 } |
| 745 | 774 |
| 746 void SchedulerStateMachine::DidEnterBeginFrame(const BeginFrameArgs& args) { | 775 void SchedulerStateMachine::DidEnterBeginFrame(const BeginFrameArgs& args) { |
| 747 current_frame_number_++; | 776 current_frame_number_++; |
| 748 inside_begin_frame_ = true; | 777 inside_begin_frame_ = true; |
| 749 last_begin_frame_args_ = args; | 778 last_begin_frame_args_ = args; |
| 750 } | 779 } |
| 751 | 780 |
| 752 void SchedulerStateMachine::DidLeaveBeginFrame() { | 781 void SchedulerStateMachine::DidLeaveBeginFrame() { |
| 753 inside_begin_frame_ = false; | 782 inside_begin_frame_ = false; |
| 754 } | 783 } |
| 755 | 784 |
| 756 void SchedulerStateMachine::PollForAnticipatedDrawTriggers() { | 785 void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() { |
| 757 current_frame_number_++; | 786 current_frame_number_++; |
| 787 inside_poll_for_anticipated_draw_triggers_ = true; |
| 788 } |
| 789 |
| 790 void SchedulerStateMachine::DidLeavePollForAnticipatedDrawTriggers() { |
| 791 inside_poll_for_anticipated_draw_triggers_ = false; |
| 758 } | 792 } |
| 759 | 793 |
| 760 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } | 794 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } |
| 761 | 795 |
| 762 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } | 796 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } |
| 763 | 797 |
| 798 void SchedulerStateMachine::SetNeedsManageTiles() { |
| 799 needs_manage_tiles_ = true; |
| 800 } |
| 801 |
| 764 void SchedulerStateMachine::SetSwapUsedIncompleteTile( | 802 void SchedulerStateMachine::SetSwapUsedIncompleteTile( |
| 765 bool used_incomplete_tile) { | 803 bool used_incomplete_tile) { |
| 766 swap_used_incomplete_tile_ = used_incomplete_tile; | 804 swap_used_incomplete_tile_ = used_incomplete_tile; |
| 767 } | 805 } |
| 768 | 806 |
| 769 void SchedulerStateMachine::DidDrawIfPossibleCompleted(bool success) { | 807 void SchedulerStateMachine::DidDrawIfPossibleCompleted(bool success) { |
| 770 draw_if_possible_failed_ = !success; | 808 draw_if_possible_failed_ = !success; |
| 771 if (draw_if_possible_failed_) { | 809 if (draw_if_possible_failed_) { |
| 772 needs_redraw_ = true; | 810 needs_redraw_ = true; |
| 773 needs_commit_ = true; | 811 needs_commit_ = true; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 861 case OUTPUT_SURFACE_ACTIVE: | 899 case OUTPUT_SURFACE_ACTIVE: |
| 862 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: | 900 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: |
| 863 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: | 901 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: |
| 864 return true; | 902 return true; |
| 865 } | 903 } |
| 866 NOTREACHED(); | 904 NOTREACHED(); |
| 867 return false; | 905 return false; |
| 868 } | 906 } |
| 869 | 907 |
| 870 } // namespace cc | 908 } // namespace cc |
| OLD | NEW |