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.h" | 5 #include "cc/scheduler/scheduler.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/profiler/scoped_tracker.h" |
11 #include "base/single_thread_task_runner.h" | 12 #include "base/single_thread_task_runner.h" |
12 #include "base/trace_event/trace_event.h" | 13 #include "base/trace_event/trace_event.h" |
13 #include "base/trace_event/trace_event_argument.h" | 14 #include "base/trace_event/trace_event_argument.h" |
14 #include "cc/debug/devtools_instrumentation.h" | 15 #include "cc/debug/devtools_instrumentation.h" |
15 #include "cc/debug/traced_value.h" | 16 #include "cc/debug/traced_value.h" |
16 #include "cc/scheduler/delay_based_time_source.h" | 17 #include "cc/scheduler/delay_based_time_source.h" |
17 #include "ui/gfx/frame_time.h" | 18 #include "ui/gfx/frame_time.h" |
18 | 19 |
19 namespace cc { | 20 namespace cc { |
20 | 21 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 scheduler->unthrottled_frame_source_internal_ = | 72 scheduler->unthrottled_frame_source_internal_ = |
72 BackToBackBeginFrameSource::Create(scheduler->task_runner_.get()); | 73 BackToBackBeginFrameSource::Create(scheduler->task_runner_.get()); |
73 return scheduler->unthrottled_frame_source_internal_.get(); | 74 return scheduler->unthrottled_frame_source_internal_.get(); |
74 } | 75 } |
75 | 76 |
76 Scheduler::Scheduler( | 77 Scheduler::Scheduler( |
77 SchedulerClient* client, | 78 SchedulerClient* client, |
78 const SchedulerSettings& scheduler_settings, | 79 const SchedulerSettings& scheduler_settings, |
79 int layer_tree_host_id, | 80 int layer_tree_host_id, |
80 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 81 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
81 base::PowerMonitor* power_monitor, | |
82 scoped_ptr<BeginFrameSource> external_begin_frame_source, | 82 scoped_ptr<BeginFrameSource> external_begin_frame_source, |
83 SchedulerFrameSourcesConstructor* frame_sources_constructor) | 83 SchedulerFrameSourcesConstructor* frame_sources_constructor) |
84 : frame_source_(), | 84 : frame_source_(), |
85 primary_frame_source_(NULL), | 85 primary_frame_source_(NULL), |
86 background_frame_source_(NULL), | 86 background_frame_source_(NULL), |
87 primary_frame_source_internal_(external_begin_frame_source.Pass()), | 87 primary_frame_source_internal_(external_begin_frame_source.Pass()), |
88 background_frame_source_internal_(), | 88 background_frame_source_internal_(), |
89 vsync_observer_(NULL), | 89 vsync_observer_(NULL), |
90 throttle_frame_production_(scheduler_settings.throttle_frame_production), | 90 throttle_frame_production_(scheduler_settings.throttle_frame_production), |
91 settings_(scheduler_settings), | 91 settings_(scheduler_settings), |
92 client_(client), | 92 client_(client), |
93 layer_tree_host_id_(layer_tree_host_id), | 93 layer_tree_host_id_(layer_tree_host_id), |
94 task_runner_(task_runner), | 94 task_runner_(task_runner), |
95 power_monitor_(power_monitor), | |
96 state_machine_(scheduler_settings), | 95 state_machine_(scheduler_settings), |
97 inside_process_scheduled_actions_(false), | 96 inside_process_scheduled_actions_(false), |
98 inside_action_(SchedulerStateMachine::ACTION_NONE), | 97 inside_action_(SchedulerStateMachine::ACTION_NONE), |
99 weak_factory_(this) { | 98 weak_factory_(this) { |
100 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | 99 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), |
101 "Scheduler::Scheduler", | 100 "Scheduler::Scheduler", |
102 "settings", | 101 "settings", |
103 settings_.AsValue()); | 102 settings_.AsValue()); |
104 DCHECK(client_); | 103 DCHECK(client_); |
105 DCHECK(!state_machine_.BeginFrameNeeded()); | 104 DCHECK(!state_machine_.BeginFrameNeeded()); |
(...skipping 18 matching lines...) Expand all Loading... |
124 | 123 |
125 // Background ticking frame source | 124 // Background ticking frame source |
126 background_frame_source_ = | 125 background_frame_source_ = |
127 frame_sources_constructor->ConstructBackgroundFrameSource(this); | 126 frame_sources_constructor->ConstructBackgroundFrameSource(this); |
128 frame_source_->AddSource(background_frame_source_); | 127 frame_source_->AddSource(background_frame_source_); |
129 | 128 |
130 // Unthrottled frame source | 129 // Unthrottled frame source |
131 unthrottled_frame_source_ = | 130 unthrottled_frame_source_ = |
132 frame_sources_constructor->ConstructUnthrottledFrameSource(this); | 131 frame_sources_constructor->ConstructUnthrottledFrameSource(this); |
133 frame_source_->AddSource(unthrottled_frame_source_); | 132 frame_source_->AddSource(unthrottled_frame_source_); |
134 | |
135 SetupPowerMonitoring(); | |
136 } | 133 } |
137 | 134 |
138 Scheduler::~Scheduler() { | 135 Scheduler::~Scheduler() { |
139 TeardownPowerMonitoring(); | |
140 if (frame_source_->NeedsBeginFrames()) | 136 if (frame_source_->NeedsBeginFrames()) |
141 frame_source_->SetNeedsBeginFrames(false); | 137 frame_source_->SetNeedsBeginFrames(false); |
142 } | 138 } |
143 | 139 |
144 base::TimeTicks Scheduler::Now() const { | 140 base::TimeTicks Scheduler::Now() const { |
145 base::TimeTicks now = gfx::FrameTime::Now(); | 141 base::TimeTicks now = gfx::FrameTime::Now(); |
146 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.now"), | 142 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.now"), |
147 "Scheduler::Now", | 143 "Scheduler::Now", |
148 "now", | 144 "now", |
149 now); | 145 now); |
150 return now; | 146 return now; |
151 } | 147 } |
152 | 148 |
153 void Scheduler::SetupPowerMonitoring() { | |
154 if (settings_.disable_hi_res_timer_tasks_on_battery) { | |
155 DCHECK(power_monitor_); | |
156 power_monitor_->AddObserver(this); | |
157 state_machine_.SetImplLatencyTakesPriorityOnBattery( | |
158 power_monitor_->IsOnBatteryPower()); | |
159 } | |
160 } | |
161 | |
162 void Scheduler::TeardownPowerMonitoring() { | |
163 if (settings_.disable_hi_res_timer_tasks_on_battery) { | |
164 DCHECK(power_monitor_); | |
165 power_monitor_->RemoveObserver(this); | |
166 } | |
167 } | |
168 | |
169 void Scheduler::OnPowerStateChange(bool on_battery_power) { | |
170 DCHECK(settings_.disable_hi_res_timer_tasks_on_battery); | |
171 state_machine_.SetImplLatencyTakesPriorityOnBattery(on_battery_power); | |
172 } | |
173 | |
174 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase, | 149 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase, |
175 base::TimeDelta interval) { | 150 base::TimeDelta interval) { |
176 // TODO(brianderson): We should not be receiving 0 intervals. | 151 // TODO(brianderson): We should not be receiving 0 intervals. |
177 if (interval == base::TimeDelta()) | 152 if (interval == base::TimeDelta()) |
178 interval = BeginFrameArgs::DefaultInterval(); | 153 interval = BeginFrameArgs::DefaultInterval(); |
179 | 154 |
180 if (vsync_observer_) | 155 if (vsync_observer_) |
181 vsync_observer_->OnUpdateVSyncParameters(timebase, interval); | 156 vsync_observer_->OnUpdateVSyncParameters(timebase, interval); |
182 } | 157 } |
183 | 158 |
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
640 void Scheduler::OnBeginImplFrameDeadline() { | 615 void Scheduler::OnBeginImplFrameDeadline() { |
641 TRACE_EVENT0("cc,benchmark", "Scheduler::OnBeginImplFrameDeadline"); | 616 TRACE_EVENT0("cc,benchmark", "Scheduler::OnBeginImplFrameDeadline"); |
642 begin_impl_frame_deadline_task_.Cancel(); | 617 begin_impl_frame_deadline_task_.Cancel(); |
643 // We split the deadline actions up into two phases so the state machine | 618 // We split the deadline actions up into two phases so the state machine |
644 // has a chance to trigger actions that should occur durring and after | 619 // has a chance to trigger actions that should occur durring and after |
645 // the deadline separately. For example: | 620 // the deadline separately. For example: |
646 // * Sending the BeginMainFrame will not occur after the deadline in | 621 // * Sending the BeginMainFrame will not occur after the deadline in |
647 // order to wait for more user-input before starting the next commit. | 622 // order to wait for more user-input before starting the next commit. |
648 // * Creating a new OuputSurface will not occur during the deadline in | 623 // * Creating a new OuputSurface will not occur during the deadline in |
649 // order to allow the state machine to "settle" first. | 624 // order to allow the state machine to "settle" first. |
| 625 |
| 626 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is fixed. |
| 627 tracked_objects::ScopedTracker tracking_profile1( |
| 628 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 629 "461509 Scheduler::OnBeginImplFrameDeadline1")); |
650 state_machine_.OnBeginImplFrameDeadline(); | 630 state_machine_.OnBeginImplFrameDeadline(); |
651 ProcessScheduledActions(); | 631 ProcessScheduledActions(); |
| 632 |
| 633 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is fixed. |
| 634 tracked_objects::ScopedTracker tracking_profile2( |
| 635 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 636 "461509 Scheduler::OnBeginImplFrameDeadline2")); |
652 state_machine_.OnBeginImplFrameIdle(); | 637 state_machine_.OnBeginImplFrameIdle(); |
653 ProcessScheduledActions(); | 638 ProcessScheduledActions(); |
654 | 639 |
| 640 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is fixed. |
| 641 tracked_objects::ScopedTracker tracking_profile3( |
| 642 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 643 "461509 Scheduler::OnBeginImplFrameDeadline3")); |
655 client_->DidBeginImplFrameDeadline(); | 644 client_->DidBeginImplFrameDeadline(); |
656 } | 645 } |
657 | 646 |
658 void Scheduler::PollForAnticipatedDrawTriggers() { | 647 void Scheduler::PollForAnticipatedDrawTriggers() { |
659 TRACE_EVENT0("cc", "Scheduler::PollForAnticipatedDrawTriggers"); | 648 TRACE_EVENT0("cc", "Scheduler::PollForAnticipatedDrawTriggers"); |
660 poll_for_draw_triggers_task_.Cancel(); | 649 poll_for_draw_triggers_task_.Cancel(); |
661 state_machine_.DidEnterPollForAnticipatedDrawTriggers(); | 650 state_machine_.DidEnterPollForAnticipatedDrawTriggers(); |
662 ProcessScheduledActions(); | 651 ProcessScheduledActions(); |
663 state_machine_.DidLeavePollForAnticipatedDrawTriggers(); | 652 state_machine_.DidLeavePollForAnticipatedDrawTriggers(); |
664 } | 653 } |
(...skipping 20 matching lines...) Expand all Loading... |
685 void Scheduler::ProcessScheduledActions() { | 674 void Scheduler::ProcessScheduledActions() { |
686 // We do not allow ProcessScheduledActions to be recursive. | 675 // We do not allow ProcessScheduledActions to be recursive. |
687 // The top-level call will iteratively execute the next action for us anyway. | 676 // The top-level call will iteratively execute the next action for us anyway. |
688 if (inside_process_scheduled_actions_) | 677 if (inside_process_scheduled_actions_) |
689 return; | 678 return; |
690 | 679 |
691 base::AutoReset<bool> mark_inside(&inside_process_scheduled_actions_, true); | 680 base::AutoReset<bool> mark_inside(&inside_process_scheduled_actions_, true); |
692 | 681 |
693 SchedulerStateMachine::Action action; | 682 SchedulerStateMachine::Action action; |
694 do { | 683 do { |
| 684 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is fixed. |
| 685 tracked_objects::ScopedTracker tracking_profile1( |
| 686 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 687 "461509 Scheduler::ProcessScheduledActions1")); |
695 action = state_machine_.NextAction(); | 688 action = state_machine_.NextAction(); |
696 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | 689 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), |
697 "SchedulerStateMachine", | 690 "SchedulerStateMachine", |
698 "state", | 691 "state", |
699 AsValue()); | 692 AsValue()); |
700 VLOG(2) << "Scheduler::ProcessScheduledActions: " | 693 VLOG(2) << "Scheduler::ProcessScheduledActions: " |
701 << SchedulerStateMachine::ActionToString(action) << " " | 694 << SchedulerStateMachine::ActionToString(action) << " " |
702 << state_machine_.GetStatesForDebugging(); | 695 << state_machine_.GetStatesForDebugging(); |
703 state_machine_.UpdateState(action); | 696 state_machine_.UpdateState(action); |
704 base::AutoReset<SchedulerStateMachine::Action> | 697 base::AutoReset<SchedulerStateMachine::Action> |
705 mark_inside_action(&inside_action_, action); | 698 mark_inside_action(&inside_action_, action); |
706 switch (action) { | 699 switch (action) { |
707 case SchedulerStateMachine::ACTION_NONE: | 700 case SchedulerStateMachine::ACTION_NONE: |
708 break; | 701 break; |
709 case SchedulerStateMachine::ACTION_ANIMATE: | 702 case SchedulerStateMachine::ACTION_ANIMATE: { |
| 703 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is |
| 704 // fixed. |
| 705 tracked_objects::ScopedTracker tracking_profile2( |
| 706 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 707 "461509 Scheduler::ProcessScheduledActions2")); |
710 client_->ScheduledActionAnimate(); | 708 client_->ScheduledActionAnimate(); |
711 break; | 709 break; |
712 case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME: | 710 } |
| 711 case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME: { |
| 712 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is |
| 713 // fixed. |
| 714 tracked_objects::ScopedTracker tracking_profile3( |
| 715 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 716 "461509 Scheduler::ProcessScheduledActions3")); |
713 client_->ScheduledActionSendBeginMainFrame(); | 717 client_->ScheduledActionSendBeginMainFrame(); |
714 break; | 718 break; |
715 case SchedulerStateMachine::ACTION_COMMIT: | 719 } |
| 720 case SchedulerStateMachine::ACTION_COMMIT: { |
| 721 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is |
| 722 // fixed. |
| 723 tracked_objects::ScopedTracker tracking_profile4( |
| 724 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 725 "461509 Scheduler::ProcessScheduledActions4")); |
716 client_->ScheduledActionCommit(); | 726 client_->ScheduledActionCommit(); |
717 break; | 727 break; |
718 case SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE: | 728 } |
| 729 case SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE: { |
| 730 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is |
| 731 // fixed. |
| 732 tracked_objects::ScopedTracker tracking_profile5( |
| 733 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 734 "461509 Scheduler::ProcessScheduledActions5")); |
719 client_->ScheduledActionActivateSyncTree(); | 735 client_->ScheduledActionActivateSyncTree(); |
720 break; | 736 break; |
721 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE: | 737 } |
| 738 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE: { |
| 739 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is |
| 740 // fixed. |
| 741 tracked_objects::ScopedTracker tracking_profile6( |
| 742 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 743 "461509 Scheduler::ProcessScheduledActions6")); |
722 DrawAndSwapIfPossible(); | 744 DrawAndSwapIfPossible(); |
723 break; | 745 break; |
724 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED: | 746 } |
| 747 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED: { |
| 748 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is |
| 749 // fixed. |
| 750 tracked_objects::ScopedTracker tracking_profile7( |
| 751 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 752 "461509 Scheduler::ProcessScheduledActions7")); |
725 client_->ScheduledActionDrawAndSwapForced(); | 753 client_->ScheduledActionDrawAndSwapForced(); |
726 break; | 754 break; |
| 755 } |
727 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT: | 756 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT: |
728 // No action is actually performed, but this allows the state machine to | 757 // No action is actually performed, but this allows the state machine to |
729 // advance out of its waiting to draw state without actually drawing. | 758 // advance out of its waiting to draw state without actually drawing. |
730 break; | 759 break; |
731 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION: | 760 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION: { |
| 761 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is |
| 762 // fixed. |
| 763 tracked_objects::ScopedTracker tracking_profile8( |
| 764 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 765 "461509 Scheduler::ProcessScheduledActions8")); |
732 client_->ScheduledActionBeginOutputSurfaceCreation(); | 766 client_->ScheduledActionBeginOutputSurfaceCreation(); |
733 break; | 767 break; |
734 case SchedulerStateMachine::ACTION_PREPARE_TILES: | 768 } |
| 769 case SchedulerStateMachine::ACTION_PREPARE_TILES: { |
| 770 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is |
| 771 // fixed. |
| 772 tracked_objects::ScopedTracker tracking_profile9( |
| 773 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 774 "461509 Scheduler::ProcessScheduledActions9")); |
735 client_->ScheduledActionPrepareTiles(); | 775 client_->ScheduledActionPrepareTiles(); |
736 break; | 776 break; |
| 777 } |
737 } | 778 } |
738 } while (action != SchedulerStateMachine::ACTION_NONE); | 779 } while (action != SchedulerStateMachine::ACTION_NONE); |
739 | 780 |
| 781 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is fixed. |
| 782 tracked_objects::ScopedTracker tracking_profile10( |
| 783 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 784 "461509 Scheduler::ProcessScheduledActions10")); |
740 SetupNextBeginFrameIfNeeded(); | 785 SetupNextBeginFrameIfNeeded(); |
741 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime()); | 786 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime()); |
742 | 787 |
| 788 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is fixed. |
| 789 tracked_objects::ScopedTracker tracking_profile11( |
| 790 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 791 "461509 Scheduler::ProcessScheduledActions11")); |
743 RescheduleBeginImplFrameDeadlineIfNeeded(); | 792 RescheduleBeginImplFrameDeadlineIfNeeded(); |
744 } | 793 } |
745 | 794 |
746 scoped_refptr<base::trace_event::ConvertableToTraceFormat> Scheduler::AsValue() | 795 scoped_refptr<base::trace_event::ConvertableToTraceFormat> Scheduler::AsValue() |
747 const { | 796 const { |
748 scoped_refptr<base::trace_event::TracedValue> state = | 797 scoped_refptr<base::trace_event::TracedValue> state = |
749 new base::trace_event::TracedValue(); | 798 new base::trace_event::TracedValue(); |
750 AsValueInto(state.get()); | 799 AsValueInto(state.get()); |
751 return state; | 800 return state; |
752 } | 801 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 } | 870 } |
822 | 871 |
823 bool Scheduler::IsBeginMainFrameSentOrStarted() const { | 872 bool Scheduler::IsBeginMainFrameSentOrStarted() const { |
824 return (state_machine_.commit_state() == | 873 return (state_machine_.commit_state() == |
825 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || | 874 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || |
826 state_machine_.commit_state() == | 875 state_machine_.commit_state() == |
827 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); | 876 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); |
828 } | 877 } |
829 | 878 |
830 } // namespace cc | 879 } // namespace cc |
OLD | NEW |