OLD | NEW |
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 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 "cc/scheduler/scheduler.h" | 5 #include "cc/scheduler/scheduler.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE), | 57 SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE), |
58 begin_impl_frame_tracker_(BEGINFRAMETRACKER_FROM_HERE), | 58 begin_impl_frame_tracker_(BEGINFRAMETRACKER_FROM_HERE), |
59 state_machine_(settings), | 59 state_machine_(settings), |
60 inside_process_scheduled_actions_(false), | 60 inside_process_scheduled_actions_(false), |
61 inside_action_(SchedulerStateMachine::ACTION_NONE), | 61 inside_action_(SchedulerStateMachine::ACTION_NONE), |
62 weak_factory_(this) { | 62 weak_factory_(this) { |
63 TRACE_EVENT1("cc", "Scheduler::Scheduler", "settings", settings_.AsValue()); | 63 TRACE_EVENT1("cc", "Scheduler::Scheduler", "settings", settings_.AsValue()); |
64 DCHECK(client_); | 64 DCHECK(client_); |
65 DCHECK(!state_machine_.BeginFrameNeeded()); | 65 DCHECK(!state_machine_.BeginFrameNeeded()); |
66 | 66 |
67 begin_retro_frame_closure_ = | |
68 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr()); | |
69 begin_impl_frame_deadline_closure_ = base::Bind( | 67 begin_impl_frame_deadline_closure_ = base::Bind( |
70 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); | 68 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); |
71 | 69 |
72 SetBeginFrameSource(begin_frame_source); | 70 SetBeginFrameSource(begin_frame_source); |
73 ProcessScheduledActions(); | 71 ProcessScheduledActions(); |
74 } | 72 } |
75 | 73 |
76 Scheduler::~Scheduler() { | 74 Scheduler::~Scheduler() { |
77 SetBeginFrameSource(nullptr); | 75 SetBeginFrameSource(nullptr); |
78 } | 76 } |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 compositor_timing_history_->WillPrepareTiles(); | 191 compositor_timing_history_->WillPrepareTiles(); |
194 } | 192 } |
195 | 193 |
196 void Scheduler::DidPrepareTiles() { | 194 void Scheduler::DidPrepareTiles() { |
197 compositor_timing_history_->DidPrepareTiles(); | 195 compositor_timing_history_->DidPrepareTiles(); |
198 state_machine_.DidPrepareTiles(); | 196 state_machine_.DidPrepareTiles(); |
199 } | 197 } |
200 | 198 |
201 void Scheduler::DidLoseOutputSurface() { | 199 void Scheduler::DidLoseOutputSurface() { |
202 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); | 200 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); |
203 begin_retro_frame_args_.clear(); | |
204 begin_retro_frame_task_.Cancel(); | |
205 state_machine_.DidLoseOutputSurface(); | 201 state_machine_.DidLoseOutputSurface(); |
206 UpdateCompositorTimingHistoryRecordingEnabled(); | 202 UpdateCompositorTimingHistoryRecordingEnabled(); |
207 ProcessScheduledActions(); | 203 ProcessScheduledActions(); |
208 } | 204 } |
209 | 205 |
210 void Scheduler::DidCreateAndInitializeOutputSurface() { | 206 void Scheduler::DidCreateAndInitializeOutputSurface() { |
211 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); | 207 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); |
212 DCHECK(!observing_begin_frame_source_); | 208 DCHECK(!observing_begin_frame_source_); |
213 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); | 209 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); |
214 state_machine_.DidCreateAndInitializeOutputSurface(); | 210 state_machine_.DidCreateAndInitializeOutputSurface(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 if (begin_frame_source_) | 243 if (begin_frame_source_) |
248 begin_frame_source_->AddObserver(this); | 244 begin_frame_source_->AddObserver(this); |
249 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, | 245 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, |
250 true); | 246 true); |
251 } else if (state_machine_.begin_impl_frame_state() == | 247 } else if (state_machine_.begin_impl_frame_state() == |
252 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) { | 248 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) { |
253 // Call RemoveObserver in between frames only. | 249 // Call RemoveObserver in between frames only. |
254 observing_begin_frame_source_ = false; | 250 observing_begin_frame_source_ = false; |
255 if (begin_frame_source_) | 251 if (begin_frame_source_) |
256 begin_frame_source_->RemoveObserver(this); | 252 begin_frame_source_->RemoveObserver(this); |
| 253 missed_begin_frame_task_.Cancel(); |
257 BeginImplFrameNotExpectedSoon(); | 254 BeginImplFrameNotExpectedSoon(); |
258 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, | 255 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, |
259 false); | 256 false); |
260 } | 257 } |
261 } | 258 } |
262 | |
263 PostBeginRetroFrameIfNeeded(); | |
264 } | 259 } |
265 | 260 |
266 void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) { | 261 void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) { |
267 if (state_machine_.begin_frame_source_paused() == paused) | 262 if (state_machine_.begin_frame_source_paused() == paused) |
268 return; | 263 return; |
269 TRACE_EVENT_INSTANT1("cc", "Scheduler::SetBeginFrameSourcePaused", | 264 TRACE_EVENT_INSTANT1("cc", "Scheduler::SetBeginFrameSourcePaused", |
270 TRACE_EVENT_SCOPE_THREAD, "paused", paused); | 265 TRACE_EVENT_SCOPE_THREAD, "paused", paused); |
271 state_machine_.SetBeginFrameSourcePaused(paused); | 266 state_machine_.SetBeginFrameSourcePaused(paused); |
272 ProcessScheduledActions(); | 267 ProcessScheduledActions(); |
273 } | 268 } |
274 | 269 |
275 // BeginFrame is the mechanism that tells us that now is a good time to start | 270 // BeginFrame is the mechanism that tells us that now is a good time to start |
276 // making a frame. Usually this means that user input for the frame is complete. | 271 // making a frame. Usually this means that user input for the frame is complete. |
277 // If the scheduler is busy, we queue the BeginFrame to be handled later as | 272 // If the scheduler is busy, we queue the BeginFrame to be handled later as |
278 // a BeginRetroFrame. | 273 // a BeginRetroFrame. |
279 bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { | 274 bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { |
280 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue()); | 275 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue()); |
281 | 276 |
| 277 if (!state_machine_.BeginFrameNeeded()) { |
| 278 TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginFrameDropped", |
| 279 TRACE_EVENT_SCOPE_THREAD); |
| 280 return false; |
| 281 } |
| 282 |
282 // Trace this begin frame time through the Chrome stack | 283 // Trace this begin frame time through the Chrome stack |
283 TRACE_EVENT_FLOW_BEGIN0( | 284 TRACE_EVENT_FLOW_BEGIN0( |
284 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs", | 285 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs", |
285 args.frame_time.ToInternalValue()); | 286 args.frame_time.ToInternalValue()); |
286 | 287 |
287 // TODO(brianderson): Adjust deadline in the DisplayScheduler. | 288 // TODO(brianderson): Adjust deadline in the DisplayScheduler. |
288 BeginFrameArgs adjusted_args(args); | 289 BeginFrameArgs adjusted_args(args); |
289 adjusted_args.deadline -= EstimatedParentDrawTime(); | 290 adjusted_args.deadline -= EstimatedParentDrawTime(); |
290 | 291 |
291 if (settings_.using_synchronous_renderer_compositor) { | 292 if (settings_.using_synchronous_renderer_compositor) { |
292 BeginImplFrameSynchronous(adjusted_args); | 293 BeginImplFrameSynchronous(adjusted_args); |
293 return true; | 294 return true; |
294 } | 295 } |
295 | 296 |
296 // We have just called SetNeedsBeginFrame(true) and the BeginFrameSource has | 297 // We have just called SetNeedsBeginFrame(true) and the BeginFrameSource has |
297 // sent us the last BeginFrame we have missed. As we might not be able to | 298 // sent us the last BeginFrame we have missed. As we might not be able to |
298 // actually make rendering for this call, handle it like a "retro frame". | 299 // actually make rendering for this call, handle it like a "retro frame". |
299 // TODO(brainderson): Add a test for this functionality ASAP! | 300 // TODO(brainderson): Add a test for this functionality ASAP! |
300 if (adjusted_args.type == BeginFrameArgs::MISSED) { | 301 if (adjusted_args.type == BeginFrameArgs::MISSED) { |
301 begin_retro_frame_args_.push_back(adjusted_args); | 302 DCHECK(missed_begin_frame_task_.IsCancelled()); |
302 PostBeginRetroFrameIfNeeded(); | 303 missed_begin_frame_task_.Reset( |
| 304 base::Bind(&Scheduler::BeginImplFrameWithDeadline, |
| 305 base::Unretained(this), adjusted_args)); |
| 306 task_runner_->PostTask(FROM_HERE, missed_begin_frame_task_.callback()); |
303 return true; | 307 return true; |
304 } | 308 } |
305 | 309 |
306 bool should_defer_begin_frame = | 310 BeginImplFrameWithDeadline(adjusted_args); |
307 !begin_retro_frame_args_.empty() || | |
308 !begin_retro_frame_task_.IsCancelled() || | |
309 !observing_begin_frame_source_ || | |
310 (state_machine_.begin_impl_frame_state() != | |
311 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | |
312 | |
313 if (should_defer_begin_frame) { | |
314 begin_retro_frame_args_.push_back(adjusted_args); | |
315 TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginFrame deferred", | |
316 TRACE_EVENT_SCOPE_THREAD); | |
317 // Queuing the frame counts as "using it", so we need to return true. | |
318 } else { | |
319 BeginImplFrameWithDeadline(adjusted_args); | |
320 } | |
321 return true; | 311 return true; |
322 } | 312 } |
323 | 313 |
324 void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) { | 314 void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) { |
325 state_machine_.SetVideoNeedsBeginFrames(video_needs_begin_frames); | 315 state_machine_.SetVideoNeedsBeginFrames(video_needs_begin_frames); |
326 ProcessScheduledActions(); | 316 ProcessScheduledActions(); |
327 } | 317 } |
328 | 318 |
329 void Scheduler::OnDrawForOutputSurface(bool resourceless_software_draw) { | 319 void Scheduler::OnDrawForOutputSurface(bool resourceless_software_draw) { |
330 DCHECK(settings_.using_synchronous_renderer_compositor); | 320 DCHECK(settings_.using_synchronous_renderer_compositor); |
331 DCHECK_EQ(state_machine_.begin_impl_frame_state(), | 321 DCHECK_EQ(state_machine_.begin_impl_frame_state(), |
332 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | 322 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
333 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); | 323 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); |
334 | 324 |
335 state_machine_.SetResourcelessSoftwareDraw(resourceless_software_draw); | 325 state_machine_.SetResourcelessSoftwareDraw(resourceless_software_draw); |
336 state_machine_.OnBeginImplFrameDeadline(); | 326 state_machine_.OnBeginImplFrameDeadline(); |
337 ProcessScheduledActions(); | 327 ProcessScheduledActions(); |
338 | 328 |
339 state_machine_.OnBeginImplFrameIdle(); | 329 state_machine_.OnBeginImplFrameIdle(); |
340 ProcessScheduledActions(); | 330 ProcessScheduledActions(); |
341 state_machine_.SetResourcelessSoftwareDraw(false); | 331 state_machine_.SetResourcelessSoftwareDraw(false); |
342 } | 332 } |
343 | 333 |
344 // BeginRetroFrame is called for BeginFrames that we've deferred because | |
345 // the scheduler was in the middle of processing a previous BeginFrame. | |
346 void Scheduler::BeginRetroFrame() { | |
347 TRACE_EVENT0("cc,benchmark", "Scheduler::BeginRetroFrame"); | |
348 DCHECK(!settings_.using_synchronous_renderer_compositor); | |
349 DCHECK(!begin_retro_frame_args_.empty()); | |
350 DCHECK(!begin_retro_frame_task_.IsCancelled()); | |
351 DCHECK_EQ(state_machine_.begin_impl_frame_state(), | |
352 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | |
353 | |
354 begin_retro_frame_task_.Cancel(); | |
355 | |
356 // Discard expired BeginRetroFrames | |
357 // Today, we should always end up with at most one un-expired BeginRetroFrame | |
358 // because deadlines will not be greater than the next frame time. We don't | |
359 // DCHECK though because some systems don't always have monotonic timestamps. | |
360 // TODO(brianderson): In the future, long deadlines could result in us not | |
361 // draining the queue if we don't catch up. If we consistently can't catch | |
362 // up, our fallback should be to lower our frame rate. | |
363 base::TimeTicks now = Now(); | |
364 | |
365 while (!begin_retro_frame_args_.empty()) { | |
366 const BeginFrameArgs& args = begin_retro_frame_args_.front(); | |
367 base::TimeTicks expiration_time = args.deadline; | |
368 if (now <= expiration_time) | |
369 break; | |
370 TRACE_EVENT_INSTANT2( | |
371 "cc", "Scheduler::BeginRetroFrame discarding", TRACE_EVENT_SCOPE_THREAD, | |
372 "expiration_time - now", (expiration_time - now).InMillisecondsF(), | |
373 "BeginFrameArgs", begin_retro_frame_args_.front().AsValue()); | |
374 begin_retro_frame_args_.pop_front(); | |
375 if (begin_frame_source_) | |
376 begin_frame_source_->DidFinishFrame(this, begin_retro_frame_args_.size()); | |
377 } | |
378 | |
379 if (begin_retro_frame_args_.empty()) { | |
380 TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginRetroFrames all expired", | |
381 TRACE_EVENT_SCOPE_THREAD); | |
382 } else { | |
383 BeginFrameArgs front = begin_retro_frame_args_.front(); | |
384 begin_retro_frame_args_.pop_front(); | |
385 BeginImplFrameWithDeadline(front); | |
386 } | |
387 } | |
388 | |
389 // There could be a race between the posted BeginRetroFrame and a new | |
390 // BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame | |
391 // will check if there is a pending BeginRetroFrame to ensure we handle | |
392 // BeginFrames in FIFO order. | |
393 void Scheduler::PostBeginRetroFrameIfNeeded() { | |
394 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | |
395 "Scheduler::PostBeginRetroFrameIfNeeded", "state", AsValue()); | |
396 if (!observing_begin_frame_source_) | |
397 return; | |
398 | |
399 if (begin_retro_frame_args_.empty() || !begin_retro_frame_task_.IsCancelled()) | |
400 return; | |
401 | |
402 // begin_retro_frame_args_ should always be empty for the | |
403 // synchronous compositor. | |
404 DCHECK(!settings_.using_synchronous_renderer_compositor); | |
405 | |
406 if (state_machine_.begin_impl_frame_state() != | |
407 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) | |
408 return; | |
409 | |
410 begin_retro_frame_task_.Reset(begin_retro_frame_closure_); | |
411 | |
412 task_runner_->PostTask(FROM_HERE, begin_retro_frame_task_.callback()); | |
413 } | |
414 | |
415 void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) { | 334 void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) { |
416 bool main_thread_is_in_high_latency_mode = | 335 bool main_thread_is_in_high_latency_mode = |
417 state_machine_.main_thread_missed_last_deadline(); | 336 state_machine_.main_thread_missed_last_deadline(); |
418 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args", | 337 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args", |
419 args.AsValue(), "main_thread_missed_last_deadline", | 338 args.AsValue(), "main_thread_missed_last_deadline", |
420 main_thread_is_in_high_latency_mode); | 339 main_thread_is_in_high_latency_mode); |
421 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | 340 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), |
422 "MainThreadLatency", main_thread_is_in_high_latency_mode); | 341 "MainThreadLatency", main_thread_is_in_high_latency_mode); |
423 | 342 |
| 343 if (state_machine_.begin_impl_frame_state() == |
| 344 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) { |
| 345 OnBeginImplFrameDeadline(); |
| 346 } |
| 347 |
| 348 DCHECK_EQ(state_machine_.begin_impl_frame_state(), |
| 349 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
| 350 |
424 BeginFrameArgs adjusted_args = args; | 351 BeginFrameArgs adjusted_args = args; |
| 352 |
| 353 // Cancel the missed begin frame task in case the BFS sends a normal begin |
| 354 // frame before the missed frame task runs. This should be done after |args| |
| 355 // is copied because destroying the task also destroys the storage for |args|. |
| 356 missed_begin_frame_task_.Cancel(); |
| 357 |
425 adjusted_args.deadline -= compositor_timing_history_->DrawDurationEstimate(); | 358 adjusted_args.deadline -= compositor_timing_history_->DrawDurationEstimate(); |
426 adjusted_args.deadline -= kDeadlineFudgeFactor; | 359 adjusted_args.deadline -= kDeadlineFudgeFactor; |
427 | 360 |
428 base::TimeDelta bmf_start_to_activate = | 361 base::TimeDelta bmf_start_to_activate = |
429 compositor_timing_history_ | 362 compositor_timing_history_ |
430 ->BeginMainFrameStartToCommitDurationEstimate() + | 363 ->BeginMainFrameStartToCommitDurationEstimate() + |
431 compositor_timing_history_->CommitToReadyToActivateDurationEstimate() + | 364 compositor_timing_history_->CommitToReadyToActivateDurationEstimate() + |
432 compositor_timing_history_->ActivateDurationEstimate(); | 365 compositor_timing_history_->ActivateDurationEstimate(); |
433 | 366 |
434 base::TimeDelta bmf_to_activate_estimate_critical = | 367 base::TimeDelta bmf_to_activate_estimate_critical = |
435 bmf_start_to_activate + | 368 bmf_start_to_activate + |
436 compositor_timing_history_->BeginMainFrameQueueDurationCriticalEstimate(); | 369 compositor_timing_history_->BeginMainFrameQueueDurationCriticalEstimate(); |
437 | 370 |
438 state_machine_.SetCriticalBeginMainFrameToActivateIsFast( | 371 state_machine_.SetCriticalBeginMainFrameToActivateIsFast( |
439 bmf_to_activate_estimate_critical < args.interval); | 372 bmf_to_activate_estimate_critical < adjusted_args.interval); |
440 | 373 |
441 // Update the BeginMainFrame args now that we know whether the main | 374 // Update the BeginMainFrame args now that we know whether the main |
442 // thread will be on the critical path or not. | 375 // thread will be on the critical path or not. |
443 begin_main_frame_args_ = adjusted_args; | 376 begin_main_frame_args_ = adjusted_args; |
444 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); | 377 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); |
445 | 378 |
446 base::TimeDelta bmf_to_activate_estimate = bmf_to_activate_estimate_critical; | 379 base::TimeDelta bmf_to_activate_estimate = bmf_to_activate_estimate_critical; |
447 if (!begin_main_frame_args_.on_critical_path) { | 380 if (!begin_main_frame_args_.on_critical_path) { |
448 bmf_to_activate_estimate = | 381 bmf_to_activate_estimate = |
449 bmf_start_to_activate + | 382 bmf_start_to_activate + |
450 compositor_timing_history_ | 383 compositor_timing_history_ |
451 ->BeginMainFrameQueueDurationNotCriticalEstimate(); | 384 ->BeginMainFrameQueueDurationNotCriticalEstimate(); |
452 } | 385 } |
453 | 386 |
454 bool can_activate_before_deadline = | 387 bool can_activate_before_deadline = |
455 CanBeginMainFrameAndActivateBeforeDeadline(adjusted_args, | 388 CanBeginMainFrameAndActivateBeforeDeadline(adjusted_args, |
456 bmf_to_activate_estimate); | 389 bmf_to_activate_estimate); |
457 | 390 |
458 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) { | 391 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) { |
459 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", | 392 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", |
460 TRACE_EVENT_SCOPE_THREAD); | 393 TRACE_EVENT_SCOPE_THREAD); |
461 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); | 394 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); |
462 } else if (ShouldRecoverImplLatency(adjusted_args, | 395 } else if (ShouldRecoverImplLatency(adjusted_args, |
463 can_activate_before_deadline)) { | 396 can_activate_before_deadline)) { |
464 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", | 397 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", |
465 TRACE_EVENT_SCOPE_THREAD); | 398 TRACE_EVENT_SCOPE_THREAD); |
466 if (begin_frame_source_) | 399 if (begin_frame_source_) |
467 begin_frame_source_->DidFinishFrame(this, begin_retro_frame_args_.size()); | 400 begin_frame_source_->DidFinishFrame(this, 0); |
468 return; | 401 return; |
469 } | 402 } |
470 | 403 |
471 BeginImplFrame(adjusted_args); | 404 BeginImplFrame(adjusted_args); |
472 } | 405 } |
473 | 406 |
474 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { | 407 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { |
475 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args", | 408 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args", |
476 args.AsValue()); | 409 args.AsValue()); |
477 | 410 |
478 // The main thread currently can't commit before we draw with the | 411 // The main thread currently can't commit before we draw with the |
479 // synchronous compositor, so never consider the BeginMainFrame fast. | 412 // synchronous compositor, so never consider the BeginMainFrame fast. |
480 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false); | 413 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false); |
481 begin_main_frame_args_ = args; | 414 begin_main_frame_args_ = args; |
482 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); | 415 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); |
483 | 416 |
484 BeginImplFrame(args); | 417 BeginImplFrame(args); |
485 compositor_timing_history_->WillFinishImplFrame( | 418 compositor_timing_history_->WillFinishImplFrame( |
486 state_machine_.needs_redraw()); | 419 state_machine_.needs_redraw()); |
487 FinishImplFrame(); | 420 FinishImplFrame(); |
488 } | 421 } |
489 | 422 |
490 void Scheduler::FinishImplFrame() { | 423 void Scheduler::FinishImplFrame() { |
491 state_machine_.OnBeginImplFrameIdle(); | 424 state_machine_.OnBeginImplFrameIdle(); |
492 ProcessScheduledActions(); | 425 ProcessScheduledActions(); |
493 | 426 |
494 client_->DidFinishImplFrame(); | 427 client_->DidFinishImplFrame(); |
495 if (begin_frame_source_) | 428 if (begin_frame_source_) |
496 begin_frame_source_->DidFinishFrame(this, begin_retro_frame_args_.size()); | 429 begin_frame_source_->DidFinishFrame(this, 0); |
497 begin_impl_frame_tracker_.Finish(); | 430 begin_impl_frame_tracker_.Finish(); |
498 } | 431 } |
499 | 432 |
500 // BeginImplFrame starts a compositor frame that will wait up until a deadline | 433 // BeginImplFrame starts a compositor frame that will wait up until a deadline |
501 // for a BeginMainFrame+activation to complete before it times out and draws | 434 // for a BeginMainFrame+activation to complete before it times out and draws |
502 // any asynchronous animation and scroll/pinch updates. | 435 // any asynchronous animation and scroll/pinch updates. |
503 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { | 436 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { |
504 DCHECK_EQ(state_machine_.begin_impl_frame_state(), | 437 DCHECK_EQ(state_machine_.begin_impl_frame_state(), |
505 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | 438 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
506 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); | 439 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 state_machine_.AsValueInto(state.get()); | 648 state_machine_.AsValueInto(state.get()); |
716 state->EndDictionary(); | 649 state->EndDictionary(); |
717 | 650 |
718 state->BeginDictionary("scheduler_state"); | 651 state->BeginDictionary("scheduler_state"); |
719 state->SetBoolean("throttle_frame_production_", | 652 state->SetBoolean("throttle_frame_production_", |
720 settings_.throttle_frame_production); | 653 settings_.throttle_frame_production); |
721 state->SetDouble("estimated_parent_draw_time_ms", | 654 state->SetDouble("estimated_parent_draw_time_ms", |
722 estimated_parent_draw_time_.InMillisecondsF()); | 655 estimated_parent_draw_time_.InMillisecondsF()); |
723 state->SetBoolean("observing_begin_frame_source", | 656 state->SetBoolean("observing_begin_frame_source", |
724 observing_begin_frame_source_); | 657 observing_begin_frame_source_); |
725 state->SetInteger("begin_retro_frame_args", | |
726 static_cast<int>(begin_retro_frame_args_.size())); | |
727 state->SetBoolean("begin_retro_frame_task", | |
728 !begin_retro_frame_task_.IsCancelled()); | |
729 state->SetBoolean("begin_impl_frame_deadline_task", | 658 state->SetBoolean("begin_impl_frame_deadline_task", |
730 !begin_impl_frame_deadline_task_.IsCancelled()); | 659 !begin_impl_frame_deadline_task_.IsCancelled()); |
| 660 state->SetBoolean("missed_begin_frame_task", |
| 661 !missed_begin_frame_task_.IsCancelled()); |
731 state->SetString("inside_action", | 662 state->SetString("inside_action", |
732 SchedulerStateMachine::ActionToString(inside_action_)); | 663 SchedulerStateMachine::ActionToString(inside_action_)); |
733 | 664 |
734 state->BeginDictionary("begin_impl_frame_args"); | 665 state->BeginDictionary("begin_impl_frame_args"); |
735 begin_impl_frame_tracker_.AsValueInto(now, state.get()); | 666 begin_impl_frame_tracker_.AsValueInto(now, state.get()); |
736 state->EndDictionary(); | 667 state->EndDictionary(); |
737 | 668 |
738 state->SetString("begin_impl_frame_deadline_mode_", | 669 state->SetString("begin_impl_frame_deadline_mode_", |
739 SchedulerStateMachine::BeginImplFrameDeadlineModeToString( | 670 SchedulerStateMachine::BeginImplFrameDeadlineModeToString( |
740 begin_impl_frame_deadline_mode_)); | 671 begin_impl_frame_deadline_mode_)); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
818 } | 749 } |
819 | 750 |
820 bool Scheduler::IsBeginMainFrameSentOrStarted() const { | 751 bool Scheduler::IsBeginMainFrameSentOrStarted() const { |
821 return (state_machine_.begin_main_frame_state() == | 752 return (state_machine_.begin_main_frame_state() == |
822 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT || | 753 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT || |
823 state_machine_.begin_main_frame_state() == | 754 state_machine_.begin_main_frame_state() == |
824 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED); | 755 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED); |
825 } | 756 } |
826 | 757 |
827 } // namespace cc | 758 } // namespace cc |
OLD | NEW |