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 |