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 |