| 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/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
| 8 #include "base/debug/trace_event_argument.h" | 8 #include "base/debug/trace_event_argument.h" |
| 9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 } | 689 } |
| 690 | 690 |
| 691 bool SchedulerStateMachine::BeginFrameNeededForChildren() const { | 691 bool SchedulerStateMachine::BeginFrameNeededForChildren() const { |
| 692 if (HasInitializedOutputSurface()) | 692 if (HasInitializedOutputSurface()) |
| 693 return children_need_begin_frames_; | 693 return children_need_begin_frames_; |
| 694 | 694 |
| 695 return false; | 695 return false; |
| 696 } | 696 } |
| 697 | 697 |
| 698 bool SchedulerStateMachine::BeginFrameNeeded() const { | 698 bool SchedulerStateMachine::BeginFrameNeeded() const { |
| 699 // We can't handle BeginFrames when output surface isn't initialized. |
| 700 // TODO(brianderson): Support output surface creation inside a BeginFrame. |
| 701 if (!HasInitializedOutputSurface()) |
| 702 return false; |
| 703 |
| 699 if (SupportsProactiveBeginFrame()) { | 704 if (SupportsProactiveBeginFrame()) { |
| 700 return (BeginFrameNeededToAnimateOrDraw() || | 705 return (BeginFrameNeededToAnimateOrDraw() || |
| 701 BeginFrameNeededForChildren() || | 706 BeginFrameNeededForChildren() || |
| 702 ProactiveBeginFrameWanted()); | 707 ProactiveBeginFrameWanted()); |
| 703 } | 708 } |
| 704 | 709 |
| 705 // Proactive BeginFrames are bad for the synchronous compositor because we | 710 // Proactive BeginFrames are bad for the synchronous compositor because we |
| 706 // have to draw when we get the BeginFrame and could end up drawing many | 711 // have to draw when we get the BeginFrame and could end up drawing many |
| 707 // duplicate frames if our new frame isn't ready in time. | 712 // duplicate frames if our new frame isn't ready in time. |
| 708 // To poll for state with the synchronous compositor without having to draw, | 713 // To poll for state with the synchronous compositor without having to draw, |
| 709 // we rely on ShouldPollForAnticipatedDrawTriggers instead. | 714 // we rely on ShouldPollForAnticipatedDrawTriggers instead. |
| 710 // Synchronous compositor doesn't have a browser. | 715 // Synchronous compositor doesn't have a browser. |
| 711 DCHECK(!children_need_begin_frames_); | 716 DCHECK(!children_need_begin_frames_); |
| 712 return BeginFrameNeededToAnimateOrDraw(); | 717 return BeginFrameNeededToAnimateOrDraw(); |
| 713 } | 718 } |
| 714 | 719 |
| 720 bool SchedulerStateMachine::ShouldSetNeedsBeginFrames( |
| 721 bool frame_source_needs_begin_frames) const { |
| 722 bool needs_begin_frame = BeginFrameNeeded(); |
| 723 |
| 724 // Never call SetNeedsBeginFrames if the frame source has the right value. |
| 725 if (needs_begin_frame == frame_source_needs_begin_frames) |
| 726 return false; |
| 727 |
| 728 // Always request the BeginFrame immediately if it's needed. |
| 729 if (needs_begin_frame) |
| 730 return true; |
| 731 |
| 732 // Stop requesting BeginFrames after a deadline. |
| 733 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) |
| 734 return true; |
| 735 |
| 736 // Stop requesting BeginFrames immediately when output surface is lost. |
| 737 if (!HasInitializedOutputSurface()) |
| 738 return true; |
| 739 |
| 740 return false; |
| 741 } |
| 742 |
| 715 bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const { | 743 bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const { |
| 716 // ShouldPollForAnticipatedDrawTriggers is what we use in place of | 744 // ShouldPollForAnticipatedDrawTriggers is what we use in place of |
| 717 // ProactiveBeginFrameWanted when we are using the synchronous | 745 // ProactiveBeginFrameWanted when we are using the synchronous |
| 718 // compositor. | 746 // compositor. |
| 719 if (!SupportsProactiveBeginFrame()) { | 747 if (!SupportsProactiveBeginFrame()) { |
| 720 return !BeginFrameNeededToAnimateOrDraw() && ProactiveBeginFrameWanted(); | 748 return !BeginFrameNeededToAnimateOrDraw() && ProactiveBeginFrameWanted(); |
| 721 } | 749 } |
| 722 | 750 |
| 723 // Non synchronous compositors should rely on | 751 // Non synchronous compositors should rely on |
| 724 // ProactiveBeginFrameWanted to poll for state instead. | 752 // ProactiveBeginFrameWanted to poll for state instead. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 737 | 765 |
| 738 void SchedulerStateMachine::SetChildrenNeedBeginFrames( | 766 void SchedulerStateMachine::SetChildrenNeedBeginFrames( |
| 739 bool children_need_begin_frames) { | 767 bool children_need_begin_frames) { |
| 740 DCHECK(settings_.forward_begin_frames_to_children); | 768 DCHECK(settings_.forward_begin_frames_to_children); |
| 741 children_need_begin_frames_ = children_need_begin_frames; | 769 children_need_begin_frames_ = children_need_begin_frames; |
| 742 } | 770 } |
| 743 | 771 |
| 744 // These are the cases where we definitely (or almost definitely) have a | 772 // These are the cases where we definitely (or almost definitely) have a |
| 745 // new frame to animate and/or draw and can draw. | 773 // new frame to animate and/or draw and can draw. |
| 746 bool SchedulerStateMachine::BeginFrameNeededToAnimateOrDraw() const { | 774 bool SchedulerStateMachine::BeginFrameNeededToAnimateOrDraw() const { |
| 747 // The output surface is the provider of BeginImplFrames, so we are not going | |
| 748 // to get them even if we ask for them. | |
| 749 if (!HasInitializedOutputSurface()) | |
| 750 return false; | |
| 751 | |
| 752 // The forced draw respects our normal draw scheduling, so we need to | 775 // The forced draw respects our normal draw scheduling, so we need to |
| 753 // request a BeginImplFrame for it. | 776 // request a BeginImplFrame for it. |
| 754 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) | 777 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) |
| 755 return true; | 778 return true; |
| 756 | 779 |
| 757 return needs_animate_ || needs_redraw_; | 780 return needs_animate_ || needs_redraw_; |
| 758 } | 781 } |
| 759 | 782 |
| 760 // These are cases where we are very likely to draw soon, but might not | 783 // These are cases where we are very likely to draw soon, but might not |
| 761 // actually have a new frame to draw when we receive the next BeginImplFrame. | 784 // actually have a new frame to draw when we receive the next BeginImplFrame. |
| 762 // Proactively requesting the BeginImplFrame helps hide the round trip latency | 785 // Proactively requesting the BeginImplFrame helps hide the round trip latency |
| 763 // of the SetNeedsBeginFrame request that has to go to the Browser. | 786 // of the SetNeedsBeginFrame request that has to go to the Browser. |
| 764 bool SchedulerStateMachine::ProactiveBeginFrameWanted() const { | 787 bool SchedulerStateMachine::ProactiveBeginFrameWanted() const { |
| 765 // The output surface is the provider of BeginImplFrames, | |
| 766 // so we are not going to get them even if we ask for them. | |
| 767 if (!HasInitializedOutputSurface()) | |
| 768 return false; | |
| 769 | |
| 770 // Do not be proactive when invisible. | 788 // Do not be proactive when invisible. |
| 771 if (!visible_) | 789 if (!visible_) |
| 772 return false; | 790 return false; |
| 773 | 791 |
| 774 // We should proactively request a BeginImplFrame if a commit is pending | 792 // We should proactively request a BeginImplFrame if a commit is pending |
| 775 // because we will want to draw if the commit completes quickly. | 793 // because we will want to draw if the commit completes quickly. |
| 776 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE) | 794 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE) |
| 777 return true; | 795 return true; |
| 778 | 796 |
| 779 // If the pending tree activates quickly, we'll want a BeginImplFrame soon | 797 // If the pending tree activates quickly, we'll want a BeginImplFrame soon |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1103 static_cast<int>(begin_impl_frame_state_), | 1121 static_cast<int>(begin_impl_frame_state_), |
| 1104 static_cast<int>(commit_state_), | 1122 static_cast<int>(commit_state_), |
| 1105 has_pending_tree_ ? 'T' : 'F', | 1123 has_pending_tree_ ? 'T' : 'F', |
| 1106 pending_tree_is_ready_for_activation_ ? 'T' : 'F', | 1124 pending_tree_is_ready_for_activation_ ? 'T' : 'F', |
| 1107 active_tree_needs_first_draw_ ? 'T' : 'F', | 1125 active_tree_needs_first_draw_ ? 'T' : 'F', |
| 1108 max_pending_swaps_, | 1126 max_pending_swaps_, |
| 1109 pending_swaps_); | 1127 pending_swaps_); |
| 1110 } | 1128 } |
| 1111 | 1129 |
| 1112 } // namespace cc | 1130 } // namespace cc |
| OLD | NEW |