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

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: Rebase + remove some unwanted changes 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"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 void SuspendTimerQueue() override; 58 void SuspendTimerQueue() override;
59 void ResumeTimerQueue() override; 59 void ResumeTimerQueue() override;
60 60
61 SchedulerHelper* GetSchedulerHelperForTesting(); 61 SchedulerHelper* GetSchedulerHelperForTesting();
62 base::TimeTicks CurrentIdleTaskDeadlineForTesting() const; 62 base::TimeTicks CurrentIdleTaskDeadlineForTesting() const;
63 63
64 private: 64 private:
65 friend class RendererSchedulerImplTest; 65 friend class RendererSchedulerImplTest;
66 friend class RendererSchedulerImplForTest; 66 friend class RendererSchedulerImplForTest;
67 67
68 // Keep RendererSchedulerImpl::PolicyToString in sync with this enum. 68 // Keep RendererSchedulerImpl::UseCaseToString in sync with this enum.
69 enum class Policy { 69 enum class UseCase {
70 NORMAL, 70 NOT_SCROLLING,
Sami 2015/08/26 13:38:02 I feel like scrolling as a term is too narrow sinc
alex clarke (OOO till 29th) 2015/08/27 12:02:51 As discussed offline I went with COMPOSITOR_GESTUR
71 COMPOSITOR_PRIORITY, 71 COMPOSITOR_SCROLLING,
72 COMPOSITOR_CRITICAL_PATH_PRIORITY, 72 MAINTHREAD_SCROLLING,
Sami 2015/08/26 13:38:02 nit: MAIN_THREAD_SCROLLING
alex clarke (OOO till 29th) 2015/08/27 12:02:51 Acknowledged.
73 TOUCHSTART_PRIORITY, 73 TOUCHSTART,
74 LOADING_PRIORITY, 74 LOADING,
75 // Must be the last entry. 75 // Must be the last entry.
76 POLICY_COUNT, 76 USE_CASE_COUNT,
77 FIRST_POLICY = NORMAL, 77 FIRST_USE_CASE = NOT_SCROLLING,
78 };
79
80 struct Policy {
81 Policy();
82
83 TaskQueue::QueuePriority compositor_queue_priority_;
Sami 2015/08/26 13:38:02 Public struct members shouldn't have trailing unde
alex clarke (OOO till 29th) 2015/08/27 12:02:51 OK lets fix em. Or at least the ones in this clas
84 TaskQueue::QueuePriority loading_queue_priority_;
85 TaskQueue::QueuePriority timer_queue_priority_;
86
87 bool operator==(const Policy& other) const {
88 return compositor_queue_priority_ == other.compositor_queue_priority_ &&
89 loading_queue_priority_ == other.loading_queue_priority_ &&
90 timer_queue_priority_ == other.timer_queue_priority_;
91 }
78 }; 92 };
79 93
80 class PollableNeedsUpdateFlag { 94 class PollableNeedsUpdateFlag {
81 public: 95 public:
82 PollableNeedsUpdateFlag(base::Lock* write_lock); 96 PollableNeedsUpdateFlag(base::Lock* write_lock);
83 ~PollableNeedsUpdateFlag(); 97 ~PollableNeedsUpdateFlag();
84 98
85 // Set the flag. May only be called if |write_lock| is held. 99 // Set the flag. May only be called if |write_lock| is held.
86 void SetWhileLocked(bool value); 100 void SetWhileLocked(bool value);
87 101
(...skipping 15 matching lines...) Expand all
103 void OnIdlePeriodStarted() override; 117 void OnIdlePeriodStarted() override;
104 void OnIdlePeriodEnded() override; 118 void OnIdlePeriodEnded() override;
105 119
106 void EndIdlePeriod(); 120 void EndIdlePeriod();
107 121
108 // Returns the serialized scheduler state for tracing. 122 // Returns the serialized scheduler state for tracing.
109 scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValue( 123 scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValue(
110 base::TimeTicks optional_now) const; 124 base::TimeTicks optional_now) const;
111 scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValueLocked( 125 scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValueLocked(
112 base::TimeTicks optional_now) const; 126 base::TimeTicks optional_now) const;
113 static const char* PolicyToString(Policy policy); 127 static const char* UseCaseToString(UseCase use_case);
114 128
115 static bool ShouldPrioritizeInputEvent( 129 static bool ShouldPrioritizeInputEvent(
116 const blink::WebInputEvent& web_input_event); 130 const blink::WebInputEvent& web_input_event);
117 131
118 // The time we should stay in a priority-escalated mode after an input event. 132 // The time we should stay in a priority-escalated mode after an input event.
119 static const int kPriorityEscalationAfterInputMillis = 100; 133 static const int kPriorityEscalationAfterInputMillis = 100;
120 134
135 // We consider further input invents to be likely if the user has interacted
136 // with the device in the past two seconds.
137 // TODO(alexclarke): Get a real number based on actual data.
138 static const int kExpectSubsequentInputMillis = 2000;
139
121 // The amount of time which idle periods can continue being scheduled when the 140 // The amount of time which idle periods can continue being scheduled when the
122 // renderer has been hidden, before going to sleep for good. 141 // renderer has been hidden, before going to sleep for good.
123 static const int kEndIdleWhenHiddenDelayMillis = 10000; 142 static const int kEndIdleWhenHiddenDelayMillis = 10000;
124 143
125 // The amount of time for which loading tasks will be prioritized over 144 // The amount of time for which loading tasks will be prioritized over
126 // other tasks during the initial page load. 145 // other tasks during the initial page load.
127 static const int kRailsInitialLoadingPrioritizationMillis = 1000; 146 static const int kRailsInitialLoadingPrioritizationMillis = 1000;
128 147
148 // TODO(alexclarke): Get a real number on actual data.
149 static const int kMinimumTypicalScrollDurationMillis = 500;
150
129 // For the purposes of deciding whether or not it's safe to turn timers and 151 // 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 152 // loading tasks on only in idle periods, we regard the system as being as
131 // being "idle period" starved if there hasn't been an idle period in the last 153 // being "idle period" starved if there hasn't been an idle period in the last
132 // 10 seconds. This was chosen to be long enough to cover most anticipated 154 // 10 seconds. This was chosen to be long enough to cover most anticipated
133 // user gestures. 155 // user gestures.
134 static const int kIdlePeriodStarvationThresholdMillis = 10000; 156 static const int kIdlePeriodStarvationThresholdMillis = 10000;
135 157
136 // Schedules an immediate PolicyUpdate, if there isn't one already pending and 158 // Schedules an immediate PolicyUpdate, if there isn't one already pending and
137 // sets |policy_may_need_update_|. Note |any_thread_lock_| must be 159 // sets |policy_may_need_update_|. Note |any_thread_lock_| must be
138 // locked. 160 // locked.
(...skipping 17 matching lines...) Expand all
156 }; 178 };
157 179
158 // The implelemtation of UpdatePolicy & ForceUpdatePolicy. It is allowed to 180 // The implelemtation of UpdatePolicy & ForceUpdatePolicy. It is allowed to
159 // early out if |update_type| is MAY_EARLY_OUT_IF_POLICY_UNCHANGED. 181 // early out if |update_type| is MAY_EARLY_OUT_IF_POLICY_UNCHANGED.
160 virtual void UpdatePolicyLocked(UpdateType update_type); 182 virtual void UpdatePolicyLocked(UpdateType update_type);
161 183
162 // Returns the amount of time left in the current input escalated priority 184 // Returns the amount of time left in the current input escalated priority
163 // policy. Can be called from any thread. 185 // policy. Can be called from any thread.
164 base::TimeDelta TimeLeftInInputEscalatedPolicy(base::TimeTicks now) const; 186 base::TimeDelta TimeLeftInInputEscalatedPolicy(base::TimeTicks now) const;
165 187
166 // Helper for computing the new policy. |new_policy_duration| will be filled 188 // Helper for computing the policy. |new_policy_duration| will be filled
167 // with the amount of time after which the policy should be updated again. If 189 // 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 190 // 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. 191 // called with |any_thread_lock_| held. Can be called from any thread.
170 Policy ComputeNewPolicy(base::TimeTicks now, 192 UseCase ComputeCurrentUseCase(base::TimeTicks now,
171 base::TimeDelta* new_policy_duration) const; 193 base::TimeDelta* new_policy_duration) const;
Sami 2015/08/26 13:38:02 Should this now be the policy duration or the use
alex clarke (OOO till 29th) 2015/08/27 12:02:51 How about expected_use_case_duration?
172 194
173 // Works out if compositor tasks would be prioritized based on the current 195 // Works out if compositor tasks would be prioritized based on the current
174 // input signals. Can be called from any thread. 196 // input signals. Can be called from any thread.
175 bool InputSignalsSuggestCompositorPriority(base::TimeTicks now) const; 197 bool InputSignalsSuggestScrolling(base::TimeTicks now) const;
Sami 2015/08/26 13:38:02 Suggest main thread scrolling?
alex clarke (OOO till 29th) 2015/08/27 12:02:51 This is used to avoid posting lots of policy updat
176 198
177 // An input event of some sort happened, the policy may need updating. 199 // An input event of some sort happened, the policy may need updating.
178 void UpdateForInputEventOnCompositorThread(blink::WebInputEvent::Type type, 200 void UpdateForInputEventOnCompositorThread(blink::WebInputEvent::Type type,
179 InputEventState input_event_state); 201 InputEventState input_event_state);
180 202
181 // Returns true if there has been at least one idle period in the last 203 // Returns true if there has been at least one idle period in the last
182 // |kIdlePeriodStarvationThresholdMillis|. 204 // |kIdlePeriodStarvationThresholdMillis|.
183 bool HadAnIdlePeriodRecently(base::TimeTicks now) const; 205 bool HadAnIdlePeriodRecently(base::TimeTicks now) const;
184 206
207 // Tries to guess if the user is likely to happen soon. Currently this is
208 // very simple, but one day I hope to do something more sophisticated here.
209 bool ScrollExpectedSoon(UseCase use_case,
Sami 2015/08/26 13:38:02 Could you split all the logic about predicting the
alex clarke (OOO till 29th) 2015/08/27 12:02:51 Done.
210 const base::TimeTicks now,
211 base::TimeDelta* new_policy_duration) const;
212
185 SchedulerHelper helper_; 213 SchedulerHelper helper_;
186 IdleHelper idle_helper_; 214 IdleHelper idle_helper_;
187 215
188 const scoped_refptr<TaskQueue> control_task_runner_; 216 const scoped_refptr<TaskQueue> control_task_runner_;
189 const scoped_refptr<TaskQueue> compositor_task_runner_; 217 const scoped_refptr<TaskQueue> compositor_task_runner_;
190 const scoped_refptr<TaskQueue> loading_task_runner_; 218 const scoped_refptr<TaskQueue> loading_task_runner_;
191 const scoped_refptr<TaskQueue> timer_task_runner_; 219 const scoped_refptr<TaskQueue> timer_task_runner_;
192 220
193 base::Closure update_policy_closure_; 221 base::Closure update_policy_closure_;
194 DeadlineTaskRunner delayed_update_policy_runner_; 222 DeadlineTaskRunner delayed_update_policy_runner_;
195 CancelableClosureHolder end_renderer_hidden_idle_period_closure_; 223 CancelableClosureHolder end_renderer_hidden_idle_period_closure_;
196 224
197 // We have decided to improve thread safety at the cost of some boilerplate 225 // We have decided to improve thread safety at the cost of some boilerplate
198 // (the accessors) for the following data members. 226 // (the accessors) for the following data members.
199 227
200 struct MainThreadOnly { 228 struct MainThreadOnly {
201 MainThreadOnly(); 229 MainThreadOnly();
202 ~MainThreadOnly(); 230 ~MainThreadOnly();
203 231
232 TaskCostEstimator loading_task_cost_estimator_;
204 TaskCostEstimator timer_task_cost_estimator_; 233 TaskCostEstimator timer_task_cost_estimator_;
205 cc::RollingTimeDeltaHistory short_idle_period_duration_; 234 cc::RollingTimeDeltaHistory short_idle_period_duration_;
235 UseCase current_use_case_;
206 Policy current_policy_; 236 Policy current_policy_;
207 base::TimeTicks current_policy_expiration_time_; 237 base::TimeTicks current_policy_expiration_time_;
208 base::TimeTicks estimated_next_frame_begin_; 238 base::TimeTicks estimated_next_frame_begin_;
209 base::TimeDelta expected_short_idle_period_duration_; 239 base::TimeDelta expected_short_idle_period_duration_;
210 int timer_queue_suspend_count_; // TIMER_TASK_QUEUE suspended if non-zero. 240 int timer_queue_suspend_count_; // TIMER_TASK_QUEUE suspended if non-zero.
211 bool renderer_hidden_; 241 bool renderer_hidden_;
212 bool was_shutdown_; 242 bool was_shutdown_;
243 bool loading_tasks_seem_expensive_;
244 bool timer_tasks_seem_expensive_;
245 bool scroll_expected_soon_;
213 }; 246 };
214 247
215 struct AnyThread { 248 struct AnyThread {
216 AnyThread(); 249 AnyThread();
217 250
218 base::TimeTicks last_input_signal_time_; 251 base::TimeTicks last_input_signal_time_;
219 base::TimeTicks last_idle_period_end_time_; 252 base::TimeTicks last_idle_period_end_time_;
220 base::TimeTicks rails_loading_priority_deadline_; 253 base::TimeTicks rails_loading_priority_deadline_;
254 base::TimeTicks last_touchstart_time_;
221 int pending_main_thread_input_event_count_; 255 int pending_main_thread_input_event_count_;
222 bool awaiting_touch_start_response_; 256 bool awaiting_touch_start_response_;
223 bool in_idle_period_; 257 bool in_idle_period_;
224 bool begin_main_frame_on_critical_path_; 258 bool begin_main_frame_on_critical_path_;
225 bool timer_tasks_seem_expensive_;
226 }; 259 };
227 260
228 struct CompositorThreadOnly { 261 struct CompositorThreadOnly {
229 CompositorThreadOnly(); 262 CompositorThreadOnly();
230 ~CompositorThreadOnly(); 263 ~CompositorThreadOnly();
231 264
232 blink::WebInputEvent::Type last_input_type_; 265 blink::WebInputEvent::Type last_input_type_;
233 scoped_ptr<base::ThreadChecker> compositor_thread_checker_; 266 scoped_ptr<base::ThreadChecker> compositor_thread_checker_;
234 267
235 void CheckOnValidThread() { 268 void CheckOnValidThread() {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 308
276 PollableThreadSafeFlag policy_may_need_update_; 309 PollableThreadSafeFlag policy_may_need_update_;
277 base::WeakPtrFactory<RendererSchedulerImpl> weak_factory_; 310 base::WeakPtrFactory<RendererSchedulerImpl> weak_factory_;
278 311
279 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImpl); 312 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImpl);
280 }; 313 };
281 314
282 } // namespace scheduler 315 } // namespace scheduler
283 316
284 #endif // COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_ 317 #endif // COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698