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

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: Fix unit tests and prioritize default tasks when loading tasks are priotized. 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
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
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
151 // thread. 150 // thread.
152 void MaybeUpdatePolicy(); 151 void MaybeUpdatePolicy();
153 152
154 // Locks |any_thread_lock_| and updates the scheduler policy. May early 153 // 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. 154 // out if the policy is unchanged. Must be called from the main thread.
156 void UpdatePolicy(); 155 void UpdatePolicy();
157 156
158 // Like UpdatePolicy, except it doesn't early out. 157 // Like UpdatePolicy, except it doesn't early out.
159 void ForceUpdatePolicy(); 158 void ForceUpdatePolicy();
160 159
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 // Helper for computing the use case. |expected_usecase_duration| will be
171 // policy. Can be called from any thread. 170 // filled with the amount of time after which the use case should be updated
172 base::TimeDelta TimeLeftInInputEscalatedPolicy(base::TimeTicks now) const; 171 // again. If the duration is zero, a new use case update should not be
172 // scheduled. Must be called with |any_thread_lock_| held. Can be called from
173 // any thread.
174 UseCase ComputeCurrentUseCase(
175 base::TimeTicks now,
176 base::TimeDelta* expected_use_case_duration) const;
173 177
174 // Helper for computing the new policy. |new_policy_duration| will be filled 178 // 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 179 // input signals. Can be called from any thread.
176 // the duration is zero, a new policy update will not be scheduled. Must be 180 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 181
185 // An input event of some sort happened, the policy may need updating. 182 // An input event of some sort happened, the policy may need updating.
186 void UpdateForInputEventOnCompositorThread(blink::WebInputEvent::Type type, 183 void UpdateForInputEventOnCompositorThread(blink::WebInputEvent::Type type,
187 InputEventState input_event_state); 184 InputEventState input_event_state);
188 185
189 // Returns true if there has been at least one idle period in the last 186 // Returns true if there has been at least one idle period in the last
190 // |kIdlePeriodStarvationThresholdMillis|. 187 // |kIdlePeriodStarvationThresholdMillis|.
191 bool HadAnIdlePeriodRecently(base::TimeTicks now) const; 188 bool HadAnIdlePeriodRecently(base::TimeTicks now) const;
192 189
193 // Helpers for safely suspending/resuming the timer queue after a 190 // Helpers for safely suspending/resuming the timer queue after a
(...skipping 14 matching lines...) Expand all
208 CancelableClosureHolder end_renderer_hidden_idle_period_closure_; 205 CancelableClosureHolder end_renderer_hidden_idle_period_closure_;
209 CancelableClosureHolder suspend_timers_when_backgrounded_closure_; 206 CancelableClosureHolder suspend_timers_when_backgrounded_closure_;
210 207
211 // We have decided to improve thread safety at the cost of some boilerplate 208 // We have decided to improve thread safety at the cost of some boilerplate
212 // (the accessors) for the following data members. 209 // (the accessors) for the following data members.
213 210
214 struct MainThreadOnly { 211 struct MainThreadOnly {
215 MainThreadOnly(); 212 MainThreadOnly();
216 ~MainThreadOnly(); 213 ~MainThreadOnly();
217 214
218 TaskCostEstimator timer_task_cost_estimator_; 215 TaskCostEstimator loading_task_cost_estimator;
219 cc::RollingTimeDeltaHistory short_idle_period_duration_; 216 TaskCostEstimator timer_task_cost_estimator;
220 Policy current_policy_; 217 cc::RollingTimeDeltaHistory short_idle_period_duration;
221 base::TimeTicks current_policy_expiration_time_; 218 UseCase current_use_case;
222 base::TimeTicks estimated_next_frame_begin_; 219 Policy current_policy;
223 base::TimeDelta expected_short_idle_period_duration_; 220 base::TimeTicks current_policy_expiration_time;
224 int timer_queue_suspend_count_; // TIMER_TASK_QUEUE suspended if non-zero. 221 base::TimeTicks estimated_next_frame_begin;
225 bool renderer_hidden_; 222 base::TimeDelta expected_short_idle_period_duration;
226 bool renderer_backgrounded_; 223 int timer_queue_suspend_count; // TIMER_TASK_QUEUE suspended if non-zero.
227 bool timer_queue_suspension_when_backgrounded_enabled_; 224 bool renderer_hidden;
228 bool timer_queue_suspended_when_backgrounded_; 225 bool renderer_backgrounded;
229 bool was_shutdown_; 226 bool timer_queue_suspension_when_backgrounded_enabled;
227 bool timer_queue_suspended_when_backgrounded;
228 bool was_shutdown;
229 bool loading_tasks_seem_expensive;
230 bool timer_tasks_seem_expensive;
231 bool touchstart_expected_soon;
230 }; 232 };
231 233
232 struct AnyThread { 234 struct AnyThread {
233 AnyThread(); 235 AnyThread();
234 236
235 base::TimeTicks last_input_signal_time_; 237 base::TimeTicks last_idle_period_end_time;
236 base::TimeTicks last_idle_period_end_time_; 238 base::TimeTicks rails_loading_priority_deadline;
237 base::TimeTicks rails_loading_priority_deadline_; 239 UserModel user_model;
238 int pending_main_thread_input_event_count_; 240 bool awaiting_touch_start_response;
239 bool awaiting_touch_start_response_; 241 bool in_idle_period;
240 bool in_idle_period_; 242 bool begin_main_frame_on_critical_path;
241 bool begin_main_frame_on_critical_path_;
242 bool timer_tasks_seem_expensive_;
243 }; 243 };
244 244
245 struct CompositorThreadOnly { 245 struct CompositorThreadOnly {
246 CompositorThreadOnly(); 246 CompositorThreadOnly();
247 ~CompositorThreadOnly(); 247 ~CompositorThreadOnly();
248 248
249 blink::WebInputEvent::Type last_input_type_; 249 blink::WebInputEvent::Type last_input_type;
250 scoped_ptr<base::ThreadChecker> compositor_thread_checker_; 250 scoped_ptr<base::ThreadChecker> compositor_thread_checker;
251 251
252 void CheckOnValidThread() { 252 void CheckOnValidThread() {
253 #if DCHECK_IS_ON() 253 #if DCHECK_IS_ON()
254 // We don't actually care which thread this called from, just so long as 254 // We don't actually care which thread this called from, just so long as
255 // its consistent. 255 // its consistent.
256 if (!compositor_thread_checker_) 256 if (!compositor_thread_checker)
257 compositor_thread_checker_.reset(new base::ThreadChecker()); 257 compositor_thread_checker.reset(new base::ThreadChecker());
258 DCHECK(compositor_thread_checker_->CalledOnValidThread()); 258 DCHECK(compositor_thread_checker->CalledOnValidThread());
259 #endif 259 #endif
260 } 260 }
261 }; 261 };
262 262
263 // Don't access main_thread_only_, instead use MainThreadOnly(). 263 // Don't access main_thread_only_, instead use MainThreadOnly().
264 MainThreadOnly main_thread_only_; 264 MainThreadOnly main_thread_only_;
265 MainThreadOnly& MainThreadOnly() { 265 MainThreadOnly& MainThreadOnly() {
266 helper_.CheckOnValidThread(); 266 helper_.CheckOnValidThread();
267 return main_thread_only_; 267 return main_thread_only_;
268 } 268 }
(...skipping 23 matching lines...) Expand all
292 292
293 PollableThreadSafeFlag policy_may_need_update_; 293 PollableThreadSafeFlag policy_may_need_update_;
294 base::WeakPtrFactory<RendererSchedulerImpl> weak_factory_; 294 base::WeakPtrFactory<RendererSchedulerImpl> weak_factory_;
295 295
296 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImpl); 296 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImpl);
297 }; 297 };
298 298
299 } // namespace scheduler 299 } // namespace scheduler
300 300
301 #endif // COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_ 301 #endif // COMPONENTS_SCHEDULER_RENDERER_RENDERER_SCHEDULER_IMPL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698