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

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: Try set OnPageLoadStarted in RenderFrameImpl::OnNavigate 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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 TaskQueue::QueuePriority default_queue_priority;
78 // Must be the last entry. 79
79 POLICY_COUNT, 80 bool operator==(const Policy& other) const {
80 FIRST_POLICY = NORMAL, 81 return compositor_queue_priority == other.compositor_queue_priority &&
82 loading_queue_priority == other.loading_queue_priority &&
83 timer_queue_priority == other.timer_queue_priority &&
84 default_queue_priority == other.default_queue_priority;
85 }
81 }; 86 };
82 87
83 class PollableNeedsUpdateFlag { 88 class PollableNeedsUpdateFlag {
84 public: 89 public:
85 PollableNeedsUpdateFlag(base::Lock* write_lock); 90 PollableNeedsUpdateFlag(base::Lock* write_lock);
86 ~PollableNeedsUpdateFlag(); 91 ~PollableNeedsUpdateFlag();
87 92
88 // Set the flag. May only be called if |write_lock| is held. 93 // Set the flag. May only be called if |write_lock| is held.
89 void SetWhileLocked(bool value); 94 void SetWhileLocked(bool value);
90 95
(...skipping 15 matching lines...) Expand all
106 void OnIdlePeriodStarted() override; 111 void OnIdlePeriodStarted() override;
107 void OnIdlePeriodEnded() override; 112 void OnIdlePeriodEnded() override;
108 113
109 void EndIdlePeriod(); 114 void EndIdlePeriod();
110 115
111 // Returns the serialized scheduler state for tracing. 116 // Returns the serialized scheduler state for tracing.
112 scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValue( 117 scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValue(
113 base::TimeTicks optional_now) const; 118 base::TimeTicks optional_now) const;
114 scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValueLocked( 119 scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValueLocked(
115 base::TimeTicks optional_now) const; 120 base::TimeTicks optional_now) const;
116 static const char* PolicyToString(Policy policy);
117 121
118 static bool ShouldPrioritizeInputEvent( 122 static bool ShouldPrioritizeInputEvent(
119 const blink::WebInputEvent& web_input_event); 123 const blink::WebInputEvent& web_input_event);
120 124
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 125 // The amount of time which idle periods can continue being scheduled when the
125 // renderer has been hidden, before going to sleep for good. 126 // renderer has been hidden, before going to sleep for good.
126 static const int kEndIdleWhenHiddenDelayMillis = 10000; 127 static const int kEndIdleWhenHiddenDelayMillis = 10000;
127 128
128 // The amount of time for which loading tasks will be prioritized over 129 // The amount of time for which loading tasks will be prioritized over
129 // other tasks during the initial page load. 130 // other tasks during the initial page load.
130 static const int kRailsInitialLoadingPrioritizationMillis = 1000; 131 static const int kRailsInitialLoadingPrioritizationMillis = 1000;
131 132
132 // For the purposes of deciding whether or not it's safe to turn timers and 133 // 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 134 // 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 135 // 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 136 // 10 seconds. This was chosen to be long enough to cover most anticipated
136 // user gestures. 137 // user gestures.
137 static const int kIdlePeriodStarvationThresholdMillis = 10000; 138 static const int kIdlePeriodStarvationThresholdMillis = 10000;
138 139
139 // The amount of time to wait before suspending shared timers after the 140 // The amount of time to wait before suspending shared timers after the
140 // renderer has been backgrounded. This is use donly if background suspension 141 // renderer has been backgrounded. This is used only if background suspension
141 // of shared timers is enabled. 142 // of shared timers is enabled.
142 static const int kSuspendTimersWhenBackgroundedDelayMillis = 5 * 60 * 1000; 143 static const int kSuspendTimersWhenBackgroundedDelayMillis = 5 * 60 * 1000;
143 144
144 // Schedules an immediate PolicyUpdate, if there isn't one already pending and 145 // Schedules an immediate PolicyUpdate, if there isn't one already pending and
145 // sets |policy_may_need_update_|. Note |any_thread_lock_| must be 146 // sets |policy_may_need_update_|. Note |any_thread_lock_| must be
146 // locked. 147 // locked.
147 void EnsureUrgentPolicyUpdatePostedOnMainThread( 148 void EnsureUrgentPolicyUpdatePostedOnMainThread(
148 const tracked_objects::Location& from_here); 149 const tracked_objects::Location& from_here);
149 150
150 // Update the policy if a new signal has arrived. Must be called from the main 151 // Update the policy if a new signal has arrived. Must be called from the main
151 // thread. 152 // thread.
152 void MaybeUpdatePolicy(); 153 void MaybeUpdatePolicy();
153 154
154 // Locks |any_thread_lock_| and updates the scheduler policy. May early 155 // Locks |any_thread_lock_| and updates the scheduler policy. May early
155 // out if the policy is unchanged. Must be called from the main thread. 156 // out if the policy is unchanged. Must be called from the main thread.
156 void UpdatePolicy(); 157 void UpdatePolicy();
157 158
158 // Like UpdatePolicy, except it doesn't early out. 159 // Like UpdatePolicy, except it doesn't early out.
159 void ForceUpdatePolicy(); 160 void ForceUpdatePolicy();
160 161
161 enum class UpdateType { 162 enum class UpdateType {
162 MAY_EARLY_OUT_IF_POLICY_UNCHANGED, 163 MAY_EARLY_OUT_IF_POLICY_UNCHANGED,
163 FORCE_UPDATE, 164 FORCE_UPDATE,
164 }; 165 };
165 166
166 // The implelemtation of UpdatePolicy & ForceUpdatePolicy. It is allowed to 167 // The implelemtation of UpdatePolicy & ForceUpdatePolicy. It is allowed to
167 // early out if |update_type| is MAY_EARLY_OUT_IF_POLICY_UNCHANGED. 168 // early out if |update_type| is MAY_EARLY_OUT_IF_POLICY_UNCHANGED.
168 virtual void UpdatePolicyLocked(UpdateType update_type); 169 virtual void UpdatePolicyLocked(UpdateType update_type);
169 170
170 // Returns the amount of time left in the current input escalated priority 171 // Helper for computing the use case. |expected_usecase_duration| will be
171 // policy. Can be called from any thread. 172 // filled with the amount of time after which the use case should be updated
172 base::TimeDelta TimeLeftInInputEscalatedPolicy(base::TimeTicks now) const; 173 // again. If the duration is zero, a new use case update should not be
174 // scheduled. Must be called with |any_thread_lock_| held. Can be called from
175 // any thread.
176 UseCase ComputeCurrentUseCase(
177 base::TimeTicks now,
178 base::TimeDelta* expected_use_case_duration) const;
173 179
174 // Helper for computing the new policy. |new_policy_duration| will be filled 180 // Works out if a gesture appears to be in progress based on the current
175 // with the amount of time after which the policy should be updated again. If 181 // input signals. Can be called from any thread.
176 // the duration is zero, a new policy update will not be scheduled. Must be 182 bool InputSignalsSuggestGestureInProgress(base::TimeTicks now) const;
177 // called with |any_thread_lock_| held. Can be called from any thread.
178 Policy ComputeNewPolicy(base::TimeTicks now,
179 base::TimeDelta* new_policy_duration) const;
180
181 // Works out if compositor tasks would be prioritized based on the current
182 // input signals. Can be called from any thread.
183 bool InputSignalsSuggestCompositorPriority(base::TimeTicks now) const;
184 183
185 // An input event of some sort happened, the policy may need updating. 184 // An input event of some sort happened, the policy may need updating.
186 void UpdateForInputEventOnCompositorThread(blink::WebInputEvent::Type type, 185 void UpdateForInputEventOnCompositorThread(blink::WebInputEvent::Type type,
187 InputEventState input_event_state); 186 InputEventState input_event_state);
188 187
189 // Returns true if there has been at least one idle period in the last 188 // Returns true if there has been at least one idle period in the last
190 // |kIdlePeriodStarvationThresholdMillis|. 189 // |kIdlePeriodStarvationThresholdMillis|.
191 bool HadAnIdlePeriodRecently(base::TimeTicks now) const; 190 bool HadAnIdlePeriodRecently(base::TimeTicks now) const;
192 191
193 // Helpers for safely suspending/resuming the timer queue after a 192 // Helpers for safely suspending/resuming the timer queue after a
194 // background/foreground signal. 193 // background/foreground signal.
195 void SuspendTimerQueueWhenBackgrounded(); 194 void SuspendTimerQueueWhenBackgrounded();
196 void ResumeTimerQueueWhenForegrounded(); 195 void ResumeTimerQueueWhenForegrounded();
197 196
197 // The task cost estimators and the UserModel need to be reset upon page
198 // nagigation. This function does that. Must be called from the main thread.
199 void ResetForNavigationLocked();
200
198 SchedulerHelper helper_; 201 SchedulerHelper helper_;
199 IdleHelper idle_helper_; 202 IdleHelper idle_helper_;
200 203
201 const scoped_refptr<TaskQueue> control_task_runner_; 204 const scoped_refptr<TaskQueue> control_task_runner_;
202 const scoped_refptr<TaskQueue> compositor_task_runner_; 205 const scoped_refptr<TaskQueue> compositor_task_runner_;
203 const scoped_refptr<TaskQueue> loading_task_runner_; 206 const scoped_refptr<TaskQueue> loading_task_runner_;
204 const scoped_refptr<TaskQueue> timer_task_runner_; 207 const scoped_refptr<TaskQueue> timer_task_runner_;
205 208
206 base::Closure update_policy_closure_; 209 base::Closure update_policy_closure_;
207 DeadlineTaskRunner delayed_update_policy_runner_; 210 DeadlineTaskRunner delayed_update_policy_runner_;
208 CancelableClosureHolder end_renderer_hidden_idle_period_closure_; 211 CancelableClosureHolder end_renderer_hidden_idle_period_closure_;
209 CancelableClosureHolder suspend_timers_when_backgrounded_closure_; 212 CancelableClosureHolder suspend_timers_when_backgrounded_closure_;
210 213
211 // We have decided to improve thread safety at the cost of some boilerplate 214 // We have decided to improve thread safety at the cost of some boilerplate
212 // (the accessors) for the following data members. 215 // (the accessors) for the following data members.
213 216
214 struct MainThreadOnly { 217 struct MainThreadOnly {
215 MainThreadOnly(); 218 MainThreadOnly();
216 ~MainThreadOnly(); 219 ~MainThreadOnly();
217 220
218 TaskCostEstimator timer_task_cost_estimator_; 221 TaskCostEstimator loading_task_cost_estimator;
219 cc::RollingTimeDeltaHistory short_idle_period_duration_; 222 TaskCostEstimator timer_task_cost_estimator;
220 Policy current_policy_; 223 cc::RollingTimeDeltaHistory short_idle_period_duration;
221 base::TimeTicks current_policy_expiration_time_; 224 UseCase current_use_case;
222 base::TimeTicks estimated_next_frame_begin_; 225 Policy current_policy;
223 base::TimeDelta expected_short_idle_period_duration_; 226 base::TimeTicks current_policy_expiration_time;
224 int timer_queue_suspend_count_; // TIMER_TASK_QUEUE suspended if non-zero. 227 base::TimeTicks estimated_next_frame_begin;
225 bool renderer_hidden_; 228 base::TimeDelta expected_short_idle_period_duration;
226 bool renderer_backgrounded_; 229 int timer_queue_suspend_count; // TIMER_TASK_QUEUE suspended if non-zero.
227 bool timer_queue_suspension_when_backgrounded_enabled_; 230 bool renderer_hidden;
228 bool timer_queue_suspended_when_backgrounded_; 231 bool renderer_backgrounded;
229 bool was_shutdown_; 232 bool timer_queue_suspension_when_backgrounded_enabled;
233 bool timer_queue_suspended_when_backgrounded;
234 bool was_shutdown;
235 bool loading_tasks_seem_expensive;
236 bool timer_tasks_seem_expensive;
237 bool touchstart_expected_soon;
238 bool have_seen_a_begin_main_frame;
230 }; 239 };
231 240
232 struct AnyThread { 241 struct AnyThread {
233 AnyThread(); 242 AnyThread();
234 243
235 base::TimeTicks last_input_signal_time_; 244 base::TimeTicks last_idle_period_end_time;
236 base::TimeTicks last_idle_period_end_time_; 245 base::TimeTicks rails_loading_priority_deadline;
237 base::TimeTicks rails_loading_priority_deadline_; 246 UserModel user_model;
238 int pending_main_thread_input_event_count_; 247 bool awaiting_touch_start_response;
239 bool awaiting_touch_start_response_; 248 bool in_idle_period;
240 bool in_idle_period_; 249 bool begin_main_frame_on_critical_path;
241 bool begin_main_frame_on_critical_path_;
242 bool timer_tasks_seem_expensive_;
243 }; 250 };
244 251
245 struct CompositorThreadOnly { 252 struct CompositorThreadOnly {
246 CompositorThreadOnly(); 253 CompositorThreadOnly();
247 ~CompositorThreadOnly(); 254 ~CompositorThreadOnly();
248 255
249 blink::WebInputEvent::Type last_input_type_; 256 blink::WebInputEvent::Type last_input_type;
250 scoped_ptr<base::ThreadChecker> compositor_thread_checker_; 257 scoped_ptr<base::ThreadChecker> compositor_thread_checker;
251 258
252 void CheckOnValidThread() { 259 void CheckOnValidThread() {
253 #if DCHECK_IS_ON() 260 #if DCHECK_IS_ON()
254 // We don't actually care which thread this called from, just so long as 261 // We don't actually care which thread this called from, just so long as
255 // its consistent. 262 // its consistent.
256 if (!compositor_thread_checker_) 263 if (!compositor_thread_checker)
257 compositor_thread_checker_.reset(new base::ThreadChecker()); 264 compositor_thread_checker.reset(new base::ThreadChecker());
258 DCHECK(compositor_thread_checker_->CalledOnValidThread()); 265 DCHECK(compositor_thread_checker->CalledOnValidThread());
259 #endif 266 #endif
260 } 267 }
261 }; 268 };
262 269
263 // Don't access main_thread_only_, instead use MainThreadOnly(). 270 // Don't access main_thread_only_, instead use MainThreadOnly().
264 MainThreadOnly main_thread_only_; 271 MainThreadOnly main_thread_only_;
265 MainThreadOnly& MainThreadOnly() { 272 MainThreadOnly& MainThreadOnly() {
266 helper_.CheckOnValidThread(); 273 helper_.CheckOnValidThread();
267 return main_thread_only_; 274 return main_thread_only_;
268 } 275 }
(...skipping 23 matching lines...) Expand all
292 299
293 PollableThreadSafeFlag policy_may_need_update_; 300 PollableThreadSafeFlag policy_may_need_update_;
294 base::WeakPtrFactory<RendererSchedulerImpl> weak_factory_; 301 base::WeakPtrFactory<RendererSchedulerImpl> weak_factory_;
295 302
296 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImpl); 303 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImpl);
297 }; 304 };
298 305
299 } // namespace scheduler 306 } // namespace scheduler
300 307
301 #endif // COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_ 308 #endif // COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_
OLDNEW
« no previous file with comments | « components/scheduler/renderer/renderer_scheduler.cc ('k') | components/scheduler/renderer/renderer_scheduler_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698