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

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

Issue 1320633002: Optimize for TouchStart responsiveness (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Introduced a UserModel class 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 #include "components/scheduler/renderer/renderer_scheduler_impl.h" 5 #include "components/scheduler/renderer/renderer_scheduler_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/debug/stack_trace.h" 8 #include "base/debug/stack_trace.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 "components/scheduler/child/scheduler_task_runner_delegate.h" 12 #include "components/scheduler/child/scheduler_task_runner_delegate.h"
13 #include "components/scheduler/child/task_queue_impl.h" 13 #include "components/scheduler/child/task_queue_impl.h"
14 #include "components/scheduler/child/task_queue_selector.h" 14 #include "components/scheduler/child/task_queue_selector.h"
15 15
16 namespace scheduler { 16 namespace scheduler {
17 namespace { 17 namespace {
18 const int kTimerTaskEstimationSampleCount = 4 * 60; 18 const int kLoadingTaskEstimationSampleCount = 200;
19 const double kTimerTaskEstimationPercentile = 80; 19 const double kLoadingTaskEstimationPercentile = 90;
20 const int kTimerTaskEstimationSampleCount = 200;
21 const double kTimerTaskEstimationPercentile = 90;
20 const int kShortIdlePeriodDurationSampleCount = 10; 22 const int kShortIdlePeriodDurationSampleCount = 10;
21 const double kShortIdlePeriodDurationPercentile = 20; 23 const double kShortIdlePeriodDurationPercentile = 20;
22 } 24 }
23 25
24 RendererSchedulerImpl::RendererSchedulerImpl( 26 RendererSchedulerImpl::RendererSchedulerImpl(
25 scoped_refptr<SchedulerTaskRunnerDelegate> main_task_runner) 27 scoped_refptr<SchedulerTaskRunnerDelegate> main_task_runner)
26 : helper_(main_task_runner, 28 : helper_(main_task_runner,
27 "renderer.scheduler", 29 "renderer.scheduler",
28 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 30 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
29 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")), 31 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug")),
(...skipping 17 matching lines...) Expand all
47 base::Bind(&RendererSchedulerImpl::UpdatePolicy, 49 base::Bind(&RendererSchedulerImpl::UpdatePolicy,
48 base::Unretained(this)), 50 base::Unretained(this)),
49 helper_.ControlTaskRunner()), 51 helper_.ControlTaskRunner()),
50 policy_may_need_update_(&any_thread_lock_), 52 policy_may_need_update_(&any_thread_lock_),
51 weak_factory_(this) { 53 weak_factory_(this) {
52 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, 54 update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy,
53 weak_factory_.GetWeakPtr()); 55 weak_factory_.GetWeakPtr());
54 end_renderer_hidden_idle_period_closure_.Reset(base::Bind( 56 end_renderer_hidden_idle_period_closure_.Reset(base::Bind(
55 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr())); 57 &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr()));
56 58
59 loading_task_runner_->AddTaskObserver(
60 &MainThreadOnly().loading_task_cost_estimator);
61
57 timer_task_runner_->AddTaskObserver( 62 timer_task_runner_->AddTaskObserver(
58 &MainThreadOnly().timer_task_cost_estimator_); 63 &MainThreadOnly().timer_task_cost_estimator);
59 64
60 TRACE_EVENT_OBJECT_CREATED_WITH_ID( 65 TRACE_EVENT_OBJECT_CREATED_WITH_ID(
61 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", 66 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
62 this); 67 this);
68
69 // Make sure that we don't initially assume there is no idle time.
70 MainThreadOnly().short_idle_period_duration.InsertSample(
71 cc::BeginFrameArgs::DefaultInterval());
63 } 72 }
64 73
65 RendererSchedulerImpl::~RendererSchedulerImpl() { 74 RendererSchedulerImpl::~RendererSchedulerImpl() {
66 TRACE_EVENT_OBJECT_DELETED_WITH_ID( 75 TRACE_EVENT_OBJECT_DELETED_WITH_ID(
67 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", 76 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
68 this); 77 this);
69 timer_task_runner_->RemoveTaskObserver( 78 timer_task_runner_->RemoveTaskObserver(
70 &MainThreadOnly().timer_task_cost_estimator_); 79 &MainThreadOnly().timer_task_cost_estimator);
71 // Ensure the renderer scheduler was shut down explicitly, because otherwise 80 // Ensure the renderer scheduler was shut down explicitly, because otherwise
72 // we could end up having stale pointers to the Blink heap which has been 81 // we could end up having stale pointers to the Blink heap which has been
73 // terminated by this point. 82 // terminated by this point.
74 DCHECK(MainThreadOnly().was_shutdown_); 83 DCHECK(MainThreadOnly().was_shutdown);
75 } 84 }
76 85
86 RendererSchedulerImpl::Policy::Policy()
87 : compositor_queue_priority(TaskQueue::NORMAL_PRIORITY),
88 loading_queue_priority(TaskQueue::NORMAL_PRIORITY),
89 timer_queue_priority(TaskQueue::NORMAL_PRIORITY) {}
90
77 RendererSchedulerImpl::MainThreadOnly::MainThreadOnly() 91 RendererSchedulerImpl::MainThreadOnly::MainThreadOnly()
78 : timer_task_cost_estimator_(kTimerTaskEstimationSampleCount, 92 : loading_task_cost_estimator(kLoadingTaskEstimationSampleCount,
79 kTimerTaskEstimationPercentile), 93 kLoadingTaskEstimationPercentile),
80 short_idle_period_duration_(kShortIdlePeriodDurationSampleCount), 94 timer_task_cost_estimator(kTimerTaskEstimationSampleCount,
81 current_policy_(Policy::NORMAL), 95 kTimerTaskEstimationPercentile),
82 timer_queue_suspend_count_(0), 96 short_idle_period_duration(kShortIdlePeriodDurationSampleCount),
83 renderer_hidden_(false), 97 current_use_case(UseCase::NONE),
84 was_shutdown_(false) {} 98 timer_queue_suspend_count(0),
99 renderer_hidden(false),
100 was_shutdown(false),
101 loading_tasks_seem_expensive(false),
102 timer_tasks_seem_expensive(false),
103 touchstart_expected_soon(false) {}
85 104
86 RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {} 105 RendererSchedulerImpl::MainThreadOnly::~MainThreadOnly() {}
87 106
88 RendererSchedulerImpl::AnyThread::AnyThread() 107 RendererSchedulerImpl::AnyThread::AnyThread()
89 : pending_main_thread_input_event_count_(0), 108 : awaiting_touch_start_response(false),
90 awaiting_touch_start_response_(false), 109 in_idle_period(false),
91 in_idle_period_(false), 110 begin_main_frame_on_critical_path(false) {}
92 begin_main_frame_on_critical_path_(false),
93 timer_tasks_seem_expensive_(false) {}
94 111
95 RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly() 112 RendererSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly()
96 : last_input_type_(blink::WebInputEvent::Undefined) { 113 : last_input_type(blink::WebInputEvent::Undefined) {}
97 }
98 114
99 RendererSchedulerImpl::CompositorThreadOnly::~CompositorThreadOnly() { 115 RendererSchedulerImpl::CompositorThreadOnly::~CompositorThreadOnly() {
100 } 116 }
101 117
102 void RendererSchedulerImpl::Shutdown() { 118 void RendererSchedulerImpl::Shutdown() {
103 helper_.Shutdown(); 119 helper_.Shutdown();
104 MainThreadOnly().was_shutdown_ = true; 120 MainThreadOnly().was_shutdown = true;
105 } 121 }
106 122
107 scoped_refptr<TaskQueue> RendererSchedulerImpl::DefaultTaskRunner() { 123 scoped_refptr<TaskQueue> RendererSchedulerImpl::DefaultTaskRunner() {
108 return helper_.DefaultTaskRunner(); 124 return helper_.DefaultTaskRunner();
109 } 125 }
110 126
111 scoped_refptr<base::SingleThreadTaskRunner> 127 scoped_refptr<base::SingleThreadTaskRunner>
112 RendererSchedulerImpl::CompositorTaskRunner() { 128 RendererSchedulerImpl::CompositorTaskRunner() {
113 helper_.CheckOnValidThread(); 129 helper_.CheckOnValidThread();
114 return compositor_task_runner_; 130 return compositor_task_runner_;
(...skipping 30 matching lines...) Expand all
145 } 161 }
146 162
147 void RendererSchedulerImpl::WillBeginFrame(const cc::BeginFrameArgs& args) { 163 void RendererSchedulerImpl::WillBeginFrame(const cc::BeginFrameArgs& args) {
148 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 164 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
149 "RendererSchedulerImpl::WillBeginFrame", "args", args.AsValue()); 165 "RendererSchedulerImpl::WillBeginFrame", "args", args.AsValue());
150 helper_.CheckOnValidThread(); 166 helper_.CheckOnValidThread();
151 if (helper_.IsShutdown()) 167 if (helper_.IsShutdown())
152 return; 168 return;
153 169
154 EndIdlePeriod(); 170 EndIdlePeriod();
155 MainThreadOnly().estimated_next_frame_begin_ = 171 MainThreadOnly().estimated_next_frame_begin = args.frame_time + args.interval;
156 args.frame_time + args.interval;
157 { 172 {
158 base::AutoLock lock(any_thread_lock_); 173 base::AutoLock lock(any_thread_lock_);
159 AnyThread().begin_main_frame_on_critical_path_ = args.on_critical_path; 174 AnyThread().begin_main_frame_on_critical_path = args.on_critical_path;
160 } 175 }
161 } 176 }
162 177
163 void RendererSchedulerImpl::DidCommitFrameToCompositor() { 178 void RendererSchedulerImpl::DidCommitFrameToCompositor() {
164 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 179 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
165 "RendererSchedulerImpl::DidCommitFrameToCompositor"); 180 "RendererSchedulerImpl::DidCommitFrameToCompositor");
166 helper_.CheckOnValidThread(); 181 helper_.CheckOnValidThread();
167 if (helper_.IsShutdown()) 182 if (helper_.IsShutdown())
168 return; 183 return;
169 184
170 base::TimeTicks now(helper_.Now()); 185 base::TimeTicks now(helper_.Now());
171 if (now < MainThreadOnly().estimated_next_frame_begin_) { 186 if (now < MainThreadOnly().estimated_next_frame_begin) {
172 // TODO(rmcilroy): Consider reducing the idle period based on the runtime of 187 // TODO(rmcilroy): Consider reducing the idle period based on the runtime of
173 // the next pending delayed tasks (as currently done in for long idle times) 188 // the next pending delayed tasks (as currently done in for long idle times)
174 idle_helper_.StartIdlePeriod( 189 idle_helper_.StartIdlePeriod(
175 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, now, 190 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, now,
176 MainThreadOnly().estimated_next_frame_begin_); 191 MainThreadOnly().estimated_next_frame_begin);
177 MainThreadOnly().short_idle_period_duration_.InsertSample( 192 MainThreadOnly().short_idle_period_duration.InsertSample(
178 MainThreadOnly().estimated_next_frame_begin_ - now); 193 MainThreadOnly().estimated_next_frame_begin - now);
179 MainThreadOnly().expected_short_idle_period_duration_ = 194 } else {
180 MainThreadOnly().short_idle_period_duration_.Percentile( 195 // There was no idle time :(
181 kShortIdlePeriodDurationPercentile); 196 MainThreadOnly().short_idle_period_duration.InsertSample(base::TimeDelta());
182 } 197 }
198
199 MainThreadOnly().expected_short_idle_period_duration =
200 MainThreadOnly().short_idle_period_duration.Percentile(
201 kShortIdlePeriodDurationPercentile);
183 } 202 }
184 203
185 void RendererSchedulerImpl::BeginFrameNotExpectedSoon() { 204 void RendererSchedulerImpl::BeginFrameNotExpectedSoon() {
186 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 205 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
187 "RendererSchedulerImpl::BeginFrameNotExpectedSoon"); 206 "RendererSchedulerImpl::BeginFrameNotExpectedSoon");
188 helper_.CheckOnValidThread(); 207 helper_.CheckOnValidThread();
189 if (helper_.IsShutdown()) 208 if (helper_.IsShutdown())
190 return; 209 return;
191 210
192 idle_helper_.EnableLongIdlePeriod(); 211 idle_helper_.EnableLongIdlePeriod();
193 } 212 }
194 213
195 void RendererSchedulerImpl::OnRendererHidden() { 214 void RendererSchedulerImpl::OnRendererHidden() {
196 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 215 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
197 "RendererSchedulerImpl::OnRendererHidden"); 216 "RendererSchedulerImpl::OnRendererHidden");
198 helper_.CheckOnValidThread(); 217 helper_.CheckOnValidThread();
199 if (helper_.IsShutdown() || MainThreadOnly().renderer_hidden_) 218 if (helper_.IsShutdown() || MainThreadOnly().renderer_hidden)
200 return; 219 return;
201 220
202 idle_helper_.EnableLongIdlePeriod(); 221 idle_helper_.EnableLongIdlePeriod();
203 222
204 // Ensure that we stop running idle tasks after a few seconds of being hidden. 223 // Ensure that we stop running idle tasks after a few seconds of being hidden.
205 end_renderer_hidden_idle_period_closure_.Cancel(); 224 end_renderer_hidden_idle_period_closure_.Cancel();
206 base::TimeDelta end_idle_when_hidden_delay = 225 base::TimeDelta end_idle_when_hidden_delay =
207 base::TimeDelta::FromMilliseconds(kEndIdleWhenHiddenDelayMillis); 226 base::TimeDelta::FromMilliseconds(kEndIdleWhenHiddenDelayMillis);
208 control_task_runner_->PostDelayedTask( 227 control_task_runner_->PostDelayedTask(
209 FROM_HERE, end_renderer_hidden_idle_period_closure_.callback(), 228 FROM_HERE, end_renderer_hidden_idle_period_closure_.callback(),
210 end_idle_when_hidden_delay); 229 end_idle_when_hidden_delay);
211 MainThreadOnly().renderer_hidden_ = true; 230 MainThreadOnly().renderer_hidden = true;
212 231
213 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( 232 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
214 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", 233 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
215 this, AsValue(helper_.Now())); 234 this, AsValue(helper_.Now()));
216 } 235 }
217 236
218 void RendererSchedulerImpl::OnRendererVisible() { 237 void RendererSchedulerImpl::OnRendererVisible() {
219 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 238 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
220 "RendererSchedulerImpl::OnRendererVisible"); 239 "RendererSchedulerImpl::OnRendererVisible");
221 helper_.CheckOnValidThread(); 240 helper_.CheckOnValidThread();
222 if (helper_.IsShutdown() || !MainThreadOnly().renderer_hidden_) 241 if (helper_.IsShutdown() || !MainThreadOnly().renderer_hidden)
223 return; 242 return;
224 243
225 end_renderer_hidden_idle_period_closure_.Cancel(); 244 end_renderer_hidden_idle_period_closure_.Cancel();
226 MainThreadOnly().renderer_hidden_ = false; 245 MainThreadOnly().renderer_hidden = false;
227 EndIdlePeriod(); 246 EndIdlePeriod();
228 247
229 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( 248 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
230 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", 249 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
231 this, AsValue(helper_.Now())); 250 this, AsValue(helper_.Now()));
232 } 251 }
233 252
234 void RendererSchedulerImpl::EndIdlePeriod() { 253 void RendererSchedulerImpl::EndIdlePeriod() {
235 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 254 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
236 "RendererSchedulerImpl::EndIdlePeriod"); 255 "RendererSchedulerImpl::EndIdlePeriod");
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 UpdateForInputEventOnCompositorThread( 295 UpdateForInputEventOnCompositorThread(
277 blink::WebInputEvent::Undefined, 296 blink::WebInputEvent::Undefined,
278 InputEventState::EVENT_CONSUMED_BY_COMPOSITOR); 297 InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
279 } 298 }
280 299
281 void RendererSchedulerImpl::UpdateForInputEventOnCompositorThread( 300 void RendererSchedulerImpl::UpdateForInputEventOnCompositorThread(
282 blink::WebInputEvent::Type type, 301 blink::WebInputEvent::Type type,
283 InputEventState input_event_state) { 302 InputEventState input_event_state) {
284 base::AutoLock lock(any_thread_lock_); 303 base::AutoLock lock(any_thread_lock_);
285 base::TimeTicks now = helper_.Now(); 304 base::TimeTicks now = helper_.Now();
286 bool was_in_compositor_priority = InputSignalsSuggestCompositorPriority(now); 305
306 // TODO(alexclarke): Move WebInputEventTraits where we can access it from here
307 // and record the name rather than the integer representation.
308 TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
309 "RendererSchedulerImpl::UpdateForInputEventOnCompositorThread",
310 "type", static_cast<int>(type), "input_event_state",
311 InputEventStateToString(input_event_state));
312
313 bool gesture_already_in_progress = InputSignalsSuggestGestureInProgress(now);
287 bool was_awaiting_touch_start_response = 314 bool was_awaiting_touch_start_response =
288 AnyThread().awaiting_touch_start_response_; 315 AnyThread().awaiting_touch_start_response;
316
317 AnyThread().user_model.DidHandleInputEventOnCompositorThread(
318 type, input_event_state, now);
289 319
290 if (type) { 320 if (type) {
291 switch (type) { 321 switch (type) {
292 case blink::WebInputEvent::TouchStart: 322 case blink::WebInputEvent::TouchStart:
293 AnyThread().awaiting_touch_start_response_ = true; 323 AnyThread().awaiting_touch_start_response = true;
294 break; 324 break;
295 325
296 case blink::WebInputEvent::TouchMove: 326 case blink::WebInputEvent::TouchMove:
297 // Observation of consecutive touchmoves is a strong signal that the 327 // Observation of consecutive touchmoves is a strong signal that the
298 // page is consuming the touch sequence, in which case touchstart 328 // page is consuming the touch sequence, in which case touchstart
299 // response prioritization is no longer necessary. Otherwise, the 329 // response prioritization is no longer necessary. Otherwise, the
300 // initial touchmove should preserve the touchstart response pending 330 // initial touchmove should preserve the touchstart response pending
301 // state. 331 // state.
302 if (AnyThread().awaiting_touch_start_response_ && 332 if (AnyThread().awaiting_touch_start_response &&
303 CompositorThreadOnly().last_input_type_ == 333 CompositorThreadOnly().last_input_type ==
304 blink::WebInputEvent::TouchMove) { 334 blink::WebInputEvent::TouchMove) {
305 AnyThread().awaiting_touch_start_response_ = false; 335 AnyThread().awaiting_touch_start_response = false;
306 } 336 }
307 break; 337 break;
308 338
309 case blink::WebInputEvent::Undefined: 339 case blink::WebInputEvent::Undefined:
310 case blink::WebInputEvent::GestureTapDown: 340 case blink::WebInputEvent::GestureTapDown:
311 case blink::WebInputEvent::GestureShowPress: 341 case blink::WebInputEvent::GestureShowPress:
312 case blink::WebInputEvent::GestureFlingCancel: 342 case blink::WebInputEvent::GestureFlingCancel:
313 case blink::WebInputEvent::GestureScrollEnd: 343 case blink::WebInputEvent::GestureScrollEnd:
314 // With no observable effect, these meta events do not indicate a 344 // With no observable effect, these meta events do not indicate a
315 // meaningful touchstart response and should not impact task priority. 345 // meaningful touchstart response and should not impact task priority.
316 break; 346 break;
317 347
318 default: 348 default:
319 AnyThread().awaiting_touch_start_response_ = false; 349 AnyThread().awaiting_touch_start_response = false;
320 break; 350 break;
321 } 351 }
322 } 352 }
323 353
324 // Avoid unnecessary policy updates, while in compositor priority. 354 // Avoid unnecessary policy updates, while a gesture is already in progress.
325 if (!was_in_compositor_priority || 355 if (!gesture_already_in_progress ||
326 was_awaiting_touch_start_response != 356 was_awaiting_touch_start_response !=
327 AnyThread().awaiting_touch_start_response_) { 357 AnyThread().awaiting_touch_start_response) {
328 EnsureUrgentPolicyUpdatePostedOnMainThread(FROM_HERE); 358 EnsureUrgentPolicyUpdatePostedOnMainThread(FROM_HERE);
329 } 359 }
330 AnyThread().last_input_signal_time_ = now; 360 CompositorThreadOnly().last_input_type = type;
331 CompositorThreadOnly().last_input_type_ = type;
332
333 if (input_event_state == InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD)
334 AnyThread().pending_main_thread_input_event_count_++;
335 } 361 }
336 362
337 void RendererSchedulerImpl::DidHandleInputEventOnMainThread( 363 void RendererSchedulerImpl::DidHandleInputEventOnMainThread(
338 const blink::WebInputEvent& web_input_event) { 364 const blink::WebInputEvent& web_input_event) {
339 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 365 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
340 "RendererSchedulerImpl::DidHandleInputEventOnMainThread"); 366 "RendererSchedulerImpl::DidHandleInputEventOnMainThread");
341 helper_.CheckOnValidThread(); 367 helper_.CheckOnValidThread();
342 if (ShouldPrioritizeInputEvent(web_input_event)) { 368 if (ShouldPrioritizeInputEvent(web_input_event)) {
343 base::AutoLock lock(any_thread_lock_); 369 base::AutoLock lock(any_thread_lock_);
344 AnyThread().last_input_signal_time_ = helper_.Now(); 370 AnyThread().user_model.DidHandleInputEventOnMainThread(helper_.Now());
345 if (AnyThread().pending_main_thread_input_event_count_ > 0)
346 AnyThread().pending_main_thread_input_event_count_--;
347 } 371 }
348 } 372 }
349 373
350 bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() { 374 bool RendererSchedulerImpl::IsHighPriorityWorkAnticipated() {
351 helper_.CheckOnValidThread(); 375 helper_.CheckOnValidThread();
352 if (helper_.IsShutdown()) 376 if (helper_.IsShutdown())
353 return false; 377 return false;
354 378
355 MaybeUpdatePolicy(); 379 MaybeUpdatePolicy();
356 // The touchstart and compositor policies indicate a strong likelihood of 380 // The touchstart and main-thread scrolling states indicate a strong
357 // high-priority work in the near future. 381 // likelihood of high-priority work in the near future.
358 return MainThreadOnly().current_policy_ == Policy::COMPOSITOR_PRIORITY || 382 UseCase use_case = MainThreadOnly().current_use_case;
359 MainThreadOnly().current_policy_ == 383 return MainThreadOnly().touchstart_expected_soon ||
360 Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY || 384 use_case == UseCase::TOUCHSTART ||
361 MainThreadOnly().current_policy_ == Policy::TOUCHSTART_PRIORITY; 385 use_case == UseCase::MAIN_THREAD_GESTURE;
362 } 386 }
363 387
364 bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() { 388 bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() {
365 helper_.CheckOnValidThread(); 389 helper_.CheckOnValidThread();
366 if (helper_.IsShutdown()) 390 if (helper_.IsShutdown())
367 return false; 391 return false;
368 392
369 MaybeUpdatePolicy(); 393 MaybeUpdatePolicy();
370 // We only yield if we are in the compositor priority and there is compositor 394 // We only yield if there's a urgent task to be run now, or we are expecting
371 // work outstanding, or if we are in the touchstart response priority. 395 // one soon (touch start).
372 // Note: even though the control queue is higher priority we don't yield for 396 // Note: even though the control queue has the highest priority we don't yield
373 // it since these tasks are not user-provided work and they are only intended 397 // for it since these tasks are not user-provided work and they are only
374 // to run before the next task, not interrupt the tasks. 398 // intended to run before the next task, not interrupt the tasks.
375 switch (MainThreadOnly().current_policy_) { 399 switch (MainThreadOnly().current_use_case) {
376 case Policy::NORMAL: 400 case UseCase::NONE:
377 return false; 401 return MainThreadOnly().touchstart_expected_soon;
378 402
379 case Policy::COMPOSITOR_PRIORITY: 403 case UseCase::COMPOSITOR_GESTURE:
380 return !compositor_task_runner_->IsQueueEmpty(); 404 return MainThreadOnly().touchstart_expected_soon;
381 405
382 case Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY: 406 case UseCase::MAIN_THREAD_GESTURE:
383 return !compositor_task_runner_->IsQueueEmpty(); 407 return !compositor_task_runner_->IsQueueEmpty() ||
408 MainThreadOnly().touchstart_expected_soon;
384 409
385 case Policy::TOUCHSTART_PRIORITY: 410 case UseCase::TOUCHSTART:
386 return true; 411 return true;
387 412
388 case Policy::LOADING_PRIORITY: 413 case UseCase::LOADING:
389 return false; 414 return false;
390 415
391 default: 416 default:
392 NOTREACHED(); 417 NOTREACHED();
393 return false; 418 return false;
394 } 419 }
395 } 420 }
396 421
397 base::TimeTicks RendererSchedulerImpl::CurrentIdleTaskDeadlineForTesting() 422 base::TimeTicks RendererSchedulerImpl::CurrentIdleTaskDeadlineForTesting()
398 const { 423 const {
(...skipping 30 matching lines...) Expand all
429 454
430 void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) { 455 void RendererSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) {
431 helper_.CheckOnValidThread(); 456 helper_.CheckOnValidThread();
432 any_thread_lock_.AssertAcquired(); 457 any_thread_lock_.AssertAcquired();
433 if (helper_.IsShutdown()) 458 if (helper_.IsShutdown())
434 return; 459 return;
435 460
436 base::TimeTicks now = helper_.Now(); 461 base::TimeTicks now = helper_.Now();
437 policy_may_need_update_.SetWhileLocked(false); 462 policy_may_need_update_.SetWhileLocked(false);
438 463
439 AnyThread().timer_tasks_seem_expensive_ = 464 base::TimeDelta expected_use_case_duration;
440 MainThreadOnly().expected_short_idle_period_duration_ > 465 UseCase use_case = ComputeCurrentUseCase(now, &expected_use_case_duration);
441 base::TimeDelta() && 466 MainThreadOnly().current_use_case = use_case;
442 MainThreadOnly().timer_task_cost_estimator_.expected_task_duration() >
443 MainThreadOnly().expected_short_idle_period_duration_;
444 467
445 base::TimeDelta new_policy_duration; 468 // TODO(alexclarke): We should wire up a signal from blink to let us know if
446 Policy new_policy = ComputeNewPolicy(now, &new_policy_duration); 469 // there are any touch handlers registerd or not, and only call
470 // TouchStartExpectedSoon if there is at least one.
471 base::TimeDelta scroll_expected_flag_valid_for_duration;
472 bool touchstart_expected_soon = AnyThread().user_model.TouchStartExpectedSoon(
473 use_case, now, &scroll_expected_flag_valid_for_duration);
474 MainThreadOnly().touchstart_expected_soon = touchstart_expected_soon;
475
476 bool loading_tasks_seem_expensive =
477 MainThreadOnly().loading_task_cost_estimator.expected_task_duration() >
478 MainThreadOnly().expected_short_idle_period_duration;
479 MainThreadOnly().loading_tasks_seem_expensive = loading_tasks_seem_expensive;
480
481 bool timer_tasks_seem_expensive =
482 MainThreadOnly().timer_task_cost_estimator.expected_task_duration() >
483 MainThreadOnly().expected_short_idle_period_duration;
484 MainThreadOnly().timer_tasks_seem_expensive = timer_tasks_seem_expensive;
485
486 // The |new_policy_duration| is the minimum of |expected_use_case_duration|
487 // and |scroll_expected_flag_valid_for_duration| unless one is zero in which
488 // case we choose the other.
489 base::TimeDelta new_policy_duration = expected_use_case_duration;
490 if (new_policy_duration == base::TimeDelta() ||
491 (scroll_expected_flag_valid_for_duration > base::TimeDelta() &&
492 new_policy_duration > scroll_expected_flag_valid_for_duration)) {
493 new_policy_duration = scroll_expected_flag_valid_for_duration;
494 }
495
447 if (new_policy_duration > base::TimeDelta()) { 496 if (new_policy_duration > base::TimeDelta()) {
448 MainThreadOnly().current_policy_expiration_time_ = 497 MainThreadOnly().current_policy_expiration_time = now + new_policy_duration;
449 now + new_policy_duration;
450 delayed_update_policy_runner_.SetDeadline(FROM_HERE, new_policy_duration, 498 delayed_update_policy_runner_.SetDeadline(FROM_HERE, new_policy_duration,
451 now); 499 now);
452 } else { 500 } else {
453 MainThreadOnly().current_policy_expiration_time_ = base::TimeTicks(); 501 MainThreadOnly().current_policy_expiration_time = base::TimeTicks();
454 } 502 }
455 503
456 if (update_type == UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED && 504 Policy new_policy;
457 new_policy == MainThreadOnly().current_policy_) 505 bool block_expensive_tasks = false;
458 return; 506 switch (use_case) {
507 case UseCase::COMPOSITOR_GESTURE:
508 if (touchstart_expected_soon)
509 block_expensive_tasks = true;
510 else
511 new_policy.loading_queue_priority = TaskQueue::HIGH_PRIORITY;
512 break;
459 513
460 TaskQueue::QueuePriority compositor_queue_priority = 514 case UseCase::MAIN_THREAD_GESTURE:
461 TaskQueue::NORMAL_PRIORITY; 515 new_policy.compositor_queue_priority = TaskQueue::HIGH_PRIORITY;
462 TaskQueue::QueuePriority loading_queue_priority = TaskQueue::NORMAL_PRIORITY; 516 block_expensive_tasks = true;
463 TaskQueue::QueuePriority timer_queue_priority = 517 break;
464 MainThreadOnly().timer_queue_suspend_count_ != 0
465 ? TaskQueue::DISABLED_PRIORITY
466 : TaskQueue::NORMAL_PRIORITY;
467 518
468 switch (new_policy) { 519 case UseCase::TOUCHSTART:
469 case Policy::COMPOSITOR_PRIORITY: 520 new_policy.compositor_queue_priority = TaskQueue::HIGH_PRIORITY;
470 compositor_queue_priority = TaskQueue::HIGH_PRIORITY; 521 new_policy.loading_queue_priority = TaskQueue::DISABLED_PRIORITY;
522 new_policy.timer_queue_priority = TaskQueue::DISABLED_PRIORITY;
471 break; 523 break;
472 case Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY: 524
473 compositor_queue_priority = TaskQueue::HIGH_PRIORITY; 525 case UseCase::NONE:
474 loading_queue_priority = TaskQueue::DISABLED_PRIORITY; 526 if (touchstart_expected_soon)
475 timer_queue_priority = TaskQueue::DISABLED_PRIORITY; 527 block_expensive_tasks = true;
528 else
529 new_policy.loading_queue_priority = TaskQueue::HIGH_PRIORITY;
476 break; 530 break;
477 case Policy::TOUCHSTART_PRIORITY: 531
478 compositor_queue_priority = TaskQueue::HIGH_PRIORITY; 532 case UseCase::LOADING:
479 loading_queue_priority = TaskQueue::DISABLED_PRIORITY; 533 new_policy.loading_queue_priority = TaskQueue::HIGH_PRIORITY;
480 timer_queue_priority = TaskQueue::DISABLED_PRIORITY;
481 break;
482 case Policy::NORMAL:
483 break;
484 case Policy::LOADING_PRIORITY:
485 // We prioritize loading tasks by deprioritizing compositing and timers.
486 compositor_queue_priority = TaskQueue::BEST_EFFORT_PRIORITY;
487 timer_queue_priority = TaskQueue::BEST_EFFORT_PRIORITY;
488 // TODO(alexclarke): See if we can safely mark the loading task queue as
489 // high priority.
490 break; 534 break;
491 default: 535 default:
492 NOTREACHED(); 536 NOTREACHED();
493 } 537 }
494 538
495 compositor_task_runner_->SetQueuePriority(compositor_queue_priority); 539 if (block_expensive_tasks && loading_tasks_seem_expensive)
496 loading_task_runner_->SetQueuePriority(loading_queue_priority); 540 new_policy.loading_queue_priority = TaskQueue::DISABLED_PRIORITY;
497 timer_task_runner_->SetQueuePriority(timer_queue_priority);
498 541
499 DCHECK(compositor_task_runner_->IsQueueEnabled()); 542 if ((block_expensive_tasks && timer_tasks_seem_expensive) ||
500 if (new_policy != Policy::TOUCHSTART_PRIORITY && 543 MainThreadOnly().timer_queue_suspend_count != 0)
501 new_policy != Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY) { 544 new_policy.timer_queue_priority = TaskQueue::DISABLED_PRIORITY;
502 DCHECK(loading_task_runner_->IsQueueEnabled());
503 }
504 MainThreadOnly().current_policy_ = new_policy;
505 545
546 // Tracing is done before the early out check, because it's quite possible we
Sami 2015/08/27 15:15:59 Should we only do this if the use case or the poli
alex clarke (OOO till 29th) 2015/09/03 10:34:25 I actually think it was way too hard to figure out
547 // will otherwise miss this information in traces.
506 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( 548 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
507 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler", 549 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "RendererScheduler",
508 this, AsValueLocked(now)); 550 this, AsValueLocked(now));
551 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "use_case",
552 use_case);
509 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 553 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
510 "RendererScheduler.policy", MainThreadOnly().current_policy_); 554 "RendererScheduler.loading_tasks_seem_expensive",
555 MainThreadOnly().loading_tasks_seem_expensive);
511 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), 556 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
512 "RendererScheduler.timer_tasks_seem_expensive", 557 "RendererScheduler.timer_tasks_seem_expensive",
513 AnyThread().timer_tasks_seem_expensive_); 558 MainThreadOnly().timer_tasks_seem_expensive);
559
560 if (update_type == UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED &&
561 new_policy == MainThreadOnly().current_policy) {
562 return;
563 }
564
565 compositor_task_runner_->SetQueuePriority(
566 new_policy.compositor_queue_priority);
567 loading_task_runner_->SetQueuePriority(new_policy.loading_queue_priority);
568 timer_task_runner_->SetQueuePriority(new_policy.timer_queue_priority);
569
570 DCHECK(compositor_task_runner_->IsQueueEnabled());
571 MainThreadOnly().current_policy = new_policy;
514 } 572 }
515 573
516 bool RendererSchedulerImpl::InputSignalsSuggestCompositorPriority( 574 bool RendererSchedulerImpl::InputSignalsSuggestGestureInProgress(
517 base::TimeTicks now) const { 575 base::TimeTicks now) const {
518 base::TimeDelta unused_policy_duration; 576 base::TimeDelta unused_policy_duration;
519 switch (ComputeNewPolicy(now, &unused_policy_duration)) { 577 switch (ComputeCurrentUseCase(now, &unused_policy_duration)) {
520 case Policy::TOUCHSTART_PRIORITY: 578 case UseCase::COMPOSITOR_GESTURE:
521 case Policy::COMPOSITOR_PRIORITY: 579 case UseCase::MAIN_THREAD_GESTURE:
522 case Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY: 580 case UseCase::TOUCHSTART:
523 return true; 581 return true;
524 582
525 default: 583 default:
526 break; 584 break;
527 } 585 }
528 return false; 586 return false;
529 } 587 }
530 588
531 RendererSchedulerImpl::Policy RendererSchedulerImpl::ComputeNewPolicy( 589 RendererSchedulerImpl::UseCase RendererSchedulerImpl::ComputeCurrentUseCase(
532 base::TimeTicks now, 590 base::TimeTicks now,
533 base::TimeDelta* new_policy_duration) const { 591 base::TimeDelta* expected_use_case_duration) const {
534 any_thread_lock_.AssertAcquired(); 592 any_thread_lock_.AssertAcquired();
535 // Above all else we want to be responsive to user input. 593 // Above all else we want to be responsive to user input.
536 *new_policy_duration = TimeLeftInInputEscalatedPolicy(now); 594 *expected_use_case_duration =
537 if (*new_policy_duration > base::TimeDelta()) { 595 AnyThread().user_model.TimeLeftInInputEscalatedPolicy(now);
538 if (AnyThread().awaiting_touch_start_response_) 596 if (*expected_use_case_duration > base::TimeDelta()) {
539 return Policy::TOUCHSTART_PRIORITY; 597 // Has scrolling been fully established?
540 // If BeginMainFrame is on the critical path, we want to try and prevent 598 if (AnyThread().awaiting_touch_start_response) {
541 // timers and loading tasks from running if we think they might be 599 // No, so arrange for compositor tasks to be run at the highest priority.
542 // expensive. 600 return UseCase::TOUCHSTART;
601 }
602 // Yes scrolling has been established. If BeginMainFrame is on the critical
603 // path, compositor tasks need to be prioritized, otherwise now might be a
604 // good time to run potentially expensive work.
543 // TODO(skyostil): Consider removing in_idle_period_ and 605 // TODO(skyostil): Consider removing in_idle_period_ and
544 // HadAnIdlePeriodRecently() unless we need them here. 606 // HadAnIdlePeriodRecently() unless we need them here.
545 if (AnyThread().timer_tasks_seem_expensive_ && 607 if (AnyThread().begin_main_frame_on_critical_path) {
546 AnyThread().begin_main_frame_on_critical_path_) { 608 return UseCase::MAIN_THREAD_GESTURE;
547 return Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY; 609 } else {
610 return UseCase::COMPOSITOR_GESTURE;
548 } 611 }
549 return Policy::COMPOSITOR_PRIORITY;
550 } 612 }
551 613
552 if (AnyThread().rails_loading_priority_deadline_ > now) { 614 if (AnyThread().rails_loading_priority_deadline > now) {
553 *new_policy_duration = AnyThread().rails_loading_priority_deadline_ - now; 615 *expected_use_case_duration =
554 return Policy::LOADING_PRIORITY; 616 AnyThread().rails_loading_priority_deadline - now;
617 return UseCase::LOADING;
555 } 618 }
556 619
557 return Policy::NORMAL; 620 return UseCase::NONE;
558 }
559
560 base::TimeDelta RendererSchedulerImpl::TimeLeftInInputEscalatedPolicy(
561 base::TimeTicks now) const {
562 any_thread_lock_.AssertAcquired();
563
564 base::TimeDelta escalated_priority_duration =
565 base::TimeDelta::FromMilliseconds(kPriorityEscalationAfterInputMillis);
566
567 // If the input event is still pending, go into input prioritized policy
568 // and check again later.
569 if (AnyThread().pending_main_thread_input_event_count_ > 0)
570 return escalated_priority_duration;
571 if (AnyThread().last_input_signal_time_.is_null() ||
572 AnyThread().last_input_signal_time_ + escalated_priority_duration < now) {
573 return base::TimeDelta();
574 }
575 return AnyThread().last_input_signal_time_ + escalated_priority_duration -
576 now;
577 } 621 }
578 622
579 bool RendererSchedulerImpl::CanEnterLongIdlePeriod( 623 bool RendererSchedulerImpl::CanEnterLongIdlePeriod(
580 base::TimeTicks now, 624 base::TimeTicks now,
581 base::TimeDelta* next_long_idle_period_delay_out) { 625 base::TimeDelta* next_long_idle_period_delay_out) {
582 helper_.CheckOnValidThread(); 626 helper_.CheckOnValidThread();
583 627
584 MaybeUpdatePolicy(); 628 MaybeUpdatePolicy();
585 if (MainThreadOnly().current_policy_ == Policy::TOUCHSTART_PRIORITY) { 629 if (MainThreadOnly().current_use_case == UseCase::TOUCHSTART) {
586 // Don't start a long idle task in touch start priority, try again when 630 // Don't start a long idle task in touch start priority, try again when
587 // the policy is scheduled to end. 631 // the policy is scheduled to end.
588 *next_long_idle_period_delay_out = 632 *next_long_idle_period_delay_out =
589 MainThreadOnly().current_policy_expiration_time_ - now; 633 MainThreadOnly().current_policy_expiration_time - now;
590 return false; 634 return false;
591 } 635 }
592 return true; 636 return true;
593 } 637 }
594 638
595 SchedulerHelper* RendererSchedulerImpl::GetSchedulerHelperForTesting() { 639 SchedulerHelper* RendererSchedulerImpl::GetSchedulerHelperForTesting() {
596 return &helper_; 640 return &helper_;
597 } 641 }
598 642
599 void RendererSchedulerImpl::SuspendTimerQueue() { 643 void RendererSchedulerImpl::SuspendTimerQueue() {
600 MainThreadOnly().timer_queue_suspend_count_++; 644 MainThreadOnly().timer_queue_suspend_count++;
601 ForceUpdatePolicy(); 645 ForceUpdatePolicy();
602 DCHECK(!timer_task_runner_->IsQueueEnabled()); 646 DCHECK(!timer_task_runner_->IsQueueEnabled());
603 } 647 }
604 648
605 void RendererSchedulerImpl::ResumeTimerQueue() { 649 void RendererSchedulerImpl::ResumeTimerQueue() {
606 MainThreadOnly().timer_queue_suspend_count_--; 650 MainThreadOnly().timer_queue_suspend_count--;
607 DCHECK_GE(MainThreadOnly().timer_queue_suspend_count_, 0); 651 DCHECK_GE(MainThreadOnly().timer_queue_suspend_count, 0);
608 ForceUpdatePolicy(); 652 ForceUpdatePolicy();
609 } 653 }
610 654
611 // static
612 const char* RendererSchedulerImpl::PolicyToString(Policy policy) {
613 switch (policy) {
614 case Policy::NORMAL:
615 return "normal";
616 case Policy::COMPOSITOR_PRIORITY:
617 return "compositor";
618 case Policy::COMPOSITOR_CRITICAL_PATH_PRIORITY:
619 return "compositor_critical_path";
620 case Policy::TOUCHSTART_PRIORITY:
621 return "touchstart";
622 case Policy::LOADING_PRIORITY:
623 return "loading";
624 default:
625 NOTREACHED();
626 return nullptr;
627 }
628 }
629
630 scoped_refptr<base::trace_event::ConvertableToTraceFormat> 655 scoped_refptr<base::trace_event::ConvertableToTraceFormat>
631 RendererSchedulerImpl::AsValue(base::TimeTicks optional_now) const { 656 RendererSchedulerImpl::AsValue(base::TimeTicks optional_now) const {
632 base::AutoLock lock(any_thread_lock_); 657 base::AutoLock lock(any_thread_lock_);
633 return AsValueLocked(optional_now); 658 return AsValueLocked(optional_now);
634 } 659 }
635 660
636 scoped_refptr<base::trace_event::ConvertableToTraceFormat> 661 scoped_refptr<base::trace_event::ConvertableToTraceFormat>
637 RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const { 662 RendererSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const {
638 helper_.CheckOnValidThread(); 663 helper_.CheckOnValidThread();
639 any_thread_lock_.AssertAcquired(); 664 any_thread_lock_.AssertAcquired();
640 665
641 if (optional_now.is_null()) 666 if (optional_now.is_null())
642 optional_now = helper_.Now(); 667 optional_now = helper_.Now();
643 scoped_refptr<base::trace_event::TracedValue> state = 668 scoped_refptr<base::trace_event::TracedValue> state =
644 new base::trace_event::TracedValue(); 669 new base::trace_event::TracedValue();
645 670
646 state->SetString("current_policy", 671 state->SetString("current_use_case",
647 PolicyToString(MainThreadOnly().current_policy_)); 672 UseCaseToString(MainThreadOnly().current_use_case));
673 state->SetBoolean("loading_tasks_seem_expensive",
674 MainThreadOnly().loading_tasks_seem_expensive);
675 state->SetBoolean("timer_tasks_seem_expensive",
676 MainThreadOnly().timer_tasks_seem_expensive);
677 state->SetBoolean("touchstart_expected_soon",
678 MainThreadOnly().touchstart_expected_soon);
648 state->SetString("idle_period_state", 679 state->SetString("idle_period_state",
649 IdleHelper::IdlePeriodStateToString( 680 IdleHelper::IdlePeriodStateToString(
650 idle_helper_.SchedulerIdlePeriodState())); 681 idle_helper_.SchedulerIdlePeriodState()));
651 state->SetBoolean("renderer_hidden", MainThreadOnly().renderer_hidden_); 682 state->SetBoolean("renderer_hidden", MainThreadOnly().renderer_hidden);
652 state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF()); 683 state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF());
653 state->SetDouble("last_input_signal_time", 684 state->SetDouble(
654 (AnyThread().last_input_signal_time_ - base::TimeTicks()) 685 "rails_loading_priority_deadline",
686 (AnyThread().rails_loading_priority_deadline - base::TimeTicks())
687 .InMillisecondsF());
688 state->SetDouble("last_idle_period_end_time",
689 (AnyThread().last_idle_period_end_time - base::TimeTicks())
655 .InMillisecondsF()); 690 .InMillisecondsF());
656 state->SetDouble("rails_loading_priority_deadline", 691 state->SetBoolean("awaiting_touch_start_response",
657 (AnyThread().rails_loading_priority_deadline_ - 692 AnyThread().awaiting_touch_start_response);
658 base::TimeTicks()).InMillisecondsF()); 693 state->SetBoolean("begin_main_frame_on_critical_path",
659 state->SetDouble("last_idle_period_end_time", 694 AnyThread().begin_main_frame_on_critical_path);
660 (AnyThread().last_idle_period_end_time_ - base::TimeTicks()) 695 state->SetDouble("expected_loading_task_duration",
696 MainThreadOnly()
697 .loading_task_cost_estimator.expected_task_duration()
661 .InMillisecondsF()); 698 .InMillisecondsF());
662 state->SetInteger("pending_main_thread_input_event_count",
663 AnyThread().pending_main_thread_input_event_count_);
664 state->SetBoolean("awaiting_touch_start_response",
665 AnyThread().awaiting_touch_start_response_);
666 state->SetBoolean("begin_main_frame_on_critical_path",
667 AnyThread().begin_main_frame_on_critical_path_);
668 state->SetDouble("expected_timer_task_duration", 699 state->SetDouble("expected_timer_task_duration",
669 MainThreadOnly() 700 MainThreadOnly()
670 .timer_task_cost_estimator_.expected_task_duration() 701 .timer_task_cost_estimator.expected_task_duration()
671 .InMillisecondsF()); 702 .InMillisecondsF());
672 // TODO(skyostil): Can we somehow trace how accurate these estimates were? 703 // TODO(skyostil): Can we somehow trace how accurate these estimates were?
673 state->SetDouble( 704 state->SetDouble(
674 "expected_short_idle_period_duration", 705 "expected_short_idle_period_duration",
675 MainThreadOnly().expected_short_idle_period_duration_.InMillisecondsF()); 706 MainThreadOnly().expected_short_idle_period_duration.InMillisecondsF());
676 state->SetBoolean("timer_tasks_seem_expensive", 707 state->SetDouble(
677 AnyThread().timer_tasks_seem_expensive_); 708 "estimated_next_frame_begin",
678 state->SetDouble("estimated_next_frame_begin", 709 (MainThreadOnly().estimated_next_frame_begin - base::TimeTicks())
679 (MainThreadOnly().estimated_next_frame_begin_ - 710 .InMillisecondsF());
680 base::TimeTicks()).InMillisecondsF()); 711 state->SetBoolean("in_idle_period", AnyThread().in_idle_period);
681 state->SetBoolean("in_idle_period", AnyThread().in_idle_period_); 712 AnyThread().user_model.AsValueInto(state.get());
682 713
683 return state; 714 return state;
684 } 715 }
685 716
686 void RendererSchedulerImpl::OnIdlePeriodStarted() { 717 void RendererSchedulerImpl::OnIdlePeriodStarted() {
687 base::AutoLock lock(any_thread_lock_); 718 base::AutoLock lock(any_thread_lock_);
688 AnyThread().in_idle_period_ = true; 719 AnyThread().in_idle_period = true;
689 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); 720 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED);
690 } 721 }
691 722
692 void RendererSchedulerImpl::OnIdlePeriodEnded() { 723 void RendererSchedulerImpl::OnIdlePeriodEnded() {
693 base::AutoLock lock(any_thread_lock_); 724 base::AutoLock lock(any_thread_lock_);
694 AnyThread().last_idle_period_end_time_ = helper_.Now(); 725 AnyThread().last_idle_period_end_time = helper_.Now();
695 AnyThread().in_idle_period_ = false; 726 AnyThread().in_idle_period = false;
696 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); 727 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED);
697 } 728 }
698 729
699 void RendererSchedulerImpl::OnPageLoadStarted() { 730 void RendererSchedulerImpl::OnPageLoadStarted() {
700 base::AutoLock lock(any_thread_lock_); 731 base::AutoLock lock(any_thread_lock_);
701 AnyThread().rails_loading_priority_deadline_ = 732 AnyThread().rails_loading_priority_deadline =
702 helper_.Now() + base::TimeDelta::FromMilliseconds( 733 helper_.Now() + base::TimeDelta::FromMilliseconds(
703 kRailsInitialLoadingPrioritizationMillis); 734 kRailsInitialLoadingPrioritizationMillis);
704 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED); 735 UpdatePolicyLocked(UpdateType::MAY_EARLY_OUT_IF_POLICY_UNCHANGED);
705 } 736 }
706 737
707 bool RendererSchedulerImpl::HadAnIdlePeriodRecently(base::TimeTicks now) const { 738 bool RendererSchedulerImpl::HadAnIdlePeriodRecently(base::TimeTicks now) const {
708 return (now - AnyThread().last_idle_period_end_time_) <= 739 return (now - AnyThread().last_idle_period_end_time) <=
709 base::TimeDelta::FromMilliseconds( 740 base::TimeDelta::FromMilliseconds(
710 kIdlePeriodStarvationThresholdMillis); 741 kIdlePeriodStarvationThresholdMillis);
711 } 742 }
712 743
713 } // namespace scheduler 744 } // namespace scheduler
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698