| 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.ForegroundRendererLoad", |
| 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.BackgroundRendererLoad", |
| 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 |