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

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

Issue 994833003: Prevent multiple pending UpdatePolicy tasks. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Forgot to change the friend declaration 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"
(...skipping 13 matching lines...) Expand all
24 control_task_runner_( 24 control_task_runner_(
25 task_queue_manager_->TaskRunnerForQueue(CONTROL_TASK_QUEUE)), 25 task_queue_manager_->TaskRunnerForQueue(CONTROL_TASK_QUEUE)),
26 control_task_after_wakeup_runner_(task_queue_manager_->TaskRunnerForQueue( 26 control_task_after_wakeup_runner_(task_queue_manager_->TaskRunnerForQueue(
27 CONTROL_TASK_AFTER_WAKEUP_QUEUE)), 27 CONTROL_TASK_AFTER_WAKEUP_QUEUE)),
28 default_task_runner_( 28 default_task_runner_(
29 task_queue_manager_->TaskRunnerForQueue(DEFAULT_TASK_QUEUE)), 29 task_queue_manager_->TaskRunnerForQueue(DEFAULT_TASK_QUEUE)),
30 compositor_task_runner_( 30 compositor_task_runner_(
31 task_queue_manager_->TaskRunnerForQueue(COMPOSITOR_TASK_QUEUE)), 31 task_queue_manager_->TaskRunnerForQueue(COMPOSITOR_TASK_QUEUE)),
32 loading_task_runner_( 32 loading_task_runner_(
33 task_queue_manager_->TaskRunnerForQueue(LOADING_TASK_QUEUE)), 33 task_queue_manager_->TaskRunnerForQueue(LOADING_TASK_QUEUE)),
34 delayed_update_policy_runner_(
35 base::Bind(&RendererSchedulerImpl::UpdatePolicy,
36 base::Unretained(this)),
37 control_task_runner_),
34 current_policy_(Policy::NORMAL), 38 current_policy_(Policy::NORMAL),
35 last_input_type_(blink::WebInputEvent::Undefined), 39 last_input_type_(blink::WebInputEvent::Undefined),
36 input_stream_state_(InputStreamState::INACTIVE), 40 input_stream_state_(InputStreamState::INACTIVE),
37 policy_may_need_update_(&incoming_signals_lock_), 41 policy_may_need_update_(&incoming_signals_lock_),
38 weak_factory_(this) { 42 weak_factory_(this) {
39 weak_renderer_scheduler_ptr_ = weak_factory_.GetWeakPtr(); 43 weak_renderer_scheduler_ptr_ = weak_factory_.GetWeakPtr();
40 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, 44 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy,
41 weak_renderer_scheduler_ptr_); 45 weak_renderer_scheduler_ptr_);
42 end_idle_period_closure_.Reset(base::Bind( 46 end_idle_period_closure_.Reset(base::Bind(
43 &RendererSchedulerImpl::EndIdlePeriod, weak_renderer_scheduler_ptr_)); 47 &RendererSchedulerImpl::EndIdlePeriod, weak_renderer_scheduler_ptr_));
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 void RendererSchedulerImpl::UpdateForInputEvent( 182 void RendererSchedulerImpl::UpdateForInputEvent(
179 blink::WebInputEvent::Type type) { 183 blink::WebInputEvent::Type type) {
180 base::AutoLock lock(incoming_signals_lock_); 184 base::AutoLock lock(incoming_signals_lock_);
181 185
182 InputStreamState new_input_stream_state = 186 InputStreamState new_input_stream_state =
183 ComputeNewInputStreamState(input_stream_state_, type, last_input_type_); 187 ComputeNewInputStreamState(input_stream_state_, type, last_input_type_);
184 188
185 if (input_stream_state_ != new_input_stream_state) { 189 if (input_stream_state_ != new_input_stream_state) {
186 // Update scheduler policy if we should start a new policy mode. 190 // Update scheduler policy if we should start a new policy mode.
187 input_stream_state_ = new_input_stream_state; 191 input_stream_state_ = new_input_stream_state;
188 policy_may_need_update_.SetWhileLocked(true); 192 EnsureUrgentPolicyUpdatePostedOnMainThread(FROM_HERE);
189 PostUpdatePolicyOnControlRunner(base::TimeDelta());
190 } 193 }
191 last_input_receipt_time_on_compositor_ = Now(); 194 last_input_receipt_time_on_compositor_ = Now();
192 // Clear the last known input processing time so that we know an input event 195 // Clear the last known input processing time so that we know an input event
193 // is still queued up. This timestamp will be updated the next time the 196 // is still queued up. This timestamp will be updated the next time the
194 // compositor commits or becomes quiescent. Note that this function is always 197 // compositor commits or becomes quiescent. Note that this function is always
195 // called before the input event is processed either on the compositor or 198 // called before the input event is processed either on the compositor or
196 // main threads. 199 // main threads.
197 last_input_process_time_on_main_ = base::TimeTicks(); 200 last_input_process_time_on_main_ = base::TimeTicks();
198 last_input_type_ = type; 201 last_input_type_ = type;
199 } 202 }
200 203
201 void RendererSchedulerImpl::DidProcessInputEvent( 204 void RendererSchedulerImpl::DidProcessInputEvent(
202 base::TimeTicks begin_frame_time) { 205 base::TimeTicks begin_frame_time) {
206 DCHECK(main_thread_checker_.CalledOnValidThread());
203 base::AutoLock lock(incoming_signals_lock_); 207 base::AutoLock lock(incoming_signals_lock_);
204 if (input_stream_state_ == InputStreamState::INACTIVE) 208 if (input_stream_state_ == InputStreamState::INACTIVE)
205 return; 209 return;
206 // Avoid marking input that arrived after the BeginFrame as processed. 210 // Avoid marking input that arrived after the BeginFrame as processed.
207 if (!begin_frame_time.is_null() && 211 if (!begin_frame_time.is_null() &&
208 begin_frame_time < last_input_receipt_time_on_compositor_) 212 begin_frame_time < last_input_receipt_time_on_compositor_)
209 return; 213 return;
210 last_input_process_time_on_main_ = Now(); 214 last_input_process_time_on_main_ = Now();
211 policy_may_need_update_.SetWhileLocked(true); 215 UpdatePolicyLocked();
212 } 216 }
213 217
214 bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() { 218 bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() {
215 DCHECK(main_thread_checker_.CalledOnValidThread()); 219 DCHECK(main_thread_checker_.CalledOnValidThread());
216 if (!task_queue_manager_) 220 if (!task_queue_manager_)
217 return false; 221 return false;
218 222
219 MaybeUpdatePolicy(); 223 MaybeUpdatePolicy();
220 // The touchstart and compositor policies indicate a strong likelihood of 224 // The touchstart and compositor policies indicate a strong likelihood of
221 // high-priority work in the near future. 225 // high-priority work in the near future.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 return current_policy_; 265 return current_policy_;
262 } 266 }
263 267
264 void RendererSchedulerImpl::MaybeUpdatePolicy() { 268 void RendererSchedulerImpl::MaybeUpdatePolicy() {
265 DCHECK(main_thread_checker_.CalledOnValidThread()); 269 DCHECK(main_thread_checker_.CalledOnValidThread());
266 if (policy_may_need_update_.IsSet()) { 270 if (policy_may_need_update_.IsSet()) {
267 UpdatePolicy(); 271 UpdatePolicy();
268 } 272 }
269 } 273 }
270 274
271 void RendererSchedulerImpl::PostUpdatePolicyOnControlRunner( 275 void RendererSchedulerImpl::EnsureUrgentPolicyUpdatePostedOnMainThread(
272 base::TimeDelta delay) { 276 const tracked_objects::Location& from_here) {
273 control_task_runner_->PostDelayedTask( 277 // TODO(scheduler-dev): Check that this method isn't called from the main
274 FROM_HERE, update_policy_closure_, delay); 278 // thread.
279 incoming_signals_lock_.AssertAcquired();
280 if (!policy_may_need_update_.IsSet()) {
281 policy_may_need_update_.SetWhileLocked(true);
282 control_task_runner_->PostTask(from_here, update_policy_closure_);
283 }
275 } 284 }
276 285
277 void RendererSchedulerImpl::UpdatePolicy() { 286 void RendererSchedulerImpl::UpdatePolicy() {
287 base::AutoLock lock(incoming_signals_lock_);
288 UpdatePolicyLocked();
289 }
290
291 void RendererSchedulerImpl::UpdatePolicyLocked() {
278 DCHECK(main_thread_checker_.CalledOnValidThread()); 292 DCHECK(main_thread_checker_.CalledOnValidThread());
293 incoming_signals_lock_.AssertAcquired();
279 if (!task_queue_manager_) 294 if (!task_queue_manager_)
280 return; 295 return;
281 296
282 base::AutoLock lock(incoming_signals_lock_); 297 base::TimeTicks now = Now();
283 base::TimeTicks now;
284 policy_may_need_update_.SetWhileLocked(false); 298 policy_may_need_update_.SetWhileLocked(false);
285 299
286 base::TimeDelta new_policy_duration; 300 base::TimeDelta new_policy_duration;
287 Policy new_policy = ComputeNewPolicy(&new_policy_duration); 301 Policy new_policy = ComputeNewPolicy(now, &new_policy_duration);
288 if (new_policy_duration > base::TimeDelta()) 302 if (new_policy_duration > base::TimeDelta()) {
289 PostUpdatePolicyOnControlRunner(new_policy_duration); 303 delayed_update_policy_runner_.SetDeadline(FROM_HERE, new_policy_duration,
304 now);
305 }
290 306
291 if (new_policy == current_policy_) 307 if (new_policy == current_policy_)
292 return; 308 return;
293 309
294 switch (new_policy) { 310 switch (new_policy) {
295 case Policy::COMPOSITOR_PRIORITY: 311 case Policy::COMPOSITOR_PRIORITY:
296 renderer_task_queue_selector_->SetQueuePriority( 312 renderer_task_queue_selector_->SetQueuePriority(
297 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY); 313 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY);
298 // TODO(scheduler-dev): Add a task priority between HIGH and BEST_EFFORT 314 // TODO(scheduler-dev): Add a task priority between HIGH and BEST_EFFORT
299 // that still has some guarantee of running. 315 // that still has some guarantee of running.
(...skipping 19 matching lines...) Expand all
319 current_policy_ = new_policy; 335 current_policy_ = new_policy;
320 336
321 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( 337 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
322 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", 338 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
323 this, AsValueLocked(now)); 339 this, AsValueLocked(now));
324 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 340 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
325 "RendererScheduler.policy", current_policy_); 341 "RendererScheduler.policy", current_policy_);
326 } 342 }
327 343
328 RendererSchedulerImpl::Policy RendererSchedulerImpl::ComputeNewPolicy( 344 RendererSchedulerImpl::Policy RendererSchedulerImpl::ComputeNewPolicy(
345 base::TimeTicks now,
329 base::TimeDelta* new_policy_duration) { 346 base::TimeDelta* new_policy_duration) {
330 DCHECK(main_thread_checker_.CalledOnValidThread()); 347 DCHECK(main_thread_checker_.CalledOnValidThread());
331 incoming_signals_lock_.AssertAcquired(); 348 incoming_signals_lock_.AssertAcquired();
332 349
333 Policy new_policy = Policy::NORMAL; 350 Policy new_policy = Policy::NORMAL;
334 *new_policy_duration = base::TimeDelta(); 351 *new_policy_duration = base::TimeDelta();
335 352
336 if (input_stream_state_ == InputStreamState::INACTIVE) 353 if (input_stream_state_ == InputStreamState::INACTIVE)
337 return new_policy; 354 return new_policy;
338 355
(...skipping 10 matching lines...) Expand all
349 if (last_input_process_time_on_main_.is_null() && 366 if (last_input_process_time_on_main_.is_null() &&
350 !task_queue_manager_->IsQueueEmpty(COMPOSITOR_TASK_QUEUE)) { 367 !task_queue_manager_->IsQueueEmpty(COMPOSITOR_TASK_QUEUE)) {
351 new_policy = input_priority_policy; 368 new_policy = input_priority_policy;
352 *new_policy_duration = new_priority_duration; 369 *new_policy_duration = new_priority_duration;
353 } else { 370 } else {
354 // Otherwise make sure the input prioritization policy ends on time. 371 // Otherwise make sure the input prioritization policy ends on time.
355 base::TimeTicks new_priority_end( 372 base::TimeTicks new_priority_end(
356 std::max(last_input_receipt_time_on_compositor_, 373 std::max(last_input_receipt_time_on_compositor_,
357 last_input_process_time_on_main_) + 374 last_input_process_time_on_main_) +
358 new_priority_duration); 375 new_priority_duration);
359 base::TimeDelta time_left_in_policy = new_priority_end - Now(); 376 base::TimeDelta time_left_in_policy = new_priority_end - now;
360 377
361 if (time_left_in_policy > base::TimeDelta()) { 378 if (time_left_in_policy > base::TimeDelta()) {
362 new_policy = input_priority_policy; 379 new_policy = input_priority_policy;
363 *new_policy_duration = time_left_in_policy; 380 *new_policy_duration = time_left_in_policy;
364 } else { 381 } else {
365 // Reset |input_stream_state_| to ensure 382 // Reset |input_stream_state_| to ensure
366 // DidReceiveInputEventOnCompositorThread will post an UpdatePolicy task 383 // DidReceiveInputEventOnCompositorThread will post an UpdatePolicy task
367 // when it's next called. 384 // when it's next called.
368 input_stream_state_ = InputStreamState::INACTIVE; 385 input_stream_state_ = InputStreamState::INACTIVE;
369 } 386 }
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 } 572 }
556 573
557 void RendererSchedulerImpl::RemoveTaskObserver( 574 void RendererSchedulerImpl::RemoveTaskObserver(
558 base::MessageLoop::TaskObserver* task_observer) { 575 base::MessageLoop::TaskObserver* task_observer) {
559 DCHECK(main_thread_checker_.CalledOnValidThread()); 576 DCHECK(main_thread_checker_.CalledOnValidThread());
560 if (task_queue_manager_) 577 if (task_queue_manager_)
561 task_queue_manager_->RemoveTaskObserver(task_observer); 578 task_queue_manager_->RemoveTaskObserver(task_observer);
562 } 579 }
563 580
564 } // namespace content 581 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/scheduler/renderer_scheduler_impl.h ('k') | content/renderer/scheduler/renderer_scheduler_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698