Chromium Code Reviews| 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 18 matching lines...) Expand all Loading... | |
| 29 // the cost of loading tasks. | 29 // the cost of loading tasks. |
| 30 const int kLoadingTaskEstimationSampleCount = 1000; | 30 const int kLoadingTaskEstimationSampleCount = 1000; |
| 31 const double kLoadingTaskEstimationPercentile = 99; | 31 const double kLoadingTaskEstimationPercentile = 99; |
| 32 const int kTimerTaskEstimationSampleCount = 1000; | 32 const int kTimerTaskEstimationSampleCount = 1000; |
| 33 const double kTimerTaskEstimationPercentile = 99; | 33 const double kTimerTaskEstimationPercentile = 99; |
| 34 const int kShortIdlePeriodDurationSampleCount = 10; | 34 const int kShortIdlePeriodDurationSampleCount = 10; |
| 35 const double kShortIdlePeriodDurationPercentile = 50; | 35 const double kShortIdlePeriodDurationPercentile = 50; |
| 36 // Amount of idle time left in a frame (as a ratio of the vsync interval) above | 36 // Amount of idle time left in a frame (as a ratio of the vsync interval) above |
| 37 // which main thread compositing can be considered fast. | 37 // which main thread compositing can be considered fast. |
| 38 const double kFastCompositingIdleTimeThreshold = .2; | 38 const double kFastCompositingIdleTimeThreshold = .2; |
| 39 // Maximum task queueing time before the main thread is considered unresponsive. | |
| 40 const base::TimeDelta kMainThreadUnresponsiveQueueingTime = | |
| 41 base::TimeDelta::FromMilliseconds(1000); | |
| 39 } // namespace | 42 } // namespace |
| 40 | 43 |
| 41 RendererSchedulerImpl::RendererSchedulerImpl( | 44 RendererSchedulerImpl::RendererSchedulerImpl( |
| 42 scoped_refptr<SchedulerTqmDelegate> main_task_runner) | 45 scoped_refptr<SchedulerTqmDelegate> main_task_runner) |
| 43 : helper_(main_task_runner, | 46 : helper_(main_task_runner, |
| 44 "renderer.scheduler", | 47 "renderer.scheduler", |
| 45 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 48 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
| 46 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")), | 49 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")), |
| 47 idle_helper_(&helper_, | 50 idle_helper_(&helper_, |
| 48 this, | 51 this, |
| 49 "renderer.scheduler", | 52 "renderer.scheduler", |
| 50 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 53 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
| 51 "RendererSchedulerIdlePeriod", | 54 "RendererSchedulerIdlePeriod", |
| 52 base::TimeDelta()), | 55 base::TimeDelta()), |
| 53 render_widget_scheduler_signals_(this), | 56 render_widget_scheduler_signals_(this), |
| 54 control_task_runner_(helper_.ControlTaskRunner()), | 57 control_task_runner_(helper_.ControlTaskRunner()), |
| 55 compositor_task_runner_(helper_.NewTaskQueue( | 58 compositor_task_runner_(helper_.NewTaskQueue( |
| 56 TaskQueue::Spec("compositor_tq").SetShouldMonitorQuiescence(true))), | 59 TaskQueue::Spec("compositor_tq").SetShouldMonitorQuiescence(true))), |
| 57 delayed_update_policy_runner_( | 60 delayed_update_policy_runner_( |
| 58 base::Bind(&RendererSchedulerImpl::UpdatePolicy, | 61 base::Bind(&RendererSchedulerImpl::UpdatePolicy, |
| 59 base::Unretained(this)), | 62 base::Unretained(this)), |
| 60 helper_.ControlTaskRunner()), | 63 helper_.ControlTaskRunner()), |
| 61 main_thread_only_(this, | 64 main_thread_only_(compositor_task_runner_, |
| 62 compositor_task_runner_, | |
| 63 helper_.scheduler_tqm_delegate().get()), | 65 helper_.scheduler_tqm_delegate().get()), |
| 66 any_thread_(this), | |
| 64 policy_may_need_update_(&any_thread_lock_), | 67 policy_may_need_update_(&any_thread_lock_), |
| 65 weak_factory_(this) { | 68 weak_factory_(this) { |
| 66 throttling_helper_.reset(new ThrottlingHelper(this, "renderer.scheduler")); | 69 throttling_helper_.reset(new ThrottlingHelper(this, "renderer.scheduler")); |
| 67 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, | 70 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, |
| 68 weak_factory_.GetWeakPtr()); | 71 weak_factory_.GetWeakPtr()); |
| 69 end_renderer_hidden_idle_period_closure_.Reset(base::Bind( | 72 end_renderer_hidden_idle_period_closure_.Reset(base::Bind( |
| 70 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr())); | 73 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr())); |
| 71 | 74 |
| 72 suspend_timers_when_backgrounded_closure_.Reset( | 75 suspend_timers_when_backgrounded_closure_.Reset( |
| 73 base::Bind(&RendererSchedulerImpl::SuspendTimerQueueWhenBackgrounded, | 76 base::Bind(&RendererSchedulerImpl::SuspendTimerQueueWhenBackgrounded, |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 101 if (virtual_time_domain_) | 104 if (virtual_time_domain_) |
| 102 UnregisterTimeDomain(virtual_time_domain_.get()); | 105 UnregisterTimeDomain(virtual_time_domain_.get()); |
| 103 | 106 |
| 104 // Ensure the renderer scheduler was shut down explicitly, because otherwise | 107 // Ensure the renderer scheduler was shut down explicitly, because otherwise |
| 105 // we could end up having stale pointers to the Blink heap which has been | 108 // we could end up having stale pointers to the Blink heap which has been |
| 106 // terminated by this point. | 109 // terminated by this point. |
| 107 DCHECK(MainThreadOnly().was_shutdown); | 110 DCHECK(MainThreadOnly().was_shutdown); |
| 108 } | 111 } |
| 109 | 112 |
| 110 RendererSchedulerImpl::MainThreadOnly::MainThreadOnly( | 113 RendererSchedulerImpl::MainThreadOnly::MainThreadOnly( |
| 111 RendererSchedulerImpl* renderer_scheduler_impl, | |
| 112 const scoped_refptr<TaskQueue>& compositor_task_runner, | 114 const scoped_refptr<TaskQueue>& compositor_task_runner, |
| 113 base::TickClock* time_source) | 115 base::TickClock* time_source) |
| 114 : loading_task_cost_estimator(time_source, | 116 : loading_task_cost_estimator(time_source, |
| 115 kLoadingTaskEstimationSampleCount, | 117 kLoadingTaskEstimationSampleCount, |
| 116 kLoadingTaskEstimationPercentile), | 118 kLoadingTaskEstimationPercentile), |
| 117 timer_task_cost_estimator(time_source, | 119 timer_task_cost_estimator(time_source, |
| 118 kTimerTaskEstimationSampleCount, | 120 kTimerTaskEstimationSampleCount, |
| 119 kTimerTaskEstimationPercentile), | 121 kTimerTaskEstimationPercentile), |
| 120 queueing_time_estimator(renderer_scheduler_impl, | |
| 121 base::TimeDelta::FromSeconds(1)), | |
| 122 idle_time_estimator(compositor_task_runner, | 122 idle_time_estimator(compositor_task_runner, |
| 123 time_source, | 123 time_source, |
| 124 kShortIdlePeriodDurationSampleCount, | 124 kShortIdlePeriodDurationSampleCount, |
| 125 kShortIdlePeriodDurationPercentile), | 125 kShortIdlePeriodDurationPercentile), |
| 126 current_use_case(UseCase::NONE), | 126 current_use_case(UseCase::NONE), |
| 127 timer_queue_suspend_count(0), | 127 timer_queue_suspend_count(0), |
| 128 navigation_task_expected_count(0), | 128 navigation_task_expected_count(0), |
| 129 expensive_task_policy(ExpensiveTaskPolicy::RUN), | 129 expensive_task_policy(ExpensiveTaskPolicy::RUN), |
| 130 renderer_hidden(false), | 130 renderer_hidden(false), |
| 131 renderer_backgrounded(false), | 131 renderer_backgrounded(false), |
| 132 renderer_suspended(false), | 132 renderer_suspended(false), |
| 133 timer_queue_suspension_when_backgrounded_enabled(false), | 133 timer_queue_suspension_when_backgrounded_enabled(false), |
| 134 timer_queue_suspended_when_backgrounded(false), | 134 timer_queue_suspended_when_backgrounded(false), |
| 135 was_shutdown(false), | 135 was_shutdown(false), |
| 136 loading_tasks_seem_expensive(false), | 136 loading_tasks_seem_expensive(false), |
| 137 timer_tasks_seem_expensive(false), | 137 timer_tasks_seem_expensive(false), |
| 138 touchstart_expected_soon(false), | 138 touchstart_expected_soon(false), |
| 139 have_seen_a_begin_main_frame(false), | 139 have_seen_a_begin_main_frame(false), |
| 140 have_reported_blocking_intervention_in_current_policy(false), | 140 have_reported_blocking_intervention_in_current_policy(false), |
| 141 have_reported_blocking_intervention_since_navigation(false), | 141 have_reported_blocking_intervention_since_navigation(false), |
| 142 has_visible_render_widget_with_touch_handler(false), | 142 has_visible_render_widget_with_touch_handler(false), |
| 143 begin_frame_not_expected_soon(false), | 143 begin_frame_not_expected_soon(false), |
| 144 in_idle_period_for_testing(false), | 144 in_idle_period_for_testing(false), |
| 145 use_virtual_time(false), | 145 use_virtual_time(false), |
| 146 rail_mode_observer(nullptr) {} | 146 rail_mode_observer(nullptr) {} |
| 147 | 147 |
| 148 RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {} | 148 RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {} |
| 149 | 149 |
| 150 RendererSchedulerImpl::AnyThread::AnyThread() | 150 RendererSchedulerImpl::AnyThread::AnyThread( |
| 151 : awaiting_touch_start_response(false), | 151 RendererSchedulerImpl* renderer_scheduler_impl) |
| 152 : queueing_time_estimator(renderer_scheduler_impl, | |
| 153 base::TimeDelta::FromSeconds(1)), | |
| 154 awaiting_touch_start_response(false), | |
| 152 in_idle_period(false), | 155 in_idle_period(false), |
| 153 begin_main_frame_on_critical_path(false), | 156 begin_main_frame_on_critical_path(false), |
| 154 last_gesture_was_compositor_driven(false), | 157 last_gesture_was_compositor_driven(false), |
| 155 default_gesture_prevented(true), | 158 default_gesture_prevented(true), |
| 156 have_seen_touchstart(false) {} | 159 have_seen_touchstart(false) {} |
| 157 | 160 |
| 158 RendererSchedulerImpl::AnyThread::~AnyThread() {} | 161 RendererSchedulerImpl::AnyThread::~AnyThread() {} |
| 159 | 162 |
| 160 RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly() | 163 RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly() |
| 161 : last_input_type(blink::WebInputEvent::Undefined) {} | 164 : last_input_type(blink::WebInputEvent::Undefined) {} |
| (...skipping 1169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1331 default_loading_task_runner_->SetBlameContext(blame_context); | 1334 default_loading_task_runner_->SetBlameContext(blame_context); |
| 1332 default_timer_task_runner_->SetBlameContext(blame_context); | 1335 default_timer_task_runner_->SetBlameContext(blame_context); |
| 1333 compositor_task_runner_->SetBlameContext(blame_context); | 1336 compositor_task_runner_->SetBlameContext(blame_context); |
| 1334 idle_helper_.IdleTaskRunner()->SetBlameContext(blame_context); | 1337 idle_helper_.IdleTaskRunner()->SetBlameContext(blame_context); |
| 1335 } | 1338 } |
| 1336 | 1339 |
| 1337 void RendererSchedulerImpl::SetRAILModeObserver(RAILModeObserver* observer) { | 1340 void RendererSchedulerImpl::SetRAILModeObserver(RAILModeObserver* observer) { |
| 1338 MainThreadOnly().rail_mode_observer = observer; | 1341 MainThreadOnly().rail_mode_observer = observer; |
| 1339 } | 1342 } |
| 1340 | 1343 |
| 1344 bool RendererSchedulerImpl:: | |
| 1345 ShouldForceEventsNonBlockingForUnresponsiveMainThread() const { | |
| 1346 base::TimeTicks now = base::TimeTicks::Now(); | |
|
dtapuska
2016/08/23 16:18:29
How does this code deal with non-high precision cl
tdresser
2016/08/23 17:25:33
What's your concern, that we'll trigger too aggres
| |
| 1347 base::TimeDelta estimated_queueing_time; | |
| 1348 | |
| 1349 { | |
| 1350 base::AutoLock lock(any_thread_lock_); | |
| 1351 | |
| 1352 estimated_queueing_time = | |
| 1353 AnyThread() | |
| 1354 .queueing_time_estimator.EstimateQueueingTimeIncludingCurrentTask( | |
| 1355 now); | |
| 1356 } | |
| 1357 | |
| 1358 return estimated_queueing_time > kMainThreadUnresponsiveQueueingTime; | |
| 1359 } | |
| 1360 | |
| 1341 void RendererSchedulerImpl::RegisterTimeDomain(TimeDomain* time_domain) { | 1361 void RendererSchedulerImpl::RegisterTimeDomain(TimeDomain* time_domain) { |
| 1342 helper_.RegisterTimeDomain(time_domain); | 1362 helper_.RegisterTimeDomain(time_domain); |
| 1343 } | 1363 } |
| 1344 | 1364 |
| 1345 void RendererSchedulerImpl::UnregisterTimeDomain(TimeDomain* time_domain) { | 1365 void RendererSchedulerImpl::UnregisterTimeDomain(TimeDomain* time_domain) { |
| 1346 helper_.UnregisterTimeDomain(time_domain); | 1366 helper_.UnregisterTimeDomain(time_domain); |
| 1347 } | 1367 } |
| 1348 | 1368 |
| 1349 base::TickClock* RendererSchedulerImpl::tick_clock() const { | 1369 base::TickClock* RendererSchedulerImpl::tick_clock() const { |
| 1350 return helper_.scheduler_tqm_delegate().get(); | 1370 return helper_.scheduler_tqm_delegate().get(); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1400 true; | 1420 true; |
| 1401 BroadcastIntervention( | 1421 BroadcastIntervention( |
| 1402 "Blink deferred a task in order to make scrolling smoother. " | 1422 "Blink deferred a task in order to make scrolling smoother. " |
| 1403 "Your timer and network tasks should take less than 50ms to run " | 1423 "Your timer and network tasks should take less than 50ms to run " |
| 1404 "to avoid this. Please see " | 1424 "to avoid this. Please see " |
| 1405 "https://developers.google.com/web/tools/chrome-devtools/profile/evaluat e-performance/rail" | 1425 "https://developers.google.com/web/tools/chrome-devtools/profile/evaluat e-performance/rail" |
| 1406 " and https://crbug.com/574343#c40 for more information."); | 1426 " and https://crbug.com/574343#c40 for more information."); |
| 1407 } | 1427 } |
| 1408 } | 1428 } |
| 1409 | 1429 |
| 1430 void RendererSchedulerImpl::ReportTaskStartTime(base::TimeTicks start_time) { | |
| 1431 base::AutoLock lock(any_thread_lock_); | |
| 1432 AnyThread().queueing_time_estimator.OnTopLevelTaskStarted(start_time); | |
| 1433 } | |
| 1434 | |
| 1410 void RendererSchedulerImpl::ReportTaskTime(base::TimeTicks start_time, | 1435 void RendererSchedulerImpl::ReportTaskTime(base::TimeTicks start_time, |
| 1411 base::TimeTicks end_time) { | 1436 base::TimeTicks end_time) { |
| 1412 MainThreadOnly().queueing_time_estimator.OnToplevelTaskCompleted(start_time, | 1437 { |
| 1413 end_time); | 1438 base::AutoLock lock(any_thread_lock_); |
| 1414 MainThreadOnly().long_task_tracker.RecordLongTask( | 1439 AnyThread().queueing_time_estimator.OnTopLevelTaskCompleted(start_time, |
| 1415 start_time, end_time - start_time); | 1440 end_time); |
| 1441 } | |
| 1442 MainThreadOnly().long_task_tracker.RecordLongTask(start_time, | |
| 1443 end_time - start_time); | |
| 1444 | |
| 1416 UMA_HISTOGRAM_CUSTOM_COUNTS("RendererScheduler.TaskTime", | 1445 UMA_HISTOGRAM_CUSTOM_COUNTS("RendererScheduler.TaskTime", |
| 1417 (end_time - start_time).InMicroseconds(), 1, | 1446 (end_time - start_time).InMicroseconds(), 1, |
| 1418 1000000, 50); | 1447 1000000, 50); |
| 1419 } | 1448 } |
| 1420 | 1449 |
| 1421 LongTaskTracker::LongTaskTiming RendererSchedulerImpl::GetLongTaskTiming() { | 1450 LongTaskTracker::LongTaskTiming RendererSchedulerImpl::GetLongTaskTiming() { |
| 1422 return MainThreadOnly().long_task_tracker.GetLongTaskTiming(); | 1451 return MainThreadOnly().long_task_tracker.GetLongTaskTiming(); |
| 1423 } | 1452 } |
| 1424 | 1453 |
| 1425 void RendererSchedulerImpl::OnQueueingTimeForWindowEstimated( | 1454 void RendererSchedulerImpl::OnQueueingTimeForWindowEstimated( |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1488 case v8::PERFORMANCE_LOAD: | 1517 case v8::PERFORMANCE_LOAD: |
| 1489 return "load"; | 1518 return "load"; |
| 1490 default: | 1519 default: |
| 1491 NOTREACHED(); | 1520 NOTREACHED(); |
| 1492 return nullptr; | 1521 return nullptr; |
| 1493 } | 1522 } |
| 1494 } | 1523 } |
| 1495 | 1524 |
| 1496 } // namespace scheduler | 1525 } // namespace scheduler |
| 1497 } // namespace blink | 1526 } // namespace blink |
| OLD | NEW |