| 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("default_loading_tq"); |
| 64 &MainThreadOnly().loading_task_cost_estimator); | 58 default_timer_task_runner_ = NewTimerTaskRunner("default_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 } |
| 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 #ifndef NDEBUG |
| 761 DCHECK(!default_timer_task_runner_->IsQueueEnabled()); |
| 762 for (const auto& runner : timer_task_runners_) { |
| 763 DCHECK(!runner->IsQueueEnabled()); |
| 764 } |
| 765 #endif |
| 719 } | 766 } |
| 720 | 767 |
| 721 void RendererSchedulerImpl::ResumeTimerQueue() { | 768 void RendererSchedulerImpl::ResumeTimerQueue() { |
| 722 MainThreadOnly().timer_queue_suspend_count--; | 769 MainThreadOnly().timer_queue_suspend_count--; |
| 723 DCHECK_GE(MainThreadOnly().timer_queue_suspend_count, 0); | 770 DCHECK_GE(MainThreadOnly().timer_queue_suspend_count, 0); |
| 724 ForceUpdatePolicy(); | 771 ForceUpdatePolicy(); |
| 725 } | 772 } |
| 726 | 773 |
| 727 void RendererSchedulerImpl::SetTimerQueueSuspensionWhenBackgroundedEnabled( | 774 void RendererSchedulerImpl::SetTimerQueueSuspensionWhenBackgroundedEnabled( |
| 728 bool enabled) { | 775 bool enabled) { |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 MainThreadOnly().short_idle_period_duration.Clear(); | 900 MainThreadOnly().short_idle_period_duration.Clear(); |
| 854 // Make sure that we don't initially assume there is no idle time. | 901 // Make sure that we don't initially assume there is no idle time. |
| 855 MainThreadOnly().short_idle_period_duration.InsertSample( | 902 MainThreadOnly().short_idle_period_duration.InsertSample( |
| 856 cc::BeginFrameArgs::DefaultInterval()); | 903 cc::BeginFrameArgs::DefaultInterval()); |
| 857 AnyThread().user_model.Reset(); | 904 AnyThread().user_model.Reset(); |
| 858 MainThreadOnly().have_seen_a_begin_main_frame = false; | 905 MainThreadOnly().have_seen_a_begin_main_frame = false; |
| 859 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); | 906 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); |
| 860 } | 907 } |
| 861 | 908 |
| 862 } // namespace scheduler | 909 } // namespace scheduler |
| OLD | NEW |