| 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 "platform/scheduler/renderer/renderer_scheduler_impl.h" | 5 #include "platform/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/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 this, | 88 this, |
| 89 "renderer.scheduler", | 89 "renderer.scheduler", |
| 90 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 90 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
| 91 "RendererSchedulerIdlePeriod", | 91 "RendererSchedulerIdlePeriod", |
| 92 base::TimeDelta()), | 92 base::TimeDelta()), |
| 93 render_widget_scheduler_signals_(this), | 93 render_widget_scheduler_signals_(this), |
| 94 control_task_runner_(helper_.ControlTaskRunner()), | 94 control_task_runner_(helper_.ControlTaskRunner()), |
| 95 compositor_task_runner_( | 95 compositor_task_runner_( |
| 96 helper_.NewTaskQueue(TaskQueue::Spec(TaskQueue::QueueType::COMPOSITOR) | 96 helper_.NewTaskQueue(TaskQueue::Spec(TaskQueue::QueueType::COMPOSITOR) |
| 97 .SetShouldMonitorQuiescence(true))), | 97 .SetShouldMonitorQuiescence(true))), |
| 98 compositor_task_runner_enabled_voter_( |
| 99 compositor_task_runner_->CreateQueueEnabledVoter()), |
| 98 delayed_update_policy_runner_( | 100 delayed_update_policy_runner_( |
| 99 base::Bind(&RendererSchedulerImpl::UpdatePolicy, | 101 base::Bind(&RendererSchedulerImpl::UpdatePolicy, |
| 100 base::Unretained(this)), | 102 base::Unretained(this)), |
| 101 helper_.ControlTaskRunner()), | 103 helper_.ControlTaskRunner()), |
| 102 main_thread_only_(this, | 104 main_thread_only_(this, |
| 103 compositor_task_runner_, | 105 compositor_task_runner_, |
| 104 helper_.scheduler_tqm_delegate().get(), | 106 helper_.scheduler_tqm_delegate().get(), |
| 105 helper_.scheduler_tqm_delegate()->NowTicks()), | 107 helper_.scheduler_tqm_delegate()->NowTicks()), |
| 106 policy_may_need_update_(&any_thread_lock_), | 108 policy_may_need_update_(&any_thread_lock_), |
| 107 weak_factory_(this) { | 109 weak_factory_(this) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 134 base::trace_event::TraceLog::GetInstance()->AddAsyncEnabledStateObserver( | 136 base::trace_event::TraceLog::GetInstance()->AddAsyncEnabledStateObserver( |
| 135 weak_factory_.GetWeakPtr()); | 137 weak_factory_.GetWeakPtr()); |
| 136 } | 138 } |
| 137 } | 139 } |
| 138 | 140 |
| 139 RendererSchedulerImpl::~RendererSchedulerImpl() { | 141 RendererSchedulerImpl::~RendererSchedulerImpl() { |
| 140 TRACE_EVENT_OBJECT_DELETED_WITH_ID( | 142 TRACE_EVENT_OBJECT_DELETED_WITH_ID( |
| 141 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", | 143 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", |
| 142 this); | 144 this); |
| 143 | 145 |
| 144 for (const scoped_refptr<TaskQueue>& loading_queue : loading_task_runners_) { | 146 for (auto& pair : loading_task_runners_) { |
| 145 loading_queue->RemoveTaskObserver( | 147 pair.first->RemoveTaskObserver( |
| 146 &MainThreadOnly().loading_task_cost_estimator); | 148 &MainThreadOnly().loading_task_cost_estimator); |
| 147 } | 149 } |
| 148 for (const scoped_refptr<TaskQueue>& timer_queue : timer_task_runners_) { | 150 for (auto& pair : timer_task_runners_) { |
| 149 timer_queue->RemoveTaskObserver( | 151 pair.first->RemoveTaskObserver(&MainThreadOnly().timer_task_cost_estimator); |
| 150 &MainThreadOnly().timer_task_cost_estimator); | |
| 151 } | 152 } |
| 152 | 153 |
| 153 if (virtual_time_domain_) | 154 if (virtual_time_domain_) |
| 154 UnregisterTimeDomain(virtual_time_domain_.get()); | 155 UnregisterTimeDomain(virtual_time_domain_.get()); |
| 155 | 156 |
| 156 helper_.RemoveTaskTimeObserver(this); | 157 helper_.RemoveTaskTimeObserver(this); |
| 157 | 158 |
| 158 base::trace_event::TraceLog::GetInstance()->RemoveAsyncEnabledStateObserver( | 159 base::trace_event::TraceLog::GetInstance()->RemoveAsyncEnabledStateObserver( |
| 159 this); | 160 this); |
| 160 | 161 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 | 279 |
| 279 scoped_refptr<TaskQueue> RendererSchedulerImpl::NewLoadingTaskRunner( | 280 scoped_refptr<TaskQueue> RendererSchedulerImpl::NewLoadingTaskRunner( |
| 280 TaskQueue::QueueType queue_type) { | 281 TaskQueue::QueueType queue_type) { |
| 281 helper_.CheckOnValidThread(); | 282 helper_.CheckOnValidThread(); |
| 282 scoped_refptr<TaskQueue> loading_task_queue( | 283 scoped_refptr<TaskQueue> loading_task_queue( |
| 283 helper_.NewTaskQueue(TaskQueue::Spec(queue_type) | 284 helper_.NewTaskQueue(TaskQueue::Spec(queue_type) |
| 284 .SetShouldMonitorQuiescence(true) | 285 .SetShouldMonitorQuiescence(true) |
| 285 .SetTimeDomain(MainThreadOnly().use_virtual_time | 286 .SetTimeDomain(MainThreadOnly().use_virtual_time |
| 286 ? GetVirtualTimeDomain() | 287 ? GetVirtualTimeDomain() |
| 287 : nullptr))); | 288 : nullptr))); |
| 288 loading_task_runners_.insert(loading_task_queue); | 289 auto insert_result = loading_task_runners_.insert(std::make_pair( |
| 289 loading_task_queue->SetQueueEnabled( | 290 loading_task_queue, loading_task_queue->CreateQueueEnabledVoter())); |
| 291 insert_result.first->second->SetQueueEnabled( |
| 290 MainThreadOnly().current_policy.loading_queue_policy.is_enabled); | 292 MainThreadOnly().current_policy.loading_queue_policy.is_enabled); |
| 291 loading_task_queue->SetQueuePriority( | 293 loading_task_queue->SetQueuePriority( |
| 292 MainThreadOnly().current_policy.loading_queue_policy.priority); | 294 MainThreadOnly().current_policy.loading_queue_policy.priority); |
| 293 if (MainThreadOnly().current_policy.loading_queue_policy.time_domain_type == | 295 if (MainThreadOnly().current_policy.loading_queue_policy.time_domain_type == |
| 294 TimeDomainType::THROTTLED) { | 296 TimeDomainType::THROTTLED) { |
| 295 task_queue_throttler_->IncreaseThrottleRefCount(loading_task_queue.get()); | 297 task_queue_throttler_->IncreaseThrottleRefCount(loading_task_queue.get()); |
| 296 } | 298 } |
| 297 loading_task_queue->AddTaskObserver( | 299 loading_task_queue->AddTaskObserver( |
| 298 &MainThreadOnly().loading_task_cost_estimator); | 300 &MainThreadOnly().loading_task_cost_estimator); |
| 299 return loading_task_queue; | 301 return loading_task_queue; |
| 300 } | 302 } |
| 301 | 303 |
| 302 scoped_refptr<TaskQueue> RendererSchedulerImpl::NewTimerTaskRunner( | 304 scoped_refptr<TaskQueue> RendererSchedulerImpl::NewTimerTaskRunner( |
| 303 TaskQueue::QueueType queue_type) { | 305 TaskQueue::QueueType queue_type) { |
| 304 helper_.CheckOnValidThread(); | 306 helper_.CheckOnValidThread(); |
| 305 // TODO(alexclarke): Consider using ApplyTaskQueuePolicy() for brevity. | 307 // TODO(alexclarke): Consider using ApplyTaskQueuePolicy() for brevity. |
| 306 scoped_refptr<TaskQueue> timer_task_queue( | 308 scoped_refptr<TaskQueue> timer_task_queue( |
| 307 helper_.NewTaskQueue(TaskQueue::Spec(queue_type) | 309 helper_.NewTaskQueue(TaskQueue::Spec(queue_type) |
| 308 .SetShouldMonitorQuiescence(true) | 310 .SetShouldMonitorQuiescence(true) |
| 309 .SetShouldReportWhenExecutionBlocked(true) | 311 .SetShouldReportWhenExecutionBlocked(true) |
| 310 .SetTimeDomain(MainThreadOnly().use_virtual_time | 312 .SetTimeDomain(MainThreadOnly().use_virtual_time |
| 311 ? GetVirtualTimeDomain() | 313 ? GetVirtualTimeDomain() |
| 312 : nullptr))); | 314 : nullptr))); |
| 313 timer_task_runners_.insert(timer_task_queue); | 315 auto insert_result = timer_task_runners_.insert(std::make_pair( |
| 314 timer_task_queue->SetQueueEnabled( | 316 timer_task_queue, timer_task_queue->CreateQueueEnabledVoter())); |
| 317 insert_result.first->second->SetQueueEnabled( |
| 315 MainThreadOnly().current_policy.timer_queue_policy.is_enabled); | 318 MainThreadOnly().current_policy.timer_queue_policy.is_enabled); |
| 316 timer_task_queue->SetQueuePriority( | 319 timer_task_queue->SetQueuePriority( |
| 317 MainThreadOnly().current_policy.timer_queue_policy.priority); | 320 MainThreadOnly().current_policy.timer_queue_policy.priority); |
| 318 if (MainThreadOnly().current_policy.timer_queue_policy.time_domain_type == | 321 if (MainThreadOnly().current_policy.timer_queue_policy.time_domain_type == |
| 319 TimeDomainType::THROTTLED) { | 322 TimeDomainType::THROTTLED) { |
| 320 task_queue_throttler_->IncreaseThrottleRefCount(timer_task_queue.get()); | 323 task_queue_throttler_->IncreaseThrottleRefCount(timer_task_queue.get()); |
| 321 } | 324 } |
| 322 timer_task_queue->AddTaskObserver( | 325 timer_task_queue->AddTaskObserver( |
| 323 &MainThreadOnly().timer_task_cost_estimator); | 326 &MainThreadOnly().timer_task_cost_estimator); |
| 324 return timer_task_queue; | 327 return timer_task_queue; |
| (...skipping 761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1086 "RendererScheduler.timer_tasks_seem_expensive", | 1089 "RendererScheduler.timer_tasks_seem_expensive", |
| 1087 MainThreadOnly().timer_tasks_seem_expensive); | 1090 MainThreadOnly().timer_tasks_seem_expensive); |
| 1088 | 1091 |
| 1089 // TODO(alexclarke): Can we get rid of force update now? | 1092 // TODO(alexclarke): Can we get rid of force update now? |
| 1090 if (update_type == UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED && | 1093 if (update_type == UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED && |
| 1091 new_policy == MainThreadOnly().current_policy) { | 1094 new_policy == MainThreadOnly().current_policy) { |
| 1092 return; | 1095 return; |
| 1093 } | 1096 } |
| 1094 | 1097 |
| 1095 ApplyTaskQueuePolicy(compositor_task_runner_.get(), | 1098 ApplyTaskQueuePolicy(compositor_task_runner_.get(), |
| 1099 compositor_task_runner_enabled_voter_.get(), |
| 1096 MainThreadOnly().current_policy.compositor_queue_policy, | 1100 MainThreadOnly().current_policy.compositor_queue_policy, |
| 1097 new_policy.compositor_queue_policy); | 1101 new_policy.compositor_queue_policy); |
| 1098 | 1102 |
| 1099 for (const scoped_refptr<TaskQueue>& loading_queue : loading_task_runners_) { | 1103 for (const auto& pair : loading_task_runners_) { |
| 1100 ApplyTaskQueuePolicy(loading_queue.get(), | 1104 ApplyTaskQueuePolicy(pair.first.get(), pair.second.get(), |
| 1101 MainThreadOnly().current_policy.loading_queue_policy, | 1105 MainThreadOnly().current_policy.loading_queue_policy, |
| 1102 new_policy.loading_queue_policy); | 1106 new_policy.loading_queue_policy); |
| 1103 } | 1107 } |
| 1104 | 1108 |
| 1105 for (const scoped_refptr<TaskQueue>& timer_queue : timer_task_runners_) { | 1109 for (const auto& pair : timer_task_runners_) { |
| 1106 ApplyTaskQueuePolicy(timer_queue.get(), | 1110 ApplyTaskQueuePolicy(pair.first.get(), pair.second.get(), |
| 1107 MainThreadOnly().current_policy.timer_queue_policy, | 1111 MainThreadOnly().current_policy.timer_queue_policy, |
| 1108 new_policy.timer_queue_policy); | 1112 new_policy.timer_queue_policy); |
| 1109 } | 1113 } |
| 1110 MainThreadOnly().have_reported_blocking_intervention_in_current_policy = | 1114 MainThreadOnly().have_reported_blocking_intervention_in_current_policy = |
| 1111 false; | 1115 false; |
| 1112 | 1116 |
| 1113 // TODO(alexclarke): We shouldn't have to prioritize the default queue, but it | 1117 // TODO(alexclarke): We shouldn't have to prioritize the default queue, but it |
| 1114 // appears to be necessary since the order of loading tasks and IPCs (which | 1118 // appears to be necessary since the order of loading tasks and IPCs (which |
| 1115 // are mostly dispatched on the default queue) need to be preserved. | 1119 // are mostly dispatched on the default queue) need to be preserved. |
| 1116 ApplyTaskQueuePolicy(helper_.DefaultTaskRunner().get(), | 1120 ApplyTaskQueuePolicy(helper_.DefaultTaskRunner().get(), nullptr, |
| 1117 MainThreadOnly().current_policy.default_queue_policy, | 1121 MainThreadOnly().current_policy.default_queue_policy, |
| 1118 new_policy.default_queue_policy); | 1122 new_policy.default_queue_policy); |
| 1119 if (MainThreadOnly().rail_mode_observer && | 1123 if (MainThreadOnly().rail_mode_observer && |
| 1120 new_policy.rail_mode != MainThreadOnly().current_policy.rail_mode) { | 1124 new_policy.rail_mode != MainThreadOnly().current_policy.rail_mode) { |
| 1121 MainThreadOnly().rail_mode_observer->OnRAILModeChanged( | 1125 MainThreadOnly().rail_mode_observer->OnRAILModeChanged( |
| 1122 new_policy.rail_mode); | 1126 new_policy.rail_mode); |
| 1123 } | 1127 } |
| 1124 | 1128 |
| 1125 if (new_policy.should_disable_throttling != | 1129 if (new_policy.should_disable_throttling != |
| 1126 MainThreadOnly().current_policy.should_disable_throttling) { | 1130 MainThreadOnly().current_policy.should_disable_throttling) { |
| 1127 if (new_policy.should_disable_throttling) { | 1131 if (new_policy.should_disable_throttling) { |
| 1128 task_queue_throttler()->DisableThrottling(); | 1132 task_queue_throttler()->DisableThrottling(); |
| 1129 } else { | 1133 } else { |
| 1130 task_queue_throttler()->EnableThrottling(); | 1134 task_queue_throttler()->EnableThrottling(); |
| 1131 } | 1135 } |
| 1132 } | 1136 } |
| 1133 | 1137 |
| 1134 DCHECK(compositor_task_runner_->IsQueueEnabled()); | 1138 DCHECK(compositor_task_runner_->IsQueueEnabled()); |
| 1135 MainThreadOnly().current_policy = new_policy; | 1139 MainThreadOnly().current_policy = new_policy; |
| 1136 } | 1140 } |
| 1137 | 1141 |
| 1138 void RendererSchedulerImpl::ApplyTaskQueuePolicy( | 1142 void RendererSchedulerImpl::ApplyTaskQueuePolicy( |
| 1139 TaskQueue* task_queue, | 1143 TaskQueue* task_queue, |
| 1144 TaskQueue::QueueEnabledVoter* task_queue_enabled_voter, |
| 1140 const TaskQueuePolicy& old_task_queue_policy, | 1145 const TaskQueuePolicy& old_task_queue_policy, |
| 1141 const TaskQueuePolicy& new_task_queue_policy) const { | 1146 const TaskQueuePolicy& new_task_queue_policy) const { |
| 1142 if (old_task_queue_policy.is_enabled != new_task_queue_policy.is_enabled) { | 1147 if (task_queue_enabled_voter && |
| 1143 task_queue->SetQueueEnabled(new_task_queue_policy.is_enabled); | 1148 old_task_queue_policy.is_enabled != new_task_queue_policy.is_enabled) { |
| 1149 task_queue_enabled_voter->SetQueueEnabled(new_task_queue_policy.is_enabled); |
| 1144 } | 1150 } |
| 1145 | 1151 |
| 1152 // Make sure if there's no voter that the task queue is enabled. |
| 1153 DCHECK(task_queue_enabled_voter || old_task_queue_policy.is_enabled); |
| 1154 |
| 1146 if (old_task_queue_policy.priority != new_task_queue_policy.priority) | 1155 if (old_task_queue_policy.priority != new_task_queue_policy.priority) |
| 1147 task_queue->SetQueuePriority(new_task_queue_policy.priority); | 1156 task_queue->SetQueuePriority(new_task_queue_policy.priority); |
| 1148 | 1157 |
| 1149 if (old_task_queue_policy.time_domain_type != | 1158 if (old_task_queue_policy.time_domain_type != |
| 1150 new_task_queue_policy.time_domain_type) { | 1159 new_task_queue_policy.time_domain_type) { |
| 1151 if (old_task_queue_policy.time_domain_type == TimeDomainType::THROTTLED) { | 1160 if (old_task_queue_policy.time_domain_type == TimeDomainType::THROTTLED) { |
| 1152 task_queue_throttler_->DecreaseThrottleRefCount(task_queue); | 1161 task_queue_throttler_->DecreaseThrottleRefCount(task_queue); |
| 1153 } else if (new_task_queue_policy.time_domain_type == | 1162 } else if (new_task_queue_policy.time_domain_type == |
| 1154 TimeDomainType::THROTTLED) { | 1163 TimeDomainType::THROTTLED) { |
| 1155 task_queue_throttler_->IncreaseThrottleRefCount(task_queue); | 1164 task_queue_throttler_->IncreaseThrottleRefCount(task_queue); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1267 IdleTimeEstimator* RendererSchedulerImpl::GetIdleTimeEstimatorForTesting() { | 1276 IdleTimeEstimator* RendererSchedulerImpl::GetIdleTimeEstimatorForTesting() { |
| 1268 return &MainThreadOnly().idle_time_estimator; | 1277 return &MainThreadOnly().idle_time_estimator; |
| 1269 } | 1278 } |
| 1270 | 1279 |
| 1271 void RendererSchedulerImpl::SuspendTimerQueue() { | 1280 void RendererSchedulerImpl::SuspendTimerQueue() { |
| 1272 MainThreadOnly().timer_queue_suspend_count++; | 1281 MainThreadOnly().timer_queue_suspend_count++; |
| 1273 ForceUpdatePolicy(); | 1282 ForceUpdatePolicy(); |
| 1274 #ifndef NDEBUG | 1283 #ifndef NDEBUG |
| 1275 DCHECK(!default_timer_task_runner_->IsQueueEnabled()); | 1284 DCHECK(!default_timer_task_runner_->IsQueueEnabled()); |
| 1276 for (const auto& runner : timer_task_runners_) { | 1285 for (const auto& runner : timer_task_runners_) { |
| 1277 DCHECK(!runner->IsQueueEnabled()); | 1286 DCHECK(!runner.first->IsQueueEnabled()); |
| 1278 } | 1287 } |
| 1279 #endif | 1288 #endif |
| 1280 } | 1289 } |
| 1281 | 1290 |
| 1282 void RendererSchedulerImpl::ResumeTimerQueue() { | 1291 void RendererSchedulerImpl::ResumeTimerQueue() { |
| 1283 MainThreadOnly().timer_queue_suspend_count--; | 1292 MainThreadOnly().timer_queue_suspend_count--; |
| 1284 DCHECK_GE(MainThreadOnly().timer_queue_suspend_count, 0); | 1293 DCHECK_GE(MainThreadOnly().timer_queue_suspend_count, 0); |
| 1285 ForceUpdatePolicy(); | 1294 ForceUpdatePolicy(); |
| 1286 } | 1295 } |
| 1287 | 1296 |
| (...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1785 case TimeDomainType::VIRTUAL: | 1794 case TimeDomainType::VIRTUAL: |
| 1786 return "virtual"; | 1795 return "virtual"; |
| 1787 default: | 1796 default: |
| 1788 NOTREACHED(); | 1797 NOTREACHED(); |
| 1789 return nullptr; | 1798 return nullptr; |
| 1790 } | 1799 } |
| 1791 } | 1800 } |
| 1792 | 1801 |
| 1793 } // namespace scheduler | 1802 } // namespace scheduler |
| 1794 } // namespace blink | 1803 } // namespace blink |
| OLD | NEW |