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 |
| 40 void ReportForegroundRendererTaskLoad(base::TimeTicks time, double load) { |
| 41 UMA_HISTOGRAM_PERCENTAGE("RendererScheduler.ForegroundRendererMainThreadLoad", |
| 42 static_cast<int>(load * 100)); |
| 43 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
| 44 "RendererScheduler.ForegroundRendererLoad", load); |
| 45 } |
| 46 |
| 47 void ReportBackgroundRendererTaskLoad(base::TimeTicks time, double load) { |
| 48 UMA_HISTOGRAM_PERCENTAGE("RendererScheduler.BackgroundRendererMainThreadLoad", |
| 49 static_cast<int>(load * 100)); |
| 50 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
| 51 "RendererScheduler.BackgroundRendererLoad", load); |
| 52 } |
| 53 |
39 } // namespace | 54 } // namespace |
40 | 55 |
41 RendererSchedulerImpl::RendererSchedulerImpl( | 56 RendererSchedulerImpl::RendererSchedulerImpl( |
42 scoped_refptr<SchedulerTqmDelegate> main_task_runner) | 57 scoped_refptr<SchedulerTqmDelegate> main_task_runner) |
43 : helper_(main_task_runner, | 58 : helper_(main_task_runner, |
44 "renderer.scheduler", | 59 "renderer.scheduler", |
45 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 60 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
46 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")), | 61 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")), |
47 idle_helper_(&helper_, | 62 idle_helper_(&helper_, |
48 this, | 63 this, |
49 "renderer.scheduler", | 64 "renderer.scheduler", |
50 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 65 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
51 "RendererSchedulerIdlePeriod", | 66 "RendererSchedulerIdlePeriod", |
52 base::TimeDelta()), | 67 base::TimeDelta()), |
53 render_widget_scheduler_signals_(this), | 68 render_widget_scheduler_signals_(this), |
54 control_task_runner_(helper_.ControlTaskRunner()), | 69 control_task_runner_(helper_.ControlTaskRunner()), |
55 compositor_task_runner_(helper_.NewTaskQueue( | 70 compositor_task_runner_(helper_.NewTaskQueue( |
56 TaskQueue::Spec("compositor_tq").SetShouldMonitorQuiescence(true))), | 71 TaskQueue::Spec("compositor_tq").SetShouldMonitorQuiescence(true))), |
57 delayed_update_policy_runner_( | 72 delayed_update_policy_runner_( |
58 base::Bind(&RendererSchedulerImpl::UpdatePolicy, | 73 base::Bind(&RendererSchedulerImpl::UpdatePolicy, |
59 base::Unretained(this)), | 74 base::Unretained(this)), |
60 helper_.ControlTaskRunner()), | 75 helper_.ControlTaskRunner()), |
61 main_thread_only_(this, | 76 main_thread_only_(this, |
62 compositor_task_runner_, | 77 compositor_task_runner_, |
63 helper_.scheduler_tqm_delegate().get()), | 78 helper_.scheduler_tqm_delegate().get(), |
| 79 helper_.scheduler_tqm_delegate()->NowTicks()), |
64 policy_may_need_update_(&any_thread_lock_), | 80 policy_may_need_update_(&any_thread_lock_), |
65 weak_factory_(this) { | 81 weak_factory_(this) { |
66 throttling_helper_.reset(new ThrottlingHelper(this, "renderer.scheduler")); | 82 throttling_helper_.reset(new ThrottlingHelper(this, "renderer.scheduler")); |
67 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, | 83 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, |
68 weak_factory_.GetWeakPtr()); | 84 weak_factory_.GetWeakPtr()); |
69 end_renderer_hidden_idle_period_closure_.Reset(base::Bind( | 85 end_renderer_hidden_idle_period_closure_.Reset(base::Bind( |
70 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr())); | 86 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr())); |
71 | 87 |
72 suspend_timers_when_backgrounded_closure_.Reset( | 88 suspend_timers_when_backgrounded_closure_.Reset( |
73 base::Bind(&RendererSchedulerImpl::SuspendTimerQueueWhenBackgrounded, | 89 base::Bind(&RendererSchedulerImpl::SuspendTimerQueueWhenBackgrounded, |
(...skipping 29 matching lines...) Expand all Loading... |
103 | 119 |
104 // Ensure the renderer scheduler was shut down explicitly, because otherwise | 120 // 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 | 121 // we could end up having stale pointers to the Blink heap which has been |
106 // terminated by this point. | 122 // terminated by this point. |
107 DCHECK(MainThreadOnly().was_shutdown); | 123 DCHECK(MainThreadOnly().was_shutdown); |
108 } | 124 } |
109 | 125 |
110 RendererSchedulerImpl::MainThreadOnly::MainThreadOnly( | 126 RendererSchedulerImpl::MainThreadOnly::MainThreadOnly( |
111 RendererSchedulerImpl* renderer_scheduler_impl, | 127 RendererSchedulerImpl* renderer_scheduler_impl, |
112 const scoped_refptr<TaskQueue>& compositor_task_runner, | 128 const scoped_refptr<TaskQueue>& compositor_task_runner, |
113 base::TickClock* time_source) | 129 base::TickClock* time_source, |
| 130 base::TimeTicks now) |
114 : loading_task_cost_estimator(time_source, | 131 : loading_task_cost_estimator(time_source, |
115 kLoadingTaskEstimationSampleCount, | 132 kLoadingTaskEstimationSampleCount, |
116 kLoadingTaskEstimationPercentile), | 133 kLoadingTaskEstimationPercentile), |
117 timer_task_cost_estimator(time_source, | 134 timer_task_cost_estimator(time_source, |
118 kTimerTaskEstimationSampleCount, | 135 kTimerTaskEstimationSampleCount, |
119 kTimerTaskEstimationPercentile), | 136 kTimerTaskEstimationPercentile), |
120 queueing_time_estimator(renderer_scheduler_impl, | 137 queueing_time_estimator(renderer_scheduler_impl, |
121 base::TimeDelta::FromSeconds(1)), | 138 base::TimeDelta::FromSeconds(1)), |
122 idle_time_estimator(compositor_task_runner, | 139 idle_time_estimator(compositor_task_runner, |
123 time_source, | 140 time_source, |
124 kShortIdlePeriodDurationSampleCount, | 141 kShortIdlePeriodDurationSampleCount, |
125 kShortIdlePeriodDurationPercentile), | 142 kShortIdlePeriodDurationPercentile), |
| 143 background_main_thread_load_tracker( |
| 144 now, |
| 145 base::Bind(&ReportBackgroundRendererTaskLoad)), |
| 146 foreground_main_thread_load_tracker( |
| 147 now, |
| 148 base::Bind(&ReportForegroundRendererTaskLoad)), |
126 current_use_case(UseCase::NONE), | 149 current_use_case(UseCase::NONE), |
127 timer_queue_suspend_count(0), | 150 timer_queue_suspend_count(0), |
128 navigation_task_expected_count(0), | 151 navigation_task_expected_count(0), |
129 expensive_task_policy(ExpensiveTaskPolicy::RUN), | 152 expensive_task_policy(ExpensiveTaskPolicy::RUN), |
130 renderer_hidden(false), | 153 renderer_hidden(false), |
131 renderer_backgrounded(false), | 154 renderer_backgrounded(false), |
132 renderer_suspended(false), | 155 renderer_suspended(false), |
133 timer_queue_suspension_when_backgrounded_enabled(false), | 156 timer_queue_suspension_when_backgrounded_enabled(false), |
134 timer_queue_suspended_when_backgrounded(false), | 157 timer_queue_suspended_when_backgrounded(false), |
135 was_shutdown(false), | 158 was_shutdown(false), |
(...skipping 20 matching lines...) Expand all Loading... |
156 have_seen_touchstart(false) {} | 179 have_seen_touchstart(false) {} |
157 | 180 |
158 RendererSchedulerImpl::AnyThread::~AnyThread() {} | 181 RendererSchedulerImpl::AnyThread::~AnyThread() {} |
159 | 182 |
160 RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly() | 183 RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly() |
161 : last_input_type(blink::WebInputEvent::Undefined) {} | 184 : last_input_type(blink::WebInputEvent::Undefined) {} |
162 | 185 |
163 RendererSchedulerImpl::CompositorThreadOnly::~CompositorThreadOnly() {} | 186 RendererSchedulerImpl::CompositorThreadOnly::~CompositorThreadOnly() {} |
164 | 187 |
165 void RendererSchedulerImpl::Shutdown() { | 188 void RendererSchedulerImpl::Shutdown() { |
| 189 base::TimeTicks now = tick_clock()->NowTicks(); |
| 190 MainThreadOnly().background_main_thread_load_tracker.RecordIdle(now); |
| 191 MainThreadOnly().foreground_main_thread_load_tracker.RecordIdle(now); |
| 192 |
166 throttling_helper_.reset(); | 193 throttling_helper_.reset(); |
167 helper_.Shutdown(); | 194 helper_.Shutdown(); |
168 MainThreadOnly().was_shutdown = true; | 195 MainThreadOnly().was_shutdown = true; |
169 MainThreadOnly().rail_mode_observer = nullptr; | 196 MainThreadOnly().rail_mode_observer = nullptr; |
170 } | 197 } |
171 | 198 |
172 std::unique_ptr<blink::WebThread> RendererSchedulerImpl::CreateMainThread() { | 199 std::unique_ptr<blink::WebThread> RendererSchedulerImpl::CreateMainThread() { |
173 return base::MakeUnique<WebThreadImplForRendererScheduler>(this); | 200 return base::MakeUnique<WebThreadImplForRendererScheduler>(this); |
174 } | 201 } |
175 | 202 |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 } | 425 } |
399 | 426 |
400 void RendererSchedulerImpl::OnRendererBackgrounded() { | 427 void RendererSchedulerImpl::OnRendererBackgrounded() { |
401 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 428 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
402 "RendererSchedulerImpl::OnRendererBackgrounded"); | 429 "RendererSchedulerImpl::OnRendererBackgrounded"); |
403 helper_.CheckOnValidThread(); | 430 helper_.CheckOnValidThread(); |
404 if (helper_.IsShutdown() || MainThreadOnly().renderer_backgrounded) | 431 if (helper_.IsShutdown() || MainThreadOnly().renderer_backgrounded) |
405 return; | 432 return; |
406 | 433 |
407 MainThreadOnly().renderer_backgrounded = true; | 434 MainThreadOnly().renderer_backgrounded = true; |
| 435 |
| 436 base::TimeTicks now = tick_clock()->NowTicks(); |
| 437 MainThreadOnly().foreground_main_thread_load_tracker.Pause(now); |
| 438 MainThreadOnly().background_main_thread_load_tracker.Resume(now); |
| 439 |
408 if (!MainThreadOnly().timer_queue_suspension_when_backgrounded_enabled) | 440 if (!MainThreadOnly().timer_queue_suspension_when_backgrounded_enabled) |
409 return; | 441 return; |
410 | 442 |
411 suspend_timers_when_backgrounded_closure_.Cancel(); | 443 suspend_timers_when_backgrounded_closure_.Cancel(); |
412 base::TimeDelta suspend_timers_when_backgrounded_delay = | 444 base::TimeDelta suspend_timers_when_backgrounded_delay = |
413 base::TimeDelta::FromMilliseconds( | 445 base::TimeDelta::FromMilliseconds( |
414 kSuspendTimersWhenBackgroundedDelayMillis); | 446 kSuspendTimersWhenBackgroundedDelayMillis); |
415 control_task_runner_->PostDelayedTask( | 447 control_task_runner_->PostDelayedTask( |
416 FROM_HERE, suspend_timers_when_backgrounded_closure_.callback(), | 448 FROM_HERE, suspend_timers_when_backgrounded_closure_.callback(), |
417 suspend_timers_when_backgrounded_delay); | 449 suspend_timers_when_backgrounded_delay); |
418 } | 450 } |
419 | 451 |
420 void RendererSchedulerImpl::OnRendererForegrounded() { | 452 void RendererSchedulerImpl::OnRendererForegrounded() { |
421 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 453 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
422 "RendererSchedulerImpl::OnRendererForegrounded"); | 454 "RendererSchedulerImpl::OnRendererForegrounded"); |
423 helper_.CheckOnValidThread(); | 455 helper_.CheckOnValidThread(); |
424 if (helper_.IsShutdown() || !MainThreadOnly().renderer_backgrounded) | 456 if (helper_.IsShutdown() || !MainThreadOnly().renderer_backgrounded) |
425 return; | 457 return; |
426 | 458 |
427 MainThreadOnly().renderer_backgrounded = false; | 459 MainThreadOnly().renderer_backgrounded = false; |
428 MainThreadOnly().renderer_suspended = false; | 460 MainThreadOnly().renderer_suspended = false; |
| 461 |
| 462 base::TimeTicks now = tick_clock()->NowTicks(); |
| 463 MainThreadOnly().foreground_main_thread_load_tracker.Resume(now); |
| 464 MainThreadOnly().background_main_thread_load_tracker.Pause(now); |
| 465 |
429 suspend_timers_when_backgrounded_closure_.Cancel(); | 466 suspend_timers_when_backgrounded_closure_.Cancel(); |
430 ResumeTimerQueueWhenForegrounded(); | 467 ResumeTimerQueueWhenForegrounded(); |
431 } | 468 } |
432 | 469 |
433 void RendererSchedulerImpl::SuspendRenderer() { | 470 void RendererSchedulerImpl::SuspendRenderer() { |
434 helper_.CheckOnValidThread(); | 471 helper_.CheckOnValidThread(); |
435 DCHECK(MainThreadOnly().renderer_backgrounded); | 472 DCHECK(MainThreadOnly().renderer_backgrounded); |
436 if (helper_.IsShutdown()) | 473 if (helper_.IsShutdown()) |
437 return; | 474 return; |
438 suspend_timers_when_backgrounded_closure_.Cancel(); | 475 suspend_timers_when_backgrounded_closure_.Cancel(); |
(...skipping 967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1406 " and https://crbug.com/574343#c40 for more information."); | 1443 " and https://crbug.com/574343#c40 for more information."); |
1407 } | 1444 } |
1408 } | 1445 } |
1409 | 1446 |
1410 void RendererSchedulerImpl::ReportTaskTime(base::TimeTicks start_time, | 1447 void RendererSchedulerImpl::ReportTaskTime(base::TimeTicks start_time, |
1411 base::TimeTicks end_time) { | 1448 base::TimeTicks end_time) { |
1412 MainThreadOnly().queueing_time_estimator.OnToplevelTaskCompleted(start_time, | 1449 MainThreadOnly().queueing_time_estimator.OnToplevelTaskCompleted(start_time, |
1413 end_time); | 1450 end_time); |
1414 MainThreadOnly().long_task_tracker.RecordLongTask( | 1451 MainThreadOnly().long_task_tracker.RecordLongTask( |
1415 start_time, end_time - start_time); | 1452 start_time, end_time - start_time); |
| 1453 // We want to measure thread time here, but for efficiency reasons |
| 1454 // we stick with wall time. |
| 1455 MainThreadOnly().foreground_main_thread_load_tracker.RecordTaskTime( |
| 1456 start_time, end_time); |
| 1457 MainThreadOnly().background_main_thread_load_tracker.RecordTaskTime( |
| 1458 start_time, end_time); |
| 1459 // TODO(altimin): Per-page metrics should also be considered. |
1416 UMA_HISTOGRAM_CUSTOM_COUNTS("RendererScheduler.TaskTime", | 1460 UMA_HISTOGRAM_CUSTOM_COUNTS("RendererScheduler.TaskTime", |
1417 (end_time - start_time).InMicroseconds(), 1, | 1461 (end_time - start_time).InMicroseconds(), 1, |
1418 1000000, 50); | 1462 1000000, 50); |
1419 } | 1463 } |
1420 | 1464 |
1421 LongTaskTracker::LongTaskTiming RendererSchedulerImpl::GetLongTaskTiming() { | 1465 LongTaskTracker::LongTaskTiming RendererSchedulerImpl::GetLongTaskTiming() { |
1422 return MainThreadOnly().long_task_tracker.GetLongTaskTiming(); | 1466 return MainThreadOnly().long_task_tracker.GetLongTaskTiming(); |
1423 } | 1467 } |
1424 | 1468 |
1425 void RendererSchedulerImpl::OnQueueingTimeForWindowEstimated( | 1469 void RendererSchedulerImpl::OnQueueingTimeForWindowEstimated( |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1488 case v8::PERFORMANCE_LOAD: | 1532 case v8::PERFORMANCE_LOAD: |
1489 return "load"; | 1533 return "load"; |
1490 default: | 1534 default: |
1491 NOTREACHED(); | 1535 NOTREACHED(); |
1492 return nullptr; | 1536 return nullptr; |
1493 } | 1537 } |
1494 } | 1538 } |
1495 | 1539 |
1496 } // namespace scheduler | 1540 } // namespace scheduler |
1497 } // namespace blink | 1541 } // namespace blink |
OLD | NEW |