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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
195 compositor_timing_history_->WillPrepareTiles(); | 193 compositor_timing_history_->WillPrepareTiles(); |
196 } | 194 } |
197 | 195 |
198 void Scheduler::DidPrepareTiles() { | 196 void Scheduler::DidPrepareTiles() { |
199 compositor_timing_history_->DidPrepareTiles(); | 197 compositor_timing_history_->DidPrepareTiles(); |
200 state_machine_.DidPrepareTiles(); | 198 state_machine_.DidPrepareTiles(); |
201 } | 199 } |
202 | 200 |
203 void Scheduler::DidLoseOutputSurface() { | 201 void Scheduler::DidLoseOutputSurface() { |
204 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); | 202 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); |
205 begin_retro_frame_args_.clear(); | |
206 begin_retro_frame_task_.Cancel(); | |
207 state_machine_.DidLoseOutputSurface(); | 203 state_machine_.DidLoseOutputSurface(); |
208 UpdateCompositorTimingHistoryRecordingEnabled(); | 204 UpdateCompositorTimingHistoryRecordingEnabled(); |
209 ProcessScheduledActions(); | 205 ProcessScheduledActions(); |
210 } | 206 } |
211 | 207 |
212 void Scheduler::DidCreateAndInitializeOutputSurface() { | 208 void Scheduler::DidCreateAndInitializeOutputSurface() { |
213 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); | 209 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); |
214 DCHECK(!observing_begin_frame_source_); | 210 DCHECK(!observing_begin_frame_source_); |
215 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); | 211 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); |
216 state_machine_.DidCreateAndInitializeOutputSurface(); | 212 state_machine_.DidCreateAndInitializeOutputSurface(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
254 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) { | 250 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) { |
255 // Call RemoveObserver in between frames only. | 251 // Call RemoveObserver in between frames only. |
256 observing_begin_frame_source_ = false; | 252 observing_begin_frame_source_ = false; |
257 if (begin_frame_source_) | 253 if (begin_frame_source_) |
258 begin_frame_source_->RemoveObserver(this); | 254 begin_frame_source_->RemoveObserver(this); |
259 BeginImplFrameNotExpectedSoon(); | 255 BeginImplFrameNotExpectedSoon(); |
260 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, | 256 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, |
261 false); | 257 false); |
262 } | 258 } |
263 } | 259 } |
264 | |
265 PostBeginRetroFrameIfNeeded(); | |
266 } | 260 } |
267 | 261 |
268 void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) { | 262 void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) { |
269 if (state_machine_.begin_frame_source_paused() == paused) | 263 if (state_machine_.begin_frame_source_paused() == paused) |
270 return; | 264 return; |
271 TRACE_EVENT_INSTANT1("cc", "Scheduler::SetBeginFrameSourcePaused", | 265 TRACE_EVENT_INSTANT1("cc", "Scheduler::SetBeginFrameSourcePaused", |
272 TRACE_EVENT_SCOPE_THREAD, "paused", paused); | 266 TRACE_EVENT_SCOPE_THREAD, "paused", paused); |
273 state_machine_.SetBeginFrameSourcePaused(paused); | 267 state_machine_.SetBeginFrameSourcePaused(paused); |
274 ProcessScheduledActions(); | 268 ProcessScheduledActions(); |
275 } | 269 } |
276 | 270 |
271 const BeginFrameArgs& Scheduler::LastUsedBeginFrameArgs() const { | |
272 return begin_impl_frame_tracker_.DangerousMethodCurrentOrLast(); | |
273 } | |
274 | |
277 // BeginFrame is the mechanism that tells us that now is a good time to start | 275 // BeginFrame is the mechanism that tells us that now is a good time to start |
278 // making a frame. Usually this means that user input for the frame is complete. | 276 // making a frame. Usually this means that user input for the frame is complete. |
279 // If the scheduler is busy, we queue the BeginFrame to be handled later as | 277 void Scheduler::OnBeginFrame(const BeginFrameArgs& args) { |
280 // a BeginRetroFrame. | 278 if (!observing_begin_frame_source_ || |
281 bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { | 279 state_machine_.begin_impl_frame_state() != |
280 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) { | |
281 return; | |
282 } | |
283 | |
282 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue()); | 284 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue()); |
283 | 285 |
284 // Trace this begin frame time through the Chrome stack | 286 // Trace this begin frame time through the Chrome stack |
285 TRACE_EVENT_FLOW_BEGIN0( | 287 TRACE_EVENT_FLOW_BEGIN0( |
286 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs", | 288 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs", |
287 args.frame_time.ToInternalValue()); | 289 args.frame_time.ToInternalValue()); |
288 | 290 |
289 // TODO(brianderson): Adjust deadline in the DisplayScheduler. | 291 // TODO(brianderson): Adjust deadline in the DisplayScheduler. |
290 BeginFrameArgs adjusted_args(args); | 292 BeginFrameArgs adjusted_args(args); |
291 adjusted_args.deadline -= EstimatedParentDrawTime(); | 293 adjusted_args.deadline -= EstimatedParentDrawTime(); |
292 | 294 |
293 // Deliver BeginFrames to children. | 295 // Deliver BeginFrames to children. |
294 // TODO(brianderson): Move this responsibility to the DisplayScheduler. | 296 // TODO(brianderson): Move this responsibility to the DisplayScheduler. |
295 if (state_machine_.children_need_begin_frames()) | 297 if (state_machine_.children_need_begin_frames()) |
296 client_->SendBeginFramesToChildren(adjusted_args); | 298 client_->SendBeginFramesToChildren(adjusted_args); |
297 | 299 |
298 if (settings_.using_synchronous_renderer_compositor) { | 300 if (settings_.using_synchronous_renderer_compositor) { |
299 BeginImplFrameSynchronous(adjusted_args); | 301 BeginImplFrameSynchronous(adjusted_args); |
300 return true; | |
301 } | |
302 | |
303 // We have just called SetNeedsBeginFrame(true) and the BeginFrameSource has | |
304 // sent us the last BeginFrame we have missed. As we might not be able to | |
305 // actually make rendering for this call, handle it like a "retro frame". | |
306 // TODO(brainderson): Add a test for this functionality ASAP! | |
307 if (adjusted_args.type == BeginFrameArgs::MISSED) { | |
enne (OOO)
2016/04/18 21:30:38
The removal of this might break https://codereview
| |
308 begin_retro_frame_args_.push_back(adjusted_args); | |
309 PostBeginRetroFrameIfNeeded(); | |
310 return true; | |
311 } | |
312 | |
313 bool should_defer_begin_frame = | |
314 !begin_retro_frame_args_.empty() || | |
315 !begin_retro_frame_task_.IsCancelled() || | |
316 !observing_begin_frame_source_ || | |
317 (state_machine_.begin_impl_frame_state() != | |
318 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | |
319 | |
320 if (should_defer_begin_frame) { | |
321 begin_retro_frame_args_.push_back(adjusted_args); | |
322 TRACE_EVENT_INSTANT0( | |
323 "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD); | |
324 // Queuing the frame counts as "using it", so we need to return true. | |
325 } else { | 302 } else { |
326 BeginImplFrameWithDeadline(adjusted_args); | 303 BeginImplFrameWithDeadline(adjusted_args); |
327 } | 304 } |
328 return true; | |
329 } | 305 } |
330 | 306 |
331 void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) { | 307 void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) { |
332 state_machine_.SetChildrenNeedBeginFrames(children_need_begin_frames); | 308 state_machine_.SetChildrenNeedBeginFrames(children_need_begin_frames); |
333 ProcessScheduledActions(); | 309 ProcessScheduledActions(); |
334 } | 310 } |
335 | 311 |
336 void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) { | 312 void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) { |
337 state_machine_.SetVideoNeedsBeginFrames(video_needs_begin_frames); | 313 state_machine_.SetVideoNeedsBeginFrames(video_needs_begin_frames); |
338 ProcessScheduledActions(); | 314 ProcessScheduledActions(); |
339 } | 315 } |
340 | 316 |
341 void Scheduler::OnDrawForOutputSurface(bool resourceless_software_draw) { | 317 void Scheduler::OnDrawForOutputSurface(bool resourceless_software_draw) { |
342 DCHECK(settings_.using_synchronous_renderer_compositor); | 318 DCHECK(settings_.using_synchronous_renderer_compositor); |
343 DCHECK_EQ(state_machine_.begin_impl_frame_state(), | 319 DCHECK_EQ(state_machine_.begin_impl_frame_state(), |
344 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | 320 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
345 DCHECK(!BeginImplFrameDeadlinePending()); | 321 DCHECK(!BeginImplFrameDeadlinePending()); |
346 | 322 |
347 state_machine_.SetResourcelessSoftareDraw(resourceless_software_draw); | 323 state_machine_.SetResourcelessSoftareDraw(resourceless_software_draw); |
348 state_machine_.OnBeginImplFrameDeadline(); | 324 state_machine_.OnBeginImplFrameDeadline(); |
349 ProcessScheduledActions(); | 325 ProcessScheduledActions(); |
350 | 326 |
351 state_machine_.OnBeginImplFrameIdle(); | 327 state_machine_.OnBeginImplFrameIdle(); |
352 ProcessScheduledActions(); | 328 ProcessScheduledActions(); |
353 state_machine_.SetResourcelessSoftareDraw(false); | 329 state_machine_.SetResourcelessSoftareDraw(false); |
354 } | 330 } |
355 | 331 |
356 // BeginRetroFrame is called for BeginFrames that we've deferred because | |
357 // the scheduler was in the middle of processing a previous BeginFrame. | |
358 void Scheduler::BeginRetroFrame() { | |
359 TRACE_EVENT0("cc,benchmark", "Scheduler::BeginRetroFrame"); | |
360 DCHECK(!settings_.using_synchronous_renderer_compositor); | |
361 DCHECK(!begin_retro_frame_args_.empty()); | |
362 DCHECK(!begin_retro_frame_task_.IsCancelled()); | |
363 DCHECK_EQ(state_machine_.begin_impl_frame_state(), | |
364 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | |
365 | |
366 begin_retro_frame_task_.Cancel(); | |
367 | |
368 // Discard expired BeginRetroFrames | |
369 // Today, we should always end up with at most one un-expired BeginRetroFrame | |
370 // because deadlines will not be greater than the next frame time. We don't | |
371 // DCHECK though because some systems don't always have monotonic timestamps. | |
372 // TODO(brianderson): In the future, long deadlines could result in us not | |
373 // draining the queue if we don't catch up. If we consistently can't catch | |
374 // up, our fallback should be to lower our frame rate. | |
375 base::TimeTicks now = Now(); | |
376 | |
377 while (!begin_retro_frame_args_.empty()) { | |
378 const BeginFrameArgs& args = begin_retro_frame_args_.front(); | |
379 base::TimeTicks expiration_time = args.deadline; | |
380 if (now <= expiration_time) | |
381 break; | |
382 TRACE_EVENT_INSTANT2( | |
383 "cc", "Scheduler::BeginRetroFrame discarding", TRACE_EVENT_SCOPE_THREAD, | |
384 "expiration_time - now", (expiration_time - now).InMillisecondsF(), | |
385 "BeginFrameArgs", begin_retro_frame_args_.front().AsValue()); | |
386 begin_retro_frame_args_.pop_front(); | |
387 if (begin_frame_source_) | |
388 begin_frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); | |
389 } | |
390 | |
391 if (begin_retro_frame_args_.empty()) { | |
392 TRACE_EVENT_INSTANT0("cc", | |
393 "Scheduler::BeginRetroFrames all expired", | |
394 TRACE_EVENT_SCOPE_THREAD); | |
395 } else { | |
396 BeginFrameArgs front = begin_retro_frame_args_.front(); | |
397 begin_retro_frame_args_.pop_front(); | |
398 BeginImplFrameWithDeadline(front); | |
399 } | |
400 } | |
401 | |
402 // There could be a race between the posted BeginRetroFrame and a new | |
403 // BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame | |
404 // will check if there is a pending BeginRetroFrame to ensure we handle | |
405 // BeginFrames in FIFO order. | |
406 void Scheduler::PostBeginRetroFrameIfNeeded() { | |
407 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | |
408 "Scheduler::PostBeginRetroFrameIfNeeded", | |
409 "state", | |
410 AsValue()); | |
411 if (!observing_begin_frame_source_) | |
412 return; | |
413 | |
414 if (begin_retro_frame_args_.empty() || !begin_retro_frame_task_.IsCancelled()) | |
415 return; | |
416 | |
417 // begin_retro_frame_args_ should always be empty for the | |
418 // synchronous compositor. | |
419 DCHECK(!settings_.using_synchronous_renderer_compositor); | |
420 | |
421 if (state_machine_.begin_impl_frame_state() != | |
422 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) | |
423 return; | |
424 | |
425 begin_retro_frame_task_.Reset(begin_retro_frame_closure_); | |
426 | |
427 task_runner_->PostTask(FROM_HERE, begin_retro_frame_task_.callback()); | |
428 } | |
429 | |
430 void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) { | 332 void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) { |
431 bool main_thread_is_in_high_latency_mode = | 333 bool main_thread_is_in_high_latency_mode = |
432 state_machine_.main_thread_missed_last_deadline(); | 334 state_machine_.main_thread_missed_last_deadline(); |
433 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args", | 335 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args", |
434 args.AsValue(), "main_thread_missed_last_deadline", | 336 args.AsValue(), "main_thread_missed_last_deadline", |
435 main_thread_is_in_high_latency_mode); | 337 main_thread_is_in_high_latency_mode); |
436 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | 338 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), |
437 "MainThreadLatency", main_thread_is_in_high_latency_mode); | 339 "MainThreadLatency", main_thread_is_in_high_latency_mode); |
438 | 340 |
439 BeginFrameArgs adjusted_args = args; | 341 BeginFrameArgs adjusted_args = args; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
471 bmf_to_activate_estimate); | 373 bmf_to_activate_estimate); |
472 | 374 |
473 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) { | 375 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) { |
474 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", | 376 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", |
475 TRACE_EVENT_SCOPE_THREAD); | 377 TRACE_EVENT_SCOPE_THREAD); |
476 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); | 378 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); |
477 } else if (ShouldRecoverImplLatency(adjusted_args, | 379 } else if (ShouldRecoverImplLatency(adjusted_args, |
478 can_activate_before_deadline)) { | 380 can_activate_before_deadline)) { |
479 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", | 381 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", |
480 TRACE_EVENT_SCOPE_THREAD); | 382 TRACE_EVENT_SCOPE_THREAD); |
481 if (begin_frame_source_) | |
482 begin_frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); | |
483 return; | 383 return; |
484 } | 384 } |
485 | 385 |
486 BeginImplFrame(adjusted_args); | 386 BeginImplFrame(adjusted_args); |
487 | |
488 // The deadline will be scheduled in ProcessScheduledActions. | |
489 state_machine_.OnBeginImplFrameDeadlinePending(); | |
490 ProcessScheduledActions(); | |
491 } | 387 } |
492 | 388 |
493 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { | 389 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { |
494 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args", | 390 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args", |
495 args.AsValue()); | 391 args.AsValue()); |
496 | 392 |
497 // The main thread currently can't commit before we draw with the | 393 // The main thread currently can't commit before we draw with the |
498 // synchronous compositor, so never consider the BeginMainFrame fast. | 394 // synchronous compositor, so never consider the BeginMainFrame fast. |
499 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false); | 395 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false); |
500 begin_main_frame_args_ = args; | 396 begin_main_frame_args_ = args; |
501 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); | 397 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); |
502 | 398 |
503 BeginImplFrame(args); | 399 BeginImplFrame(args); |
504 compositor_timing_history_->WillFinishImplFrame( | 400 compositor_timing_history_->WillFinishImplFrame( |
505 state_machine_.needs_redraw()); | 401 state_machine_.needs_redraw()); |
506 FinishImplFrame(); | 402 FinishImplFrame(); |
507 } | 403 } |
508 | 404 |
509 void Scheduler::FinishImplFrame() { | 405 void Scheduler::FinishImplFrame() { |
510 state_machine_.OnBeginImplFrameIdle(); | 406 state_machine_.OnBeginImplFrameIdle(); |
511 ProcessScheduledActions(); | 407 ProcessScheduledActions(); |
512 | 408 |
409 begin_impl_frame_tracker_.Finish(); | |
410 | |
513 client_->DidFinishImplFrame(); | 411 client_->DidFinishImplFrame(); |
412 | |
514 if (begin_frame_source_) | 413 if (begin_frame_source_) |
515 begin_frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); | 414 begin_frame_source_->DidFinishFrame(this); |
516 begin_impl_frame_tracker_.Finish(); | |
517 } | 415 } |
518 | 416 |
519 // BeginImplFrame starts a compositor frame that will wait up until a deadline | 417 // BeginImplFrame starts a compositor frame that will wait up until a deadline |
520 // for a BeginMainFrame+activation to complete before it times out and draws | 418 // for a BeginMainFrame+activation to complete before it times out and draws |
521 // any asynchronous animation and scroll/pinch updates. | 419 // any asynchronous animation and scroll/pinch updates. |
522 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { | 420 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { |
523 DCHECK_EQ(state_machine_.begin_impl_frame_state(), | 421 DCHECK_EQ(state_machine_.begin_impl_frame_state(), |
524 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | 422 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
525 DCHECK(!BeginImplFrameDeadlinePending()); | 423 DCHECK(!BeginImplFrameDeadlinePending()); |
526 DCHECK(state_machine_.HasInitializedOutputSurface()); | 424 DCHECK(state_machine_.HasInitializedOutputSurface()); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
654 TRACE_EVENT1("cc", "Scheduler::SetDeferCommits", | 552 TRACE_EVENT1("cc", "Scheduler::SetDeferCommits", |
655 "defer_commits", | 553 "defer_commits", |
656 defer_commits); | 554 defer_commits); |
657 state_machine_.SetDeferCommits(defer_commits); | 555 state_machine_.SetDeferCommits(defer_commits); |
658 ProcessScheduledActions(); | 556 ProcessScheduledActions(); |
659 } | 557 } |
660 | 558 |
661 void Scheduler::ProcessScheduledActions() { | 559 void Scheduler::ProcessScheduledActions() { |
662 // We do not allow ProcessScheduledActions to be recursive. | 560 // We do not allow ProcessScheduledActions to be recursive. |
663 // The top-level call will iteratively execute the next action for us anyway. | 561 // The top-level call will iteratively execute the next action for us anyway. |
664 if (inside_process_scheduled_actions_) | 562 if (!inside_process_scheduled_actions_) { |
665 return; | 563 base::AutoReset<bool> mark_inside(&inside_process_scheduled_actions_, true); |
564 SchedulerStateMachine::Action action; | |
565 do { | |
566 action = state_machine_.NextAction(); | |
567 PerformAction(action); | |
568 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | |
569 "SchedulerStateMachine", "state", AsValue()); | |
570 } while (action != SchedulerStateMachine::ACTION_NONE); | |
571 } | |
572 SetupNextBeginFrameIfNeeded(); | |
573 ScheduleBeginImplFrameDeadlineIfNeeded(); | |
574 } | |
666 | 575 |
667 base::AutoReset<bool> mark_inside(&inside_process_scheduled_actions_, true); | 576 void Scheduler::PerformAction(SchedulerStateMachine::Action action) { |
668 | 577 base::AutoReset<SchedulerStateMachine::Action> mark_inside_action( |
669 SchedulerStateMachine::Action action; | 578 &inside_action_, action); |
670 do { | 579 switch (action) { |
671 action = state_machine_.NextAction(); | 580 case SchedulerStateMachine::ACTION_NONE: |
672 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | 581 break; |
673 "SchedulerStateMachine", | 582 case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME: |
674 "state", | 583 compositor_timing_history_->WillBeginMainFrame( |
675 AsValue()); | 584 begin_main_frame_args_.on_critical_path, |
676 base::AutoReset<SchedulerStateMachine::Action> | 585 begin_main_frame_args_.frame_time); |
677 mark_inside_action(&inside_action_, action); | 586 state_machine_.WillSendBeginMainFrame(); |
678 switch (action) { | 587 // TODO(brianderson): Pass begin_main_frame_args_ directly to client. |
679 case SchedulerStateMachine::ACTION_NONE: | 588 client_->ScheduledActionSendBeginMainFrame(begin_main_frame_args_); |
680 break; | 589 break; |
681 case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME: | 590 case SchedulerStateMachine::ACTION_COMMIT: { |
682 compositor_timing_history_->WillBeginMainFrame( | 591 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is |
683 begin_main_frame_args_.on_critical_path, | 592 // fixed. |
684 begin_main_frame_args_.frame_time); | 593 tracked_objects::ScopedTracker tracking_profile4( |
685 state_machine_.WillSendBeginMainFrame(); | 594 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
686 // TODO(brianderson): Pass begin_main_frame_args_ directly to client. | 595 "461509 Scheduler::ProcessScheduledActions4")); |
687 client_->ScheduledActionSendBeginMainFrame(begin_main_frame_args_); | 596 bool commit_has_no_updates = false; |
688 break; | 597 state_machine_.WillCommit(commit_has_no_updates); |
689 case SchedulerStateMachine::ACTION_COMMIT: { | 598 client_->ScheduledActionCommit(); |
690 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is | 599 break; |
691 // fixed. | |
692 tracked_objects::ScopedTracker tracking_profile4( | |
693 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
694 "461509 Scheduler::ProcessScheduledActions4")); | |
695 bool commit_has_no_updates = false; | |
696 state_machine_.WillCommit(commit_has_no_updates); | |
697 client_->ScheduledActionCommit(); | |
698 break; | |
699 } | |
700 case SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE: | |
701 compositor_timing_history_->WillActivate(); | |
702 state_machine_.WillActivate(); | |
703 client_->ScheduledActionActivateSyncTree(); | |
704 compositor_timing_history_->DidActivate(); | |
705 break; | |
706 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE: { | |
707 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is | |
708 // fixed. | |
709 tracked_objects::ScopedTracker tracking_profile6( | |
710 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
711 "461509 Scheduler::ProcessScheduledActions6")); | |
712 DrawAndSwapIfPossible(); | |
713 break; | |
714 } | |
715 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED: | |
716 DrawAndSwapForced(); | |
717 break; | |
718 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT: { | |
719 // No action is actually performed, but this allows the state machine to | |
720 // drain the pipeline without actually drawing. | |
721 state_machine_.AbortDrawAndSwap(); | |
722 compositor_timing_history_->DrawAborted(); | |
723 break; | |
724 } | |
725 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION: | |
726 state_machine_.WillBeginOutputSurfaceCreation(); | |
727 client_->ScheduledActionBeginOutputSurfaceCreation(); | |
728 break; | |
729 case SchedulerStateMachine::ACTION_PREPARE_TILES: | |
730 state_machine_.WillPrepareTiles(); | |
731 client_->ScheduledActionPrepareTiles(); | |
732 break; | |
733 case SchedulerStateMachine::ACTION_INVALIDATE_OUTPUT_SURFACE: { | |
734 state_machine_.WillInvalidateOutputSurface(); | |
735 client_->ScheduledActionInvalidateOutputSurface(); | |
736 break; | |
737 } | |
738 } | 600 } |
739 } while (action != SchedulerStateMachine::ACTION_NONE); | 601 case SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE: |
740 | 602 compositor_timing_history_->WillActivate(); |
741 ScheduleBeginImplFrameDeadlineIfNeeded(); | 603 state_machine_.WillActivate(); |
742 SetupNextBeginFrameIfNeeded(); | 604 client_->ScheduledActionActivateSyncTree(); |
605 compositor_timing_history_->DidActivate(); | |
606 break; | |
607 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE: { | |
608 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is | |
609 // fixed. | |
610 tracked_objects::ScopedTracker tracking_profile6( | |
611 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
612 "461509 Scheduler::ProcessScheduledActions6")); | |
613 DrawAndSwapIfPossible(); | |
614 break; | |
615 } | |
616 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED: | |
617 DrawAndSwapForced(); | |
618 break; | |
619 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT: { | |
620 // No action is actually performed, but this allows the state machine | |
621 // to | |
622 // drain the pipeline without actually drawing. | |
623 state_machine_.AbortDrawAndSwap(); | |
624 compositor_timing_history_->DrawAborted(); | |
625 break; | |
626 } | |
627 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION: | |
628 state_machine_.WillBeginOutputSurfaceCreation(); | |
629 client_->ScheduledActionBeginOutputSurfaceCreation(); | |
630 break; | |
631 case SchedulerStateMachine::ACTION_PREPARE_TILES: | |
632 state_machine_.WillPrepareTiles(); | |
633 client_->ScheduledActionPrepareTiles(); | |
634 break; | |
635 case SchedulerStateMachine::ACTION_INVALIDATE_OUTPUT_SURFACE: { | |
636 state_machine_.WillInvalidateOutputSurface(); | |
637 client_->ScheduledActionInvalidateOutputSurface(); | |
638 break; | |
639 } | |
640 } | |
743 } | 641 } |
744 | 642 |
745 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> | 643 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> |
746 Scheduler::AsValue() const { | 644 Scheduler::AsValue() const { |
747 std::unique_ptr<base::trace_event::TracedValue> state( | 645 std::unique_ptr<base::trace_event::TracedValue> state( |
748 new base::trace_event::TracedValue()); | 646 new base::trace_event::TracedValue()); |
749 AsValueInto(state.get()); | 647 AsValueInto(state.get()); |
750 return std::move(state); | 648 return std::move(state); |
751 } | 649 } |
752 | 650 |
(...skipping 15 matching lines...) Expand all Loading... | |
768 state->EndDictionary(); | 666 state->EndDictionary(); |
769 } | 667 } |
770 | 668 |
771 state->BeginDictionary("scheduler_state"); | 669 state->BeginDictionary("scheduler_state"); |
772 state->SetBoolean("throttle_frame_production_", | 670 state->SetBoolean("throttle_frame_production_", |
773 settings_.throttle_frame_production); | 671 settings_.throttle_frame_production); |
774 state->SetDouble("estimated_parent_draw_time_ms", | 672 state->SetDouble("estimated_parent_draw_time_ms", |
775 estimated_parent_draw_time_.InMillisecondsF()); | 673 estimated_parent_draw_time_.InMillisecondsF()); |
776 state->SetBoolean("observing_begin_frame_source", | 674 state->SetBoolean("observing_begin_frame_source", |
777 observing_begin_frame_source_); | 675 observing_begin_frame_source_); |
778 state->SetInteger("begin_retro_frame_args", | |
779 static_cast<int>(begin_retro_frame_args_.size())); | |
780 state->SetBoolean("begin_retro_frame_task", | |
781 !begin_retro_frame_task_.IsCancelled()); | |
782 state->SetBoolean("begin_impl_frame_deadline_task", | 676 state->SetBoolean("begin_impl_frame_deadline_task", |
783 !begin_impl_frame_deadline_task_.IsCancelled()); | 677 !begin_impl_frame_deadline_task_.IsCancelled()); |
784 state->SetString("inside_action", | 678 state->SetString("inside_action", |
785 SchedulerStateMachine::ActionToString(inside_action_)); | 679 SchedulerStateMachine::ActionToString(inside_action_)); |
786 | 680 |
787 state->BeginDictionary("begin_impl_frame_args"); | 681 state->BeginDictionary("begin_impl_frame_args"); |
788 begin_impl_frame_tracker_.AsValueInto(now, state); | 682 begin_impl_frame_tracker_.AsValueInto(now, state); |
789 state->EndDictionary(); | 683 state->EndDictionary(); |
790 | 684 |
791 state->SetString("begin_impl_frame_deadline_mode_", | 685 state->SetString("begin_impl_frame_deadline_mode_", |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
869 } | 763 } |
870 | 764 |
871 bool Scheduler::IsBeginMainFrameSentOrStarted() const { | 765 bool Scheduler::IsBeginMainFrameSentOrStarted() const { |
872 return (state_machine_.begin_main_frame_state() == | 766 return (state_machine_.begin_main_frame_state() == |
873 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT || | 767 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT || |
874 state_machine_.begin_main_frame_state() == | 768 state_machine_.begin_main_frame_state() == |
875 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED); | 769 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED); |
876 } | 770 } |
877 | 771 |
878 } // namespace cc | 772 } // namespace cc |
OLD | NEW |