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

Side by Side Diff: components/scheduler/renderer/renderer_scheduler_impl.h

Issue 1320633002: Optimize for TouchStart responsiveness (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Introduced a UserModel class Created 5 years, 3 months 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 #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
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
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
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698