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"); |
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_.SetQueueObserver(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 loading_task_runners_.erase(task_queue); |
| 188 timer_task_runners_.erase(task_queue); |
158 } | 189 } |
159 | 190 |
160 bool RendererSchedulerImpl::CanExceedIdleDeadlineIfRequired() const { | 191 bool RendererSchedulerImpl::CanExceedIdleDeadlineIfRequired() const { |
161 return idle_helper_.CanExceedIdleDeadlineIfRequired(); | 192 return idle_helper_.CanExceedIdleDeadlineIfRequired(); |
162 } | 193 } |
163 | 194 |
164 void RendererSchedulerImpl::AddTaskObserver( | 195 void RendererSchedulerImpl::AddTaskObserver( |
165 base::MessageLoop::TaskObserver* task_observer) { | 196 base::MessageLoop::TaskObserver* task_observer) { |
166 helper_.AddTaskObserver(task_observer); | 197 helper_.AddTaskObserver(task_observer); |
167 } | 198 } |
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
616 "RendererScheduler.timer_tasks_seem_expensive", | 647 "RendererScheduler.timer_tasks_seem_expensive", |
617 MainThreadOnly().timer_tasks_seem_expensive); | 648 MainThreadOnly().timer_tasks_seem_expensive); |
618 | 649 |
619 if (update_type == UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED && | 650 if (update_type == UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED && |
620 new_policy == MainThreadOnly().current_policy) { | 651 new_policy == MainThreadOnly().current_policy) { |
621 return; | 652 return; |
622 } | 653 } |
623 | 654 |
624 compositor_task_runner_->SetQueuePriority( | 655 compositor_task_runner_->SetQueuePriority( |
625 new_policy.compositor_queue_priority); | 656 new_policy.compositor_queue_priority); |
626 loading_task_runner_->SetQueuePriority(new_policy.loading_queue_priority); | 657 for (const scoped_refptr<TaskQueue>& loading_queue : loading_task_runners_) { |
627 timer_task_runner_->SetQueuePriority(new_policy.timer_queue_priority); | 658 loading_queue->SetQueuePriority(new_policy.loading_queue_priority); |
| 659 } |
| 660 for (const scoped_refptr<TaskQueue>& timer_queue : timer_task_runners_) { |
| 661 timer_queue->SetQueuePriority(new_policy.timer_queue_priority); |
| 662 } |
628 | 663 |
629 // TODO(alexclarke): We shouldn't have to prioritize the default queue, but it | 664 // 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 | 665 // 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. | 666 // are mostly dispatched on the default queue) need to be preserved. |
632 helper_.DefaultTaskRunner()->SetQueuePriority( | 667 helper_.DefaultTaskRunner()->SetQueuePriority( |
633 new_policy.default_queue_priority); | 668 new_policy.default_queue_priority); |
634 | 669 |
635 DCHECK(compositor_task_runner_->IsQueueEnabled()); | 670 DCHECK(compositor_task_runner_->IsQueueEnabled()); |
636 MainThreadOnly().current_policy = new_policy; | 671 MainThreadOnly().current_policy = new_policy; |
637 } | 672 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 return true; | 733 return true; |
699 } | 734 } |
700 | 735 |
701 SchedulerHelper* RendererSchedulerImpl::GetSchedulerHelperForTesting() { | 736 SchedulerHelper* RendererSchedulerImpl::GetSchedulerHelperForTesting() { |
702 return &helper_; | 737 return &helper_; |
703 } | 738 } |
704 | 739 |
705 void RendererSchedulerImpl::SuspendTimerQueue() { | 740 void RendererSchedulerImpl::SuspendTimerQueue() { |
706 MainThreadOnly().timer_queue_suspend_count++; | 741 MainThreadOnly().timer_queue_suspend_count++; |
707 ForceUpdatePolicy(); | 742 ForceUpdatePolicy(); |
708 DCHECK(!timer_task_runner_->IsQueueEnabled()); | 743 DCHECK(!default_timer_task_runner_->IsQueueEnabled()); |
709 } | 744 } |
710 | 745 |
711 void RendererSchedulerImpl::ResumeTimerQueue() { | 746 void RendererSchedulerImpl::ResumeTimerQueue() { |
712 MainThreadOnly().timer_queue_suspend_count--; | 747 MainThreadOnly().timer_queue_suspend_count--; |
713 DCHECK_GE(MainThreadOnly().timer_queue_suspend_count, 0); | 748 DCHECK_GE(MainThreadOnly().timer_queue_suspend_count, 0); |
714 ForceUpdatePolicy(); | 749 ForceUpdatePolicy(); |
715 } | 750 } |
716 | 751 |
717 void RendererSchedulerImpl::SetTimerQueueSuspensionWhenBackgroundedEnabled( | 752 void RendererSchedulerImpl::SetTimerQueueSuspensionWhenBackgroundedEnabled( |
718 bool enabled) { | 753 bool enabled) { |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
843 MainThreadOnly().short_idle_period_duration.Clear(); | 878 MainThreadOnly().short_idle_period_duration.Clear(); |
844 // Make sure that we don't initially assume there is no idle time. | 879 // Make sure that we don't initially assume there is no idle time. |
845 MainThreadOnly().short_idle_period_duration.InsertSample( | 880 MainThreadOnly().short_idle_period_duration.InsertSample( |
846 cc::BeginFrameArgs::DefaultInterval()); | 881 cc::BeginFrameArgs::DefaultInterval()); |
847 AnyThread().user_model.Reset(); | 882 AnyThread().user_model.Reset(); |
848 MainThreadOnly().have_seen_a_begin_main_frame = false; | 883 MainThreadOnly().have_seen_a_begin_main_frame = false; |
849 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); | 884 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); |
850 } | 885 } |
851 | 886 |
852 } // namespace scheduler | 887 } // namespace scheduler |
OLD | NEW |