Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(276)

Side by Side Diff: third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc

Issue 2408003002: Revert "[scheduler] Teach scheduler about audio state" (Closed)
Patch Set: Rebase. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
11 #include "base/metrics/histogram_macros.h" 11 #include "base/metrics/histogram_macros.h"
12 #include "base/trace_event/trace_event.h" 12 #include "base/trace_event/trace_event.h"
13 #include "base/trace_event/trace_event_argument.h" 13 #include "base/trace_event/trace_event_argument.h"
14 #include "cc/output/begin_frame_args.h" 14 #include "cc/output/begin_frame_args.h"
15 #include "platform/scheduler/base/real_time_domain.h"
16 #include "platform/scheduler/base/task_queue_impl.h" 15 #include "platform/scheduler/base/task_queue_impl.h"
17 #include "platform/scheduler/base/task_queue_selector.h" 16 #include "platform/scheduler/base/task_queue_selector.h"
18 #include "platform/scheduler/base/virtual_time_domain.h" 17 #include "platform/scheduler/base/virtual_time_domain.h"
19 #include "platform/scheduler/child/scheduler_tqm_delegate.h" 18 #include "platform/scheduler/child/scheduler_tqm_delegate.h"
20 #include "platform/scheduler/renderer/auto_advancing_virtual_time_domain.h" 19 #include "platform/scheduler/renderer/auto_advancing_virtual_time_domain.h"
21 #include "platform/scheduler/renderer/task_queue_throttler.h" 20 #include "platform/scheduler/renderer/task_queue_throttler.h"
22 #include "platform/scheduler/renderer/web_view_scheduler_impl.h" 21 #include "platform/scheduler/renderer/web_view_scheduler_impl.h"
23 #include "platform/scheduler/renderer/webthread_impl_for_renderer_scheduler.h" 22 #include "platform/scheduler/renderer/webthread_impl_for_renderer_scheduler.h"
24 23
25 namespace blink { 24 namespace blink {
26 namespace scheduler { 25 namespace scheduler {
27 namespace { 26 namespace {
28 // The run time of loading tasks is strongly bimodal. The vast majority are 27 // The run time of loading tasks is strongly bimodal. The vast majority are
29 // very cheap, but there are usually a handful of very expensive tasks (e.g ~1 28 // very cheap, but there are usually a handful of very expensive tasks (e.g ~1
30 // second on a mobile device) so we take a very pessimistic view when estimating 29 // second on a mobile device) so we take a very pessimistic view when estimating
31 // the cost of loading tasks. 30 // the cost of loading tasks.
32 const int kLoadingTaskEstimationSampleCount = 1000; 31 const int kLoadingTaskEstimationSampleCount = 1000;
33 const double kLoadingTaskEstimationPercentile = 99; 32 const double kLoadingTaskEstimationPercentile = 99;
34 const int kTimerTaskEstimationSampleCount = 1000; 33 const int kTimerTaskEstimationSampleCount = 1000;
35 const double kTimerTaskEstimationPercentile = 99; 34 const double kTimerTaskEstimationPercentile = 99;
36 const int kShortIdlePeriodDurationSampleCount = 10; 35 const int kShortIdlePeriodDurationSampleCount = 10;
37 const double kShortIdlePeriodDurationPercentile = 50; 36 const double kShortIdlePeriodDurationPercentile = 50;
38 // Amount of idle time left in a frame (as a ratio of the vsync interval) above 37 // Amount of idle time left in a frame (as a ratio of the vsync interval) above
39 // which main thread compositing can be considered fast. 38 // which main thread compositing can be considered fast.
40 const double kFastCompositingIdleTimeThreshold = .2; 39 const double kFastCompositingIdleTimeThreshold = .2;
41 // We do not throttle anything while audio is played and shortly after that.
42 constexpr base::TimeDelta kThrottlingDelayAfterAudioIsPlayed =
43 base::TimeDelta::FromSeconds(5);
44 constexpr base::TimeDelta kThreadLoadTrackerReportingInterval = 40 constexpr base::TimeDelta kThreadLoadTrackerReportingInterval =
45 base::TimeDelta::FromMinutes(1); 41 base::TimeDelta::FromMinutes(1);
46 constexpr base::TimeDelta kThreadLoadTrackerWaitingPeriodBeforeReporting = 42 constexpr base::TimeDelta kThreadLoadTrackerWaitingPeriodBeforeReporting =
47 base::TimeDelta::FromMinutes(2); 43 base::TimeDelta::FromMinutes(2);
48 44
49 void ReportForegroundRendererTaskLoad(base::TimeTicks time, double load) { 45 void ReportForegroundRendererTaskLoad(base::TimeTicks time, double load) {
50 int load_percentage = static_cast<int>(load * 100); 46 int load_percentage = static_cast<int>(load * 100);
51 UMA_HISTOGRAM_PERCENTAGE("RendererScheduler.ForegroundRendererMainThreadLoad", 47 UMA_HISTOGRAM_PERCENTAGE("RendererScheduler.ForegroundRendererMainThreadLoad",
52 load_percentage); 48 load_percentage);
53 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 49 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 loading_tasks_seem_expensive(false), 178 loading_tasks_seem_expensive(false),
183 timer_tasks_seem_expensive(false), 179 timer_tasks_seem_expensive(false),
184 touchstart_expected_soon(false), 180 touchstart_expected_soon(false),
185 have_seen_a_begin_main_frame(false), 181 have_seen_a_begin_main_frame(false),
186 have_reported_blocking_intervention_in_current_policy(false), 182 have_reported_blocking_intervention_in_current_policy(false),
187 have_reported_blocking_intervention_since_navigation(false), 183 have_reported_blocking_intervention_since_navigation(false),
188 has_visible_render_widget_with_touch_handler(false), 184 has_visible_render_widget_with_touch_handler(false),
189 begin_frame_not_expected_soon(false), 185 begin_frame_not_expected_soon(false),
190 in_idle_period_for_testing(false), 186 in_idle_period_for_testing(false),
191 use_virtual_time(false), 187 use_virtual_time(false),
192 is_audio_playing(false),
193 rail_mode_observer(nullptr) {} 188 rail_mode_observer(nullptr) {}
194 189
195 RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {} 190 RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {}
196 191
197 RendererSchedulerImpl::AnyThread::AnyThread() 192 RendererSchedulerImpl::AnyThread::AnyThread()
198 : awaiting_touch_start_response(false), 193 : awaiting_touch_start_response(false),
199 in_idle_period(false), 194 in_idle_period(false),
200 begin_main_frame_on_critical_path(false), 195 begin_main_frame_on_critical_path(false),
201 last_gesture_was_compositor_driven(false), 196 last_gesture_was_compositor_driven(false),
202 default_gesture_prevented(true), 197 default_gesture_prevented(true),
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 MainThreadOnly().renderer_suspended = false; 477 MainThreadOnly().renderer_suspended = false;
483 478
484 base::TimeTicks now = tick_clock()->NowTicks(); 479 base::TimeTicks now = tick_clock()->NowTicks();
485 MainThreadOnly().foreground_main_thread_load_tracker.Resume(now); 480 MainThreadOnly().foreground_main_thread_load_tracker.Resume(now);
486 MainThreadOnly().background_main_thread_load_tracker.Pause(now); 481 MainThreadOnly().background_main_thread_load_tracker.Pause(now);
487 482
488 suspend_timers_when_backgrounded_closure_.Cancel(); 483 suspend_timers_when_backgrounded_closure_.Cancel();
489 ResumeTimerQueueWhenForegrounded(); 484 ResumeTimerQueueWhenForegrounded();
490 } 485 }
491 486
492 void RendererSchedulerImpl::OnAudioStateChanged() {
493 bool is_audio_playing = false;
494 for (WebViewSchedulerImpl* web_view_scheduler :
495 MainThreadOnly().web_view_schedulers) {
496 is_audio_playing = is_audio_playing || web_view_scheduler->IsAudioPlaying();
497 }
498
499 if (is_audio_playing == MainThreadOnly().is_audio_playing)
500 return;
501
502 MainThreadOnly().last_audio_state_change =
503 helper_.scheduler_tqm_delegate()->NowTicks();
504 MainThreadOnly().is_audio_playing = is_audio_playing;
505
506 UpdatePolicy();
507 }
508
509 void RendererSchedulerImpl::SuspendRenderer() { 487 void RendererSchedulerImpl::SuspendRenderer() {
510 helper_.CheckOnValidThread(); 488 helper_.CheckOnValidThread();
511 DCHECK(MainThreadOnly().renderer_backgrounded); 489 DCHECK(MainThreadOnly().renderer_backgrounded);
512 if (helper_.IsShutdown()) 490 if (helper_.IsShutdown())
513 return; 491 return;
514 suspend_timers_when_backgrounded_closure_.Cancel(); 492 suspend_timers_when_backgrounded_closure_.Cancel();
515 // TODO(hajimehoshi): We might need to suspend not only timer queue but also 493 // TODO(hajimehoshi): We might need to suspend not only timer queue but also
516 // e.g. loading tasks or postMessage. 494 // e.g. loading tasks or postMessage.
517 MainThreadOnly().renderer_suspended = true; 495 MainThreadOnly().renderer_suspended = true;
518 SuspendTimerQueueWhenBackgrounded(); 496 SuspendTimerQueueWhenBackgrounded();
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 // The |new_policy_duration| is the minimum of |expected_use_case_duration| 807 // The |new_policy_duration| is the minimum of |expected_use_case_duration|
830 // and |touchstart_expected_flag_valid_for_duration| unless one is zero in 808 // and |touchstart_expected_flag_valid_for_duration| unless one is zero in
831 // which case we choose the other. 809 // which case we choose the other.
832 base::TimeDelta new_policy_duration = expected_use_case_duration; 810 base::TimeDelta new_policy_duration = expected_use_case_duration;
833 if (new_policy_duration.is_zero() || 811 if (new_policy_duration.is_zero() ||
834 (touchstart_expected_flag_valid_for_duration > base::TimeDelta() && 812 (touchstart_expected_flag_valid_for_duration > base::TimeDelta() &&
835 new_policy_duration > touchstart_expected_flag_valid_for_duration)) { 813 new_policy_duration > touchstart_expected_flag_valid_for_duration)) {
836 new_policy_duration = touchstart_expected_flag_valid_for_duration; 814 new_policy_duration = touchstart_expected_flag_valid_for_duration;
837 } 815 }
838 816
839 // Do not throttle while audio is playing or for a short period after that
840 // to make sure that pages playing short audio clips powered by timers
841 // work.
842 if (MainThreadOnly().last_audio_state_change &&
843 !MainThreadOnly().is_audio_playing) {
844 base::TimeTicks audio_will_expire =
845 MainThreadOnly().last_audio_state_change.value() +
846 kThrottlingDelayAfterAudioIsPlayed;
847
848 base::TimeDelta audio_will_expire_after = audio_will_expire - now;
849
850 if (audio_will_expire_after > base::TimeDelta()) {
851 if (new_policy_duration.is_zero()) {
852 new_policy_duration = audio_will_expire_after;
853 } else {
854 new_policy_duration =
855 std::min(new_policy_duration, audio_will_expire_after);
856 }
857 }
858 }
859
860 if (new_policy_duration > base::TimeDelta()) { 817 if (new_policy_duration > base::TimeDelta()) {
861 MainThreadOnly().current_policy_expiration_time = now + new_policy_duration; 818 MainThreadOnly().current_policy_expiration_time = now + new_policy_duration;
862 delayed_update_policy_runner_.SetDeadline(FROM_HERE, new_policy_duration, 819 delayed_update_policy_runner_.SetDeadline(FROM_HERE, new_policy_duration,
863 now); 820 now);
864 } else { 821 } else {
865 MainThreadOnly().current_policy_expiration_time = base::TimeTicks(); 822 MainThreadOnly().current_policy_expiration_time = base::TimeTicks();
866 } 823 }
867 824
868 // Avoid prioritizing main thread compositing (e.g., rAF) if it is extremely 825 // Avoid prioritizing main thread compositing (e.g., rAF) if it is extremely
869 // slow, because that can cause starvation in other task sources. 826 // slow, because that can cause starvation in other task sources.
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1005 } 962 }
1006 963
1007 if (MainThreadOnly().use_virtual_time) { 964 if (MainThreadOnly().use_virtual_time) {
1008 new_policy.compositor_queue_policy.time_domain_type = 965 new_policy.compositor_queue_policy.time_domain_type =
1009 TimeDomainType::VIRTUAL; 966 TimeDomainType::VIRTUAL;
1010 new_policy.default_queue_policy.time_domain_type = TimeDomainType::VIRTUAL; 967 new_policy.default_queue_policy.time_domain_type = TimeDomainType::VIRTUAL;
1011 new_policy.loading_queue_policy.time_domain_type = TimeDomainType::VIRTUAL; 968 new_policy.loading_queue_policy.time_domain_type = TimeDomainType::VIRTUAL;
1012 new_policy.timer_queue_policy.time_domain_type = TimeDomainType::VIRTUAL; 969 new_policy.timer_queue_policy.time_domain_type = TimeDomainType::VIRTUAL;
1013 } 970 }
1014 971
1015 new_policy.should_disable_throttling =
1016 ShouldDisableThrottlingBecauseOfAudio(now) ||
1017 MainThreadOnly().use_virtual_time;
1018
1019 // Tracing is done before the early out check, because it's quite possible we 972 // Tracing is done before the early out check, because it's quite possible we
1020 // will otherwise miss this information in traces. 973 // will otherwise miss this information in traces.
1021 CreateTraceEventObjectSnapshotLocked(); 974 CreateTraceEventObjectSnapshotLocked();
1022 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "use_case", 975 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "use_case",
1023 use_case); 976 use_case);
1024 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "rail_mode", 977 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "rail_mode",
1025 new_policy.rail_mode); 978 new_policy.rail_mode);
1026 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 979 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
1027 "touchstart_expected_soon", 980 "touchstart_expected_soon",
1028 MainThreadOnly().touchstart_expected_soon); 981 MainThreadOnly().touchstart_expected_soon);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 // are mostly dispatched on the default queue) need to be preserved. 1017 // are mostly dispatched on the default queue) need to be preserved.
1065 ApplyTaskQueuePolicy(helper_.DefaultTaskRunner().get(), 1018 ApplyTaskQueuePolicy(helper_.DefaultTaskRunner().get(),
1066 MainThreadOnly().current_policy.default_queue_policy, 1019 MainThreadOnly().current_policy.default_queue_policy,
1067 new_policy.default_queue_policy); 1020 new_policy.default_queue_policy);
1068 if (MainThreadOnly().rail_mode_observer && 1021 if (MainThreadOnly().rail_mode_observer &&
1069 new_policy.rail_mode != MainThreadOnly().current_policy.rail_mode) { 1022 new_policy.rail_mode != MainThreadOnly().current_policy.rail_mode) {
1070 MainThreadOnly().rail_mode_observer->OnRAILModeChanged( 1023 MainThreadOnly().rail_mode_observer->OnRAILModeChanged(
1071 new_policy.rail_mode); 1024 new_policy.rail_mode);
1072 } 1025 }
1073 1026
1074 if (new_policy.should_disable_throttling !=
1075 MainThreadOnly().current_policy.should_disable_throttling) {
1076 if (new_policy.should_disable_throttling) {
1077 task_queue_throttler()->DisableThrottling();
1078 } else {
1079 task_queue_throttler()->EnableThrottling();
1080 }
1081 }
1082
1083 DCHECK(compositor_task_runner_->IsQueueEnabled()); 1027 DCHECK(compositor_task_runner_->IsQueueEnabled());
1084 MainThreadOnly().current_policy = new_policy; 1028 MainThreadOnly().current_policy = new_policy;
1085 } 1029 }
1086 1030
1087 void RendererSchedulerImpl::ApplyTaskQueuePolicy( 1031 void RendererSchedulerImpl::ApplyTaskQueuePolicy(
1088 TaskQueue* task_queue, 1032 TaskQueue* task_queue,
1089 const TaskQueuePolicy& old_task_queue_policy, 1033 const TaskQueuePolicy& old_task_queue_policy,
1090 const TaskQueuePolicy& new_task_queue_policy) const { 1034 const TaskQueuePolicy& new_task_queue_policy) const {
1091 if (old_task_queue_policy.is_enabled != new_task_queue_policy.is_enabled) { 1035 if (old_task_queue_policy.is_enabled != new_task_queue_policy.is_enabled) {
1092 task_queue_throttler_->SetQueueEnabled(task_queue, 1036 task_queue_throttler_->SetQueueEnabled(task_queue,
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after
1595 } 1539 }
1596 1540
1597 void RendererSchedulerImpl::EnableVirtualTime() { 1541 void RendererSchedulerImpl::EnableVirtualTime() {
1598 MainThreadOnly().use_virtual_time = true; 1542 MainThreadOnly().use_virtual_time = true;
1599 1543
1600 // The |unthrottled_task_runners_| are not actively managed by UpdatePolicy(). 1544 // The |unthrottled_task_runners_| are not actively managed by UpdatePolicy().
1601 AutoAdvancingVirtualTimeDomain* time_domain = GetVirtualTimeDomain(); 1545 AutoAdvancingVirtualTimeDomain* time_domain = GetVirtualTimeDomain();
1602 for (const scoped_refptr<TaskQueue>& task_queue : unthrottled_task_runners_) 1546 for (const scoped_refptr<TaskQueue>& task_queue : unthrottled_task_runners_)
1603 task_queue->SetTimeDomain(time_domain); 1547 task_queue->SetTimeDomain(time_domain);
1604 1548
1549 task_queue_throttler_->EnableVirtualTime();
1550
1605 ForceUpdatePolicy(); 1551 ForceUpdatePolicy();
1606 } 1552 }
1607 1553
1608 bool RendererSchedulerImpl::ShouldDisableThrottlingBecauseOfAudio(
1609 base::TimeTicks now) {
1610 if (!MainThreadOnly().last_audio_state_change)
1611 return false;
1612
1613 if (MainThreadOnly().is_audio_playing)
1614 return true;
1615
1616 return MainThreadOnly().last_audio_state_change.value() +
1617 kThrottlingDelayAfterAudioIsPlayed >
1618 now;
1619 }
1620
1621 TimeDomain* RendererSchedulerImpl::GetActiveTimeDomain() {
1622 if (MainThreadOnly().use_virtual_time) {
1623 return GetVirtualTimeDomain();
1624 } else {
1625 return real_time_domain();
1626 }
1627 }
1628
1629 // static 1554 // static
1630 const char* RendererSchedulerImpl::UseCaseToString(UseCase use_case) { 1555 const char* RendererSchedulerImpl::UseCaseToString(UseCase use_case) {
1631 switch (use_case) { 1556 switch (use_case) {
1632 case UseCase::NONE: 1557 case UseCase::NONE:
1633 return "none"; 1558 return "none";
1634 case UseCase::COMPOSITOR_GESTURE: 1559 case UseCase::COMPOSITOR_GESTURE:
1635 return "compositor_gesture"; 1560 return "compositor_gesture";
1636 case UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING: 1561 case UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING:
1637 return "main_thread_custom_input_handling"; 1562 return "main_thread_custom_input_handling";
1638 case UseCase::SYNCHRONIZED_GESTURE: 1563 case UseCase::SYNCHRONIZED_GESTURE:
(...skipping 22 matching lines...) Expand all
1661 case v8::PERFORMANCE_LOAD: 1586 case v8::PERFORMANCE_LOAD:
1662 return "load"; 1587 return "load";
1663 default: 1588 default:
1664 NOTREACHED(); 1589 NOTREACHED();
1665 return nullptr; 1590 return nullptr;
1666 } 1591 }
1667 } 1592 }
1668 1593
1669 } // namespace scheduler 1594 } // namespace scheduler
1670 } // namespace blink 1595 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698