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

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

Issue 2483843002: Revert of [scheduler] Teach scheduler about audio state (Closed)
Patch Set: Rebase Created 4 years, 1 month 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 constexpr base::TimeDelta kThreadLoadTrackerReportingInterval = 40 constexpr base::TimeDelta kThreadLoadTrackerReportingInterval =
42 base::TimeDelta::FromMinutes(1); 41 base::TimeDelta::FromMinutes(1);
43 constexpr base::TimeDelta kThreadLoadTrackerWaitingPeriodBeforeReporting = 42 constexpr base::TimeDelta kThreadLoadTrackerWaitingPeriodBeforeReporting =
44 base::TimeDelta::FromMinutes(2); 43 base::TimeDelta::FromMinutes(2);
45 // We do not throttle anything while audio is played and shortly after that.
46 constexpr base::TimeDelta kThrottlingDelayAfterAudioIsPlayed =
47 base::TimeDelta::FromSeconds(5);
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"),
54 "RendererScheduler.ForegroundRendererLoad", load_percentage); 50 "RendererScheduler.ForegroundRendererLoad", load_percentage);
55 } 51 }
56 52
57 void ReportBackgroundRendererTaskLoad(base::TimeTicks time, double load) { 53 void ReportBackgroundRendererTaskLoad(base::TimeTicks time, double load) {
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 loading_tasks_seem_expensive(false), 182 loading_tasks_seem_expensive(false),
187 timer_tasks_seem_expensive(false), 183 timer_tasks_seem_expensive(false),
188 touchstart_expected_soon(false), 184 touchstart_expected_soon(false),
189 have_seen_a_begin_main_frame(false), 185 have_seen_a_begin_main_frame(false),
190 have_reported_blocking_intervention_in_current_policy(false), 186 have_reported_blocking_intervention_in_current_policy(false),
191 have_reported_blocking_intervention_since_navigation(false), 187 have_reported_blocking_intervention_since_navigation(false),
192 has_visible_render_widget_with_touch_handler(false), 188 has_visible_render_widget_with_touch_handler(false),
193 begin_frame_not_expected_soon(false), 189 begin_frame_not_expected_soon(false),
194 in_idle_period_for_testing(false), 190 in_idle_period_for_testing(false),
195 use_virtual_time(false), 191 use_virtual_time(false),
196 is_audio_playing(false),
197 rail_mode_observer(nullptr) {} 192 rail_mode_observer(nullptr) {}
198 193
199 RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {} 194 RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {}
200 195
201 RendererSchedulerImpl::AnyThread::AnyThread() 196 RendererSchedulerImpl::AnyThread::AnyThread()
202 : awaiting_touch_start_response(false), 197 : awaiting_touch_start_response(false),
203 in_idle_period(false), 198 in_idle_period(false),
204 begin_main_frame_on_critical_path(false), 199 begin_main_frame_on_critical_path(false),
205 last_gesture_was_compositor_driven(false), 200 last_gesture_was_compositor_driven(false),
206 default_gesture_prevented(true), 201 default_gesture_prevented(true),
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 MainThreadOnly().renderer_suspended = false; 485 MainThreadOnly().renderer_suspended = false;
491 486
492 base::TimeTicks now = tick_clock()->NowTicks(); 487 base::TimeTicks now = tick_clock()->NowTicks();
493 MainThreadOnly().foreground_main_thread_load_tracker.Resume(now); 488 MainThreadOnly().foreground_main_thread_load_tracker.Resume(now);
494 MainThreadOnly().background_main_thread_load_tracker.Pause(now); 489 MainThreadOnly().background_main_thread_load_tracker.Pause(now);
495 490
496 suspend_timers_when_backgrounded_closure_.Cancel(); 491 suspend_timers_when_backgrounded_closure_.Cancel();
497 ResumeTimerQueueWhenForegroundedOrResumed(); 492 ResumeTimerQueueWhenForegroundedOrResumed();
498 } 493 }
499 494
500 void RendererSchedulerImpl::OnAudioStateChanged() {
501 bool is_audio_playing = false;
502 for (WebViewSchedulerImpl* web_view_scheduler :
503 MainThreadOnly().web_view_schedulers) {
504 is_audio_playing = is_audio_playing || web_view_scheduler->IsAudioPlaying();
505 }
506
507 if (is_audio_playing == MainThreadOnly().is_audio_playing)
508 return;
509
510 MainThreadOnly().last_audio_state_change =
511 helper_.scheduler_tqm_delegate()->NowTicks();
512 MainThreadOnly().is_audio_playing = is_audio_playing;
513
514 UpdatePolicy();
515 }
516
517 void RendererSchedulerImpl::SuspendRenderer() { 495 void RendererSchedulerImpl::SuspendRenderer() {
518 helper_.CheckOnValidThread(); 496 helper_.CheckOnValidThread();
519 DCHECK(MainThreadOnly().renderer_backgrounded); 497 DCHECK(MainThreadOnly().renderer_backgrounded);
520 if (helper_.IsShutdown()) 498 if (helper_.IsShutdown())
521 return; 499 return;
522 suspend_timers_when_backgrounded_closure_.Cancel(); 500 suspend_timers_when_backgrounded_closure_.Cancel();
523 501
524 UMA_HISTOGRAM_COUNTS("PurgeAndSuspend.PendingTaskCount", 502 UMA_HISTOGRAM_COUNTS("PurgeAndSuspend.PendingTaskCount",
525 helper_.GetNumberOfPendingTasks()); 503 helper_.GetNumberOfPendingTasks());
526 504
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 // The |new_policy_duration| is the minimum of |expected_use_case_duration| 829 // The |new_policy_duration| is the minimum of |expected_use_case_duration|
852 // and |touchstart_expected_flag_valid_for_duration| unless one is zero in 830 // and |touchstart_expected_flag_valid_for_duration| unless one is zero in
853 // which case we choose the other. 831 // which case we choose the other.
854 base::TimeDelta new_policy_duration = expected_use_case_duration; 832 base::TimeDelta new_policy_duration = expected_use_case_duration;
855 if (new_policy_duration.is_zero() || 833 if (new_policy_duration.is_zero() ||
856 (touchstart_expected_flag_valid_for_duration > base::TimeDelta() && 834 (touchstart_expected_flag_valid_for_duration > base::TimeDelta() &&
857 new_policy_duration > touchstart_expected_flag_valid_for_duration)) { 835 new_policy_duration > touchstart_expected_flag_valid_for_duration)) {
858 new_policy_duration = touchstart_expected_flag_valid_for_duration; 836 new_policy_duration = touchstart_expected_flag_valid_for_duration;
859 } 837 }
860 838
861 // Do not throttle while audio is playing or for a short period after that
862 // to make sure that pages playing short audio clips powered by timers
863 // work.
864 if (MainThreadOnly().last_audio_state_change &&
865 !MainThreadOnly().is_audio_playing) {
866 base::TimeTicks audio_will_expire =
867 MainThreadOnly().last_audio_state_change.value() +
868 kThrottlingDelayAfterAudioIsPlayed;
869
870 base::TimeDelta audio_will_expire_after = audio_will_expire - now;
871
872 if (audio_will_expire_after > base::TimeDelta()) {
873 if (new_policy_duration.is_zero()) {
874 new_policy_duration = audio_will_expire_after;
875 } else {
876 new_policy_duration =
877 std::min(new_policy_duration, audio_will_expire_after);
878 }
879 }
880 }
881
882 if (new_policy_duration > base::TimeDelta()) { 839 if (new_policy_duration > base::TimeDelta()) {
883 MainThreadOnly().current_policy_expiration_time = now + new_policy_duration; 840 MainThreadOnly().current_policy_expiration_time = now + new_policy_duration;
884 delayed_update_policy_runner_.SetDeadline(FROM_HERE, new_policy_duration, 841 delayed_update_policy_runner_.SetDeadline(FROM_HERE, new_policy_duration,
885 now); 842 now);
886 } else { 843 } else {
887 MainThreadOnly().current_policy_expiration_time = base::TimeTicks(); 844 MainThreadOnly().current_policy_expiration_time = base::TimeTicks();
888 } 845 }
889 846
890 // Avoid prioritizing main thread compositing (e.g., rAF) if it is extremely 847 // Avoid prioritizing main thread compositing (e.g., rAF) if it is extremely
891 // slow, because that can cause starvation in other task sources. 848 // slow, because that can cause starvation in other task sources.
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 } 984 }
1028 985
1029 if (MainThreadOnly().use_virtual_time) { 986 if (MainThreadOnly().use_virtual_time) {
1030 new_policy.compositor_queue_policy.time_domain_type = 987 new_policy.compositor_queue_policy.time_domain_type =
1031 TimeDomainType::VIRTUAL; 988 TimeDomainType::VIRTUAL;
1032 new_policy.default_queue_policy.time_domain_type = TimeDomainType::VIRTUAL; 989 new_policy.default_queue_policy.time_domain_type = TimeDomainType::VIRTUAL;
1033 new_policy.loading_queue_policy.time_domain_type = TimeDomainType::VIRTUAL; 990 new_policy.loading_queue_policy.time_domain_type = TimeDomainType::VIRTUAL;
1034 new_policy.timer_queue_policy.time_domain_type = TimeDomainType::VIRTUAL; 991 new_policy.timer_queue_policy.time_domain_type = TimeDomainType::VIRTUAL;
1035 } 992 }
1036 993
1037 new_policy.should_disable_throttling =
1038 ShouldDisableThrottlingBecauseOfAudio(now) ||
1039 MainThreadOnly().use_virtual_time;
1040
1041 // Tracing is done before the early out check, because it's quite possible we 994 // Tracing is done before the early out check, because it's quite possible we
1042 // will otherwise miss this information in traces. 995 // will otherwise miss this information in traces.
1043 CreateTraceEventObjectSnapshotLocked(); 996 CreateTraceEventObjectSnapshotLocked();
1044 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "use_case", 997 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "use_case",
1045 use_case); 998 use_case);
1046 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "rail_mode", 999 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "rail_mode",
1047 new_policy.rail_mode); 1000 new_policy.rail_mode);
1048 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 1001 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
1049 "touchstart_expected_soon", 1002 "touchstart_expected_soon",
1050 MainThreadOnly().touchstart_expected_soon); 1003 MainThreadOnly().touchstart_expected_soon);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1086 // are mostly dispatched on the default queue) need to be preserved. 1039 // are mostly dispatched on the default queue) need to be preserved.
1087 ApplyTaskQueuePolicy(helper_.DefaultTaskRunner().get(), 1040 ApplyTaskQueuePolicy(helper_.DefaultTaskRunner().get(),
1088 MainThreadOnly().current_policy.default_queue_policy, 1041 MainThreadOnly().current_policy.default_queue_policy,
1089 new_policy.default_queue_policy); 1042 new_policy.default_queue_policy);
1090 if (MainThreadOnly().rail_mode_observer && 1043 if (MainThreadOnly().rail_mode_observer &&
1091 new_policy.rail_mode != MainThreadOnly().current_policy.rail_mode) { 1044 new_policy.rail_mode != MainThreadOnly().current_policy.rail_mode) {
1092 MainThreadOnly().rail_mode_observer->OnRAILModeChanged( 1045 MainThreadOnly().rail_mode_observer->OnRAILModeChanged(
1093 new_policy.rail_mode); 1046 new_policy.rail_mode);
1094 } 1047 }
1095 1048
1096 if (new_policy.should_disable_throttling !=
1097 MainThreadOnly().current_policy.should_disable_throttling) {
1098 if (new_policy.should_disable_throttling) {
1099 task_queue_throttler()->DisableThrottling();
1100 } else {
1101 task_queue_throttler()->EnableThrottling();
1102 }
1103 }
1104
1105 DCHECK(compositor_task_runner_->IsQueueEnabled()); 1049 DCHECK(compositor_task_runner_->IsQueueEnabled());
1106 MainThreadOnly().current_policy = new_policy; 1050 MainThreadOnly().current_policy = new_policy;
1107 } 1051 }
1108 1052
1109 void RendererSchedulerImpl::ApplyTaskQueuePolicy( 1053 void RendererSchedulerImpl::ApplyTaskQueuePolicy(
1110 TaskQueue* task_queue, 1054 TaskQueue* task_queue,
1111 const TaskQueuePolicy& old_task_queue_policy, 1055 const TaskQueuePolicy& old_task_queue_policy,
1112 const TaskQueuePolicy& new_task_queue_policy) const { 1056 const TaskQueuePolicy& new_task_queue_policy) const {
1113 if (old_task_queue_policy.is_enabled != new_task_queue_policy.is_enabled) { 1057 if (old_task_queue_policy.is_enabled != new_task_queue_policy.is_enabled) {
1114 task_queue_throttler_->SetQueueEnabled(task_queue, 1058 task_queue_throttler_->SetQueueEnabled(task_queue,
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after
1624 } 1568 }
1625 1569
1626 void RendererSchedulerImpl::EnableVirtualTime() { 1570 void RendererSchedulerImpl::EnableVirtualTime() {
1627 MainThreadOnly().use_virtual_time = true; 1571 MainThreadOnly().use_virtual_time = true;
1628 1572
1629 // The |unthrottled_task_runners_| are not actively managed by UpdatePolicy(). 1573 // The |unthrottled_task_runners_| are not actively managed by UpdatePolicy().
1630 AutoAdvancingVirtualTimeDomain* time_domain = GetVirtualTimeDomain(); 1574 AutoAdvancingVirtualTimeDomain* time_domain = GetVirtualTimeDomain();
1631 for (const scoped_refptr<TaskQueue>& task_queue : unthrottled_task_runners_) 1575 for (const scoped_refptr<TaskQueue>& task_queue : unthrottled_task_runners_)
1632 task_queue->SetTimeDomain(time_domain); 1576 task_queue->SetTimeDomain(time_domain);
1633 1577
1578 task_queue_throttler_->EnableVirtualTime();
1579
1634 ForceUpdatePolicy(); 1580 ForceUpdatePolicy();
1635 } 1581 }
1636 1582
1637 bool RendererSchedulerImpl::ShouldDisableThrottlingBecauseOfAudio(
1638 base::TimeTicks now) {
1639 if (!MainThreadOnly().last_audio_state_change)
1640 return false;
1641
1642 if (MainThreadOnly().is_audio_playing)
1643 return true;
1644
1645 return MainThreadOnly().last_audio_state_change.value() +
1646 kThrottlingDelayAfterAudioIsPlayed >
1647 now;
1648 }
1649
1650 TimeDomain* RendererSchedulerImpl::GetActiveTimeDomain() {
1651 if (MainThreadOnly().use_virtual_time) {
1652 return GetVirtualTimeDomain();
1653 } else {
1654 return real_time_domain();
1655 }
1656 }
1657
1658 // static 1583 // static
1659 const char* RendererSchedulerImpl::UseCaseToString(UseCase use_case) { 1584 const char* RendererSchedulerImpl::UseCaseToString(UseCase use_case) {
1660 switch (use_case) { 1585 switch (use_case) {
1661 case UseCase::NONE: 1586 case UseCase::NONE:
1662 return "none"; 1587 return "none";
1663 case UseCase::COMPOSITOR_GESTURE: 1588 case UseCase::COMPOSITOR_GESTURE:
1664 return "compositor_gesture"; 1589 return "compositor_gesture";
1665 case UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING: 1590 case UseCase::MAIN_THREAD_CUSTOM_INPUT_HANDLING:
1666 return "main_thread_custom_input_handling"; 1591 return "main_thread_custom_input_handling";
1667 case UseCase::SYNCHRONIZED_GESTURE: 1592 case UseCase::SYNCHRONIZED_GESTURE:
(...skipping 22 matching lines...) Expand all
1690 case v8::PERFORMANCE_LOAD: 1615 case v8::PERFORMANCE_LOAD:
1691 return "load"; 1616 return "load";
1692 default: 1617 default:
1693 NOTREACHED(); 1618 NOTREACHED();
1694 return nullptr; 1619 return nullptr;
1695 } 1620 }
1696 } 1621 }
1697 1622
1698 } // namespace scheduler 1623 } // namespace scheduler
1699 } // namespace blink 1624 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698