| 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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 policy_may_need_update_(&any_thread_lock_), | 116 policy_may_need_update_(&any_thread_lock_), |
| 117 main_thread_responsiveness_threshold_(kMainThreadResponsivenessThreshold), | 117 main_thread_responsiveness_threshold_(kMainThreadResponsivenessThreshold), |
| 118 weak_factory_(this) { | 118 weak_factory_(this) { |
| 119 task_queue_throttler_.reset( | 119 task_queue_throttler_.reset( |
| 120 new TaskQueueThrottler(this, "renderer.scheduler")); | 120 new TaskQueueThrottler(this, "renderer.scheduler")); |
| 121 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, | 121 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, |
| 122 weak_factory_.GetWeakPtr()); | 122 weak_factory_.GetWeakPtr()); |
| 123 end_renderer_hidden_idle_period_closure_.Reset(base::Bind( | 123 end_renderer_hidden_idle_period_closure_.Reset(base::Bind( |
| 124 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr())); | 124 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr())); |
| 125 | 125 |
| 126 suspend_timers_when_backgrounded_closure_.Reset( | |
| 127 base::Bind(&RendererSchedulerImpl::SuspendTimerQueueWhenBackgrounded, | |
| 128 weak_factory_.GetWeakPtr())); | |
| 129 | |
| 130 default_loading_task_runner_ = | 126 default_loading_task_runner_ = |
| 131 NewLoadingTaskRunner(TaskQueue::QueueType::DEFAULT_LOADING); | 127 NewLoadingTaskRunner(TaskQueue::QueueType::DEFAULT_LOADING); |
| 132 default_timer_task_runner_ = | 128 default_timer_task_runner_ = |
| 133 NewTimerTaskRunner(TaskQueue::QueueType::DEFAULT_TIMER); | 129 NewTimerTaskRunner(TaskQueue::QueueType::DEFAULT_TIMER); |
| 134 | 130 |
| 135 TRACE_EVENT_OBJECT_CREATED_WITH_ID( | 131 TRACE_EVENT_OBJECT_CREATED_WITH_ID( |
| 136 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", | 132 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", |
| 137 this); | 133 this); |
| 138 | 134 |
| 139 helper_.SetObserver(this); | 135 helper_.SetObserver(this); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 base::Bind(&ReportForegroundRendererTaskLoad), | 195 base::Bind(&ReportForegroundRendererTaskLoad), |
| 200 kThreadLoadTrackerReportingInterval, | 196 kThreadLoadTrackerReportingInterval, |
| 201 kThreadLoadTrackerWaitingPeriodBeforeReporting), | 197 kThreadLoadTrackerWaitingPeriodBeforeReporting), |
| 202 current_use_case(UseCase::NONE), | 198 current_use_case(UseCase::NONE), |
| 203 timer_queue_suspend_count(0), | 199 timer_queue_suspend_count(0), |
| 204 navigation_task_expected_count(0), | 200 navigation_task_expected_count(0), |
| 205 expensive_task_policy(ExpensiveTaskPolicy::RUN), | 201 expensive_task_policy(ExpensiveTaskPolicy::RUN), |
| 206 renderer_hidden(false), | 202 renderer_hidden(false), |
| 207 renderer_backgrounded(false), | 203 renderer_backgrounded(false), |
| 208 renderer_suspended(false), | 204 renderer_suspended(false), |
| 209 timer_queue_suspension_when_backgrounded_enabled(false), | |
| 210 timer_queue_suspended_when_backgrounded(false), | 205 timer_queue_suspended_when_backgrounded(false), |
| 211 was_shutdown(false), | 206 was_shutdown(false), |
| 212 loading_tasks_seem_expensive(false), | 207 loading_tasks_seem_expensive(false), |
| 213 timer_tasks_seem_expensive(false), | 208 timer_tasks_seem_expensive(false), |
| 214 touchstart_expected_soon(false), | 209 touchstart_expected_soon(false), |
| 215 have_seen_a_begin_main_frame(false), | 210 have_seen_a_begin_main_frame(false), |
| 216 have_reported_blocking_intervention_in_current_policy(false), | 211 have_reported_blocking_intervention_in_current_policy(false), |
| 217 have_reported_blocking_intervention_since_navigation(false), | 212 have_reported_blocking_intervention_since_navigation(false), |
| 218 has_visible_render_widget_with_touch_handler(false), | 213 has_visible_render_widget_with_touch_handler(false), |
| 219 begin_frame_not_expected_soon(false), | 214 begin_frame_not_expected_soon(false), |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 if (helper_.IsShutdown() || MainThreadOnly().renderer_backgrounded) | 488 if (helper_.IsShutdown() || MainThreadOnly().renderer_backgrounded) |
| 494 return; | 489 return; |
| 495 | 490 |
| 496 MainThreadOnly().renderer_backgrounded = true; | 491 MainThreadOnly().renderer_backgrounded = true; |
| 497 | 492 |
| 498 UpdatePolicy(); | 493 UpdatePolicy(); |
| 499 | 494 |
| 500 base::TimeTicks now = tick_clock()->NowTicks(); | 495 base::TimeTicks now = tick_clock()->NowTicks(); |
| 501 MainThreadOnly().foreground_main_thread_load_tracker.Pause(now); | 496 MainThreadOnly().foreground_main_thread_load_tracker.Pause(now); |
| 502 MainThreadOnly().background_main_thread_load_tracker.Resume(now); | 497 MainThreadOnly().background_main_thread_load_tracker.Resume(now); |
| 503 | |
| 504 if (!MainThreadOnly().timer_queue_suspension_when_backgrounded_enabled) | |
| 505 return; | |
| 506 | |
| 507 suspend_timers_when_backgrounded_closure_.Cancel(); | |
| 508 base::TimeDelta suspend_timers_when_backgrounded_delay = | |
| 509 base::TimeDelta::FromMilliseconds( | |
| 510 kSuspendTimersWhenBackgroundedDelayMillis); | |
| 511 control_task_runner_->PostDelayedTask( | |
| 512 FROM_HERE, suspend_timers_when_backgrounded_closure_.callback(), | |
| 513 suspend_timers_when_backgrounded_delay); | |
| 514 } | 498 } |
| 515 | 499 |
| 516 void RendererSchedulerImpl::OnRendererForegrounded() { | 500 void RendererSchedulerImpl::OnRendererForegrounded() { |
| 517 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 501 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
| 518 "RendererSchedulerImpl::OnRendererForegrounded"); | 502 "RendererSchedulerImpl::OnRendererForegrounded"); |
| 519 helper_.CheckOnValidThread(); | 503 helper_.CheckOnValidThread(); |
| 520 if (helper_.IsShutdown() || !MainThreadOnly().renderer_backgrounded) | 504 if (helper_.IsShutdown() || !MainThreadOnly().renderer_backgrounded) |
| 521 return; | 505 return; |
| 522 | 506 |
| 523 MainThreadOnly().renderer_backgrounded = false; | 507 MainThreadOnly().renderer_backgrounded = false; |
| 524 MainThreadOnly().renderer_suspended = false; | 508 MainThreadOnly().renderer_suspended = false; |
| 525 | 509 |
| 526 UpdatePolicy(); | 510 UpdatePolicy(); |
| 527 | 511 |
| 528 base::TimeTicks now = tick_clock()->NowTicks(); | 512 base::TimeTicks now = tick_clock()->NowTicks(); |
| 529 MainThreadOnly().foreground_main_thread_load_tracker.Resume(now); | 513 MainThreadOnly().foreground_main_thread_load_tracker.Resume(now); |
| 530 MainThreadOnly().background_main_thread_load_tracker.Pause(now); | 514 MainThreadOnly().background_main_thread_load_tracker.Pause(now); |
| 531 | 515 |
| 532 suspend_timers_when_backgrounded_closure_.Cancel(); | |
| 533 ResumeTimerQueueWhenForegroundedOrResumed(); | 516 ResumeTimerQueueWhenForegroundedOrResumed(); |
| 534 } | 517 } |
| 535 | 518 |
| 536 void RendererSchedulerImpl::OnAudioStateChanged() { | 519 void RendererSchedulerImpl::OnAudioStateChanged() { |
| 537 bool is_audio_playing = false; | 520 bool is_audio_playing = false; |
| 538 for (WebViewSchedulerImpl* web_view_scheduler : | 521 for (WebViewSchedulerImpl* web_view_scheduler : |
| 539 MainThreadOnly().web_view_schedulers) { | 522 MainThreadOnly().web_view_schedulers) { |
| 540 is_audio_playing = is_audio_playing || web_view_scheduler->IsAudioPlaying(); | 523 is_audio_playing = is_audio_playing || web_view_scheduler->IsAudioPlaying(); |
| 541 } | 524 } |
| 542 | 525 |
| 543 if (is_audio_playing == MainThreadOnly().is_audio_playing) | 526 if (is_audio_playing == MainThreadOnly().is_audio_playing) |
| 544 return; | 527 return; |
| 545 | 528 |
| 546 MainThreadOnly().last_audio_state_change = | 529 MainThreadOnly().last_audio_state_change = |
| 547 helper_.scheduler_tqm_delegate()->NowTicks(); | 530 helper_.scheduler_tqm_delegate()->NowTicks(); |
| 548 MainThreadOnly().is_audio_playing = is_audio_playing; | 531 MainThreadOnly().is_audio_playing = is_audio_playing; |
| 549 | 532 |
| 550 UpdatePolicy(); | 533 UpdatePolicy(); |
| 551 } | 534 } |
| 552 | 535 |
| 553 void RendererSchedulerImpl::SuspendRenderer() { | 536 void RendererSchedulerImpl::SuspendRenderer() { |
| 554 helper_.CheckOnValidThread(); | 537 helper_.CheckOnValidThread(); |
| 555 if (helper_.IsShutdown()) | 538 if (helper_.IsShutdown()) |
| 556 return; | 539 return; |
| 557 if (!MainThreadOnly().renderer_backgrounded) | 540 if (!MainThreadOnly().renderer_backgrounded) |
| 558 return; | 541 return; |
| 559 suspend_timers_when_backgrounded_closure_.Cancel(); | |
| 560 | 542 |
| 561 UMA_HISTOGRAM_COUNTS("PurgeAndSuspend.PendingTaskCount", | 543 UMA_HISTOGRAM_COUNTS("PurgeAndSuspend.PendingTaskCount", |
| 562 helper_.GetNumberOfPendingTasks()); | 544 helper_.GetNumberOfPendingTasks()); |
| 563 | 545 |
| 564 // TODO(hajimehoshi): We might need to suspend not only timer queue but also | 546 // TODO(hajimehoshi): We might need to suspend not only timer queue but also |
| 565 // e.g. loading tasks or postMessage. | 547 // e.g. loading tasks or postMessage. |
| 566 MainThreadOnly().renderer_suspended = true; | 548 MainThreadOnly().renderer_suspended = true; |
| 567 SuspendTimerQueueWhenBackgrounded(); | 549 SuspendTimerQueueWhenBackgrounded(); |
| 568 } | 550 } |
| 569 | 551 |
| 570 void RendererSchedulerImpl::ResumeRenderer() { | 552 void RendererSchedulerImpl::ResumeRenderer() { |
| 571 helper_.CheckOnValidThread(); | 553 helper_.CheckOnValidThread(); |
| 572 if (helper_.IsShutdown()) | 554 if (helper_.IsShutdown()) |
| 573 return; | 555 return; |
| 574 if (!MainThreadOnly().renderer_backgrounded) | 556 if (!MainThreadOnly().renderer_backgrounded) |
| 575 return; | 557 return; |
| 576 suspend_timers_when_backgrounded_closure_.Cancel(); | 558 |
| 577 MainThreadOnly().renderer_suspended = false; | 559 MainThreadOnly().renderer_suspended = false; |
| 578 ResumeTimerQueueWhenForegroundedOrResumed(); | 560 ResumeTimerQueueWhenForegroundedOrResumed(); |
| 579 } | 561 } |
| 580 | 562 |
| 581 void RendererSchedulerImpl::EndIdlePeriod() { | 563 void RendererSchedulerImpl::EndIdlePeriod() { |
| 582 if (MainThreadOnly().in_idle_period_for_testing) | 564 if (MainThreadOnly().in_idle_period_for_testing) |
| 583 return; | 565 return; |
| 584 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 566 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
| 585 "RendererSchedulerImpl::EndIdlePeriod"); | 567 "RendererSchedulerImpl::EndIdlePeriod"); |
| 586 helper_.CheckOnValidThread(); | 568 helper_.CheckOnValidThread(); |
| (...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1326 } | 1308 } |
| 1327 #endif | 1309 #endif |
| 1328 } | 1310 } |
| 1329 | 1311 |
| 1330 void RendererSchedulerImpl::ResumeTimerQueue() { | 1312 void RendererSchedulerImpl::ResumeTimerQueue() { |
| 1331 MainThreadOnly().timer_queue_suspend_count--; | 1313 MainThreadOnly().timer_queue_suspend_count--; |
| 1332 DCHECK_GE(MainThreadOnly().timer_queue_suspend_count, 0); | 1314 DCHECK_GE(MainThreadOnly().timer_queue_suspend_count, 0); |
| 1333 ForceUpdatePolicy(); | 1315 ForceUpdatePolicy(); |
| 1334 } | 1316 } |
| 1335 | 1317 |
| 1336 void RendererSchedulerImpl::SetTimerQueueSuspensionWhenBackgroundedEnabled( | |
| 1337 bool enabled) { | |
| 1338 // Note that this will only take effect for the next backgrounded signal. | |
| 1339 MainThreadOnly().timer_queue_suspension_when_backgrounded_enabled = enabled; | |
| 1340 } | |
| 1341 | |
| 1342 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> | 1318 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> |
| 1343 RendererSchedulerImpl::AsValue(base::TimeTicks optional_now) const { | 1319 RendererSchedulerImpl::AsValue(base::TimeTicks optional_now) const { |
| 1344 base::AutoLock lock(any_thread_lock_); | 1320 base::AutoLock lock(any_thread_lock_); |
| 1345 return AsValueLocked(optional_now); | 1321 return AsValueLocked(optional_now); |
| 1346 } | 1322 } |
| 1347 | 1323 |
| 1348 void RendererSchedulerImpl::CreateTraceEventObjectSnapshot() const { | 1324 void RendererSchedulerImpl::CreateTraceEventObjectSnapshot() const { |
| 1349 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( | 1325 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( |
| 1350 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", | 1326 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", |
| 1351 this, AsValue(helper_.scheduler_tqm_delegate()->NowTicks())); | 1327 this, AsValue(helper_.scheduler_tqm_delegate()->NowTicks())); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1406 state->SetBoolean("have_seen_input_since_navigation", | 1382 state->SetBoolean("have_seen_input_since_navigation", |
| 1407 AnyThread().have_seen_input_since_navigation); | 1383 AnyThread().have_seen_input_since_navigation); |
| 1408 state->SetBoolean( | 1384 state->SetBoolean( |
| 1409 "have_reported_blocking_intervention_in_current_policy", | 1385 "have_reported_blocking_intervention_in_current_policy", |
| 1410 MainThreadOnly().have_reported_blocking_intervention_in_current_policy); | 1386 MainThreadOnly().have_reported_blocking_intervention_in_current_policy); |
| 1411 state->SetBoolean( | 1387 state->SetBoolean( |
| 1412 "have_reported_blocking_intervention_since_navigation", | 1388 "have_reported_blocking_intervention_since_navigation", |
| 1413 MainThreadOnly().have_reported_blocking_intervention_since_navigation); | 1389 MainThreadOnly().have_reported_blocking_intervention_since_navigation); |
| 1414 state->SetBoolean("renderer_backgrounded", | 1390 state->SetBoolean("renderer_backgrounded", |
| 1415 MainThreadOnly().renderer_backgrounded); | 1391 MainThreadOnly().renderer_backgrounded); |
| 1416 state->SetBoolean("timer_queue_suspended_when_backgrounded", | |
| 1417 MainThreadOnly().timer_queue_suspended_when_backgrounded); | |
| 1418 state->SetInteger("timer_queue_suspend_count", | 1392 state->SetInteger("timer_queue_suspend_count", |
| 1419 MainThreadOnly().timer_queue_suspend_count); | 1393 MainThreadOnly().timer_queue_suspend_count); |
| 1420 state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF()); | 1394 state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF()); |
| 1421 state->SetDouble( | 1395 state->SetDouble( |
| 1422 "fling_compositor_escalation_deadline", | 1396 "fling_compositor_escalation_deadline", |
| 1423 (AnyThread().fling_compositor_escalation_deadline - base::TimeTicks()) | 1397 (AnyThread().fling_compositor_escalation_deadline - base::TimeTicks()) |
| 1424 .InMillisecondsF()); | 1398 .InMillisecondsF()); |
| 1425 state->SetInteger("navigation_task_expected_count", | 1399 state->SetInteger("navigation_task_expected_count", |
| 1426 MainThreadOnly().navigation_task_expected_count); | 1400 MainThreadOnly().navigation_task_expected_count); |
| 1427 state->SetDouble("last_idle_period_end_time", | 1401 state->SetDouble("last_idle_period_end_time", |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1886 case TimeDomainType::VIRTUAL: | 1860 case TimeDomainType::VIRTUAL: |
| 1887 return "virtual"; | 1861 return "virtual"; |
| 1888 default: | 1862 default: |
| 1889 NOTREACHED(); | 1863 NOTREACHED(); |
| 1890 return nullptr; | 1864 return nullptr; |
| 1891 } | 1865 } |
| 1892 } | 1866 } |
| 1893 | 1867 |
| 1894 } // namespace scheduler | 1868 } // namespace scheduler |
| 1895 } // namespace blink | 1869 } // namespace blink |
| OLD | NEW |