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

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: Refactored 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 17 matching lines...) Expand all
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 current_policy_(Policy::NORMAL), 34 current_policy_(Policy::NORMAL),
35 last_input_type_(blink::WebInputEvent::Undefined), 35 last_input_type_(blink::WebInputEvent::Undefined),
36 input_stream_state_(InputStreamState::INACTIVE), 36 input_stream_state_(InputStreamState::INACTIVE),
37 policy_may_need_update_(&incoming_signals_lock_), 37 policy_may_need_update_(&incoming_signals_lock_),
38 pending_delayed_policy_update_(false),
38 weak_factory_(this) { 39 weak_factory_(this) {
39 weak_renderer_scheduler_ptr_ = weak_factory_.GetWeakPtr(); 40 weak_renderer_scheduler_ptr_ = weak_factory_.GetWeakPtr();
40 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, 41 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy,
41 weak_renderer_scheduler_ptr_); 42 weak_renderer_scheduler_ptr_);
43 delayed_update_policy_closure_ =
44 base::Bind(&RendererSchedulerImpl::DelayedPolicyUpdateTask,
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_));
44 idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner( 48 idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner(
45 task_queue_manager_->TaskRunnerForQueue(IDLE_TASK_QUEUE), 49 task_queue_manager_->TaskRunnerForQueue(IDLE_TASK_QUEUE),
46 control_task_after_wakeup_runner_, 50 control_task_after_wakeup_runner_,
47 base::Bind(&RendererSchedulerImpl::CurrentIdleTaskDeadlineCallback, 51 base::Bind(&RendererSchedulerImpl::CurrentIdleTaskDeadlineCallback,
48 weak_renderer_scheduler_ptr_))); 52 weak_renderer_scheduler_ptr_)));
49 53
50 renderer_task_queue_selector_->SetQueuePriority( 54 renderer_task_queue_selector_->SetQueuePriority(
51 CONTROL_TASK_QUEUE, RendererTaskQueueSelector::CONTROL_PRIORITY); 55 CONTROL_TASK_QUEUE, RendererTaskQueueSelector::CONTROL_PRIORITY);
(...skipping 126 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 ScheduleUrgentPolicyUpdate(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) {
203 base::AutoLock lock(incoming_signals_lock_); 206 base::AutoLock lock(incoming_signals_lock_);
204 if (input_stream_state_ == InputStreamState::INACTIVE) 207 if (input_stream_state_ == InputStreamState::INACTIVE)
205 return; 208 return;
206 // Avoid marking input that arrived after the BeginFrame as processed. 209 // Avoid marking input that arrived after the BeginFrame as processed.
207 if (!begin_frame_time.is_null() && 210 if (!begin_frame_time.is_null() &&
208 begin_frame_time < last_input_receipt_time_on_compositor_) 211 begin_frame_time < last_input_receipt_time_on_compositor_)
209 return; 212 return;
210 last_input_process_time_on_main_ = Now(); 213 last_input_process_time_on_main_ = Now();
211 policy_may_need_update_.SetWhileLocked(true); 214 UpdatePolicyLocked();
Sami 2015/03/11 16:58:25 Could you add a DCHECK that this function is only
alex clarke (OOO till 29th) 2015/03/12 13:41:31 Done.
212 } 215 }
213 216
214 bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() { 217 bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() {
215 DCHECK(main_thread_checker_.CalledOnValidThread()); 218 DCHECK(main_thread_checker_.CalledOnValidThread());
216 if (!task_queue_manager_) 219 if (!task_queue_manager_)
217 return false; 220 return false;
218 221
219 MaybeUpdatePolicy(); 222 MaybeUpdatePolicy();
220 // The touchstart and compositor policies indicate a strong likelihood of 223 // The touchstart and compositor policies indicate a strong likelihood of
221 // high-priority work in the near future. 224 // high-priority work in the near future.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 return current_policy_; 264 return current_policy_;
262 } 265 }
263 266
264 void RendererSchedulerImpl::MaybeUpdatePolicy() { 267 void RendererSchedulerImpl::MaybeUpdatePolicy() {
265 DCHECK(main_thread_checker_.CalledOnValidThread()); 268 DCHECK(main_thread_checker_.CalledOnValidThread());
266 if (policy_may_need_update_.IsSet()) { 269 if (policy_may_need_update_.IsSet()) {
267 UpdatePolicy(); 270 UpdatePolicy();
268 } 271 }
269 } 272 }
270 273
271 void RendererSchedulerImpl::PostUpdatePolicyOnControlRunner( 274 void RendererSchedulerImpl::ScheduleUrgentPolicyUpdate(
rmcilroy 2015/03/11 17:15:07 nit on naming - how about PostUpdatePolicyToMainTh
alex clarke (OOO till 29th) 2015/03/12 13:41:31 I like the OnMainThread, but it doesn't always pos
275 const tracked_objects::Location& from_here) {
276 incoming_signals_lock_.AssertAcquired();
Sami 2015/03/11 16:58:25 Maybe add a DCHECK() that this is never called on
rmcilroy 2015/03/11 17:15:07 It feels like this would make it easy to introduce
alex clarke (OOO till 29th) 2015/03/12 13:41:31 In principle this is a good idea, but it makes tes
alex clarke (OOO till 29th) 2015/03/12 13:41:31 The de-duping for ScheduleDelayedPolicyUpdate is s
277 if (!policy_may_need_update_.IsSet()) {
278 policy_may_need_update_.SetWhileLocked(true);
279 control_task_runner_->PostTask(from_here, update_policy_closure_);
280 }
281 }
282
283 void RendererSchedulerImpl::ScheduleDelayedPolicyUpdate(
284 const tracked_objects::Location& from_here,
272 base::TimeDelta delay) { 285 base::TimeDelta delay) {
273 control_task_runner_->PostDelayedTask( 286 incoming_signals_lock_.AssertAcquired();
Sami 2015/03/11 16:58:25 I think this is probably flexible enough for now,
alex clarke (OOO till 29th) 2015/03/12 13:41:31 I ended up adding a DeadlineTaskRunner that should
274 FROM_HERE, update_policy_closure_, delay); 287 if (!pending_delayed_policy_update_) {
288 pending_delayed_policy_update_ = true;
289 control_task_runner_->PostDelayedTask(
290 from_here, delayed_update_policy_closure_, delay);
291 }
292 }
293
294 void RendererSchedulerImpl::DelayedPolicyUpdateTask() {
295 base::AutoLock lock(incoming_signals_lock_);
296 pending_delayed_policy_update_ = false;
297 UpdatePolicyLocked();
275 } 298 }
276 299
277 void RendererSchedulerImpl::UpdatePolicy() { 300 void RendererSchedulerImpl::UpdatePolicy() {
301 base::AutoLock lock(incoming_signals_lock_);
302 UpdatePolicyLocked();
303 }
304
305 void RendererSchedulerImpl::UpdatePolicyLocked() {
278 DCHECK(main_thread_checker_.CalledOnValidThread()); 306 DCHECK(main_thread_checker_.CalledOnValidThread());
307 incoming_signals_lock_.AssertAcquired();
279 if (!task_queue_manager_) 308 if (!task_queue_manager_)
280 return; 309 return;
281 310
282 base::AutoLock lock(incoming_signals_lock_);
283 base::TimeTicks now; 311 base::TimeTicks now;
284 policy_may_need_update_.SetWhileLocked(false); 312 policy_may_need_update_.SetWhileLocked(false);
285 313
286 base::TimeDelta new_policy_duration; 314 base::TimeDelta new_policy_duration;
287 Policy new_policy = ComputeNewPolicy(&new_policy_duration); 315 Policy new_policy = ComputeNewPolicy(&new_policy_duration);
288 if (new_policy_duration > base::TimeDelta()) 316 if (new_policy_duration > base::TimeDelta())
289 PostUpdatePolicyOnControlRunner(new_policy_duration); 317 ScheduleDelayedPolicyUpdate(FROM_HERE, new_policy_duration);
290 318
291 if (new_policy == current_policy_) 319 if (new_policy == current_policy_)
292 return; 320 return;
293 321
294 switch (new_policy) { 322 switch (new_policy) {
295 case Policy::COMPOSITOR_PRIORITY: 323 case Policy::COMPOSITOR_PRIORITY:
296 renderer_task_queue_selector_->SetQueuePriority( 324 renderer_task_queue_selector_->SetQueuePriority(
297 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY); 325 COMPOSITOR_TASK_QUEUE, RendererTaskQueueSelector::HIGH_PRIORITY);
298 // TODO(scheduler-dev): Add a task priority between HIGH and BEST_EFFORT 326 // TODO(scheduler-dev): Add a task priority between HIGH and BEST_EFFORT
299 // that still has some guarantee of running. 327 // that still has some guarantee of running.
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 } 583 }
556 584
557 void RendererSchedulerImpl::RemoveTaskObserver( 585 void RendererSchedulerImpl::RemoveTaskObserver(
558 base::MessageLoop::TaskObserver* task_observer) { 586 base::MessageLoop::TaskObserver* task_observer) {
559 DCHECK(main_thread_checker_.CalledOnValidThread()); 587 DCHECK(main_thread_checker_.CalledOnValidThread());
560 if (task_queue_manager_) 588 if (task_queue_manager_)
561 task_queue_manager_->RemoveTaskObserver(task_observer); 589 task_queue_manager_->RemoveTaskObserver(task_observer);
562 } 590 }
563 591
564 } // namespace content 592 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698