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 24 matching lines...) Expand all Loading... | |
| 35 const int kShortIdlePeriodDurationSampleCount = 10; | 35 const int kShortIdlePeriodDurationSampleCount = 10; |
| 36 const double kShortIdlePeriodDurationPercentile = 50; | 36 const double kShortIdlePeriodDurationPercentile = 50; |
| 37 // Amount of idle time left in a frame (as a ratio of the vsync interval) above | 37 // Amount of idle time left in a frame (as a ratio of the vsync interval) above |
| 38 // which main thread compositing can be considered fast. | 38 // which main thread compositing can be considered fast. |
| 39 const double kFastCompositingIdleTimeThreshold = .2; | 39 const double kFastCompositingIdleTimeThreshold = .2; |
| 40 constexpr base::TimeDelta kThreadLoadTrackerReportingInterval = | 40 constexpr base::TimeDelta kThreadLoadTrackerReportingInterval = |
| 41 base::TimeDelta::FromMinutes(1); | 41 base::TimeDelta::FromMinutes(1); |
| 42 constexpr base::TimeDelta kThreadLoadTrackerWaitingPeriodBeforeReporting = | 42 constexpr base::TimeDelta kThreadLoadTrackerWaitingPeriodBeforeReporting = |
| 43 base::TimeDelta::FromMinutes(2); | 43 base::TimeDelta::FromMinutes(2); |
| 44 | 44 |
| 45 // Maximum task queueing time before the main thread is considered unresponsive. | |
| 46 const base::TimeDelta kMainThreadUnresponsiveQueueingTime = | |
|
Sami
2016/11/02 19:01:42
constexpr to avoid a global static initializer.
tdresser
2016/11/03 13:56:10
Done.
| |
| 47 base::TimeDelta::FromMilliseconds(200); | |
| 48 | |
| 45 void ReportForegroundRendererTaskLoad(base::TimeTicks time, double load) { | 49 void ReportForegroundRendererTaskLoad(base::TimeTicks time, double load) { |
| 46 int load_percentage = static_cast<int>(load * 100); | 50 int load_percentage = static_cast<int>(load * 100); |
| 47 UMA_HISTOGRAM_PERCENTAGE("RendererScheduler.ForegroundRendererMainThreadLoad", | 51 UMA_HISTOGRAM_PERCENTAGE("RendererScheduler.ForegroundRendererMainThreadLoad", |
| 48 load_percentage); | 52 load_percentage); |
| 49 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 53 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
| 50 "RendererScheduler.ForegroundRendererLoad", load_percentage); | 54 "RendererScheduler.ForegroundRendererLoad", load_percentage); |
| 51 } | 55 } |
| 52 | 56 |
| 53 void ReportBackgroundRendererTaskLoad(base::TimeTicks time, double load) { | 57 void ReportBackgroundRendererTaskLoad(base::TimeTicks time, double load) { |
| 54 int load_percentage = static_cast<int>(load * 100); | 58 int load_percentage = static_cast<int>(load * 100); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 79 base::TimeDelta()), | 83 base::TimeDelta()), |
| 80 render_widget_scheduler_signals_(this), | 84 render_widget_scheduler_signals_(this), |
| 81 control_task_runner_(helper_.ControlTaskRunner()), | 85 control_task_runner_(helper_.ControlTaskRunner()), |
| 82 compositor_task_runner_( | 86 compositor_task_runner_( |
| 83 helper_.NewTaskQueue(TaskQueue::Spec(TaskQueue::QueueType::COMPOSITOR) | 87 helper_.NewTaskQueue(TaskQueue::Spec(TaskQueue::QueueType::COMPOSITOR) |
| 84 .SetShouldMonitorQuiescence(true))), | 88 .SetShouldMonitorQuiescence(true))), |
| 85 delayed_update_policy_runner_( | 89 delayed_update_policy_runner_( |
| 86 base::Bind(&RendererSchedulerImpl::UpdatePolicy, | 90 base::Bind(&RendererSchedulerImpl::UpdatePolicy, |
| 87 base::Unretained(this)), | 91 base::Unretained(this)), |
| 88 helper_.ControlTaskRunner()), | 92 helper_.ControlTaskRunner()), |
| 93 seqlock_queueing_time_estimator_( | |
| 94 QueueingTimeEstimator(this, base::TimeDelta::FromSeconds(1))), | |
| 89 main_thread_only_(this, | 95 main_thread_only_(this, |
| 90 compositor_task_runner_, | 96 compositor_task_runner_, |
| 91 helper_.scheduler_tqm_delegate().get(), | 97 helper_.scheduler_tqm_delegate().get(), |
| 92 helper_.scheduler_tqm_delegate()->NowTicks()), | 98 helper_.scheduler_tqm_delegate()->NowTicks()), |
| 99 any_thread_(this), | |
| 93 policy_may_need_update_(&any_thread_lock_), | 100 policy_may_need_update_(&any_thread_lock_), |
| 94 weak_factory_(this) { | 101 weak_factory_(this) { |
| 95 task_queue_throttler_.reset( | 102 task_queue_throttler_.reset( |
| 96 new TaskQueueThrottler(this, "renderer.scheduler")); | 103 new TaskQueueThrottler(this, "renderer.scheduler")); |
| 97 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, | 104 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, |
| 98 weak_factory_.GetWeakPtr()); | 105 weak_factory_.GetWeakPtr()); |
| 99 end_renderer_hidden_idle_period_closure_.Reset(base::Bind( | 106 end_renderer_hidden_idle_period_closure_.Reset(base::Bind( |
| 100 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr())); | 107 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr())); |
| 101 | 108 |
| 102 suspend_timers_when_backgrounded_closure_.Reset( | 109 suspend_timers_when_backgrounded_closure_.Reset( |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 145 RendererSchedulerImpl* renderer_scheduler_impl, | 152 RendererSchedulerImpl* renderer_scheduler_impl, |
| 146 const scoped_refptr<TaskQueue>& compositor_task_runner, | 153 const scoped_refptr<TaskQueue>& compositor_task_runner, |
| 147 base::TickClock* time_source, | 154 base::TickClock* time_source, |
| 148 base::TimeTicks now) | 155 base::TimeTicks now) |
| 149 : loading_task_cost_estimator(time_source, | 156 : loading_task_cost_estimator(time_source, |
| 150 kLoadingTaskEstimationSampleCount, | 157 kLoadingTaskEstimationSampleCount, |
| 151 kLoadingTaskEstimationPercentile), | 158 kLoadingTaskEstimationPercentile), |
| 152 timer_task_cost_estimator(time_source, | 159 timer_task_cost_estimator(time_source, |
| 153 kTimerTaskEstimationSampleCount, | 160 kTimerTaskEstimationSampleCount, |
| 154 kTimerTaskEstimationPercentile), | 161 kTimerTaskEstimationPercentile), |
| 155 queueing_time_estimator(renderer_scheduler_impl, | |
| 156 base::TimeDelta::FromSeconds(1)), | |
| 157 idle_time_estimator(compositor_task_runner, | 162 idle_time_estimator(compositor_task_runner, |
| 158 time_source, | 163 time_source, |
| 159 kShortIdlePeriodDurationSampleCount, | 164 kShortIdlePeriodDurationSampleCount, |
| 160 kShortIdlePeriodDurationPercentile), | 165 kShortIdlePeriodDurationPercentile), |
| 161 background_main_thread_load_tracker( | 166 background_main_thread_load_tracker( |
| 162 now, | 167 now, |
| 163 base::Bind(&ReportBackgroundRendererTaskLoad), | 168 base::Bind(&ReportBackgroundRendererTaskLoad), |
| 164 kThreadLoadTrackerReportingInterval, | 169 kThreadLoadTrackerReportingInterval, |
| 165 kThreadLoadTrackerWaitingPeriodBeforeReporting), | 170 kThreadLoadTrackerWaitingPeriodBeforeReporting), |
| 166 foreground_main_thread_load_tracker( | 171 foreground_main_thread_load_tracker( |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 185 have_reported_blocking_intervention_in_current_policy(false), | 190 have_reported_blocking_intervention_in_current_policy(false), |
| 186 have_reported_blocking_intervention_since_navigation(false), | 191 have_reported_blocking_intervention_since_navigation(false), |
| 187 has_visible_render_widget_with_touch_handler(false), | 192 has_visible_render_widget_with_touch_handler(false), |
| 188 begin_frame_not_expected_soon(false), | 193 begin_frame_not_expected_soon(false), |
| 189 in_idle_period_for_testing(false), | 194 in_idle_period_for_testing(false), |
| 190 use_virtual_time(false), | 195 use_virtual_time(false), |
| 191 rail_mode_observer(nullptr) {} | 196 rail_mode_observer(nullptr) {} |
| 192 | 197 |
| 193 RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {} | 198 RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {} |
| 194 | 199 |
| 195 RendererSchedulerImpl::AnyThread::AnyThread() | 200 RendererSchedulerImpl::AnyThread::AnyThread( |
| 201 RendererSchedulerImpl* renderer_scheduler_impl) | |
| 196 : awaiting_touch_start_response(false), | 202 : awaiting_touch_start_response(false), |
| 197 in_idle_period(false), | 203 in_idle_period(false), |
| 198 begin_main_frame_on_critical_path(false), | 204 begin_main_frame_on_critical_path(false), |
| 199 last_gesture_was_compositor_driven(false), | 205 last_gesture_was_compositor_driven(false), |
| 200 default_gesture_prevented(true), | 206 default_gesture_prevented(true), |
| 201 have_seen_touchstart(false) {} | 207 have_seen_touchstart(false) {} |
| 202 | 208 |
| 203 RendererSchedulerImpl::AnyThread::~AnyThread() {} | 209 RendererSchedulerImpl::AnyThread::~AnyThread() {} |
| 204 | 210 |
| 205 RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly() | 211 RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly() |
| (...skipping 1224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1430 default_loading_task_runner_->SetBlameContext(blame_context); | 1436 default_loading_task_runner_->SetBlameContext(blame_context); |
| 1431 default_timer_task_runner_->SetBlameContext(blame_context); | 1437 default_timer_task_runner_->SetBlameContext(blame_context); |
| 1432 compositor_task_runner_->SetBlameContext(blame_context); | 1438 compositor_task_runner_->SetBlameContext(blame_context); |
| 1433 idle_helper_.IdleTaskRunner()->SetBlameContext(blame_context); | 1439 idle_helper_.IdleTaskRunner()->SetBlameContext(blame_context); |
| 1434 } | 1440 } |
| 1435 | 1441 |
| 1436 void RendererSchedulerImpl::SetRAILModeObserver(RAILModeObserver* observer) { | 1442 void RendererSchedulerImpl::SetRAILModeObserver(RAILModeObserver* observer) { |
| 1437 MainThreadOnly().rail_mode_observer = observer; | 1443 MainThreadOnly().rail_mode_observer = observer; |
| 1438 } | 1444 } |
| 1439 | 1445 |
| 1446 bool RendererSchedulerImpl:: | |
| 1447 ShouldForceEventsNonBlockingForUnresponsiveMainThread() const { | |
| 1448 base::TimeTicks now = base::TimeTicks::Now(); | |
| 1449 base::TimeDelta estimated_queueing_time; | |
| 1450 | |
| 1451 std::unique_ptr<QueueingTimeEstimator> queueing_time_estimator; | |
| 1452 { | |
| 1453 bool can_read = false; | |
| 1454 base::subtle::Atomic32 version; | |
| 1455 seqlock_queueing_time_estimator_.seqlock.ReadOrFail(&can_read, &version); | |
| 1456 | |
| 1457 if (can_read) { | |
| 1458 // TODO - is this copy okay? Use memcpy? | |
|
Sami
2016/11/02 19:01:42
I'd need to think about this a bit more, but I thi
tdresser
2016/11/03 13:56:10
Done, though it's a bit ugly. This is probably a b
alex clarke (OOO till 29th)
2016/11/03 15:20:53
I'm not sure what we gain by /not/ copying the bas
| |
| 1459 queueing_time_estimator.reset( | |
| 1460 new QueueingTimeEstimator(seqlock_queueing_time_estimator_.data)); | |
| 1461 } | |
| 1462 | |
| 1463 // If we didn't successfully read the first time, assume we aren't busy. | |
| 1464 if (seqlock_queueing_time_estimator_.seqlock.ReadRetry(version)) | |
| 1465 queueing_time_estimator.reset(); | |
| 1466 } | |
| 1467 | |
| 1468 if (queueing_time_estimator) { | |
| 1469 estimated_queueing_time = | |
| 1470 queueing_time_estimator->EstimateQueueingTimeIncludingCurrentTask(now); | |
| 1471 } | |
| 1472 | |
| 1473 return estimated_queueing_time > kMainThreadUnresponsiveQueueingTime; | |
| 1474 } | |
| 1475 | |
| 1440 void RendererSchedulerImpl::RegisterTimeDomain(TimeDomain* time_domain) { | 1476 void RendererSchedulerImpl::RegisterTimeDomain(TimeDomain* time_domain) { |
| 1441 helper_.RegisterTimeDomain(time_domain); | 1477 helper_.RegisterTimeDomain(time_domain); |
| 1442 } | 1478 } |
| 1443 | 1479 |
| 1444 void RendererSchedulerImpl::UnregisterTimeDomain(TimeDomain* time_domain) { | 1480 void RendererSchedulerImpl::UnregisterTimeDomain(TimeDomain* time_domain) { |
| 1445 helper_.UnregisterTimeDomain(time_domain); | 1481 helper_.UnregisterTimeDomain(time_domain); |
| 1446 } | 1482 } |
| 1447 | 1483 |
| 1448 base::TickClock* RendererSchedulerImpl::tick_clock() const { | 1484 base::TickClock* RendererSchedulerImpl::tick_clock() const { |
| 1449 return helper_.scheduler_tqm_delegate().get(); | 1485 return helper_.scheduler_tqm_delegate().get(); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1499 true; | 1535 true; |
| 1500 BroadcastIntervention( | 1536 BroadcastIntervention( |
| 1501 "Blink deferred a task in order to make scrolling smoother. " | 1537 "Blink deferred a task in order to make scrolling smoother. " |
| 1502 "Your timer and network tasks should take less than 50ms to run " | 1538 "Your timer and network tasks should take less than 50ms to run " |
| 1503 "to avoid this. Please see " | 1539 "to avoid this. Please see " |
| 1504 "https://developers.google.com/web/tools/chrome-devtools/profile/evaluat e-performance/rail" | 1540 "https://developers.google.com/web/tools/chrome-devtools/profile/evaluat e-performance/rail" |
| 1505 " and https://crbug.com/574343#c40 for more information."); | 1541 " and https://crbug.com/574343#c40 for more information."); |
| 1506 } | 1542 } |
| 1507 } | 1543 } |
| 1508 | 1544 |
| 1509 void RendererSchedulerImpl::ReportTaskTime(TaskQueue* task_queue, | 1545 void RendererSchedulerImpl::ReportTaskStartTime(double start_time) { |
| 1510 double start_time, | 1546 base::TimeTicks start_time_ticks = |
| 1511 double end_time) { | 1547 MonotonicTimeInSecondsToTimeTicks(start_time); |
| 1548 MainThreadOnly().current_task_start_time = start_time_ticks; | |
| 1549 | |
| 1550 seqlock_queueing_time_estimator_.seqlock.WriteBegin(); | |
| 1551 seqlock_queueing_time_estimator_.data.OnTopLevelTaskStarted(start_time_ticks); | |
| 1552 seqlock_queueing_time_estimator_.seqlock.WriteEnd(); | |
| 1553 } | |
| 1554 | |
| 1555 void RendererSchedulerImpl::ReportTaskEndTime(TaskQueue* task_queue, | |
| 1556 double start_time, | |
| 1557 double end_time) { | |
| 1512 // TODO(scheduler-dev): Remove conversions when Blink starts using | 1558 // TODO(scheduler-dev): Remove conversions when Blink starts using |
| 1513 // base::TimeTicks instead of doubles for time. | 1559 // base::TimeTicks instead of doubles for time. |
| 1514 base::TimeTicks start_time_ticks = | 1560 base::TimeTicks start_time_ticks = |
| 1515 MonotonicTimeInSecondsToTimeTicks(start_time); | 1561 MonotonicTimeInSecondsToTimeTicks(start_time); |
| 1516 base::TimeTicks end_time_ticks = MonotonicTimeInSecondsToTimeTicks(end_time); | 1562 base::TimeTicks end_time_ticks = MonotonicTimeInSecondsToTimeTicks(end_time); |
| 1517 | 1563 |
| 1518 MainThreadOnly().queueing_time_estimator.OnToplevelTaskCompleted( | 1564 seqlock_queueing_time_estimator_.seqlock.WriteBegin(); |
| 1519 start_time_ticks, end_time_ticks); | 1565 seqlock_queueing_time_estimator_.data.OnTopLevelTaskCompleted(end_time_ticks); |
| 1566 seqlock_queueing_time_estimator_.seqlock.WriteEnd(); | |
| 1520 | 1567 |
| 1521 task_queue_throttler()->OnTaskRunTimeReported(task_queue, start_time_ticks, | 1568 task_queue_throttler()->OnTaskRunTimeReported(task_queue, start_time_ticks, |
| 1522 end_time_ticks); | 1569 end_time_ticks); |
| 1523 | 1570 |
| 1524 // We want to measure thread time here, but for efficiency reasons | 1571 // We want to measure thread time here, but for efficiency reasons |
| 1525 // we stick with wall time. | 1572 // we stick with wall time. |
| 1526 MainThreadOnly().foreground_main_thread_load_tracker.RecordTaskTime( | 1573 MainThreadOnly().foreground_main_thread_load_tracker.RecordTaskTime( |
| 1527 start_time_ticks, end_time_ticks); | 1574 start_time_ticks, end_time_ticks); |
| 1528 MainThreadOnly().background_main_thread_load_tracker.RecordTaskTime( | 1575 MainThreadOnly().background_main_thread_load_tracker.RecordTaskTime( |
| 1529 start_time_ticks, end_time_ticks); | 1576 start_time_ticks, end_time_ticks); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1612 case v8::PERFORMANCE_LOAD: | 1659 case v8::PERFORMANCE_LOAD: |
| 1613 return "load"; | 1660 return "load"; |
| 1614 default: | 1661 default: |
| 1615 NOTREACHED(); | 1662 NOTREACHED(); |
| 1616 return nullptr; | 1663 return nullptr; |
| 1617 } | 1664 } |
| 1618 } | 1665 } |
| 1619 | 1666 |
| 1620 } // namespace scheduler | 1667 } // namespace scheduler |
| 1621 } // namespace blink | 1668 } // namespace blink |
| OLD | NEW |