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 last_frame_number_where_manage_tiles_was_called_(-1), | |
26 consecutive_failed_draws_(0), | 27 consecutive_failed_draws_(0), |
27 needs_redraw_(false), | 28 needs_redraw_(false), |
29 needs_manage_tiles_(false), | |
28 swap_used_incomplete_tile_(false), | 30 swap_used_incomplete_tile_(false), |
29 needs_commit_(false), | 31 needs_commit_(false), |
30 main_thread_needs_layer_textures_(false), | 32 main_thread_needs_layer_textures_(false), |
31 inside_begin_frame_(false), | 33 inside_begin_frame_(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), |
(...skipping 101 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 16 matching lines...) Expand all Loading... | |
238 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const { | 243 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const { |
239 return current_frame_number_ == | 244 return current_frame_number_ == |
240 last_frame_number_where_update_visible_tiles_was_called_; | 245 last_frame_number_where_update_visible_tiles_was_called_; |
241 } | 246 } |
242 | 247 |
243 bool SchedulerStateMachine::HasSentBeginFrameToMainThreadThisFrame() const { | 248 bool SchedulerStateMachine::HasSentBeginFrameToMainThreadThisFrame() const { |
244 return current_frame_number_ == | 249 return current_frame_number_ == |
245 last_frame_number_where_begin_frame_sent_to_main_thread_; | 250 last_frame_number_where_begin_frame_sent_to_main_thread_; |
246 } | 251 } |
247 | 252 |
253 bool SchedulerStateMachine::HasScheduledManageTilesThisFrame() const { | |
254 return current_frame_number_ == | |
255 last_frame_number_where_manage_tiles_was_called_; | |
256 } | |
257 | |
248 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const { | 258 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const { |
249 // These are all the cases where we normally cannot or do not want to draw | 259 // These are all the cases where we normally cannot or do not want to draw |
250 // but, if needs_redraw_ is true and we do not draw to make forward progress, | 260 // but, if needs_redraw_ is true and we do not draw to make forward progress, |
251 // we might deadlock with the main thread. | 261 // we might deadlock with the main thread. |
252 // This should be a superset of PendingActivationsShouldBeForced() since | 262 // This should be a superset of PendingActivationsShouldBeForced() since |
253 // activation of the pending tree is blocked by drawing of the active tree and | 263 // activation of the pending tree is blocked by drawing of the active tree and |
254 // the main thread might be blocked on activation of the most recent commit. | 264 // the main thread might be blocked on activation of the most recent commit. |
255 if (PendingActivationsShouldBeForced()) | 265 if (PendingActivationsShouldBeForced()) |
256 return true; | 266 return true; |
257 | 267 |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
435 if (!HasInitializedOutputSurface()) | 445 if (!HasInitializedOutputSurface()) |
436 return false; | 446 return false; |
437 | 447 |
438 return true; | 448 return true; |
439 } | 449 } |
440 | 450 |
441 bool SchedulerStateMachine::ShouldCommit() const { | 451 bool SchedulerStateMachine::ShouldCommit() const { |
442 return commit_state_ == COMMIT_STATE_READY_TO_COMMIT; | 452 return commit_state_ == COMMIT_STATE_READY_TO_COMMIT; |
443 } | 453 } |
444 | 454 |
455 bool SchedulerStateMachine::ShouldManageTiles() const { | |
enne (OOO)
2013/09/13 00:47:01
I liked the previous version of this patch where i
epennerAtGoogle
2013/09/13 00:53:06
Good catch! I was only thinking of the two top lev
brianderson
2013/09/13 00:59:52
The issue with restricting it to occur only inside
| |
456 if (HasScheduledManageTilesThisFrame()) | |
457 return false; | |
458 return needs_manage_tiles_; | |
459 } | |
460 | |
445 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { | 461 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { |
446 if (ShouldAcquireLayerTexturesForMainThread()) | 462 if (ShouldAcquireLayerTexturesForMainThread()) |
447 return ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD; | 463 return ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD; |
448 if (ShouldUpdateVisibleTiles()) | 464 if (ShouldUpdateVisibleTiles()) |
449 return ACTION_UPDATE_VISIBLE_TILES; | 465 return ACTION_UPDATE_VISIBLE_TILES; |
450 if (ShouldActivatePendingTree()) | 466 if (ShouldActivatePendingTree()) |
451 return ACTION_ACTIVATE_PENDING_TREE; | 467 return ACTION_ACTIVATE_PENDING_TREE; |
452 if (ShouldCommit()) | 468 if (ShouldCommit()) |
453 return ACTION_COMMIT; | 469 return ACTION_COMMIT; |
454 if (ShouldDraw()) { | 470 if (ShouldDraw()) { |
455 if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) | 471 if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) |
456 return ACTION_DRAW_AND_READBACK; | 472 return ACTION_DRAW_AND_READBACK; |
457 else if (PendingDrawsShouldBeAborted()) | 473 else if (PendingDrawsShouldBeAborted()) |
458 return ACTION_DRAW_AND_SWAP_ABORT; | 474 return ACTION_DRAW_AND_SWAP_ABORT; |
459 else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) | 475 else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) |
460 return ACTION_DRAW_AND_SWAP_FORCED; | 476 return ACTION_DRAW_AND_SWAP_FORCED; |
461 else | 477 else |
462 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE; | 478 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE; |
463 } | 479 } |
480 if (ShouldManageTiles()) | |
481 return ACTION_MANAGE_TILES; | |
464 if (ShouldSendBeginFrameToMainThread()) | 482 if (ShouldSendBeginFrameToMainThread()) |
465 return ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD; | 483 return ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD; |
466 if (ShouldBeginOutputSurfaceCreation()) | 484 if (ShouldBeginOutputSurfaceCreation()) |
467 return ACTION_BEGIN_OUTPUT_SURFACE_CREATION; | 485 return ACTION_BEGIN_OUTPUT_SURFACE_CREATION; |
468 return ACTION_NONE; | 486 return ACTION_NONE; |
469 } | 487 } |
470 | 488 |
471 void SchedulerStateMachine::CheckInvariants() { | 489 void SchedulerStateMachine::CheckInvariants() { |
472 // We should never try to perform a draw for readback and forced draw due to | 490 // We should never try to perform a draw for readback and forced draw due to |
473 // timeout simultaneously. | 491 // timeout simultaneously. |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
529 // surface creation to avoid complicated corner cases. | 547 // surface creation to avoid complicated corner cases. |
530 DCHECK_EQ(commit_state_, COMMIT_STATE_IDLE); | 548 DCHECK_EQ(commit_state_, COMMIT_STATE_IDLE); |
531 DCHECK(!has_pending_tree_); | 549 DCHECK(!has_pending_tree_); |
532 DCHECK(!active_tree_needs_first_draw_); | 550 DCHECK(!active_tree_needs_first_draw_); |
533 return; | 551 return; |
534 | 552 |
535 case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: | 553 case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: |
536 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD; | 554 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD; |
537 main_thread_needs_layer_textures_ = false; | 555 main_thread_needs_layer_textures_ = false; |
538 return; | 556 return; |
557 | |
558 case ACTION_MANAGE_TILES: | |
559 UpdateStateOnManageTiles(); | |
560 return; | |
539 } | 561 } |
540 } | 562 } |
541 | 563 |
542 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { | 564 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { |
543 commit_count_++; | 565 commit_count_++; |
544 | 566 |
545 // If we are impl-side-painting but the commit was aborted, then we behave | 567 // 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. | 568 // 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; | 569 has_pending_tree_ = settings_.impl_side_painting && !commit_was_aborted; |
548 | 570 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
670 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED; | 692 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED; |
671 | 693 |
672 needs_redraw_ = false; | 694 needs_redraw_ = false; |
673 draw_if_possible_failed_ = false; | 695 draw_if_possible_failed_ = false; |
674 active_tree_needs_first_draw_ = false; | 696 active_tree_needs_first_draw_ = false; |
675 | 697 |
676 if (did_swap) | 698 if (did_swap) |
677 last_frame_number_swap_performed_ = current_frame_number_; | 699 last_frame_number_swap_performed_ = current_frame_number_; |
678 } | 700 } |
679 | 701 |
702 void SchedulerStateMachine::UpdateStateOnManageTiles() { | |
703 needs_manage_tiles_ = false; | |
704 last_frame_number_where_manage_tiles_was_called_ = | |
705 current_frame_number_; | |
706 } | |
707 | |
680 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() { | 708 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() { |
681 DCHECK(!main_thread_needs_layer_textures_); | 709 DCHECK(!main_thread_needs_layer_textures_); |
682 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD); | 710 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD); |
683 main_thread_needs_layer_textures_ = true; | 711 main_thread_needs_layer_textures_ = true; |
684 } | 712 } |
685 | 713 |
686 // These are the cases where we definitely (or almost definitely) have a | 714 // These are the cases where we definitely (or almost definitely) have a |
687 // new frame to draw and can draw. | 715 // new frame to draw and can draw. |
688 bool SchedulerStateMachine::BeginFrameNeededToDrawByImplThread() const { | 716 bool SchedulerStateMachine::BeginFrameNeededToDrawByImplThread() const { |
689 // The output surface is the provider of BeginFrames for the impl thread, | 717 // 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 | 761 // We should proactively request a BeginFrame if a commit is pending |
734 // because we will want to draw if the commit completes quickly. | 762 // because we will want to draw if the commit completes quickly. |
735 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE) | 763 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE) |
736 return true; | 764 return true; |
737 | 765 |
738 // If the pending tree activates quickly, we'll want a BeginFrame soon | 766 // If the pending tree activates quickly, we'll want a BeginFrame soon |
739 // to draw the new active tree. | 767 // to draw the new active tree. |
740 if (has_pending_tree_) | 768 if (has_pending_tree_) |
741 return true; | 769 return true; |
742 | 770 |
771 // Changing priorities may allow us to activate (given the new priorities), | |
772 // which may result in a new frame. | |
773 if (needs_manage_tiles_) | |
774 return true; | |
775 | |
743 return false; | 776 return false; |
744 } | 777 } |
745 | 778 |
746 void SchedulerStateMachine::DidEnterBeginFrame(const BeginFrameArgs& args) { | 779 void SchedulerStateMachine::DidEnterBeginFrame(const BeginFrameArgs& args) { |
747 current_frame_number_++; | 780 current_frame_number_++; |
748 inside_begin_frame_ = true; | 781 inside_begin_frame_ = true; |
749 last_begin_frame_args_ = args; | 782 last_begin_frame_args_ = args; |
750 } | 783 } |
751 | 784 |
752 void SchedulerStateMachine::DidLeaveBeginFrame() { | 785 void SchedulerStateMachine::DidLeaveBeginFrame() { |
753 inside_begin_frame_ = false; | 786 inside_begin_frame_ = false; |
754 } | 787 } |
755 | 788 |
756 void SchedulerStateMachine::PollForAnticipatedDrawTriggers() { | 789 void SchedulerStateMachine::PollForAnticipatedDrawTriggers() { |
757 current_frame_number_++; | 790 current_frame_number_++; |
758 } | 791 } |
759 | 792 |
760 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } | 793 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } |
761 | 794 |
762 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } | 795 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } |
763 | 796 |
797 void SchedulerStateMachine::SetNeedsManageTiles() { | |
798 needs_manage_tiles_ = true; | |
799 } | |
800 | |
764 void SchedulerStateMachine::SetSwapUsedIncompleteTile( | 801 void SchedulerStateMachine::SetSwapUsedIncompleteTile( |
765 bool used_incomplete_tile) { | 802 bool used_incomplete_tile) { |
766 swap_used_incomplete_tile_ = used_incomplete_tile; | 803 swap_used_incomplete_tile_ = used_incomplete_tile; |
767 } | 804 } |
768 | 805 |
769 void SchedulerStateMachine::DidDrawIfPossibleCompleted(bool success) { | 806 void SchedulerStateMachine::DidDrawIfPossibleCompleted(bool success) { |
770 draw_if_possible_failed_ = !success; | 807 draw_if_possible_failed_ = !success; |
771 if (draw_if_possible_failed_) { | 808 if (draw_if_possible_failed_) { |
772 needs_redraw_ = true; | 809 needs_redraw_ = true; |
773 needs_commit_ = true; | 810 needs_commit_ = true; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
861 case OUTPUT_SURFACE_ACTIVE: | 898 case OUTPUT_SURFACE_ACTIVE: |
862 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: | 899 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: |
863 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: | 900 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: |
864 return true; | 901 return true; |
865 } | 902 } |
866 NOTREACHED(); | 903 NOTREACHED(); |
867 return false; | 904 return false; |
868 } | 905 } |
869 | 906 |
870 } // namespace cc | 907 } // namespace cc |
OLD | NEW |