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 |