OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/scheduler/renderer/renderer_scheduler_impl.h" | 5 #include "components/scheduler/renderer/renderer_scheduler_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/debug/stack_trace.h" | 8 #include "base/debug/stack_trace.h" |
9 #include "base/trace_event/trace_event.h" | 9 #include "base/trace_event/trace_event.h" |
10 #include "base/trace_event/trace_event_argument.h" | 10 #include "base/trace_event/trace_event_argument.h" |
(...skipping 21 matching lines...) Expand all Loading... | |
32 idle_helper_(&helper_, | 32 idle_helper_(&helper_, |
33 this, | 33 this, |
34 "renderer.scheduler", | 34 "renderer.scheduler", |
35 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 35 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
36 "RendererSchedulerIdlePeriod", | 36 "RendererSchedulerIdlePeriod", |
37 base::TimeDelta()), | 37 base::TimeDelta()), |
38 control_task_runner_(helper_.ControlTaskRunner()), | 38 control_task_runner_(helper_.ControlTaskRunner()), |
39 compositor_task_runner_( | 39 compositor_task_runner_( |
40 helper_.NewTaskQueue(TaskQueue::Spec("compositor_tq") | 40 helper_.NewTaskQueue(TaskQueue::Spec("compositor_tq") |
41 .SetShouldMonitorQuiescence(true))), | 41 .SetShouldMonitorQuiescence(true))), |
42 loading_task_runner_( | |
43 helper_.NewTaskQueue(TaskQueue::Spec("loading_tq") | |
44 .SetShouldMonitorQuiescence(true))), | |
45 timer_task_runner_( | |
46 helper_.NewTaskQueue(TaskQueue::Spec("timer_tq") | |
47 .SetShouldMonitorQuiescence(true))), | |
48 delayed_update_policy_runner_( | 42 delayed_update_policy_runner_( |
49 base::Bind(&RendererSchedulerImpl::UpdatePolicy, | 43 base::Bind(&RendererSchedulerImpl::UpdatePolicy, |
50 base::Unretained(this)), | 44 base::Unretained(this)), |
51 helper_.ControlTaskRunner()), | 45 helper_.ControlTaskRunner()), |
52 policy_may_need_update_(&any_thread_lock_), | 46 policy_may_need_update_(&any_thread_lock_), |
53 weak_factory_(this) { | 47 weak_factory_(this) { |
54 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, | 48 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, |
55 weak_factory_.GetWeakPtr()); | 49 weak_factory_.GetWeakPtr()); |
56 end_renderer_hidden_idle_period_closure_.Reset(base::Bind( | 50 end_renderer_hidden_idle_period_closure_.Reset(base::Bind( |
57 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr())); | 51 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr())); |
58 | 52 |
59 suspend_timers_when_backgrounded_closure_.Reset( | 53 suspend_timers_when_backgrounded_closure_.Reset( |
60 base::Bind(&RendererSchedulerImpl::SuspendTimerQueueWhenBackgrounded, | 54 base::Bind(&RendererSchedulerImpl::SuspendTimerQueueWhenBackgrounded, |
61 weak_factory_.GetWeakPtr())); | 55 weak_factory_.GetWeakPtr())); |
62 | 56 |
63 loading_task_runner_->AddTaskObserver( | 57 default_loading_task_runner_ = NewLoadingTaskRunner("loading_tq"); |
rmcilroy
2015/09/18 13:15:46
nit - "default_loading_tq" and same for timer_tq b
Sami
2015/09/21 10:52:36
Good idea, done.
| |
64 &MainThreadOnly().loading_task_cost_estimator); | 58 default_timer_task_runner_ = NewTimerTaskRunner("timer_tq"); |
65 | |
66 timer_task_runner_->AddTaskObserver( | |
67 &MainThreadOnly().timer_task_cost_estimator); | |
68 | 59 |
69 TRACE_EVENT_OBJECT_CREATED_WITH_ID( | 60 TRACE_EVENT_OBJECT_CREATED_WITH_ID( |
70 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", | 61 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", |
71 this); | 62 this); |
72 | 63 |
73 // Make sure that we don't initially assume there is no idle time. | 64 // Make sure that we don't initially assume there is no idle time. |
74 MainThreadOnly().short_idle_period_duration.InsertSample( | 65 MainThreadOnly().short_idle_period_duration.InsertSample( |
75 cc::BeginFrameArgs::DefaultInterval()); | 66 cc::BeginFrameArgs::DefaultInterval()); |
67 | |
68 helper_.SetObserver(this); | |
76 } | 69 } |
77 | 70 |
78 RendererSchedulerImpl::~RendererSchedulerImpl() { | 71 RendererSchedulerImpl::~RendererSchedulerImpl() { |
79 TRACE_EVENT_OBJECT_DELETED_WITH_ID( | 72 TRACE_EVENT_OBJECT_DELETED_WITH_ID( |
80 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", | 73 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", |
81 this); | 74 this); |
82 timer_task_runner_->RemoveTaskObserver( | 75 |
83 &MainThreadOnly().timer_task_cost_estimator); | 76 for (const scoped_refptr<TaskQueue>& loading_queue : loading_task_runners_) { |
84 loading_task_runner_->RemoveTaskObserver( | 77 loading_queue->RemoveTaskObserver( |
85 &MainThreadOnly().loading_task_cost_estimator); | 78 &MainThreadOnly().loading_task_cost_estimator); |
79 } | |
80 for (const scoped_refptr<TaskQueue>& timer_queue : timer_task_runners_) { | |
81 timer_queue->RemoveTaskObserver( | |
82 &MainThreadOnly().timer_task_cost_estimator); | |
83 } | |
84 | |
86 // Ensure the renderer scheduler was shut down explicitly, because otherwise | 85 // Ensure the renderer scheduler was shut down explicitly, because otherwise |
87 // we could end up having stale pointers to the Blink heap which has been | 86 // we could end up having stale pointers to the Blink heap which has been |
88 // terminated by this point. | 87 // terminated by this point. |
89 DCHECK(MainThreadOnly().was_shutdown); | 88 DCHECK(MainThreadOnly().was_shutdown); |
90 } | 89 } |
91 | 90 |
92 RendererSchedulerImpl::Policy::Policy() | 91 RendererSchedulerImpl::Policy::Policy() |
93 : compositor_queue_priority(TaskQueue::NORMAL_PRIORITY), | 92 : compositor_queue_priority(TaskQueue::NORMAL_PRIORITY), |
94 loading_queue_priority(TaskQueue::NORMAL_PRIORITY), | 93 loading_queue_priority(TaskQueue::NORMAL_PRIORITY), |
95 timer_queue_priority(TaskQueue::NORMAL_PRIORITY), | 94 timer_queue_priority(TaskQueue::NORMAL_PRIORITY), |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
142 } | 141 } |
143 | 142 |
144 scoped_refptr<SingleThreadIdleTaskRunner> | 143 scoped_refptr<SingleThreadIdleTaskRunner> |
145 RendererSchedulerImpl::IdleTaskRunner() { | 144 RendererSchedulerImpl::IdleTaskRunner() { |
146 return idle_helper_.IdleTaskRunner(); | 145 return idle_helper_.IdleTaskRunner(); |
147 } | 146 } |
148 | 147 |
149 scoped_refptr<base::SingleThreadTaskRunner> | 148 scoped_refptr<base::SingleThreadTaskRunner> |
150 RendererSchedulerImpl::LoadingTaskRunner() { | 149 RendererSchedulerImpl::LoadingTaskRunner() { |
151 helper_.CheckOnValidThread(); | 150 helper_.CheckOnValidThread(); |
152 return loading_task_runner_; | 151 return default_loading_task_runner_; |
153 } | 152 } |
154 | 153 |
155 scoped_refptr<TaskQueue> RendererSchedulerImpl::TimerTaskRunner() { | 154 scoped_refptr<TaskQueue> RendererSchedulerImpl::TimerTaskRunner() { |
156 helper_.CheckOnValidThread(); | 155 helper_.CheckOnValidThread(); |
157 return timer_task_runner_; | 156 return default_timer_task_runner_; |
157 } | |
158 | |
159 scoped_refptr<TaskQueue> RendererSchedulerImpl::NewLoadingTaskRunner( | |
160 const char* name) { | |
161 helper_.CheckOnValidThread(); | |
162 scoped_refptr<TaskQueue> loading_task_queue(helper_.NewTaskQueue( | |
163 TaskQueue::Spec(name).SetShouldMonitorQuiescence(true))); | |
164 loading_task_runners_.insert(loading_task_queue); | |
165 loading_task_queue->SetQueuePriority( | |
166 MainThreadOnly().current_policy.loading_queue_priority); | |
167 loading_task_queue->AddTaskObserver( | |
168 &MainThreadOnly().loading_task_cost_estimator); | |
169 return loading_task_queue; | |
170 } | |
171 | |
172 scoped_refptr<TaskQueue> RendererSchedulerImpl::NewTimerTaskRunner( | |
173 const char* name) { | |
174 helper_.CheckOnValidThread(); | |
175 scoped_refptr<TaskQueue> timer_task_queue(helper_.NewTaskQueue( | |
176 TaskQueue::Spec(name).SetShouldMonitorQuiescence(true))); | |
177 timer_task_runners_.insert(timer_task_queue); | |
178 timer_task_queue->SetQueuePriority( | |
179 MainThreadOnly().current_policy.timer_queue_priority); | |
180 timer_task_queue->AddTaskObserver( | |
181 &MainThreadOnly().timer_task_cost_estimator); | |
182 return timer_task_queue; | |
183 } | |
184 | |
185 void RendererSchedulerImpl::OnUnregisterTaskQueue( | |
186 const scoped_refptr<TaskQueue>& task_queue) { | |
187 if (loading_task_runners_.find(task_queue) != loading_task_runners_.end()) { | |
188 task_queue->RemoveTaskObserver( | |
189 &MainThreadOnly().loading_task_cost_estimator); | |
190 loading_task_runners_.erase(task_queue); | |
191 } else if (timer_task_runners_.find(task_queue) != | |
192 timer_task_runners_.end()) { | |
193 task_queue->RemoveTaskObserver(&MainThreadOnly().timer_task_cost_estimator); | |
194 timer_task_runners_.erase(task_queue); | |
195 } | |
rmcilroy
2015/09/18 13:15:46
Should we DCHECK that we find it in one or the oth
Sami
2015/09/21 10:52:36
I had exactly the same thought first, but the prob
rmcilroy
2015/09/23 09:44:25
Acknowledged.
| |
158 } | 196 } |
159 | 197 |
160 bool RendererSchedulerImpl::CanExceedIdleDeadlineIfRequired() const { | 198 bool RendererSchedulerImpl::CanExceedIdleDeadlineIfRequired() const { |
161 return idle_helper_.CanExceedIdleDeadlineIfRequired(); | 199 return idle_helper_.CanExceedIdleDeadlineIfRequired(); |
162 } | 200 } |
163 | 201 |
164 void RendererSchedulerImpl::AddTaskObserver( | 202 void RendererSchedulerImpl::AddTaskObserver( |
165 base::MessageLoop::TaskObserver* task_observer) { | 203 base::MessageLoop::TaskObserver* task_observer) { |
166 helper_.AddTaskObserver(task_observer); | 204 helper_.AddTaskObserver(task_observer); |
167 } | 205 } |
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
616 "RendererScheduler.timer_tasks_seem_expensive", | 654 "RendererScheduler.timer_tasks_seem_expensive", |
617 MainThreadOnly().timer_tasks_seem_expensive); | 655 MainThreadOnly().timer_tasks_seem_expensive); |
618 | 656 |
619 if (update_type == UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED && | 657 if (update_type == UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED && |
620 new_policy == MainThreadOnly().current_policy) { | 658 new_policy == MainThreadOnly().current_policy) { |
621 return; | 659 return; |
622 } | 660 } |
623 | 661 |
624 compositor_task_runner_->SetQueuePriority( | 662 compositor_task_runner_->SetQueuePriority( |
625 new_policy.compositor_queue_priority); | 663 new_policy.compositor_queue_priority); |
626 loading_task_runner_->SetQueuePriority(new_policy.loading_queue_priority); | 664 for (const scoped_refptr<TaskQueue>& loading_queue : loading_task_runners_) { |
627 timer_task_runner_->SetQueuePriority(new_policy.timer_queue_priority); | 665 loading_queue->SetQueuePriority(new_policy.loading_queue_priority); |
666 } | |
667 for (const scoped_refptr<TaskQueue>& timer_queue : timer_task_runners_) { | |
668 timer_queue->SetQueuePriority(new_policy.timer_queue_priority); | |
669 } | |
628 | 670 |
629 // TODO(alexclarke): We shouldn't have to prioritize the default queue, but it | 671 // TODO(alexclarke): We shouldn't have to prioritize the default queue, but it |
630 // appears to be necessary since the order of loading tasks and IPCs (which | 672 // appears to be necessary since the order of loading tasks and IPCs (which |
631 // are mostly dispatched on the default queue) need to be preserved. | 673 // are mostly dispatched on the default queue) need to be preserved. |
632 helper_.DefaultTaskRunner()->SetQueuePriority( | 674 helper_.DefaultTaskRunner()->SetQueuePriority( |
633 new_policy.default_queue_priority); | 675 new_policy.default_queue_priority); |
634 | 676 |
635 DCHECK(compositor_task_runner_->IsQueueEnabled()); | 677 DCHECK(compositor_task_runner_->IsQueueEnabled()); |
636 MainThreadOnly().current_policy = new_policy; | 678 MainThreadOnly().current_policy = new_policy; |
637 } | 679 } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
708 } | 750 } |
709 | 751 |
710 TaskCostEstimator* | 752 TaskCostEstimator* |
711 RendererSchedulerImpl::GetTimerTaskCostEstimatorForTesting() { | 753 RendererSchedulerImpl::GetTimerTaskCostEstimatorForTesting() { |
712 return &MainThreadOnly().timer_task_cost_estimator; | 754 return &MainThreadOnly().timer_task_cost_estimator; |
713 } | 755 } |
714 | 756 |
715 void RendererSchedulerImpl::SuspendTimerQueue() { | 757 void RendererSchedulerImpl::SuspendTimerQueue() { |
716 MainThreadOnly().timer_queue_suspend_count++; | 758 MainThreadOnly().timer_queue_suspend_count++; |
717 ForceUpdatePolicy(); | 759 ForceUpdatePolicy(); |
718 DCHECK(!timer_task_runner_->IsQueueEnabled()); | 760 DCHECK(!default_timer_task_runner_->IsQueueEnabled()); |
761 for (const auto& runner : timer_task_runners_) { | |
rmcilroy
2015/09/18 13:15:46
Can you make this for loop only run in DEBUG since
Sami
2015/09/21 10:52:36
Sure. I was hoping the compiler would do that for
| |
762 DCHECK(!runner->IsQueueEnabled()); | |
763 } | |
719 } | 764 } |
720 | 765 |
721 void RendererSchedulerImpl::ResumeTimerQueue() { | 766 void RendererSchedulerImpl::ResumeTimerQueue() { |
722 MainThreadOnly().timer_queue_suspend_count--; | 767 MainThreadOnly().timer_queue_suspend_count--; |
723 DCHECK_GE(MainThreadOnly().timer_queue_suspend_count, 0); | 768 DCHECK_GE(MainThreadOnly().timer_queue_suspend_count, 0); |
724 ForceUpdatePolicy(); | 769 ForceUpdatePolicy(); |
725 } | 770 } |
726 | 771 |
727 void RendererSchedulerImpl::SetTimerQueueSuspensionWhenBackgroundedEnabled( | 772 void RendererSchedulerImpl::SetTimerQueueSuspensionWhenBackgroundedEnabled( |
728 bool enabled) { | 773 bool enabled) { |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
853 MainThreadOnly().short_idle_period_duration.Clear(); | 898 MainThreadOnly().short_idle_period_duration.Clear(); |
854 // Make sure that we don't initially assume there is no idle time. | 899 // Make sure that we don't initially assume there is no idle time. |
855 MainThreadOnly().short_idle_period_duration.InsertSample( | 900 MainThreadOnly().short_idle_period_duration.InsertSample( |
856 cc::BeginFrameArgs::DefaultInterval()); | 901 cc::BeginFrameArgs::DefaultInterval()); |
857 AnyThread().user_model.Reset(); | 902 AnyThread().user_model.Reset(); |
858 MainThreadOnly().have_seen_a_begin_main_frame = false; | 903 MainThreadOnly().have_seen_a_begin_main_frame = false; |
859 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); | 904 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); |
860 } | 905 } |
861 | 906 |
862 } // namespace scheduler | 907 } // namespace scheduler |
OLD | NEW |