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 #ifndef COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_ | 5 #ifndef COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_ |
6 #define COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_ | 6 #define COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_ |
7 | 7 |
8 #include "base/atomicops.h" | 8 #include "base/atomicops.h" |
9 #include "base/synchronization/lock.h" | 9 #include "base/synchronization/lock.h" |
10 #include "components/scheduler/child/idle_helper.h" | 10 #include "components/scheduler/child/idle_helper.h" |
11 #include "components/scheduler/child/pollable_thread_safe_flag.h" | 11 #include "components/scheduler/child/pollable_thread_safe_flag.h" |
12 #include "components/scheduler/child/scheduler_helper.h" | 12 #include "components/scheduler/child/scheduler_helper.h" |
13 #include "components/scheduler/renderer/deadline_task_runner.h" | 13 #include "components/scheduler/renderer/deadline_task_runner.h" |
14 #include "components/scheduler/renderer/renderer_scheduler.h" | 14 #include "components/scheduler/renderer/renderer_scheduler.h" |
15 #include "components/scheduler/renderer/task_cost_estimator.h" | 15 #include "components/scheduler/renderer/task_cost_estimator.h" |
16 #include "components/scheduler/renderer/user_model.h" | |
16 #include "components/scheduler/scheduler_export.h" | 17 #include "components/scheduler/scheduler_export.h" |
17 | 18 |
18 namespace base { | 19 namespace base { |
19 namespace trace_event { | 20 namespace trace_event { |
20 class ConvertableToTraceFormat; | 21 class ConvertableToTraceFormat; |
21 } | 22 } |
22 } | 23 } |
23 | 24 |
24 namespace scheduler { | 25 namespace scheduler { |
25 | 26 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
61 void ResumeTimerQueue() override; | 62 void ResumeTimerQueue() override; |
62 void SetTimerQueueSuspensionWhenBackgroundedEnabled(bool enabled) override; | 63 void SetTimerQueueSuspensionWhenBackgroundedEnabled(bool enabled) override; |
63 | 64 |
64 SchedulerHelper* GetSchedulerHelperForTesting(); | 65 SchedulerHelper* GetSchedulerHelperForTesting(); |
65 base::TimeTicks CurrentIdleTaskDeadlineForTesting() const; | 66 base::TimeTicks CurrentIdleTaskDeadlineForTesting() const; |
66 | 67 |
67 private: | 68 private: |
68 friend class RendererSchedulerImplTest; | 69 friend class RendererSchedulerImplTest; |
69 friend class RendererSchedulerImplForTest; | 70 friend class RendererSchedulerImplForTest; |
70 | 71 |
71 // Keep RendererSchedulerImpl::PolicyToString in sync with this enum. | 72 struct Policy { |
72 enum class Policy { | 73 Policy(); |
73 NORMAL, | 74 |
74 COMPOSITOR_PRIORITY, | 75 TaskQueue::QueuePriority compositor_queue_priority; |
75 COMPOSITOR_CRITICAL_PATH_PRIORITY, | 76 TaskQueue::QueuePriority loading_queue_priority; |
76 TOUCHSTART_PRIORITY, | 77 TaskQueue::QueuePriority timer_queue_priority; |
77 LOADING_PRIORITY, | 78 |
78 // Must be the last entry. | 79 bool operator==(const Policy& other) const { |
79 POLICY_COUNT, | 80 return compositor_queue_priority == other.compositor_queue_priority && |
80 FIRST_POLICY = NORMAL, | 81 loading_queue_priority == other.loading_queue_priority && |
82 timer_queue_priority == other.timer_queue_priority; | |
83 } | |
81 }; | 84 }; |
82 | 85 |
83 class PollableNeedsUpdateFlag { | 86 class PollableNeedsUpdateFlag { |
84 public: | 87 public: |
85 PollableNeedsUpdateFlag(base::Lock* write_lock); | 88 PollableNeedsUpdateFlag(base::Lock* write_lock); |
86 ~PollableNeedsUpdateFlag(); | 89 ~PollableNeedsUpdateFlag(); |
87 | 90 |
88 // Set the flag. May only be called if |write_lock| is held. | 91 // Set the flag. May only be called if |write_lock| is held. |
89 void SetWhileLocked(bool value); | 92 void SetWhileLocked(bool value); |
90 | 93 |
(...skipping 15 matching lines...) Expand all Loading... | |
106 void OnIdlePeriodStarted() override; | 109 void OnIdlePeriodStarted() override; |
107 void OnIdlePeriodEnded() override; | 110 void OnIdlePeriodEnded() override; |
108 | 111 |
109 void EndIdlePeriod(); | 112 void EndIdlePeriod(); |
110 | 113 |
111 // Returns the serialized scheduler state for tracing. | 114 // Returns the serialized scheduler state for tracing. |
112 scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValue( | 115 scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValue( |
113 base::TimeTicks optional_now) const; | 116 base::TimeTicks optional_now) const; |
114 scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValueLocked( | 117 scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValueLocked( |
115 base::TimeTicks optional_now) const; | 118 base::TimeTicks optional_now) const; |
116 static const char* PolicyToString(Policy policy); | |
117 | 119 |
118 static bool ShouldPrioritizeInputEvent( | 120 static bool ShouldPrioritizeInputEvent( |
119 const blink::WebInputEvent& web_input_event); | 121 const blink::WebInputEvent& web_input_event); |
120 | 122 |
121 // The time we should stay in a priority-escalated mode after an input event. | |
122 static const int kPriorityEscalationAfterInputMillis = 100; | |
123 | |
124 // The amount of time which idle periods can continue being scheduled when the | 123 // The amount of time which idle periods can continue being scheduled when the |
125 // renderer has been hidden, before going to sleep for good. | 124 // renderer has been hidden, before going to sleep for good. |
126 static const int kEndIdleWhenHiddenDelayMillis = 10000; | 125 static const int kEndIdleWhenHiddenDelayMillis = 10000; |
127 | 126 |
128 // The amount of time for which loading tasks will be prioritized over | 127 // The amount of time for which loading tasks will be prioritized over |
129 // other tasks during the initial page load. | 128 // other tasks during the initial page load. |
130 static const int kRailsInitialLoadingPrioritizationMillis = 1000; | 129 static const int kRailsInitialLoadingPrioritizationMillis = 1000; |
131 | 130 |
132 // For the purposes of deciding whether or not it's safe to turn timers and | 131 // For the purposes of deciding whether or not it's safe to turn timers and |
133 // loading tasks on only in idle periods, we regard the system as being as | 132 // loading tasks on only in idle periods, we regard the system as being as |
134 // being "idle period" starved if there hasn't been an idle period in the last | 133 // being "idle period" starved if there hasn't been an idle period in the last |
135 // 10 seconds. This was chosen to be long enough to cover most anticipated | 134 // 10 seconds. This was chosen to be long enough to cover most anticipated |
136 // user gestures. | 135 // user gestures. |
137 static const int kIdlePeriodStarvationThresholdMillis = 10000; | 136 static const int kIdlePeriodStarvationThresholdMillis = 10000; |
138 | 137 |
139 // The amount of time to wait before suspending shared timers after the | 138 // The amount of time to wait before suspending shared timers after the |
140 // renderer has been backgrounded. This is use donly if background suspension | 139 // renderer has been backgrounded. This is used only if background suspension |
141 // of shared timers is enabled. | 140 // of shared timers is enabled. |
142 static const int kSuspendTimersWhenBackgroundedDelayMillis = 5 * 60 * 1000; | 141 static const int kSuspendTimersWhenBackgroundedDelayMillis = 5 * 60 * 1000; |
143 | 142 |
144 // Schedules an immediate PolicyUpdate, if there isn't one already pending and | 143 // Schedules an immediate PolicyUpdate, if there isn't one already pending and |
145 // sets |policy_may_need_update_|. Note |any_thread_lock_| must be | 144 // sets |policy_may_need_update_|. Note |any_thread_lock_| must be |
146 // locked. | 145 // locked. |
147 void EnsureUrgentPolicyUpdatePostedOnMainThread( | 146 void EnsureUrgentPolicyUpdatePostedOnMainThread( |
148 const tracked_objects::Location& from_here); | 147 const tracked_objects::Location& from_here); |
149 | 148 |
150 // Update the policy if a new signal has arrived. Must be called from the main | 149 // Update the policy if a new signal has arrived. Must be called from the main |
(...skipping 10 matching lines...) Expand all Loading... | |
161 enum class UpdateType { | 160 enum class UpdateType { |
162 MAY_EARLY_OUT_IF_POLICY_UNCHANGED, | 161 MAY_EARLY_OUT_IF_POLICY_UNCHANGED, |
163 FORCE_UPDATE, | 162 FORCE_UPDATE, |
164 }; | 163 }; |
165 | 164 |
166 // The implelemtation of UpdatePolicy & ForceUpdatePolicy. It is allowed to | 165 // The implelemtation of UpdatePolicy & ForceUpdatePolicy. It is allowed to |
167 // early out if |update_type| is MAY_EARLY_OUT_IF_POLICY_UNCHANGED. | 166 // early out if |update_type| is MAY_EARLY_OUT_IF_POLICY_UNCHANGED. |
168 virtual void UpdatePolicyLocked(UpdateType update_type); | 167 virtual void UpdatePolicyLocked(UpdateType update_type); |
169 | 168 |
170 // Returns the amount of time left in the current input escalated priority | 169 // Returns the amount of time left in the current input escalated priority |
171 // policy. Can be called from any thread. | 170 // policy. Can be called from any thread. |
172 base::TimeDelta TimeLeftInInputEscalatedPolicy(base::TimeTicks now) const; | 171 base::TimeDelta TimeLeftInUserGesture(base::TimeTicks now) const; |
Sami
2015/09/07 11:37:23
This method and the one below are no longer in thi
alex clarke (OOO till 29th)
2015/09/07 16:33:01
Done.
| |
173 | 172 |
174 // Helper for computing the new policy. |new_policy_duration| will be filled | 173 // Tries to guess if a Touchstart is expected soon. |
175 // with the amount of time after which the policy should be updated again. If | 174 bool IsGestureExpectedSoon(UseCase use_case, |
176 // the duration is zero, a new policy update will not be scheduled. Must be | 175 const base::TimeTicks now, |
177 // called with |any_thread_lock_| held. Can be called from any thread. | 176 base::TimeDelta* new_policy_duration) const; |
178 Policy ComputeNewPolicy(base::TimeTicks now, | |
179 base::TimeDelta* new_policy_duration) const; | |
180 | 177 |
181 // Works out if compositor tasks would be prioritized based on the current | 178 // Helper for computing the use case. |expected_usecase_duration| will be |
182 // input signals. Can be called from any thread. | 179 // filled with the amount of time after which the use case should be updated |
183 bool InputSignalsSuggestCompositorPriority(base::TimeTicks now) const; | 180 // again. If the duration is zero, a new use case update should not be |
181 // scheduled. Must be called with |any_thread_lock_| held. Can be called from | |
182 // any thread. | |
183 UseCase ComputeCurrentUseCase( | |
184 base::TimeTicks now, | |
185 base::TimeDelta* expected_use_case_duration) const; | |
186 | |
187 // Works out if a gesture appears to be in progress based on the current | |
188 // input signals. Can be called from any thread. | |
189 bool InputSignalsSuggestGestureInProgress(base::TimeTicks now) const; | |
184 | 190 |
185 // An input event of some sort happened, the policy may need updating. | 191 // An input event of some sort happened, the policy may need updating. |
186 void UpdateForInputEventOnCompositorThread(blink::WebInputEvent::Type type, | 192 void UpdateForInputEventOnCompositorThread(blink::WebInputEvent::Type type, |
187 InputEventState input_event_state); | 193 InputEventState input_event_state); |
188 | 194 |
189 // Returns true if there has been at least one idle period in the last | 195 // Returns true if there has been at least one idle period in the last |
190 // |kIdlePeriodStarvationThresholdMillis|. | 196 // |kIdlePeriodStarvationThresholdMillis|. |
191 bool HadAnIdlePeriodRecently(base::TimeTicks now) const; | 197 bool HadAnIdlePeriodRecently(base::TimeTicks now) const; |
192 | 198 |
193 // Helpers for safely suspending/resuming the timer queue after a | 199 // Helpers for safely suspending/resuming the timer queue after a |
(...skipping 14 matching lines...) Expand all Loading... | |
208 CancelableClosureHolder end_renderer_hidden_idle_period_closure_; | 214 CancelableClosureHolder end_renderer_hidden_idle_period_closure_; |
209 CancelableClosureHolder suspend_timers_when_backgrounded_closure_; | 215 CancelableClosureHolder suspend_timers_when_backgrounded_closure_; |
210 | 216 |
211 // We have decided to improve thread safety at the cost of some boilerplate | 217 // We have decided to improve thread safety at the cost of some boilerplate |
212 // (the accessors) for the following data members. | 218 // (the accessors) for the following data members. |
213 | 219 |
214 struct MainThreadOnly { | 220 struct MainThreadOnly { |
215 MainThreadOnly(); | 221 MainThreadOnly(); |
216 ~MainThreadOnly(); | 222 ~MainThreadOnly(); |
217 | 223 |
218 TaskCostEstimator timer_task_cost_estimator_; | 224 TaskCostEstimator loading_task_cost_estimator; |
219 cc::RollingTimeDeltaHistory short_idle_period_duration_; | 225 TaskCostEstimator timer_task_cost_estimator; |
220 Policy current_policy_; | 226 cc::RollingTimeDeltaHistory short_idle_period_duration; |
221 base::TimeTicks current_policy_expiration_time_; | 227 UseCase current_use_case; |
222 base::TimeTicks estimated_next_frame_begin_; | 228 Policy current_policy; |
223 base::TimeDelta expected_short_idle_period_duration_; | 229 base::TimeTicks current_policy_expiration_time; |
224 int timer_queue_suspend_count_; // TIMER_TASK_QUEUE suspended if non-zero. | 230 base::TimeTicks estimated_next_frame_begin; |
225 bool renderer_hidden_; | 231 base::TimeDelta expected_short_idle_period_duration; |
226 bool renderer_backgrounded_; | 232 int timer_queue_suspend_count; // TIMER_TASK_QUEUE suspended if non-zero. |
227 bool timer_queue_suspension_when_backgrounded_enabled_; | 233 bool renderer_hidden; |
228 bool timer_queue_suspended_when_backgrounded_; | 234 bool renderer_backgrounded; |
229 bool was_shutdown_; | 235 bool timer_queue_suspension_when_backgrounded_enabled; |
236 bool timer_queue_suspended_when_backgrounded; | |
237 bool was_shutdown; | |
238 bool loading_tasks_seem_expensive; | |
239 bool timer_tasks_seem_expensive; | |
240 bool touchstart_expected_soon; | |
230 }; | 241 }; |
231 | 242 |
232 struct AnyThread { | 243 struct AnyThread { |
233 AnyThread(); | 244 AnyThread(); |
234 | 245 |
235 base::TimeTicks last_input_signal_time_; | 246 base::TimeTicks last_idle_period_end_time; |
236 base::TimeTicks last_idle_period_end_time_; | 247 base::TimeTicks rails_loading_priority_deadline; |
237 base::TimeTicks rails_loading_priority_deadline_; | 248 UserModel user_model; |
238 int pending_main_thread_input_event_count_; | 249 bool awaiting_touch_start_response; |
239 bool awaiting_touch_start_response_; | 250 bool in_idle_period; |
240 bool in_idle_period_; | 251 bool begin_main_frame_on_critical_path; |
241 bool begin_main_frame_on_critical_path_; | |
242 bool timer_tasks_seem_expensive_; | |
243 }; | 252 }; |
244 | 253 |
245 struct CompositorThreadOnly { | 254 struct CompositorThreadOnly { |
246 CompositorThreadOnly(); | 255 CompositorThreadOnly(); |
247 ~CompositorThreadOnly(); | 256 ~CompositorThreadOnly(); |
248 | 257 |
249 blink::WebInputEvent::Type last_input_type_; | 258 blink::WebInputEvent::Type last_input_type; |
250 scoped_ptr<base::ThreadChecker> compositor_thread_checker_; | 259 scoped_ptr<base::ThreadChecker> compositor_thread_checker; |
251 | 260 |
252 void CheckOnValidThread() { | 261 void CheckOnValidThread() { |
253 #if DCHECK_IS_ON() | 262 #if DCHECK_IS_ON() |
254 // We don't actually care which thread this called from, just so long as | 263 // We don't actually care which thread this called from, just so long as |
255 // its consistent. | 264 // its consistent. |
256 if (!compositor_thread_checker_) | 265 if (!compositor_thread_checker) |
257 compositor_thread_checker_.reset(new base::ThreadChecker()); | 266 compositor_thread_checker.reset(new base::ThreadChecker()); |
258 DCHECK(compositor_thread_checker_->CalledOnValidThread()); | 267 DCHECK(compositor_thread_checker->CalledOnValidThread()); |
259 #endif | 268 #endif |
260 } | 269 } |
261 }; | 270 }; |
262 | 271 |
263 // Don't access main_thread_only_, instead use MainThreadOnly(). | 272 // Don't access main_thread_only_, instead use MainThreadOnly(). |
264 MainThreadOnly main_thread_only_; | 273 MainThreadOnly main_thread_only_; |
265 MainThreadOnly& MainThreadOnly() { | 274 MainThreadOnly& MainThreadOnly() { |
266 helper_.CheckOnValidThread(); | 275 helper_.CheckOnValidThread(); |
267 return main_thread_only_; | 276 return main_thread_only_; |
268 } | 277 } |
(...skipping 23 matching lines...) Expand all Loading... | |
292 | 301 |
293 PollableThreadSafeFlag policy_may_need_update_; | 302 PollableThreadSafeFlag policy_may_need_update_; |
294 base::WeakPtrFactory<RendererSchedulerImpl> weak_factory_; | 303 base::WeakPtrFactory<RendererSchedulerImpl> weak_factory_; |
295 | 304 |
296 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImpl); | 305 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImpl); |
297 }; | 306 }; |
298 | 307 |
299 } // namespace scheduler | 308 } // namespace scheduler |
300 | 309 |
301 #endif // COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_ | 310 #endif // COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_ |
OLD | NEW |