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

Side by Side Diff: content/renderer/scheduler/renderer_scheduler_impl.cc

Issue 1025323003: Introduce a SchedulerHelper in content/child/scheduler (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Sami's suggestions Created 5 years, 9 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 #include "content/renderer/scheduler/renderer_scheduler_impl.h" 5 #include "content/renderer/scheduler/renderer_scheduler_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/message_loop/message_loop_proxy.h" 8 #include "base/message_loop/message_loop_proxy.h"
9 #include "base/trace_event/trace_event.h" 9 #include "base/trace_event/trace_event.h"
10 #include "base/trace_event/trace_event_argument.h" 10 #include "base/trace_event/trace_event_argument.h"
11 #include "cc/output/begin_frame_args.h" 11 #include "cc/output/begin_frame_args.h"
12 #include "content/renderer/scheduler/nestable_single_thread_task_runner.h" 12 #include "content/child/scheduler/nestable_single_thread_task_runner.h"
13 #include "content/renderer/scheduler/renderer_task_queue_selector.h" 13 #include "content/child/scheduler/prioritizing_task_queue_selector.h"
14 #include "ui/gfx/frame_time.h" 14 #include "ui/gfx/frame_time.h"
15 15
16 namespace content { 16 namespace content {
17 17
18 RendererSchedulerImpl::RendererSchedulerImpl( 18 RendererSchedulerImpl::RendererSchedulerImpl(
19 scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner) 19 scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner)
20 : renderer_task_queue_selector_(new RendererTaskQueueSelector()), 20 : helper_(main_task_runner,
21 task_queue_manager_( 21 "renderer.scheduler",
22 new TaskQueueManager(TASK_QUEUE_COUNT, 22 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
23 main_task_runner, 23 TASK_QUEUE_COUNT,
24 renderer_task_queue_selector_.get())), 24 this),
25 control_task_runner_( 25 control_task_runner_(helper_.ControlTaskRunner()),
26 task_queue_manager_->TaskRunnerForQueue(CONTROL_TASK_QUEUE)),
27 control_task_after_wakeup_runner_(task_queue_manager_->TaskRunnerForQueue(
28 CONTROL_TASK_AFTER_WAKEUP_QUEUE)),
29 default_task_runner_(
30 task_queue_manager_->TaskRunnerForQueue(DEFAULT_TASK_QUEUE)),
31 compositor_task_runner_( 26 compositor_task_runner_(
32 task_queue_manager_->TaskRunnerForQueue(COMPOSITOR_TASK_QUEUE)), 27 helper_.SchedulerTaskQueueManager()->TaskRunnerForQueue(
28 COMPOSITOR_TASK_QUEUE)),
33 loading_task_runner_( 29 loading_task_runner_(
34 task_queue_manager_->TaskRunnerForQueue(LOADING_TASK_QUEUE)), 30 helper_.SchedulerTaskQueueManager()->TaskRunnerForQueue(
31 LOADING_TASK_QUEUE)),
35 delayed_update_policy_runner_( 32 delayed_update_policy_runner_(
36 base::Bind(&RendererSchedulerImpl::UpdatePolicy, 33 base::Bind(&RendererSchedulerImpl::UpdatePolicy,
37 base::Unretained(this)), 34 base::Unretained(this)),
38 control_task_runner_), 35 helper_.ControlTaskRunner()),
39 current_policy_(Policy::NORMAL), 36 current_policy_(Policy::NORMAL),
40 idle_period_state_(IdlePeriodState::NOT_IN_IDLE_PERIOD),
41 last_input_type_(blink::WebInputEvent::Undefined), 37 last_input_type_(blink::WebInputEvent::Undefined),
42 input_stream_state_(InputStreamState::INACTIVE), 38 input_stream_state_(InputStreamState::INACTIVE),
43 policy_may_need_update_(&incoming_signals_lock_), 39 policy_may_need_update_(&incoming_signals_lock_),
44 weak_factory_(this) { 40 weak_factory_(this) {
45 weak_renderer_scheduler_ptr_ = weak_factory_.GetWeakPtr();
46 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, 41 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy,
47 weak_renderer_scheduler_ptr_); 42 weak_factory_.GetWeakPtr());
48 end_idle_period_closure_.Reset(base::Bind(
49 &RendererSchedulerImpl::EndIdlePeriod, weak_renderer_scheduler_ptr_));
50 initiate_next_long_idle_period_closure_.Reset(base::Bind(
51 &RendererSchedulerImpl::InitiateLongIdlePeriod,
52 weak_renderer_scheduler_ptr_));
53 initiate_next_long_idle_period_after_wakeup_closure_.Reset(base::Bind(
54 &RendererSchedulerImpl::InitiateLongIdlePeriodAfterWakeup,
55 weak_renderer_scheduler_ptr_));
56
57 idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner(
58 task_queue_manager_->TaskRunnerForQueue(IDLE_TASK_QUEUE),
59 control_task_after_wakeup_runner_,
60 base::Bind(&RendererSchedulerImpl::CurrentIdleTaskDeadlineCallback,
61 weak_renderer_scheduler_ptr_)));
62
63 renderer_task_queue_selector_->SetQueuePriority(
64 CONTROL_TASK_QUEUE, RendererTaskQueueSelector::CONTROL_PRIORITY);
65
66 renderer_task_queue_selector_->SetQueuePriority(
67 CONTROL_TASK_AFTER_WAKEUP_QUEUE,
68 RendererTaskQueueSelector::CONTROL_PRIORITY);
69 task_queue_manager_->SetPumpPolicy(
70 CONTROL_TASK_AFTER_WAKEUP_QUEUE,
71 TaskQueueManager::PumpPolicy::AFTER_WAKEUP);
72
73 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE);
74 task_queue_manager_->SetPumpPolicy(IDLE_TASK_QUEUE,
75 TaskQueueManager::PumpPolicy::MANUAL);
76
77 // TODO(skyostil): Increase this to 4 (crbug.com/444764).
78 task_queue_manager_->SetWorkBatchSize(1);
79 43
80 for (size_t i = 0; i < TASK_QUEUE_COUNT; i++) { 44 for (size_t i = 0; i < TASK_QUEUE_COUNT; i++) {
81 task_queue_manager_->SetQueueName( 45 helper_.SchedulerTaskQueueManager()->SetQueueName(
82 i, TaskQueueIdToString(static_cast<QueueId>(i))); 46 i, TaskQueueIdToString(static_cast<QueueId>(i)));
83 } 47 }
84 TRACE_EVENT_OBJECT_CREATED_WITH_ID( 48 TRACE_EVENT_OBJECT_CREATED_WITH_ID(
85 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", 49 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
86 this); 50 this);
87 } 51 }
88 52
89 RendererSchedulerImpl::~RendererSchedulerImpl() { 53 RendererSchedulerImpl::~RendererSchedulerImpl() {
90 TRACE_EVENT_OBJECT_DELETED_WITH_ID( 54 TRACE_EVENT_OBJECT_DELETED_WITH_ID(
91 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", 55 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
92 this); 56 this);
93 } 57 }
94 58
95 void RendererSchedulerImpl::Shutdown() { 59 void RendererSchedulerImpl::Shutdown() {
96 DCHECK(main_thread_checker_.CalledOnValidThread()); 60 helper_.Shutdown();
97 task_queue_manager_.reset();
98 } 61 }
99 62
100 scoped_refptr<base::SingleThreadTaskRunner> 63 scoped_refptr<base::SingleThreadTaskRunner>
101 RendererSchedulerImpl::DefaultTaskRunner() { 64 RendererSchedulerImpl::DefaultTaskRunner() {
102 DCHECK(main_thread_checker_.CalledOnValidThread()); 65 return helper_.DefaultTaskRunner();
103 return default_task_runner_;
104 } 66 }
105 67
106 scoped_refptr<base::SingleThreadTaskRunner> 68 scoped_refptr<base::SingleThreadTaskRunner>
107 RendererSchedulerImpl::CompositorTaskRunner() { 69 RendererSchedulerImpl::CompositorTaskRunner() {
108 DCHECK(main_thread_checker_.CalledOnValidThread()); 70 helper_.CheckOnValidThread();
109 return compositor_task_runner_; 71 return compositor_task_runner_;
110 } 72 }
111 73
112 scoped_refptr<SingleThreadIdleTaskRunner> 74 scoped_refptr<SingleThreadIdleTaskRunner>
113 RendererSchedulerImpl::IdleTaskRunner() { 75 RendererSchedulerImpl::IdleTaskRunner() {
114 DCHECK(main_thread_checker_.CalledOnValidThread()); 76 return helper_.IdleTaskRunner();
115 return idle_task_runner_;
116 } 77 }
117 78
118 scoped_refptr<base::SingleThreadTaskRunner> 79 scoped_refptr<base::SingleThreadTaskRunner>
119 RendererSchedulerImpl::LoadingTaskRunner() { 80 RendererSchedulerImpl::LoadingTaskRunner() {
120 DCHECK(main_thread_checker_.CalledOnValidThread()); 81 helper_.CheckOnValidThread();
121 return loading_task_runner_; 82 return loading_task_runner_;
122 } 83 }
123 84
85 bool RendererSchedulerImpl::CanExceedIdleDeadlineIfRequired() const {
86 return helper_.CanExceedIdleDeadlineIfRequired();
87 }
88
89 void RendererSchedulerImpl::AddTaskObserver(
90 base::MessageLoop::TaskObserver* task_observer) {
91 helper_.AddTaskObserver(task_observer);
92 }
93
94 void RendererSchedulerImpl::RemoveTaskObserver(
95 base::MessageLoop::TaskObserver* task_observer) {
96 helper_.RemoveTaskObserver(task_observer);
97 }
98
124 void RendererSchedulerImpl::WillBeginFrame(const cc::BeginFrameArgs& args) { 99 void RendererSchedulerImpl::WillBeginFrame(const cc::BeginFrameArgs& args) {
125 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 100 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
126 "RendererSchedulerImpl::WillBeginFrame", "args", args.AsValue()); 101 "RendererSchedulerImpl::WillBeginFrame", "args", args.AsValue());
127 DCHECK(main_thread_checker_.CalledOnValidThread()); 102 helper_.CheckOnValidThread();
128 if (!task_queue_manager_) 103 if (!helper_.SchedulerTaskQueueManager())
rmcilroy 2015/03/27 14:34:41 Could we make this a more obvious method name - i.
alex clarke (OOO till 29th) 2015/03/27 16:09:17 Done.
129 return; 104 return;
130 105
131 EndIdlePeriod(); 106 helper_.EndIdlePeriod();
132 estimated_next_frame_begin_ = args.frame_time + args.interval; 107 helper_.SetEstimatedNextFrameBegin(args.frame_time + args.interval);
133 // TODO(skyostil): Wire up real notification of input events processing 108 // TODO(skyostil): Wire up real notification of input events processing
134 // instead of this approximation. 109 // instead of this approximation.
135 DidProcessInputEvent(args.frame_time); 110 DidProcessInputEvent(args.frame_time);
136 } 111 }
137 112
138 void RendererSchedulerImpl::DidCommitFrameToCompositor() { 113 void RendererSchedulerImpl::DidCommitFrameToCompositor() {
139 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 114 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
140 "RendererSchedulerImpl::DidCommitFrameToCompositor"); 115 "RendererSchedulerImpl::DidCommitFrameToCompositor");
141 DCHECK(main_thread_checker_.CalledOnValidThread()); 116 helper_.CheckOnValidThread();
142 if (!task_queue_manager_) 117 if (!helper_.SchedulerTaskQueueManager())
143 return; 118 return;
144 119
145 base::TimeTicks now(Now()); 120 base::TimeTicks now(helper_.Now());
146 if (now < estimated_next_frame_begin_) { 121 if (now < helper_.EstimatedNextFrameBegin()) {
147 // TODO(rmcilroy): Consider reducing the idle period based on the runtime of 122 // TODO(rmcilroy): Consider reducing the idle period based on the runtime of
148 // the next pending delayed tasks (as currently done in for long idle times) 123 // the next pending delayed tasks (as currently done in for long idle times)
149 StartIdlePeriod(IdlePeriodState::IN_SHORT_IDLE_PERIOD); 124 helper_.StartIdlePeriod(
150 control_task_runner_->PostDelayedTask(FROM_HERE, 125 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD);
151 end_idle_period_closure_.callback(), 126 control_task_runner_->PostDelayedTask(
152 estimated_next_frame_begin_ - now); 127 FROM_HERE, helper_.EndIdlePeriodClosure().callback(),
128 helper_.EstimatedNextFrameBegin() - now);
153 } 129 }
154 } 130 }
155 131
156 void RendererSchedulerImpl::BeginFrameNotExpectedSoon() { 132 void RendererSchedulerImpl::BeginFrameNotExpectedSoon() {
157 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 133 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
158 "RendererSchedulerImpl::BeginFrameNotExpectedSoon"); 134 "RendererSchedulerImpl::BeginFrameNotExpectedSoon");
159 DCHECK(main_thread_checker_.CalledOnValidThread()); 135 helper_.CheckOnValidThread();
160 if (!task_queue_manager_) 136 if (!helper_.SchedulerTaskQueueManager())
161 return; 137 return;
162 138
163 // TODO(skyostil): Wire up real notification of input events processing 139 // TODO(skyostil): Wire up real notification of input events processing
164 // instead of this approximation. 140 // instead of this approximation.
165 DidProcessInputEvent(base::TimeTicks()); 141 DidProcessInputEvent(base::TimeTicks());
166 142
167 InitiateLongIdlePeriod(); 143 helper_.InitiateLongIdlePeriod();
168 } 144 }
169 145
170 void RendererSchedulerImpl::DidReceiveInputEventOnCompositorThread( 146 void RendererSchedulerImpl::DidReceiveInputEventOnCompositorThread(
171 const blink::WebInputEvent& web_input_event) { 147 const blink::WebInputEvent& web_input_event) {
172 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 148 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
173 "RendererSchedulerImpl::DidReceiveInputEventOnCompositorThread"); 149 "RendererSchedulerImpl::DidReceiveInputEventOnCompositorThread");
174 // We regard MouseMove events with the left mouse button down as a signal 150 // We regard MouseMove events with the left mouse button down as a signal
175 // that the user is doing something requiring a smooth frame rate. 151 // that the user is doing something requiring a smooth frame rate.
176 if (web_input_event.type == blink::WebInputEvent::MouseMove && 152 if (web_input_event.type == blink::WebInputEvent::MouseMove &&
177 (web_input_event.modifiers & blink::WebInputEvent::LeftButtonDown)) { 153 (web_input_event.modifiers & blink::WebInputEvent::LeftButtonDown)) {
(...skipping 21 matching lines...) Expand all
199 base::AutoLock lock(incoming_signals_lock_); 175 base::AutoLock lock(incoming_signals_lock_);
200 176
201 InputStreamState new_input_stream_state = 177 InputStreamState new_input_stream_state =
202 ComputeNewInputStreamState(input_stream_state_, type, last_input_type_); 178 ComputeNewInputStreamState(input_stream_state_, type, last_input_type_);
203 179
204 if (input_stream_state_ != new_input_stream_state) { 180 if (input_stream_state_ != new_input_stream_state) {
205 // Update scheduler policy if we should start a new policy mode. 181 // Update scheduler policy if we should start a new policy mode.
206 input_stream_state_ = new_input_stream_state; 182 input_stream_state_ = new_input_stream_state;
207 EnsureUrgentPolicyUpdatePostedOnMainThread(FROM_HERE); 183 EnsureUrgentPolicyUpdatePostedOnMainThread(FROM_HERE);
208 } 184 }
209 last_input_receipt_time_on_compositor_ = Now(); 185 last_input_receipt_time_on_compositor_ = helper_.Now();
210 // Clear the last known input processing time so that we know an input event 186 // Clear the last known input processing time so that we know an input event
211 // is still queued up. This timestamp will be updated the next time the 187 // is still queued up. This timestamp will be updated the next time the
212 // compositor commits or becomes quiescent. Note that this function is always 188 // compositor commits or becomes quiescent. Note that this function is always
213 // called before the input event is processed either on the compositor or 189 // called before the input event is processed either on the compositor or
214 // main threads. 190 // main threads.
215 last_input_process_time_on_main_ = base::TimeTicks(); 191 last_input_process_time_on_main_ = base::TimeTicks();
216 last_input_type_ = type; 192 last_input_type_ = type;
217 } 193 }
218 194
219 void RendererSchedulerImpl::DidProcessInputEvent( 195 void RendererSchedulerImpl::DidProcessInputEvent(
220 base::TimeTicks begin_frame_time) { 196 base::TimeTicks begin_frame_time) {
221 DCHECK(main_thread_checker_.CalledOnValidThread()); 197 helper_.CheckOnValidThread();
222 base::AutoLock lock(incoming_signals_lock_); 198 base::AutoLock lock(incoming_signals_lock_);
223 if (input_stream_state_ == InputStreamState::INACTIVE) 199 if (input_stream_state_ == InputStreamState::INACTIVE)
224 return; 200 return;
225 // Avoid marking input that arrived after the BeginFrame as processed. 201 // Avoid marking input that arrived after the BeginFrame as processed.
226 if (!begin_frame_time.is_null() && 202 if (!begin_frame_time.is_null() &&
227 begin_frame_time < last_input_receipt_time_on_compositor_) 203 begin_frame_time < last_input_receipt_time_on_compositor_)
228 return; 204 return;
229 last_input_process_time_on_main_ = Now(); 205 last_input_process_time_on_main_ = helper_.Now();
230 UpdatePolicyLocked(); 206 UpdatePolicyLocked();
231 } 207 }
232 208
233 bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() { 209 bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() {
234 DCHECK(main_thread_checker_.CalledOnValidThread()); 210 helper_.CheckOnValidThread();
235 if (!task_queue_manager_) 211 if (!helper_.SchedulerTaskQueueManager())
236 return false; 212 return false;
237 213
238 MaybeUpdatePolicy(); 214 MaybeUpdatePolicy();
239 // The touchstart and compositor policies indicate a strong likelihood of 215 // The touchstart and compositor policies indicate a strong likelihood of
240 // high-priority work in the near future. 216 // high-priority work in the near future.
241 return SchedulerPolicy() == Policy::COMPOSITOR_PRIORITY || 217 return SchedulerPolicy() == Policy::COMPOSITOR_PRIORITY ||
242 SchedulerPolicy() == Policy::TOUCHSTART_PRIORITY; 218 SchedulerPolicy() == Policy::TOUCHSTART_PRIORITY;
243 } 219 }
244 220
245 bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() { 221 bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() {
246 DCHECK(main_thread_checker_.CalledOnValidThread()); 222 helper_.CheckOnValidThread();
247 if (!task_queue_manager_) 223 if (!helper_.SchedulerTaskQueueManager())
248 return false; 224 return false;
249 225
250 MaybeUpdatePolicy(); 226 MaybeUpdatePolicy();
251 // We only yield if we are in the compositor priority and there is compositor 227 // We only yield if we are in the compositor priority and there is compositor
252 // work outstanding, or if we are in the touchstart response priority. 228 // work outstanding, or if we are in the touchstart response priority.
253 // Note: even though the control queue is higher priority we don't yield for 229 // Note: even though the control queue is higher priority we don't yield for
254 // it since these tasks are not user-provided work and they are only intended 230 // it since these tasks are not user-provided work and they are only intended
255 // to run before the next task, not interrupt the tasks. 231 // to run before the next task, not interrupt the tasks.
256 switch (SchedulerPolicy()) { 232 switch (SchedulerPolicy()) {
257 case Policy::NORMAL: 233 case Policy::NORMAL:
258 return false; 234 return false;
259 235
260 case Policy::COMPOSITOR_PRIORITY: 236 case Policy::COMPOSITOR_PRIORITY:
261 return !task_queue_manager_->IsQueueEmpty(COMPOSITOR_TASK_QUEUE); 237 return !helper_.SchedulerTaskQueueManager()->IsQueueEmpty(
238 COMPOSITOR_TASK_QUEUE);
262 239
263 case Policy::TOUCHSTART_PRIORITY: 240 case Policy::TOUCHSTART_PRIORITY:
264 return true; 241 return true;
265 242
266 default: 243 default:
267 NOTREACHED(); 244 NOTREACHED();
268 return false; 245 return false;
269 } 246 }
270 } 247 }
271 248
272 void RendererSchedulerImpl::CurrentIdleTaskDeadlineCallback( 249 void RendererSchedulerImpl::CurrentIdleTaskDeadlineCallbackForTesting(
273 base::TimeTicks* deadline_out) const { 250 base::TimeTicks* deadline_out) const {
274 DCHECK(main_thread_checker_.CalledOnValidThread()); 251 helper_.CurrentIdleTaskDeadlineCallback(deadline_out);
275 *deadline_out = estimated_next_frame_begin_;
276 } 252 }
277 253
278 RendererSchedulerImpl::Policy RendererSchedulerImpl::SchedulerPolicy() const { 254 RendererSchedulerImpl::Policy RendererSchedulerImpl::SchedulerPolicy() const {
279 DCHECK(main_thread_checker_.CalledOnValidThread()); 255 helper_.CheckOnValidThread();
280 return current_policy_; 256 return current_policy_;
281 } 257 }
282 258
283 void RendererSchedulerImpl::MaybeUpdatePolicy() { 259 void RendererSchedulerImpl::MaybeUpdatePolicy() {
284 DCHECK(main_thread_checker_.CalledOnValidThread()); 260 helper_.CheckOnValidThread();
285 if (policy_may_need_update_.IsSet()) { 261 if (policy_may_need_update_.IsSet()) {
286 UpdatePolicy(); 262 UpdatePolicy();
287 } 263 }
288 } 264 }
289 265
290 void RendererSchedulerImpl::EnsureUrgentPolicyUpdatePostedOnMainThread( 266 void RendererSchedulerImpl::EnsureUrgentPolicyUpdatePostedOnMainThread(
291 const tracked_objects::Location& from_here) { 267 const tracked_objects::Location& from_here) {
292 // TODO(scheduler-dev): Check that this method isn't called from the main 268 // TODO(scheduler-dev): Check that this method isn't called from the main
293 // thread. 269 // thread.
294 incoming_signals_lock_.AssertAcquired(); 270 incoming_signals_lock_.AssertAcquired();
295 if (!policy_may_need_update_.IsSet()) { 271 if (!policy_may_need_update_.IsSet()) {
296 policy_may_need_update_.SetWhileLocked(true); 272 policy_may_need_update_.SetWhileLocked(true);
297 control_task_runner_->PostTask(from_here, update_policy_closure_); 273 control_task_runner_->PostTask(from_here, update_policy_closure_);
298 } 274 }
299 } 275 }
300 276
301 void RendererSchedulerImpl::UpdatePolicy() { 277 void RendererSchedulerImpl::UpdatePolicy() {
302 base::AutoLock lock(incoming_signals_lock_); 278 base::AutoLock lock(incoming_signals_lock_);
303 UpdatePolicyLocked(); 279 UpdatePolicyLocked();
304 } 280 }
305 281
306 void RendererSchedulerImpl::UpdatePolicyLocked() { 282 void RendererSchedulerImpl::UpdatePolicyLocked() {
307 DCHECK(main_thread_checker_.CalledOnValidThread()); 283 helper_.CheckOnValidThread();
308 incoming_signals_lock_.AssertAcquired(); 284 incoming_signals_lock_.AssertAcquired();
309 if (!task_queue_manager_) 285 if (!helper_.SchedulerTaskQueueManager())
310 return; 286 return;
311 287
312 base::TimeTicks now = Now(); 288 base::TimeTicks now = helper_.Now();
313 policy_may_need_update_.SetWhileLocked(false); 289 policy_may_need_update_.SetWhileLocked(false);
314 290
315 base::TimeDelta new_policy_duration; 291 base::TimeDelta new_policy_duration;
316 Policy new_policy = ComputeNewPolicy(now, &new_policy_duration); 292 Policy new_policy = ComputeNewPolicy(now, &new_policy_duration);
317 if (new_policy_duration > base::TimeDelta()) { 293 if (new_policy_duration > base::TimeDelta()) {
318 current_policy_expiration_time_ = now + new_policy_duration; 294 current_policy_expiration_time_ = now + new_policy_duration;
319 delayed_update_policy_runner_.SetDeadline(FROM_HERE, new_policy_duration, 295 delayed_update_policy_runner_.SetDeadline(FROM_HERE, new_policy_duration,
320 now); 296 now);
321 } else { 297 } else {
322 current_policy_expiration_time_ = base::TimeTicks(); 298 current_policy_expiration_time_ = base::TimeTicks();
323 } 299 }
324 300
325 if (new_policy == current_policy_) 301 if (new_policy == current_policy_)
326 return; 302 return;
327 303
304 PrioritizingTaskQueueSelector* task_queue_selector =
305 helper_.SchedulerTaskQueueSelector();
306
328 switch (new_policy) { 307 switch (new_policy) {
329 case Policy::COMPOSITOR_PRIORITY: 308 case Policy::COMPOSITOR_PRIORITY:
330 renderer_task_queue_selector_->SetQueuePriority( 309 task_queue_selector->SetQueuePriority(
331 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY); 310 COMPOSITOR_TASK_QUEUE, PrioritizingTaskQueueSelector::HIGH_PRIORITY);
332 // TODO(scheduler-dev): Add a task priority between HIGH and BEST_EFFORT 311 // TODO(scheduler-dev): Add a task priority between HIGH and BEST_EFFORT
333 // that still has some guarantee of running. 312 // that still has some guarantee of running.
334 renderer_task_queue_selector_->SetQueuePriority( 313 task_queue_selector->SetQueuePriority(
335 LOADING_TASK_QUEUE, RendererTaskQueueSelector::BEST_EFFORT_PRIORITY); 314 LOADING_TASK_QUEUE,
315 PrioritizingTaskQueueSelector::BEST_EFFORT_PRIORITY);
336 break; 316 break;
337 case Policy::TOUCHSTART_PRIORITY: 317 case Policy::TOUCHSTART_PRIORITY:
338 renderer_task_queue_selector_->SetQueuePriority( 318 task_queue_selector->SetQueuePriority(
339 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY); 319 COMPOSITOR_TASK_QUEUE, PrioritizingTaskQueueSelector::HIGH_PRIORITY);
340 renderer_task_queue_selector_->DisableQueue(LOADING_TASK_QUEUE); 320 task_queue_selector->DisableQueue(LOADING_TASK_QUEUE);
341 break; 321 break;
342 case Policy::NORMAL: 322 case Policy::NORMAL:
343 renderer_task_queue_selector_->SetQueuePriority( 323 task_queue_selector->SetQueuePriority(
344 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::NORMAL_PRIORITY); 324 COMPOSITOR_TASK_QUEUE,
345 renderer_task_queue_selector_->SetQueuePriority( 325 PrioritizingTaskQueueSelector::NORMAL_PRIORITY);
346 LOADING_TASK_QUEUE, RendererTaskQueueSelector::NORMAL_PRIORITY); 326 task_queue_selector->SetQueuePriority(
327 LOADING_TASK_QUEUE, PrioritizingTaskQueueSelector::NORMAL_PRIORITY);
347 break; 328 break;
348 } 329 }
349 DCHECK(renderer_task_queue_selector_->IsQueueEnabled(COMPOSITOR_TASK_QUEUE)); 330 DCHECK(task_queue_selector->IsQueueEnabled(COMPOSITOR_TASK_QUEUE));
350 if (new_policy != Policy::TOUCHSTART_PRIORITY) 331 if (new_policy != Policy::TOUCHSTART_PRIORITY)
351 DCHECK(renderer_task_queue_selector_->IsQueueEnabled(LOADING_TASK_QUEUE)); 332 DCHECK(task_queue_selector->IsQueueEnabled(LOADING_TASK_QUEUE));
352 333
353 current_policy_ = new_policy; 334 current_policy_ = new_policy;
354 335
355 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( 336 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
356 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", 337 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
357 this, AsValueLocked(now)); 338 this, AsValueLocked(now));
358 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 339 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
359 "RendererScheduler.policy", current_policy_); 340 "RendererScheduler.policy", current_policy_);
360 } 341 }
361 342
362 RendererSchedulerImpl::Policy RendererSchedulerImpl::ComputeNewPolicy( 343 RendererSchedulerImpl::Policy RendererSchedulerImpl::ComputeNewPolicy(
363 base::TimeTicks now, 344 base::TimeTicks now,
364 base::TimeDelta* new_policy_duration) { 345 base::TimeDelta* new_policy_duration) {
365 DCHECK(main_thread_checker_.CalledOnValidThread()); 346 helper_.CheckOnValidThread();
366 incoming_signals_lock_.AssertAcquired(); 347 incoming_signals_lock_.AssertAcquired();
367 348
368 Policy new_policy = Policy::NORMAL; 349 Policy new_policy = Policy::NORMAL;
369 *new_policy_duration = base::TimeDelta(); 350 *new_policy_duration = base::TimeDelta();
370 351
371 if (input_stream_state_ == InputStreamState::INACTIVE) 352 if (input_stream_state_ == InputStreamState::INACTIVE)
372 return new_policy; 353 return new_policy;
373 354
374 Policy input_priority_policy = 355 Policy input_priority_policy =
375 input_stream_state_ == 356 input_stream_state_ ==
376 InputStreamState::ACTIVE_AND_AWAITING_TOUCHSTART_RESPONSE 357 InputStreamState::ACTIVE_AND_AWAITING_TOUCHSTART_RESPONSE
377 ? Policy::TOUCHSTART_PRIORITY 358 ? Policy::TOUCHSTART_PRIORITY
378 : Policy::COMPOSITOR_PRIORITY; 359 : Policy::COMPOSITOR_PRIORITY;
379 base::TimeDelta time_left_in_policy = TimeLeftInInputEscalatedPolicy(now); 360 base::TimeDelta time_left_in_policy = TimeLeftInInputEscalatedPolicy(now);
380 if (time_left_in_policy > base::TimeDelta()) { 361 if (time_left_in_policy > base::TimeDelta()) {
381 new_policy = input_priority_policy; 362 new_policy = input_priority_policy;
382 *new_policy_duration = time_left_in_policy; 363 *new_policy_duration = time_left_in_policy;
383 } else { 364 } else {
384 // Reset |input_stream_state_| to ensure 365 // Reset |input_stream_state_| to ensure
385 // DidReceiveInputEventOnCompositorThread will post an UpdatePolicy task 366 // DidReceiveInputEventOnCompositorThread will post an UpdatePolicy task
386 // when it's next called. 367 // when it's next called.
387 input_stream_state_ = InputStreamState::INACTIVE; 368 input_stream_state_ = InputStreamState::INACTIVE;
388 } 369 }
389 return new_policy; 370 return new_policy;
390 } 371 }
391 372
392 base::TimeDelta RendererSchedulerImpl::TimeLeftInInputEscalatedPolicy( 373 base::TimeDelta RendererSchedulerImpl::TimeLeftInInputEscalatedPolicy(
393 base::TimeTicks now) const { 374 base::TimeTicks now) const {
394 DCHECK(main_thread_checker_.CalledOnValidThread()); 375 helper_.CheckOnValidThread();
395 // TODO(rmcilroy): Change this to DCHECK_EQ when crbug.com/463869 is fixed. 376 // TODO(rmcilroy): Change this to DCHECK_EQ when crbug.com/463869 is fixed.
396 DCHECK(input_stream_state_ != InputStreamState::INACTIVE); 377 DCHECK(input_stream_state_ != InputStreamState::INACTIVE);
397 incoming_signals_lock_.AssertAcquired(); 378 incoming_signals_lock_.AssertAcquired();
398 379
399 base::TimeDelta escalated_priority_duration = 380 base::TimeDelta escalated_priority_duration =
400 base::TimeDelta::FromMilliseconds(kPriorityEscalationAfterInputMillis); 381 base::TimeDelta::FromMilliseconds(kPriorityEscalationAfterInputMillis);
401 base::TimeDelta time_left_in_policy; 382 base::TimeDelta time_left_in_policy;
402 if (last_input_process_time_on_main_.is_null() && 383 if (last_input_process_time_on_main_.is_null() &&
403 !task_queue_manager_->IsQueueEmpty(COMPOSITOR_TASK_QUEUE)) { 384 !helper_.SchedulerTaskQueueManager()->IsQueueEmpty(
385 COMPOSITOR_TASK_QUEUE)) {
404 // If the input event is still pending, go into input prioritized policy 386 // If the input event is still pending, go into input prioritized policy
405 // and check again later. 387 // and check again later.
406 time_left_in_policy = escalated_priority_duration; 388 time_left_in_policy = escalated_priority_duration;
407 } else { 389 } else {
408 // Otherwise make sure the input prioritization policy ends on time. 390 // Otherwise make sure the input prioritization policy ends on time.
409 base::TimeTicks new_priority_end( 391 base::TimeTicks new_priority_end(
410 std::max(last_input_receipt_time_on_compositor_, 392 std::max(last_input_receipt_time_on_compositor_,
411 last_input_process_time_on_main_) + 393 last_input_process_time_on_main_) +
412 escalated_priority_duration); 394 escalated_priority_duration);
413 time_left_in_policy = new_priority_end - now; 395 time_left_in_policy = new_priority_end - now;
414 } 396 }
415 return time_left_in_policy; 397 return time_left_in_policy;
416 } 398 }
417 399
418 RendererSchedulerImpl::IdlePeriodState 400 bool RendererSchedulerImpl::CanEnterLongIdlePeriod(
419 RendererSchedulerImpl::ComputeNewLongIdlePeriodState( 401 base::TimeTicks now,
420 const base::TimeTicks now,
421 base::TimeDelta* next_long_idle_period_delay_out) { 402 base::TimeDelta* next_long_idle_period_delay_out) {
422 DCHECK(main_thread_checker_.CalledOnValidThread()); 403 helper_.CheckOnValidThread();
423 404
424 MaybeUpdatePolicy(); 405 MaybeUpdatePolicy();
425 if (SchedulerPolicy() == Policy::TOUCHSTART_PRIORITY) { 406 if (SchedulerPolicy() == Policy::TOUCHSTART_PRIORITY) {
426 // Don't start a long idle task in touch start priority, try again when 407 // Don't start a long idle task in touch start priority, try again when
427 // the policy is scheduled to end. 408 // the policy is scheduled to end.
428 *next_long_idle_period_delay_out = current_policy_expiration_time_ - now; 409 *next_long_idle_period_delay_out = current_policy_expiration_time_ - now;
429 return IdlePeriodState::NOT_IN_IDLE_PERIOD; 410 return false;
430 } 411 }
431 412 return true;
432 base::TimeTicks next_pending_delayed_task =
433 task_queue_manager_->NextPendingDelayedTaskRunTime();
434 base::TimeDelta max_long_idle_period_duration =
435 base::TimeDelta::FromMilliseconds(kMaximumIdlePeriodMillis);
436 base::TimeDelta long_idle_period_duration;
437 if (next_pending_delayed_task.is_null()) {
438 long_idle_period_duration = max_long_idle_period_duration;
439 } else {
440 // Limit the idle period duration to be before the next pending task.
441 long_idle_period_duration = std::min(next_pending_delayed_task - now,
442 max_long_idle_period_duration);
443 }
444
445 if (long_idle_period_duration > base::TimeDelta()) {
446 *next_long_idle_period_delay_out = long_idle_period_duration;
447 return long_idle_period_duration == max_long_idle_period_duration
448 ? IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE
449 : IdlePeriodState::IN_LONG_IDLE_PERIOD;
450 } else {
451 // If we can't start the idle period yet then try again after wakeup.
452 *next_long_idle_period_delay_out = base::TimeDelta::FromMilliseconds(
453 kRetryInitiateLongIdlePeriodDelayMillis);
454 return IdlePeriodState::NOT_IN_IDLE_PERIOD;
455 }
456 }
457
458 void RendererSchedulerImpl::InitiateLongIdlePeriod() {
459 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
460 "InitiateLongIdlePeriod");
461 DCHECK(main_thread_checker_.CalledOnValidThread());
462
463 // End any previous idle period.
464 EndIdlePeriod();
465
466 base::TimeTicks now(Now());
467 base::TimeDelta next_long_idle_period_delay;
468 IdlePeriodState new_idle_period_state =
469 ComputeNewLongIdlePeriodState(now, &next_long_idle_period_delay);
470 if (IsInIdlePeriod(new_idle_period_state)) {
471 estimated_next_frame_begin_ = now + next_long_idle_period_delay;
472 StartIdlePeriod(new_idle_period_state);
473 }
474
475 if (task_queue_manager_->IsQueueEmpty(IDLE_TASK_QUEUE)) {
476 // If there are no current idle tasks then post the call to initiate the
477 // next idle for execution after wakeup (at which point after-wakeup idle
478 // tasks might be eligible to run or more idle tasks posted).
479 control_task_after_wakeup_runner_->PostDelayedTask(
480 FROM_HERE,
481 initiate_next_long_idle_period_after_wakeup_closure_.callback(),
482 next_long_idle_period_delay);
483 } else {
484 // Otherwise post on the normal control task queue.
485 control_task_runner_->PostDelayedTask(
486 FROM_HERE,
487 initiate_next_long_idle_period_closure_.callback(),
488 next_long_idle_period_delay);
489 }
490 }
491
492 void RendererSchedulerImpl::InitiateLongIdlePeriodAfterWakeup() {
493 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
494 "InitiateLongIdlePeriodAfterWakeup");
495 DCHECK(main_thread_checker_.CalledOnValidThread());
496
497 if (IsInIdlePeriod(idle_period_state_)) {
498 // Since we were asleep until now, end the async idle period trace event at
499 // the time when it would have ended were we awake.
500 TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0(
501 "renderer.scheduler", "RendererSchedulerIdlePeriod", this,
502 std::min(estimated_next_frame_begin_, Now()).ToInternalValue());
503 idle_period_state_ = IdlePeriodState::ENDING_LONG_IDLE_PERIOD;
504 EndIdlePeriod();
505 }
506
507 // Post a task to initiate the next long idle period rather than calling it
508 // directly to allow all pending PostIdleTaskAfterWakeup tasks to get enqueued
509 // on the idle task queue before the next idle period starts so they are
510 // eligible to be run during the new idle period.
511 control_task_runner_->PostTask(
512 FROM_HERE,
513 initiate_next_long_idle_period_closure_.callback());
514 }
515
516 void RendererSchedulerImpl::StartIdlePeriod(IdlePeriodState new_state) {
517 TRACE_EVENT_ASYNC_BEGIN0("renderer.scheduler",
518 "RendererSchedulerIdlePeriod", this);
519 DCHECK(main_thread_checker_.CalledOnValidThread());
520 DCHECK(IsInIdlePeriod(new_state));
521
522 renderer_task_queue_selector_->EnableQueue(
523 IDLE_TASK_QUEUE, RendererTaskQueueSelector::BEST_EFFORT_PRIORITY);
524 task_queue_manager_->PumpQueue(IDLE_TASK_QUEUE);
525 idle_period_state_ = new_state;
526 }
527
528 void RendererSchedulerImpl::EndIdlePeriod() {
529 DCHECK(main_thread_checker_.CalledOnValidThread());
530
531 end_idle_period_closure_.Cancel();
532 initiate_next_long_idle_period_closure_.Cancel();
533 initiate_next_long_idle_period_after_wakeup_closure_.Cancel();
534
535 // If we weren't already within an idle period then early-out.
536 if (!IsInIdlePeriod(idle_period_state_))
537 return;
538
539 // If we are in the ENDING_LONG_IDLE_PERIOD state we have already logged the
540 // trace event.
541 if (idle_period_state_ != IdlePeriodState::ENDING_LONG_IDLE_PERIOD) {
542 bool is_tracing;
543 TRACE_EVENT_CATEGORY_GROUP_ENABLED("renderer.scheduler", &is_tracing);
544 if (is_tracing && !estimated_next_frame_begin_.is_null() &&
545 base::TimeTicks::Now() > estimated_next_frame_begin_) {
546 TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0(
547 "renderer.scheduler",
548 "RendererSchedulerIdlePeriod",
549 this,
550 "DeadlineOverrun",
551 estimated_next_frame_begin_.ToInternalValue());
552 }
553 TRACE_EVENT_ASYNC_END0("renderer.scheduler",
554 "RendererSchedulerIdlePeriod", this);
555 }
556
557 renderer_task_queue_selector_->DisableQueue(IDLE_TASK_QUEUE);
558 idle_period_state_ = IdlePeriodState::NOT_IN_IDLE_PERIOD;
559 }
560
561 // static
562 bool RendererSchedulerImpl::IsInIdlePeriod(IdlePeriodState state) {
563 return state != IdlePeriodState::NOT_IN_IDLE_PERIOD;
564 }
565
566 bool RendererSchedulerImpl::CanExceedIdleDeadlineIfRequired() const {
567 TRACE_EVENT_BEGIN0("renderer.scheduler", "CanExceedIdleDeadlineIfRequired");
568 DCHECK(main_thread_checker_.CalledOnValidThread());
569 return idle_period_state_ ==
570 IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE;
571 } 413 }
572 414
573 void RendererSchedulerImpl::SetTimeSourceForTesting( 415 void RendererSchedulerImpl::SetTimeSourceForTesting(
574 scoped_refptr<cc::TestNowSource> time_source) { 416 scoped_refptr<cc::TestNowSource> time_source) {
575 DCHECK(main_thread_checker_.CalledOnValidThread()); 417 helper_.SetTimeSourceForTesting(time_source);
576 time_source_ = time_source;
577 task_queue_manager_->SetTimeSourceForTesting(time_source);
578 } 418 }
579 419
580 void RendererSchedulerImpl::SetWorkBatchSizeForTesting(size_t work_batch_size) { 420 void RendererSchedulerImpl::SetWorkBatchSizeForTesting(size_t work_batch_size) {
581 DCHECK(main_thread_checker_.CalledOnValidThread()); 421 helper_.SetWorkBatchSizeForTesting(work_batch_size);
582 task_queue_manager_->SetWorkBatchSize(work_batch_size);
583 }
584
585 base::TimeTicks RendererSchedulerImpl::Now() const {
586 return UNLIKELY(time_source_) ? time_source_->Now() : base::TimeTicks::Now();
587 } 422 }
588 423
589 RendererSchedulerImpl::PollableNeedsUpdateFlag::PollableNeedsUpdateFlag( 424 RendererSchedulerImpl::PollableNeedsUpdateFlag::PollableNeedsUpdateFlag(
590 base::Lock* write_lock_) 425 base::Lock* write_lock_)
591 : flag_(false), write_lock_(write_lock_) { 426 : flag_(false), write_lock_(write_lock_) {
592 } 427 }
593 428
594 RendererSchedulerImpl::PollableNeedsUpdateFlag::~PollableNeedsUpdateFlag() { 429 RendererSchedulerImpl::PollableNeedsUpdateFlag::~PollableNeedsUpdateFlag() {
595 } 430 }
596 431
597 void RendererSchedulerImpl::PollableNeedsUpdateFlag::SetWhileLocked( 432 void RendererSchedulerImpl::PollableNeedsUpdateFlag::SetWhileLocked(
598 bool value) { 433 bool value) {
599 write_lock_->AssertAcquired(); 434 write_lock_->AssertAcquired();
600 base::subtle::Release_Store(&flag_, value); 435 base::subtle::Release_Store(&flag_, value);
601 } 436 }
602 437
603 bool RendererSchedulerImpl::PollableNeedsUpdateFlag::IsSet() const { 438 bool RendererSchedulerImpl::PollableNeedsUpdateFlag::IsSet() const {
604 return base::subtle::Acquire_Load(&flag_) != 0; 439 return base::subtle::Acquire_Load(&flag_) != 0;
605 } 440 }
606 441
607 // static 442 // static
608 const char* RendererSchedulerImpl::TaskQueueIdToString(QueueId queue_id) { 443 const char* RendererSchedulerImpl::TaskQueueIdToString(QueueId queue_id) {
609 switch (queue_id) { 444 switch (queue_id) {
610 case DEFAULT_TASK_QUEUE:
611 return "default_tq";
612 case COMPOSITOR_TASK_QUEUE: 445 case COMPOSITOR_TASK_QUEUE:
613 return "compositor_tq"; 446 return "compositor_tq";
614 case LOADING_TASK_QUEUE: 447 case LOADING_TASK_QUEUE:
615 return "loading_tq"; 448 return "loading_tq";
616 case IDLE_TASK_QUEUE:
617 return "idle_tq";
618 case CONTROL_TASK_QUEUE:
619 return "control_tq";
620 case CONTROL_TASK_AFTER_WAKEUP_QUEUE:
621 return "control_after_wakeup_tq";
622 default: 449 default:
623 NOTREACHED(); 450 return SchedulerHelper::TaskQueueIdToString(
624 return nullptr; 451 static_cast<SchedulerHelper::QueueId>(queue_id));
625 } 452 }
626 } 453 }
627 454
628 // static 455 // static
629 const char* RendererSchedulerImpl::PolicyToString(Policy policy) { 456 const char* RendererSchedulerImpl::PolicyToString(Policy policy) {
630 switch (policy) { 457 switch (policy) {
631 case Policy::NORMAL: 458 case Policy::NORMAL:
632 return "normal"; 459 return "normal";
633 case Policy::COMPOSITOR_PRIORITY: 460 case Policy::COMPOSITOR_PRIORITY:
634 return "compositor"; 461 return "compositor";
(...skipping 13 matching lines...) Expand all
648 case InputStreamState::ACTIVE: 475 case InputStreamState::ACTIVE:
649 return "active"; 476 return "active";
650 case InputStreamState::ACTIVE_AND_AWAITING_TOUCHSTART_RESPONSE: 477 case InputStreamState::ACTIVE_AND_AWAITING_TOUCHSTART_RESPONSE:
651 return "active_and_awaiting_touchstart_response"; 478 return "active_and_awaiting_touchstart_response";
652 default: 479 default:
653 NOTREACHED(); 480 NOTREACHED();
654 return nullptr; 481 return nullptr;
655 } 482 }
656 } 483 }
657 484
658 const char* RendererSchedulerImpl::IdlePeriodStateToString(
659 IdlePeriodState idle_period_state) {
660 switch (idle_period_state) {
661 case IdlePeriodState::NOT_IN_IDLE_PERIOD:
662 return "not_in_idle_period";
663 case IdlePeriodState::IN_SHORT_IDLE_PERIOD:
664 return "in_short_idle_period";
665 case IdlePeriodState::IN_LONG_IDLE_PERIOD:
666 return "in_long_idle_period";
667 case IdlePeriodState::IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE:
668 return "in_long_idle_period_with_max_deadline";
669 case IdlePeriodState::ENDING_LONG_IDLE_PERIOD:
670 return "ending_long_idle_period";
671 default:
672 NOTREACHED();
673 return nullptr;
674 }
675 }
676
677 scoped_refptr<base::trace_event::ConvertableToTraceFormat> 485 scoped_refptr<base::trace_event::ConvertableToTraceFormat>
678 RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const { 486 RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const {
679 DCHECK(main_thread_checker_.CalledOnValidThread()); 487 helper_.CheckOnValidThread();
680 incoming_signals_lock_.AssertAcquired(); 488 incoming_signals_lock_.AssertAcquired();
681 489
682 if (optional_now.is_null()) 490 if (optional_now.is_null())
683 optional_now = Now(); 491 optional_now = helper_.Now();
684 scoped_refptr<base::trace_event::TracedValue> state = 492 scoped_refptr<base::trace_event::TracedValue> state =
685 new base::trace_event::TracedValue(); 493 new base::trace_event::TracedValue();
686 494
687 state->SetString("current_policy", PolicyToString(current_policy_)); 495 state->SetString("current_policy", PolicyToString(current_policy_));
688 state->SetString("idle_period_state", 496 state->SetString("idle_period_state",
689 IdlePeriodStateToString(idle_period_state_)); 497 SchedulerHelper::IdlePeriodStateToString(
498 helper_.SchedulerIdlePeriodState()));
690 state->SetString("input_stream_state", 499 state->SetString("input_stream_state",
691 InputStreamStateToString(input_stream_state_)); 500 InputStreamStateToString(input_stream_state_));
692 state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF()); 501 state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF());
693 state->SetDouble("last_input_receipt_time_on_compositor_", 502 state->SetDouble("last_input_receipt_time_on_compositor_",
694 (last_input_receipt_time_on_compositor_ - base::TimeTicks()) 503 (last_input_receipt_time_on_compositor_ - base::TimeTicks())
695 .InMillisecondsF()); 504 .InMillisecondsF());
696 state->SetDouble( 505 state->SetDouble(
697 "last_input_process_time_on_main_", 506 "last_input_process_time_on_main_",
698 (last_input_process_time_on_main_ - base::TimeTicks()).InMillisecondsF()); 507 (last_input_process_time_on_main_ - base::TimeTicks()).InMillisecondsF());
699 state->SetDouble( 508 state->SetDouble("estimated_next_frame_begin",
700 "estimated_next_frame_begin", 509 (helper_.EstimatedNextFrameBegin() - base::TimeTicks())
701 (estimated_next_frame_begin_ - base::TimeTicks()).InMillisecondsF()); 510 .InMillisecondsF());
702 511
703 return state; 512 return state;
704 } 513 }
705 514
706 RendererSchedulerImpl::InputStreamState 515 RendererSchedulerImpl::InputStreamState
707 RendererSchedulerImpl::ComputeNewInputStreamState( 516 RendererSchedulerImpl::ComputeNewInputStreamState(
708 InputStreamState current_state, 517 InputStreamState current_state,
709 blink::WebInputEvent::Type new_input_type, 518 blink::WebInputEvent::Type new_input_type,
710 blink::WebInputEvent::Type last_input_type) { 519 blink::WebInputEvent::Type last_input_type) {
711 switch (new_input_type) { 520 switch (new_input_type) {
(...skipping 20 matching lines...) Expand all
732 // With no observable effect, these meta events do not indicate a 541 // With no observable effect, these meta events do not indicate a
733 // meaningful touchstart response and should not impact task priority. 542 // meaningful touchstart response and should not impact task priority.
734 return current_state; 543 return current_state;
735 544
736 default: 545 default:
737 break; 546 break;
738 } 547 }
739 return InputStreamState::ACTIVE; 548 return InputStreamState::ACTIVE;
740 } 549 }
741 550
742 void RendererSchedulerImpl::AddTaskObserver(
743 base::MessageLoop::TaskObserver* task_observer) {
744 DCHECK(main_thread_checker_.CalledOnValidThread());
745 if (task_queue_manager_)
746 task_queue_manager_->AddTaskObserver(task_observer);
747 }
748
749 void RendererSchedulerImpl::RemoveTaskObserver(
750 base::MessageLoop::TaskObserver* task_observer) {
751 DCHECK(main_thread_checker_.CalledOnValidThread());
752 if (task_queue_manager_)
753 task_queue_manager_->RemoveTaskObserver(task_observer);
754 }
755
756 } // namespace content 551 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698