| 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 // Amount of idle time left in a frame (as a ratio of the vsync interval) above | 43 // Amount of idle time left in a frame (as a ratio of the vsync interval) above |
| 44 // which main thread compositing can be considered fast. | 44 // which main thread compositing can be considered fast. |
| 45 const double kFastCompositingIdleTimeThreshold = .2; | 45 const double kFastCompositingIdleTimeThreshold = .2; |
| 46 constexpr base::TimeDelta kThreadLoadTrackerReportingInterval = | 46 constexpr base::TimeDelta kThreadLoadTrackerReportingInterval = |
| 47 base::TimeDelta::FromMinutes(1); | 47 base::TimeDelta::FromMinutes(1); |
| 48 constexpr base::TimeDelta kThreadLoadTrackerWaitingPeriodBeforeReporting = | 48 constexpr base::TimeDelta kThreadLoadTrackerWaitingPeriodBeforeReporting = |
| 49 base::TimeDelta::FromMinutes(2); | 49 base::TimeDelta::FromMinutes(2); |
| 50 // We do not throttle anything while audio is played and shortly after that. | 50 // We do not throttle anything while audio is played and shortly after that. |
| 51 constexpr base::TimeDelta kThrottlingDelayAfterAudioIsPlayed = | 51 constexpr base::TimeDelta kThrottlingDelayAfterAudioIsPlayed = |
| 52 base::TimeDelta::FromSeconds(5); | 52 base::TimeDelta::FromSeconds(5); |
| 53 constexpr base::TimeDelta kQueueingTimeWindowDuration = |
| 54 base::TimeDelta::FromSeconds(1); |
| 53 | 55 |
| 54 void ReportForegroundRendererTaskLoad(base::TimeTicks time, double load) { | 56 void ReportForegroundRendererTaskLoad(base::TimeTicks time, double load) { |
| 55 if (!blink::RuntimeEnabledFeatures::timerThrottlingForBackgroundTabsEnabled()) | 57 if (!blink::RuntimeEnabledFeatures::timerThrottlingForBackgroundTabsEnabled()) |
| 56 return; | 58 return; |
| 57 | 59 |
| 58 int load_percentage = static_cast<int>(load * 100); | 60 int load_percentage = static_cast<int>(load * 100); |
| 59 DCHECK_LE(load_percentage, 100); | 61 DCHECK_LE(load_percentage, 100); |
| 60 | 62 |
| 61 UMA_HISTOGRAM_PERCENTAGE("RendererScheduler.ForegroundRendererMainThreadLoad", | 63 UMA_HISTOGRAM_PERCENTAGE("RendererScheduler.ForegroundRendererMainThreadLoad", |
| 62 load_percentage); | 64 load_percentage); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 93 compositor_task_queue_( | 95 compositor_task_queue_( |
| 94 helper_.NewTaskQueue(TaskQueue::Spec(TaskQueue::QueueType::COMPOSITOR) | 96 helper_.NewTaskQueue(TaskQueue::Spec(TaskQueue::QueueType::COMPOSITOR) |
| 95 .SetShouldMonitorQuiescence(true))), | 97 .SetShouldMonitorQuiescence(true))), |
| 96 compositor_task_queue_enabled_voter_( | 98 compositor_task_queue_enabled_voter_( |
| 97 compositor_task_queue_->CreateQueueEnabledVoter()), | 99 compositor_task_queue_->CreateQueueEnabledVoter()), |
| 98 delayed_update_policy_runner_( | 100 delayed_update_policy_runner_( |
| 99 base::Bind(&RendererSchedulerImpl::UpdatePolicy, | 101 base::Bind(&RendererSchedulerImpl::UpdatePolicy, |
| 100 base::Unretained(this)), | 102 base::Unretained(this)), |
| 101 helper_.ControlTaskQueue()), | 103 helper_.ControlTaskQueue()), |
| 102 seqlock_queueing_time_estimator_( | 104 seqlock_queueing_time_estimator_( |
| 103 QueueingTimeEstimator(this, base::TimeDelta::FromSeconds(1))), | 105 QueueingTimeEstimator(this, kQueueingTimeWindowDuration, 20)), |
| 104 main_thread_only_(this, | 106 main_thread_only_(this, |
| 105 compositor_task_queue_, | 107 compositor_task_queue_, |
| 106 helper_.scheduler_tqm_delegate().get(), | 108 helper_.scheduler_tqm_delegate().get(), |
| 107 helper_.scheduler_tqm_delegate()->NowTicks()), | 109 helper_.scheduler_tqm_delegate()->NowTicks()), |
| 108 policy_may_need_update_(&any_thread_lock_), | 110 policy_may_need_update_(&any_thread_lock_), |
| 109 weak_factory_(this) { | 111 weak_factory_(this) { |
| 110 task_queue_throttler_.reset(new TaskQueueThrottler(this)); | 112 task_queue_throttler_.reset(new TaskQueueThrottler(this)); |
| 111 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, | 113 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, |
| 112 weak_factory_.GetWeakPtr()); | 114 weak_factory_.GetWeakPtr()); |
| 113 end_renderer_hidden_idle_period_closure_.Reset(base::Bind( | 115 end_renderer_hidden_idle_period_closure_.Reset(base::Bind( |
| (...skipping 1572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1686 void RendererSchedulerImpl::SetRAILModeObserver(RAILModeObserver* observer) { | 1688 void RendererSchedulerImpl::SetRAILModeObserver(RAILModeObserver* observer) { |
| 1687 GetMainThreadOnly().rail_mode_observer = observer; | 1689 GetMainThreadOnly().rail_mode_observer = observer; |
| 1688 } | 1690 } |
| 1689 | 1691 |
| 1690 bool RendererSchedulerImpl::MainThreadSeemsUnresponsive( | 1692 bool RendererSchedulerImpl::MainThreadSeemsUnresponsive( |
| 1691 base::TimeDelta main_thread_responsiveness_threshold) { | 1693 base::TimeDelta main_thread_responsiveness_threshold) { |
| 1692 base::TimeTicks now = tick_clock()->NowTicks(); | 1694 base::TimeTicks now = tick_clock()->NowTicks(); |
| 1693 base::TimeDelta estimated_queueing_time; | 1695 base::TimeDelta estimated_queueing_time; |
| 1694 | 1696 |
| 1695 bool can_read = false; | 1697 bool can_read = false; |
| 1696 QueueingTimeEstimator::State queueing_time_estimator_state; | |
| 1697 | 1698 |
| 1698 base::subtle::Atomic32 version; | 1699 base::subtle::Atomic32 version; |
| 1699 seqlock_queueing_time_estimator_.seqlock.TryRead(&can_read, &version); | 1700 seqlock_queueing_time_estimator_.seqlock.TryRead(&can_read, &version); |
| 1700 | 1701 |
| 1701 // If we fail to determine if the main thread is busy, assume whether or not | 1702 // If we fail to determine if the main thread is busy, assume whether or not |
| 1702 // it's busy hasn't change since the last time we asked. | 1703 // it's busy hasn't change since the last time we asked. |
| 1703 if (!can_read) | 1704 if (!can_read) |
| 1704 return GetCompositorThreadOnly().main_thread_seems_unresponsive; | 1705 return GetCompositorThreadOnly().main_thread_seems_unresponsive; |
| 1705 | 1706 |
| 1706 queueing_time_estimator_state = | 1707 QueueingTimeEstimator::State queueing_time_estimator_state = |
| 1707 seqlock_queueing_time_estimator_.data.GetState(); | 1708 seqlock_queueing_time_estimator_.data.GetState(); |
| 1708 | 1709 |
| 1709 // If we fail to determine if the main thread is busy, assume whether or not | 1710 // If we fail to determine if the main thread is busy, assume whether or not |
| 1710 // it's busy hasn't change since the last time we asked. | 1711 // it's busy hasn't change since the last time we asked. |
| 1711 if (seqlock_queueing_time_estimator_.seqlock.ReadRetry(version)) | 1712 if (seqlock_queueing_time_estimator_.seqlock.ReadRetry(version)) |
| 1712 return GetCompositorThreadOnly().main_thread_seems_unresponsive; | 1713 return GetCompositorThreadOnly().main_thread_seems_unresponsive; |
| 1713 | 1714 |
| 1714 QueueingTimeEstimator queueing_time_estimator(queueing_time_estimator_state); | 1715 QueueingTimeEstimator queueing_time_estimator(queueing_time_estimator_state); |
| 1715 | 1716 |
| 1716 estimated_queueing_time = | 1717 estimated_queueing_time = |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1847 TaskTimeObserver* task_time_observer) { | 1848 TaskTimeObserver* task_time_observer) { |
| 1848 helper_.AddTaskTimeObserver(task_time_observer); | 1849 helper_.AddTaskTimeObserver(task_time_observer); |
| 1849 } | 1850 } |
| 1850 | 1851 |
| 1851 void RendererSchedulerImpl::RemoveTaskTimeObserver( | 1852 void RendererSchedulerImpl::RemoveTaskTimeObserver( |
| 1852 TaskTimeObserver* task_time_observer) { | 1853 TaskTimeObserver* task_time_observer) { |
| 1853 helper_.RemoveTaskTimeObserver(task_time_observer); | 1854 helper_.RemoveTaskTimeObserver(task_time_observer); |
| 1854 } | 1855 } |
| 1855 | 1856 |
| 1856 void RendererSchedulerImpl::OnQueueingTimeForWindowEstimated( | 1857 void RendererSchedulerImpl::OnQueueingTimeForWindowEstimated( |
| 1857 base::TimeDelta queueing_time) { | 1858 base::TimeDelta queueing_time, |
| 1859 base::TimeTicks window_start_time) { |
| 1860 // RendererScheduler reports the queueing time once per window's duration. |
| 1861 // |stepEQT|stepEQT|stepEQT|stepEQT|stepEQT|stepEQT| |
| 1862 // Report: |-------window EQT------| |
| 1863 // Discard: |-------window EQT------| |
| 1864 // Discard: |-------window EQT------| |
| 1865 // Report: |-------window EQT------| |
| 1866 if (window_start_time - |
| 1867 GetMainThreadOnly().uma_last_queueing_time_report_window_start_time < |
| 1868 kQueueingTimeWindowDuration) { |
| 1869 return; |
| 1870 } |
| 1858 UMA_HISTOGRAM_TIMES("RendererScheduler.ExpectedTaskQueueingDuration", | 1871 UMA_HISTOGRAM_TIMES("RendererScheduler.ExpectedTaskQueueingDuration", |
| 1859 queueing_time); | 1872 queueing_time); |
| 1860 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), | 1873 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), |
| 1861 "estimated_queueing_time_for_window", | 1874 "estimated_queueing_time_for_window", |
| 1862 queueing_time.InMillisecondsF()); | 1875 queueing_time.InMillisecondsF()); |
| 1876 GetMainThreadOnly().uma_last_queueing_time_report_window_start_time = |
| 1877 window_start_time; |
| 1863 } | 1878 } |
| 1864 | 1879 |
| 1865 AutoAdvancingVirtualTimeDomain* RendererSchedulerImpl::GetVirtualTimeDomain() { | 1880 AutoAdvancingVirtualTimeDomain* RendererSchedulerImpl::GetVirtualTimeDomain() { |
| 1866 if (!virtual_time_domain_) { | 1881 if (!virtual_time_domain_) { |
| 1867 virtual_time_domain_.reset( | 1882 virtual_time_domain_.reset( |
| 1868 new AutoAdvancingVirtualTimeDomain(tick_clock()->NowTicks())); | 1883 new AutoAdvancingVirtualTimeDomain(tick_clock()->NowTicks())); |
| 1869 RegisterTimeDomain(virtual_time_domain_.get()); | 1884 RegisterTimeDomain(virtual_time_domain_.get()); |
| 1870 } | 1885 } |
| 1871 return virtual_time_domain_.get(); | 1886 return virtual_time_domain_.get(); |
| 1872 } | 1887 } |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1992 case TimeDomainType::VIRTUAL: | 2007 case TimeDomainType::VIRTUAL: |
| 1993 return "virtual"; | 2008 return "virtual"; |
| 1994 default: | 2009 default: |
| 1995 NOTREACHED(); | 2010 NOTREACHED(); |
| 1996 return nullptr; | 2011 return nullptr; |
| 1997 } | 2012 } |
| 1998 } | 2013 } |
| 1999 | 2014 |
| 2000 } // namespace scheduler | 2015 } // namespace scheduler |
| 2001 } // namespace blink | 2016 } // namespace blink |
| OLD | NEW |