Chromium Code Reviews| Index: third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc |
| diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc |
| index 5f5473e063b6fb024c50bfca4320a751adce8db6..bcda3734bd241c78e7cabc223f76cbfb9c2bf2fd 100644 |
| --- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc |
| +++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc |
| @@ -12,6 +12,7 @@ |
| #include "base/trace_event/trace_event.h" |
| #include "base/trace_event/trace_event_argument.h" |
| #include "cc/output/begin_frame_args.h" |
| +#include "platform/scheduler/base/real_time_domain.h" |
| #include "platform/scheduler/base/task_queue_impl.h" |
| #include "platform/scheduler/base/task_queue_selector.h" |
| #include "platform/scheduler/base/virtual_time_domain.h" |
| @@ -37,6 +38,8 @@ const double kShortIdlePeriodDurationPercentile = 50; |
| // Amount of idle time left in a frame (as a ratio of the vsync interval) above |
| // which main thread compositing can be considered fast. |
| const double kFastCompositingIdleTimeThreshold = .2; |
| +// We do not throttle anything while audio is played and shortly after that. |
| +const int kThrottlingDelayAfterAudioIsPlayedInSeconds = 5; |
| void ReportForegroundRendererTaskLoad(base::TimeTicks time, double load) { |
| int load_percentage = static_cast<int>(load * 100); |
| @@ -158,6 +161,8 @@ RendererSchedulerImpl::MainThreadOnly::MainThreadOnly( |
| now, |
| base::Bind(&ReportForegroundRendererTaskLoad)), |
| current_use_case(UseCase::NONE), |
| + throttling_delay_after_audio_is_played(base::TimeDelta::FromSeconds( |
| + kThrottlingDelayAfterAudioIsPlayedInSeconds)), |
| timer_queue_suspend_count(0), |
| navigation_task_expected_count(0), |
| expensive_task_policy(ExpensiveTaskPolicy::RUN), |
| @@ -476,6 +481,14 @@ void RendererSchedulerImpl::OnRendererForegrounded() { |
| ResumeTimerQueueWhenForegrounded(); |
| } |
| +void RendererSchedulerImpl::OnAudioStateChanged(bool is_audio_playing) { |
| + MainThreadOnly().last_audio_state_change = |
| + helper_.scheduler_tqm_delegate()->NowTicks(); |
| + MainThreadOnly().is_audio_playing = is_audio_playing; |
| + |
| + UpdatePolicy(); |
| +} |
| + |
| void RendererSchedulerImpl::SuspendRenderer() { |
| helper_.CheckOnValidThread(); |
| DCHECK(MainThreadOnly().renderer_backgrounded); |
| @@ -806,6 +819,24 @@ void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) { |
| new_policy_duration = touchstart_expected_flag_valid_for_duration; |
| } |
| + if (MainThreadOnly().last_audio_state_change && |
|
alex clarke (OOO till 29th)
2016/09/30 10:33:46
Please add a brief comment outlining why we do thi
altimin
2016/10/03 11:15:25
Done.
|
| + !MainThreadOnly().is_audio_playing) { |
| + base::TimeTicks audio_will_expire = |
| + MainThreadOnly().last_audio_state_change.value() + |
| + MainThreadOnly().throttling_delay_after_audio_is_played; |
| + |
| + base::TimeDelta audio_will_expire_after = audio_will_expire - now; |
| + |
| + if (audio_will_expire_after > base::TimeDelta()) { |
| + if (new_policy_duration.is_zero()) { |
| + new_policy_duration = audio_will_expire_after; |
| + } else { |
| + new_policy_duration = |
| + std::min(new_policy_duration, audio_will_expire_after); |
| + } |
| + } |
| + } |
| + |
| if (new_policy_duration > base::TimeDelta()) { |
| MainThreadOnly().current_policy_expiration_time = now + new_policy_duration; |
| delayed_update_policy_runner_.SetDeadline(FROM_HERE, new_policy_duration, |
| @@ -961,6 +992,10 @@ void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) { |
| new_policy.timer_queue_policy.time_domain_type = TimeDomainType::VIRTUAL; |
| } |
| + new_policy.should_disable_throttling = |
| + ShouldDisableThrottlingBecauseOfAudio(now) || |
|
Sami
2016/09/30 11:52:09
By the way, this means that we might get more scro
altimin
2016/10/03 11:15:25
How are throttling and scroll jank related? Are yo
Sami
2016/10/03 14:36:31
Not just visibility-based throttling. Previously w
|
| + MainThreadOnly().use_virtual_time; |
| + |
| // Tracing is done before the early out check, because it's quite possible we |
| // will otherwise miss this information in traces. |
| CreateTraceEventObjectSnapshotLocked(); |
| @@ -1016,6 +1051,15 @@ void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) { |
| new_policy.rail_mode); |
| } |
| + if (new_policy.should_disable_throttling != |
| + MainThreadOnly().current_policy.should_disable_throttling) { |
| + if (new_policy.should_disable_throttling) { |
| + task_queue_throttler()->DisableThrottling(); |
| + } else { |
| + task_queue_throttler()->EnableThrottling(); |
| + } |
| + } |
| + |
| DCHECK(compositor_task_runner_->IsQueueEnabled()); |
| MainThreadOnly().current_policy = new_policy; |
| } |
| @@ -1538,11 +1582,30 @@ void RendererSchedulerImpl::EnableVirtualTime() { |
| for (const scoped_refptr<TaskQueue>& task_queue : unthrottled_task_runners_) |
| task_queue->SetTimeDomain(time_domain); |
| - task_queue_throttler_->EnableVirtualTime(); |
| - |
| ForceUpdatePolicy(); |
| } |
| +bool RendererSchedulerImpl::ShouldDisableThrottlingBecauseOfAudio( |
| + base::TimeTicks now) { |
| + if (!MainThreadOnly().last_audio_state_change) |
| + return false; |
| + |
| + if (MainThreadOnly().is_audio_playing) |
| + return true; |
| + |
| + return MainThreadOnly().last_audio_state_change.value() + |
| + MainThreadOnly().throttling_delay_after_audio_is_played > |
| + now; |
| +} |
| + |
| +TimeDomain* RendererSchedulerImpl::GetActiveTimeDomain() { |
| + if (MainThreadOnly().use_virtual_time) { |
| + return GetVirtualTimeDomain(); |
| + } else { |
| + return real_time_domain(); |
| + } |
| +} |
| + |
| // static |
| const char* RendererSchedulerImpl::UseCaseToString(UseCase use_case) { |
| switch (use_case) { |