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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
58 void SuspendTimerQueue() override; | 59 void SuspendTimerQueue() override; |
59 void ResumeTimerQueue() override; | 60 void ResumeTimerQueue() override; |
60 | 61 |
61 SchedulerHelper* GetSchedulerHelperForTesting(); | 62 SchedulerHelper* GetSchedulerHelperForTesting(); |
62 base::TimeTicks CurrentIdleTaskDeadlineForTesting() const; | 63 base::TimeTicks CurrentIdleTaskDeadlineForTesting() const; |
63 | 64 |
64 private: | 65 private: |
65 friend class RendererSchedulerImplTest; | 66 friend class RendererSchedulerImplTest; |
66 friend class RendererSchedulerImplForTest; | 67 friend class RendererSchedulerImplForTest; |
67 | 68 |
68 // Keep RendererSchedulerImpl::PolicyToString in sync with this enum. | 69 struct Policy { |
69 enum class Policy { | 70 Policy(); |
70 NORMAL, | 71 |
71 COMPOSITOR_PRIORITY, | 72 TaskQueue::QueuePriority compositor_queue_priority; |
72 COMPOSITOR_CRITICAL_PATH_PRIORITY, | 73 TaskQueue::QueuePriority loading_queue_priority; |
73 TOUCHSTART_PRIORITY, | 74 TaskQueue::QueuePriority timer_queue_priority; |
74 LOADING_PRIORITY, | 75 |
75 // Must be the last entry. | 76 bool operator==(const Policy& other) const { |
76 POLICY_COUNT, | 77 return compositor_queue_priority == other.compositor_queue_priority && |
77 FIRST_POLICY = NORMAL, | 78 loading_queue_priority == other.loading_queue_priority && |
79 timer_queue_priority == other.timer_queue_priority; | |
80 } | |
78 }; | 81 }; |
79 | 82 |
80 class PollableNeedsUpdateFlag { | 83 class PollableNeedsUpdateFlag { |
81 public: | 84 public: |
82 PollableNeedsUpdateFlag(base::Lock* write_lock); | 85 PollableNeedsUpdateFlag(base::Lock* write_lock); |
83 ~PollableNeedsUpdateFlag(); | 86 ~PollableNeedsUpdateFlag(); |
84 | 87 |
85 // Set the flag. May only be called if |write_lock| is held. | 88 // Set the flag. May only be called if |write_lock| is held. |
86 void SetWhileLocked(bool value); | 89 void SetWhileLocked(bool value); |
87 | 90 |
(...skipping 15 matching lines...) Expand all Loading... | |
103 void OnIdlePeriodStarted() override; | 106 void OnIdlePeriodStarted() override; |
104 void OnIdlePeriodEnded() override; | 107 void OnIdlePeriodEnded() override; |
105 | 108 |
106 void EndIdlePeriod(); | 109 void EndIdlePeriod(); |
107 | 110 |
108 // Returns the serialized scheduler state for tracing. | 111 // Returns the serialized scheduler state for tracing. |
109 scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValue( | 112 scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValue( |
110 base::TimeTicks optional_now) const; | 113 base::TimeTicks optional_now) const; |
111 scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValueLocked( | 114 scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValueLocked( |
112 base::TimeTicks optional_now) const; | 115 base::TimeTicks optional_now) const; |
113 static const char* PolicyToString(Policy policy); | |
114 | 116 |
115 static bool ShouldPrioritizeInputEvent( | 117 static bool ShouldPrioritizeInputEvent( |
116 const blink::WebInputEvent& web_input_event); | 118 const blink::WebInputEvent& web_input_event); |
117 | 119 |
118 // The time we should stay in a priority-escalated mode after an input event. | |
119 static const int kPriorityEscalationAfterInputMillis = 100; | |
120 | |
121 // The amount of time which idle periods can continue being scheduled when the | 120 // The amount of time which idle periods can continue being scheduled when the |
122 // renderer has been hidden, before going to sleep for good. | 121 // renderer has been hidden, before going to sleep for good. |
123 static const int kEndIdleWhenHiddenDelayMillis = 10000; | 122 static const int kEndIdleWhenHiddenDelayMillis = 10000; |
124 | 123 |
125 // The amount of time for which loading tasks will be prioritized over | 124 // The amount of time for which loading tasks will be prioritized over |
126 // other tasks during the initial page load. | 125 // other tasks during the initial page load. |
127 static const int kRailsInitialLoadingPrioritizationMillis = 1000; | 126 static const int kRailsInitialLoadingPrioritizationMillis = 1000; |
128 | 127 |
129 // For the purposes of deciding whether or not it's safe to turn timers and | 128 // For the purposes of deciding whether or not it's safe to turn timers and |
130 // loading tasks on only in idle periods, we regard the system as being as | 129 // loading tasks on only in idle periods, we regard the system as being as |
(...skipping 22 matching lines...) Expand all Loading... | |
153 enum class UpdateType { | 152 enum class UpdateType { |
154 MAY_EARLY_OUT_IF_POLICY_UNCHANGED, | 153 MAY_EARLY_OUT_IF_POLICY_UNCHANGED, |
155 FORCE_UPDATE, | 154 FORCE_UPDATE, |
156 }; | 155 }; |
157 | 156 |
158 // The implelemtation of UpdatePolicy & ForceUpdatePolicy. It is allowed to | 157 // The implelemtation of UpdatePolicy & ForceUpdatePolicy. It is allowed to |
159 // early out if |update_type| is MAY_EARLY_OUT_IF_POLICY_UNCHANGED. | 158 // early out if |update_type| is MAY_EARLY_OUT_IF_POLICY_UNCHANGED. |
160 virtual void UpdatePolicyLocked(UpdateType update_type); | 159 virtual void UpdatePolicyLocked(UpdateType update_type); |
161 | 160 |
162 // Returns the amount of time left in the current input escalated priority | 161 // Returns the amount of time left in the current input escalated priority |
163 // policy. Can be called from any thread. | 162 // policy. Can be called from any thread. |
164 base::TimeDelta TimeLeftInInputEscalatedPolicy(base::TimeTicks now) const; | 163 base::TimeDelta TimeLeftInInputEscalatedPolicy(base::TimeTicks now) const; |
165 | 164 |
166 // Helper for computing the new policy. |new_policy_duration| will be filled | 165 // Tries to guess if a Touchstart is expected soon. Currently this is |
Sami
2015/08/27 15:15:59
nit: the second sentence is guaranteed to get out
alex clarke (OOO till 29th)
2015/09/03 10:34:25
Done.
| |
166 // very simple, but one day I hope to do something more sophisticated here. | |
167 bool TouchStartExpectedSoon(UseCase use_case, | |
168 const base::TimeTicks now, | |
169 base::TimeDelta* new_policy_duration) const; | |
170 | |
171 // Helper for computing the policy. |expected_usecase_duration| will be filled | |
Sami
2015/08/27 15:15:59
s/policy/use case/
alex clarke (OOO till 29th)
2015/09/03 10:34:25
Done.
| |
167 // with the amount of time after which the policy should be updated again. If | 172 // with the amount of time after which the policy should be updated again. If |
168 // the duration is zero, a new policy update will not be scheduled. Must be | 173 // the duration is zero, a new policy update will not be scheduled. Must be |
169 // called with |any_thread_lock_| held. Can be called from any thread. | 174 // called with |any_thread_lock_| held. Can be called from any thread. |
170 Policy ComputeNewPolicy(base::TimeTicks now, | 175 UseCase ComputeCurrentUseCase( |
Sami
2015/08/27 15:15:59
Idle thought for the future: maybe the use case de
alex clarke (OOO till 29th)
2015/09/03 10:34:25
Acknowledged.
| |
171 base::TimeDelta* new_policy_duration) const; | 176 base::TimeTicks now, |
177 base::TimeDelta* expected_use_case_duration) const; | |
172 | 178 |
173 // Works out if compositor tasks would be prioritized based on the current | 179 // Works out if a gesture appears to be in progress based on the current |
174 // input signals. Can be called from any thread. | 180 // input signals. Can be called from any thread. |
175 bool InputSignalsSuggestCompositorPriority(base::TimeTicks now) const; | 181 bool InputSignalsSuggestGestureInProgress(base::TimeTicks now) const; |
176 | 182 |
177 // An input event of some sort happened, the policy may need updating. | 183 // An input event of some sort happened, the policy may need updating. |
178 void UpdateForInputEventOnCompositorThread(blink::WebInputEvent::Type type, | 184 void UpdateForInputEventOnCompositorThread(blink::WebInputEvent::Type type, |
179 InputEventState input_event_state); | 185 InputEventState input_event_state); |
180 | 186 |
181 // Returns true if there has been at least one idle period in the last | 187 // Returns true if there has been at least one idle period in the last |
182 // |kIdlePeriodStarvationThresholdMillis|. | 188 // |kIdlePeriodStarvationThresholdMillis|. |
183 bool HadAnIdlePeriodRecently(base::TimeTicks now) const; | 189 bool HadAnIdlePeriodRecently(base::TimeTicks now) const; |
184 | 190 |
185 SchedulerHelper helper_; | 191 SchedulerHelper helper_; |
186 IdleHelper idle_helper_; | 192 IdleHelper idle_helper_; |
187 | 193 |
188 const scoped_refptr<TaskQueue> control_task_runner_; | 194 const scoped_refptr<TaskQueue> control_task_runner_; |
189 const scoped_refptr<TaskQueue> compositor_task_runner_; | 195 const scoped_refptr<TaskQueue> compositor_task_runner_; |
190 const scoped_refptr<TaskQueue> loading_task_runner_; | 196 const scoped_refptr<TaskQueue> loading_task_runner_; |
191 const scoped_refptr<TaskQueue> timer_task_runner_; | 197 const scoped_refptr<TaskQueue> timer_task_runner_; |
192 | 198 |
193 base::Closure update_policy_closure_; | 199 base::Closure update_policy_closure_; |
194 DeadlineTaskRunner delayed_update_policy_runner_; | 200 DeadlineTaskRunner delayed_update_policy_runner_; |
195 CancelableClosureHolder end_renderer_hidden_idle_period_closure_; | 201 CancelableClosureHolder end_renderer_hidden_idle_period_closure_; |
196 | 202 |
197 // We have decided to improve thread safety at the cost of some boilerplate | 203 // We have decided to improve thread safety at the cost of some boilerplate |
198 // (the accessors) for the following data members. | 204 // (the accessors) for the following data members. |
199 | 205 |
200 struct MainThreadOnly { | 206 struct MainThreadOnly { |
201 MainThreadOnly(); | 207 MainThreadOnly(); |
202 ~MainThreadOnly(); | 208 ~MainThreadOnly(); |
203 | 209 |
204 TaskCostEstimator timer_task_cost_estimator_; | 210 TaskCostEstimator loading_task_cost_estimator; |
205 cc::RollingTimeDeltaHistory short_idle_period_duration_; | 211 TaskCostEstimator timer_task_cost_estimator; |
206 Policy current_policy_; | 212 cc::RollingTimeDeltaHistory short_idle_period_duration; |
207 base::TimeTicks current_policy_expiration_time_; | 213 UseCase current_use_case; |
208 base::TimeTicks estimated_next_frame_begin_; | 214 Policy current_policy; |
209 base::TimeDelta expected_short_idle_period_duration_; | 215 base::TimeTicks current_policy_expiration_time; |
210 int timer_queue_suspend_count_; // TIMER_TASK_QUEUE suspended if non-zero. | 216 base::TimeTicks estimated_next_frame_begin; |
211 bool renderer_hidden_; | 217 base::TimeDelta expected_short_idle_period_duration; |
212 bool was_shutdown_; | 218 int timer_queue_suspend_count; // TIMER_TASK_QUEUE suspended if non-zero. |
219 bool renderer_hidden; | |
220 bool was_shutdown; | |
221 bool loading_tasks_seem_expensive; | |
222 bool timer_tasks_seem_expensive; | |
223 bool touchstart_expected_soon; | |
213 }; | 224 }; |
214 | 225 |
215 struct AnyThread { | 226 struct AnyThread { |
216 AnyThread(); | 227 AnyThread(); |
217 | 228 |
218 base::TimeTicks last_input_signal_time_; | 229 base::TimeTicks last_idle_period_end_time; |
219 base::TimeTicks last_idle_period_end_time_; | 230 base::TimeTicks rails_loading_priority_deadline; |
220 base::TimeTicks rails_loading_priority_deadline_; | 231 UserModel user_model; |
221 int pending_main_thread_input_event_count_; | 232 bool awaiting_touch_start_response; |
222 bool awaiting_touch_start_response_; | 233 bool in_idle_period; |
223 bool in_idle_period_; | 234 bool begin_main_frame_on_critical_path; |
224 bool begin_main_frame_on_critical_path_; | |
225 bool timer_tasks_seem_expensive_; | |
226 }; | 235 }; |
227 | 236 |
228 struct CompositorThreadOnly { | 237 struct CompositorThreadOnly { |
229 CompositorThreadOnly(); | 238 CompositorThreadOnly(); |
230 ~CompositorThreadOnly(); | 239 ~CompositorThreadOnly(); |
231 | 240 |
232 blink::WebInputEvent::Type last_input_type_; | 241 blink::WebInputEvent::Type last_input_type; |
233 scoped_ptr<base::ThreadChecker> compositor_thread_checker_; | 242 scoped_ptr<base::ThreadChecker> compositor_thread_checker; |
234 | 243 |
235 void CheckOnValidThread() { | 244 void CheckOnValidThread() { |
236 #if DCHECK_IS_ON() | 245 #if DCHECK_IS_ON() |
237 // We don't actually care which thread this called from, just so long as | 246 // We don't actually care which thread this called from, just so long as |
238 // its consistent. | 247 // its consistent. |
239 if (!compositor_thread_checker_) | 248 if (!compositor_thread_checker) |
240 compositor_thread_checker_.reset(new base::ThreadChecker()); | 249 compositor_thread_checker.reset(new base::ThreadChecker()); |
241 DCHECK(compositor_thread_checker_->CalledOnValidThread()); | 250 DCHECK(compositor_thread_checker->CalledOnValidThread()); |
242 #endif | 251 #endif |
243 } | 252 } |
244 }; | 253 }; |
245 | 254 |
246 // Don't access main_thread_only_, instead use MainThreadOnly(). | 255 // Don't access main_thread_only_, instead use MainThreadOnly(). |
247 MainThreadOnly main_thread_only_; | 256 MainThreadOnly main_thread_only_; |
248 MainThreadOnly& MainThreadOnly() { | 257 MainThreadOnly& MainThreadOnly() { |
249 helper_.CheckOnValidThread(); | 258 helper_.CheckOnValidThread(); |
250 return main_thread_only_; | 259 return main_thread_only_; |
251 } | 260 } |
(...skipping 23 matching lines...) Expand all Loading... | |
275 | 284 |
276 PollableThreadSafeFlag policy_may_need_update_; | 285 PollableThreadSafeFlag policy_may_need_update_; |
277 base::WeakPtrFactory<RendererSchedulerImpl> weak_factory_; | 286 base::WeakPtrFactory<RendererSchedulerImpl> weak_factory_; |
278 | 287 |
279 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImpl); | 288 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImpl); |
280 }; | 289 }; |
281 | 290 |
282 } // namespace scheduler | 291 } // namespace scheduler |
283 | 292 |
284 #endif // COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_ | 293 #endif // COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_ |
OLD | NEW |