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

Side by Side Diff: cc/scheduler/scheduler.cc

Issue 817603002: cc: Make scheduling be driven by vsync for android webview. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix rebase compile errors. Created 5 years, 8 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
« no previous file with comments | « cc/scheduler/scheduler.h ('k') | cc/scheduler/scheduler_state_machine.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 primary_frame_source_internal_(external_begin_frame_source.Pass()), 87 primary_frame_source_internal_(external_begin_frame_source.Pass()),
88 background_frame_source_internal_(), 88 background_frame_source_internal_(),
89 vsync_observer_(NULL), 89 vsync_observer_(NULL),
90 authoritative_vsync_interval_(base::TimeDelta()), 90 authoritative_vsync_interval_(base::TimeDelta()),
91 last_vsync_timebase_(base::TimeTicks()), 91 last_vsync_timebase_(base::TimeTicks()),
92 throttle_frame_production_(scheduler_settings.throttle_frame_production), 92 throttle_frame_production_(scheduler_settings.throttle_frame_production),
93 settings_(scheduler_settings), 93 settings_(scheduler_settings),
94 client_(client), 94 client_(client),
95 layer_tree_host_id_(layer_tree_host_id), 95 layer_tree_host_id_(layer_tree_host_id),
96 task_runner_(task_runner), 96 task_runner_(task_runner),
97 begin_impl_frame_deadline_mode_(
98 SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE),
97 state_machine_(scheduler_settings), 99 state_machine_(scheduler_settings),
98 inside_process_scheduled_actions_(false), 100 inside_process_scheduled_actions_(false),
99 inside_action_(SchedulerStateMachine::ACTION_NONE), 101 inside_action_(SchedulerStateMachine::ACTION_NONE),
100 weak_factory_(this) { 102 weak_factory_(this) {
101 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 103 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
102 "Scheduler::Scheduler", 104 "Scheduler::Scheduler",
103 "settings", 105 "settings",
104 settings_.AsValue()); 106 settings_.AsValue());
105 DCHECK(client_); 107 DCHECK(client_);
106 DCHECK(!state_machine_.BeginFrameNeeded()); 108 DCHECK(!state_machine_.BeginFrameNeeded());
107 109
108 begin_retro_frame_closure_ = 110 begin_retro_frame_closure_ =
109 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr()); 111 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr());
110 begin_impl_frame_deadline_closure_ = base::Bind( 112 begin_impl_frame_deadline_closure_ = base::Bind(
111 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); 113 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
112 poll_for_draw_triggers_closure_ = base::Bind(
113 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr());
114 advance_commit_state_closure_ = base::Bind( 114 advance_commit_state_closure_ = base::Bind(
115 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr()); 115 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr());
116 116
117 frame_source_ = BeginFrameSourceMultiplexer::Create(); 117 frame_source_ = BeginFrameSourceMultiplexer::Create();
118 frame_source_->AddObserver(this); 118 frame_source_->AddObserver(this);
119 119
120 // Primary frame source 120 // Primary frame source
121 primary_frame_source_ = 121 primary_frame_source_ =
122 frame_sources_constructor->ConstructPrimaryFrameSource(this); 122 frame_sources_constructor->ConstructPrimaryFrameSource(this);
123 frame_source_->AddSource(primary_frame_source_); 123 frame_source_->AddSource(primary_frame_source_);
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 client_->SendBeginMainFrameNotExpectedSoon(); 330 client_->SendBeginMainFrameNotExpectedSoon();
331 } 331 }
332 } 332 }
333 333
334 PostBeginRetroFrameIfNeeded(); 334 PostBeginRetroFrameIfNeeded();
335 } 335 }
336 336
337 // We may need to poll when we can't rely on BeginFrame to advance certain 337 // We may need to poll when we can't rely on BeginFrame to advance certain
338 // state or to avoid deadlock. 338 // state or to avoid deadlock.
339 void Scheduler::SetupPollingMechanisms() { 339 void Scheduler::SetupPollingMechanisms() {
340 bool needs_advance_commit_state_timer = false; 340 // At this point we'd prefer to advance through the commit flow by
341 // Setup PollForAnticipatedDrawTriggers if we need to monitor state but 341 // drawing a frame, however it's possible that the frame rate controller
342 // aren't expecting any more BeginFrames. This should only be needed by 342 // will not give us a BeginFrame until the commit completes. See
343 // the synchronous compositor when BeginFrameNeeded is false. 343 // crbug.com/317430 for an example of a swap ack being held on commit. Thus
344 if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) { 344 // we set a repeating timer to poll on ProcessScheduledActions until we
345 DCHECK(!state_machine_.SupportsProactiveBeginFrame()); 345 // successfully reach BeginFrame. Synchronous compositor does not use
346 if (poll_for_draw_triggers_task_.IsCancelled()) { 346 // frame rate controller or have the circular wait in the bug.
347 poll_for_draw_triggers_task_.Reset(poll_for_draw_triggers_closure_); 347 if (IsBeginMainFrameSentOrStarted() &&
348 base::TimeDelta delay = begin_impl_frame_args_.IsValid() 348 !settings_.using_synchronous_renderer_compositor) {
349 ? begin_impl_frame_args_.interval
350 : BeginFrameArgs::DefaultInterval();
351 task_runner_->PostDelayedTask(
352 FROM_HERE, poll_for_draw_triggers_task_.callback(), delay);
353 }
354 } else {
355 poll_for_draw_triggers_task_.Cancel();
356
357 // At this point we'd prefer to advance through the commit flow by
358 // drawing a frame, however it's possible that the frame rate controller
359 // will not give us a BeginFrame until the commit completes. See
360 // crbug.com/317430 for an example of a swap ack being held on commit. Thus
361 // we set a repeating timer to poll on ProcessScheduledActions until we
362 // successfully reach BeginFrame. Synchronous compositor does not use
363 // frame rate controller or have the circular wait in the bug.
364 if (IsBeginMainFrameSentOrStarted() &&
365 !settings_.using_synchronous_renderer_compositor) {
366 needs_advance_commit_state_timer = true;
367 }
368 }
369
370 if (needs_advance_commit_state_timer) {
371 if (advance_commit_state_task_.IsCancelled() && 349 if (advance_commit_state_task_.IsCancelled() &&
372 begin_impl_frame_args_.IsValid()) { 350 begin_impl_frame_args_.IsValid()) {
373 // Since we'd rather get a BeginImplFrame by the normal mechanism, we 351 // Since we'd rather get a BeginImplFrame by the normal mechanism, we
374 // set the interval to twice the interval from the previous frame. 352 // set the interval to twice the interval from the previous frame.
375 advance_commit_state_task_.Reset(advance_commit_state_closure_); 353 advance_commit_state_task_.Reset(advance_commit_state_closure_);
376 task_runner_->PostDelayedTask(FROM_HERE, 354 task_runner_->PostDelayedTask(FROM_HERE,
377 advance_commit_state_task_.callback(), 355 advance_commit_state_task_.callback(),
378 begin_impl_frame_args_.interval * 2); 356 begin_impl_frame_args_.interval * 2);
379 } 357 }
380 } else { 358 } else {
(...skipping 18 matching lines...) Expand all
399 adjusted_args_for_children.deadline -= 377 adjusted_args_for_children.deadline -=
400 (client_->BeginMainFrameToCommitDurationEstimate() + 378 (client_->BeginMainFrameToCommitDurationEstimate() +
401 client_->CommitToActivateDurationEstimate() + 379 client_->CommitToActivateDurationEstimate() +
402 client_->DrawDurationEstimate() + EstimatedParentDrawTime()); 380 client_->DrawDurationEstimate() + EstimatedParentDrawTime());
403 client_->SendBeginFramesToChildren(adjusted_args_for_children); 381 client_->SendBeginFramesToChildren(adjusted_args_for_children);
404 } 382 }
405 383
406 BeginFrameArgs adjusted_args(args); 384 BeginFrameArgs adjusted_args(args);
407 adjusted_args.deadline -= EstimatedParentDrawTime(); 385 adjusted_args.deadline -= EstimatedParentDrawTime();
408 386
387 if (settings_.using_synchronous_renderer_compositor) {
388 BeginImplFrameSynchronous(adjusted_args);
389 return true;
390 }
391
409 // We have just called SetNeedsBeginFrame(true) and the BeginFrameSource has 392 // We have just called SetNeedsBeginFrame(true) and the BeginFrameSource has
410 // sent us the last BeginFrame we have missed. As we might not be able to 393 // sent us the last BeginFrame we have missed. As we might not be able to
411 // actually make rendering for this call, handle it like a "retro frame". 394 // actually make rendering for this call, handle it like a "retro frame".
412 // TODO(brainderson): Add a test for this functionality ASAP! 395 // TODO(brainderson): Add a test for this functionality ASAP!
413 if (adjusted_args.type == BeginFrameArgs::MISSED) { 396 if (adjusted_args.type == BeginFrameArgs::MISSED) {
414 begin_retro_frame_args_.push_back(adjusted_args); 397 begin_retro_frame_args_.push_back(adjusted_args);
415 PostBeginRetroFrameIfNeeded(); 398 PostBeginRetroFrameIfNeeded();
416 return true; 399 return true;
417 } 400 }
418 401
419 bool should_defer_begin_frame; 402 bool should_defer_begin_frame =
420 if (settings_.using_synchronous_renderer_compositor) { 403 !begin_retro_frame_args_.empty() ||
421 should_defer_begin_frame = false; 404 !begin_retro_frame_task_.IsCancelled() ||
422 } else { 405 !frame_source_->NeedsBeginFrames() ||
423 should_defer_begin_frame = 406 (state_machine_.begin_impl_frame_state() !=
424 !begin_retro_frame_args_.empty() || 407 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
425 !begin_retro_frame_task_.IsCancelled() ||
426 !frame_source_->NeedsBeginFrames() ||
427 (state_machine_.begin_impl_frame_state() !=
428 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
429 }
430 408
431 if (should_defer_begin_frame) { 409 if (should_defer_begin_frame) {
432 begin_retro_frame_args_.push_back(adjusted_args); 410 begin_retro_frame_args_.push_back(adjusted_args);
433 TRACE_EVENT_INSTANT0( 411 TRACE_EVENT_INSTANT0(
434 "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD); 412 "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD);
435 // Queuing the frame counts as "using it", so we need to return true. 413 // Queuing the frame counts as "using it", so we need to return true.
436 } else { 414 } else {
437 BeginImplFrame(adjusted_args); 415 BeginImplFrameWithDeadline(adjusted_args);
438 } 416 }
439 return true; 417 return true;
440 } 418 }
441 419
442 void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) { 420 void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) {
443 state_machine_.SetChildrenNeedBeginFrames(children_need_begin_frames); 421 state_machine_.SetChildrenNeedBeginFrames(children_need_begin_frames);
444 ProcessScheduledActions(); 422 ProcessScheduledActions();
445 } 423 }
446 424
447 void Scheduler::SetAuthoritativeVSyncInterval(const base::TimeDelta& interval) { 425 void Scheduler::SetAuthoritativeVSyncInterval(const base::TimeDelta& interval) {
448 authoritative_vsync_interval_ = interval; 426 authoritative_vsync_interval_ = interval;
449 if (vsync_observer_) 427 if (vsync_observer_)
450 vsync_observer_->OnUpdateVSyncParameters(last_vsync_timebase_, interval); 428 vsync_observer_->OnUpdateVSyncParameters(last_vsync_timebase_, interval);
451 } 429 }
452 430
431 void Scheduler::OnDrawForOutputSurface() {
432 DCHECK(settings_.using_synchronous_renderer_compositor);
433 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
434 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
435 DCHECK(!BeginImplFrameDeadlinePending());
436
437 state_machine_.OnBeginImplFrameDeadline();
438 ProcessScheduledActions();
439
440 state_machine_.OnBeginImplFrameIdle();
441 ProcessScheduledActions();
442 }
443
453 // BeginRetroFrame is called for BeginFrames that we've deferred because 444 // BeginRetroFrame is called for BeginFrames that we've deferred because
454 // the scheduler was in the middle of processing a previous BeginFrame. 445 // the scheduler was in the middle of processing a previous BeginFrame.
455 void Scheduler::BeginRetroFrame() { 446 void Scheduler::BeginRetroFrame() {
456 TRACE_EVENT0("cc,benchmark", "Scheduler::BeginRetroFrame"); 447 TRACE_EVENT0("cc,benchmark", "Scheduler::BeginRetroFrame");
457 DCHECK(!settings_.using_synchronous_renderer_compositor); 448 DCHECK(!settings_.using_synchronous_renderer_compositor);
458 DCHECK(!begin_retro_frame_args_.empty()); 449 DCHECK(!begin_retro_frame_args_.empty());
459 DCHECK(!begin_retro_frame_task_.IsCancelled()); 450 DCHECK(!begin_retro_frame_task_.IsCancelled());
460 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 451 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
461 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 452 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
462 453
(...skipping 21 matching lines...) Expand all
484 frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); 475 frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
485 } 476 }
486 477
487 if (begin_retro_frame_args_.empty()) { 478 if (begin_retro_frame_args_.empty()) {
488 TRACE_EVENT_INSTANT0("cc", 479 TRACE_EVENT_INSTANT0("cc",
489 "Scheduler::BeginRetroFrames all expired", 480 "Scheduler::BeginRetroFrames all expired",
490 TRACE_EVENT_SCOPE_THREAD); 481 TRACE_EVENT_SCOPE_THREAD);
491 } else { 482 } else {
492 BeginFrameArgs front = begin_retro_frame_args_.front(); 483 BeginFrameArgs front = begin_retro_frame_args_.front();
493 begin_retro_frame_args_.pop_front(); 484 begin_retro_frame_args_.pop_front();
494 BeginImplFrame(front); 485 BeginImplFrameWithDeadline(front);
495 } 486 }
496 } 487 }
497 488
498 // There could be a race between the posted BeginRetroFrame and a new 489 // There could be a race between the posted BeginRetroFrame and a new
499 // BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame 490 // BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame
500 // will check if there is a pending BeginRetroFrame to ensure we handle 491 // will check if there is a pending BeginRetroFrame to ensure we handle
501 // BeginFrames in FIFO order. 492 // BeginFrames in FIFO order.
502 void Scheduler::PostBeginRetroFrameIfNeeded() { 493 void Scheduler::PostBeginRetroFrameIfNeeded() {
503 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 494 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
504 "Scheduler::PostBeginRetroFrameIfNeeded", 495 "Scheduler::PostBeginRetroFrameIfNeeded",
(...skipping 11 matching lines...) Expand all
516 507
517 if (state_machine_.begin_impl_frame_state() != 508 if (state_machine_.begin_impl_frame_state() !=
518 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) 509 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE)
519 return; 510 return;
520 511
521 begin_retro_frame_task_.Reset(begin_retro_frame_closure_); 512 begin_retro_frame_task_.Reset(begin_retro_frame_closure_);
522 513
523 task_runner_->PostTask(FROM_HERE, begin_retro_frame_task_.callback()); 514 task_runner_->PostTask(FROM_HERE, begin_retro_frame_task_.callback());
524 } 515 }
525 516
517 void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) {
518 BeginImplFrame(args);
519
520 // The deadline will be scheduled in ProcessScheduledActions.
521 state_machine_.OnBeginImplFrameDeadlinePending();
522 ProcessScheduledActions();
523 }
524
525 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) {
526 BeginImplFrame(args);
527 FinishImplFrame();
528 }
529
530 void Scheduler::FinishImplFrame() {
531 state_machine_.OnBeginImplFrameIdle();
532 ProcessScheduledActions();
533
534 client_->DidBeginImplFrameDeadline();
535 frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
536 }
537
526 // BeginImplFrame starts a compositor frame that will wait up until a deadline 538 // BeginImplFrame starts a compositor frame that will wait up until a deadline
527 // for a BeginMainFrame+activation to complete before it times out and draws 539 // for a BeginMainFrame+activation to complete before it times out and draws
528 // any asynchronous animation and scroll/pinch updates. 540 // any asynchronous animation and scroll/pinch updates.
529 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { 541 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
530 bool main_thread_is_in_high_latency_mode = 542 bool main_thread_is_in_high_latency_mode =
531 state_machine_.MainThreadIsInHighLatencyMode(); 543 state_machine_.MainThreadIsInHighLatencyMode();
532 TRACE_EVENT2("cc,benchmark", 544 TRACE_EVENT2("cc,benchmark",
533 "Scheduler::BeginImplFrame", 545 "Scheduler::BeginImplFrame",
534 "args", 546 "args",
535 args.AsValue(), 547 args.AsValue(),
536 "main_thread_is_high_latency", 548 "main_thread_is_high_latency",
537 main_thread_is_in_high_latency_mode); 549 main_thread_is_in_high_latency_mode);
538 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 550 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
539 "MainThreadLatency", 551 "MainThreadLatency",
540 main_thread_is_in_high_latency_mode); 552 main_thread_is_in_high_latency_mode);
541 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 553 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
542 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 554 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
555 DCHECK(!BeginImplFrameDeadlinePending());
543 DCHECK(state_machine_.HasInitializedOutputSurface()); 556 DCHECK(state_machine_.HasInitializedOutputSurface());
544 557
545 advance_commit_state_task_.Cancel(); 558 advance_commit_state_task_.Cancel();
546 559
547 begin_impl_frame_args_ = args; 560 begin_impl_frame_args_ = args;
548 begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate(); 561 begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate();
549 562
550 if (!state_machine_.impl_latency_takes_priority() && 563 if (!state_machine_.impl_latency_takes_priority() &&
551 main_thread_is_in_high_latency_mode && 564 main_thread_is_in_high_latency_mode &&
552 CanCommitAndActivateBeforeDeadline()) { 565 CanCommitAndActivateBeforeDeadline()) {
553 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); 566 state_machine_.SetSkipNextBeginMainFrameToReduceLatency();
554 } 567 }
555 568
556 state_machine_.OnBeginImplFrame(); 569 state_machine_.OnBeginImplFrame();
557 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_); 570 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_);
558 client_->WillBeginImplFrame(begin_impl_frame_args_); 571 client_->WillBeginImplFrame(begin_impl_frame_args_);
559 572
560 ProcessScheduledActions(); 573 ProcessScheduledActions();
561
562 state_machine_.OnBeginImplFrameDeadlinePending();
563
564 if (settings_.using_synchronous_renderer_compositor) {
565 // The synchronous renderer compositor has to make its GL calls
566 // within this call.
567 // TODO(brianderson): Have the OutputSurface initiate the deadline tasks
568 // so the synchronous renderer compositor can take advantage of splitting
569 // up the BeginImplFrame and deadline as well.
570 OnBeginImplFrameDeadline();
571 } else {
572 ScheduleBeginImplFrameDeadline();
573 }
574 } 574 }
575 575
576 void Scheduler::ScheduleBeginImplFrameDeadline() { 576 void Scheduler::ScheduleBeginImplFrameDeadline() {
577 // The synchronous compositor does not post a deadline task. 577 // The synchronous compositor does not post a deadline task.
578 DCHECK(!settings_.using_synchronous_renderer_compositor); 578 DCHECK(!settings_.using_synchronous_renderer_compositor);
579 579
580 begin_impl_frame_deadline_task_.Cancel(); 580 begin_impl_frame_deadline_task_.Cancel();
581 begin_impl_frame_deadline_task_.Reset(begin_impl_frame_deadline_closure_); 581 begin_impl_frame_deadline_task_.Reset(begin_impl_frame_deadline_closure_);
582 582
583 begin_impl_frame_deadline_mode_ = 583 begin_impl_frame_deadline_mode_ =
584 state_machine_.CurrentBeginImplFrameDeadlineMode(); 584 state_machine_.CurrentBeginImplFrameDeadlineMode();
585 585
586 base::TimeTicks deadline; 586 base::TimeTicks deadline;
587 switch (begin_impl_frame_deadline_mode_) { 587 switch (begin_impl_frame_deadline_mode_) {
588 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE:
589 // No deadline.
590 return;
588 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE: 591 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE:
589 // We are ready to draw a new active tree immediately. 592 // We are ready to draw a new active tree immediately.
590 // We don't use Now() here because it's somewhat expensive to call. 593 // We don't use Now() here because it's somewhat expensive to call.
591 deadline = base::TimeTicks(); 594 deadline = base::TimeTicks();
592 break; 595 break;
593 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR: 596 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR:
594 // We are animating on the impl thread but we can wait for some time. 597 // We are animating on the impl thread but we can wait for some time.
595 deadline = begin_impl_frame_args_.deadline; 598 deadline = begin_impl_frame_args_.deadline;
596 break; 599 break;
597 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE: 600 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE:
598 // We are blocked for one reason or another and we should wait. 601 // We are blocked for one reason or another and we should wait.
599 // TODO(brianderson): Handle long deadlines (that are past the next 602 // TODO(brianderson): Handle long deadlines (that are past the next
600 // frame's frame time) properly instead of using this hack. 603 // frame's frame time) properly instead of using this hack.
601 deadline = 604 deadline =
602 begin_impl_frame_args_.frame_time + begin_impl_frame_args_.interval; 605 begin_impl_frame_args_.frame_time + begin_impl_frame_args_.interval;
603 break; 606 break;
604 case SchedulerStateMachine:: 607 case SchedulerStateMachine::
605 BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW: 608 BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW:
606 // We are blocked because we are waiting for ReadyToDraw signal. We would 609 // We are blocked because we are waiting for ReadyToDraw signal. We would
607 // post deadline after we received ReadyToDraw singal. 610 // post deadline after we received ReadyToDraw singal.
608 TRACE_EVENT1("cc", "Scheduler::ScheduleBeginImplFrameDeadline", 611 TRACE_EVENT1("cc", "Scheduler::ScheduleBeginImplFrameDeadline",
609 "deadline_mode", "blocked_on_ready_to_draw"); 612 "deadline_mode", "blocked_on_ready_to_draw");
610 return; 613 return;
611 } 614 }
612 615
613 TRACE_EVENT1( 616 TRACE_EVENT2("cc", "Scheduler::ScheduleBeginImplFrameDeadline", "mode",
614 "cc", "Scheduler::ScheduleBeginImplFrameDeadline", "deadline", deadline); 617 SchedulerStateMachine::BeginImplFrameDeadlineModeToString(
618 begin_impl_frame_deadline_mode_),
619 "deadline", deadline);
615 620
616 base::TimeDelta delta = deadline - Now(); 621 base::TimeDelta delta = std::max(deadline - Now(), base::TimeDelta());
617 if (delta <= base::TimeDelta())
618 delta = base::TimeDelta();
619 task_runner_->PostDelayedTask( 622 task_runner_->PostDelayedTask(
620 FROM_HERE, begin_impl_frame_deadline_task_.callback(), delta); 623 FROM_HERE, begin_impl_frame_deadline_task_.callback(), delta);
621 } 624 }
622 625
623 void Scheduler::RescheduleBeginImplFrameDeadlineIfNeeded() { 626 void Scheduler::ScheduleBeginImplFrameDeadlineIfNeeded() {
624 if (settings_.using_synchronous_renderer_compositor) 627 if (settings_.using_synchronous_renderer_compositor)
625 return; 628 return;
626 629
627 if (state_machine_.begin_impl_frame_state() != 630 if (state_machine_.begin_impl_frame_state() !=
628 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) 631 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)
629 return; 632 return;
630 633
631 if (begin_impl_frame_deadline_mode_ != 634 if (begin_impl_frame_deadline_mode_ ==
632 state_machine_.CurrentBeginImplFrameDeadlineMode()) 635 state_machine_.CurrentBeginImplFrameDeadlineMode() &&
633 ScheduleBeginImplFrameDeadline(); 636 BeginImplFrameDeadlinePending())
637 return;
638
639 ScheduleBeginImplFrameDeadline();
634 } 640 }
635 641
636 void Scheduler::OnBeginImplFrameDeadline() { 642 void Scheduler::OnBeginImplFrameDeadline() {
637 TRACE_EVENT0("cc,benchmark", "Scheduler::OnBeginImplFrameDeadline"); 643 TRACE_EVENT0("cc,benchmark", "Scheduler::OnBeginImplFrameDeadline");
638 begin_impl_frame_deadline_task_.Cancel(); 644 begin_impl_frame_deadline_task_.Cancel();
639 // We split the deadline actions up into two phases so the state machine 645 // We split the deadline actions up into two phases so the state machine
640 // has a chance to trigger actions that should occur durring and after 646 // has a chance to trigger actions that should occur durring and after
641 // the deadline separately. For example: 647 // the deadline separately. For example:
642 // * Sending the BeginMainFrame will not occur after the deadline in 648 // * Sending the BeginMainFrame will not occur after the deadline in
643 // order to wait for more user-input before starting the next commit. 649 // order to wait for more user-input before starting the next commit.
644 // * Creating a new OuputSurface will not occur during the deadline in 650 // * Creating a new OuputSurface will not occur during the deadline in
645 // order to allow the state machine to "settle" first. 651 // order to allow the state machine to "settle" first.
646 652
647 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is fixed. 653 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is fixed.
648 tracked_objects::ScopedTracker tracking_profile1( 654 tracked_objects::ScopedTracker tracking_profile1(
649 FROM_HERE_WITH_EXPLICIT_FUNCTION( 655 FROM_HERE_WITH_EXPLICIT_FUNCTION(
650 "461509 Scheduler::OnBeginImplFrameDeadline1")); 656 "461509 Scheduler::OnBeginImplFrameDeadline1"));
651 state_machine_.OnBeginImplFrameDeadline(); 657 state_machine_.OnBeginImplFrameDeadline();
652 ProcessScheduledActions(); 658 ProcessScheduledActions();
653 state_machine_.OnBeginImplFrameIdle(); 659 FinishImplFrame();
654 ProcessScheduledActions();
655
656 client_->DidBeginImplFrameDeadline();
657 frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
658 } 660 }
659 661
660 void Scheduler::PollForAnticipatedDrawTriggers() {
661 TRACE_EVENT0("cc", "Scheduler::PollForAnticipatedDrawTriggers");
662 poll_for_draw_triggers_task_.Cancel();
663 state_machine_.DidEnterPollForAnticipatedDrawTriggers();
664 ProcessScheduledActions();
665 state_machine_.DidLeavePollForAnticipatedDrawTriggers();
666 }
667 662
668 void Scheduler::PollToAdvanceCommitState() { 663 void Scheduler::PollToAdvanceCommitState() {
669 TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState"); 664 TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState");
670 advance_commit_state_task_.Cancel(); 665 advance_commit_state_task_.Cancel();
671 ProcessScheduledActions(); 666 ProcessScheduledActions();
672 } 667 }
673 668
674 void Scheduler::DrawAndSwapIfPossible() { 669 void Scheduler::DrawAndSwapIfPossible() {
675 DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible(); 670 DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible();
676 state_machine_.DidDrawIfPossibleCompleted(result); 671 state_machine_.DidDrawIfPossibleCompleted(result);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT: 736 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT:
742 // No action is actually performed, but this allows the state machine to 737 // No action is actually performed, but this allows the state machine to
743 // advance out of its waiting to draw state without actually drawing. 738 // advance out of its waiting to draw state without actually drawing.
744 break; 739 break;
745 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION: 740 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
746 client_->ScheduledActionBeginOutputSurfaceCreation(); 741 client_->ScheduledActionBeginOutputSurfaceCreation();
747 break; 742 break;
748 case SchedulerStateMachine::ACTION_PREPARE_TILES: 743 case SchedulerStateMachine::ACTION_PREPARE_TILES:
749 client_->ScheduledActionPrepareTiles(); 744 client_->ScheduledActionPrepareTiles();
750 break; 745 break;
746 case SchedulerStateMachine::ACTION_INVALIDATE_OUTPUT_SURFACE: {
747 client_->ScheduledActionInvalidateOutputSurface();
748 break;
749 }
751 } 750 }
752 } while (action != SchedulerStateMachine::ACTION_NONE); 751 } while (action != SchedulerStateMachine::ACTION_NONE);
753 752
754 SetupPollingMechanisms(); 753 SetupPollingMechanisms();
755 754
756 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime()); 755 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime());
757 756
758 RescheduleBeginImplFrameDeadlineIfNeeded(); 757 ScheduleBeginImplFrameDeadlineIfNeeded();
759 758
760 SetupNextBeginFrameIfNeeded(); 759 SetupNextBeginFrameIfNeeded();
761 } 760 }
762 761
763 scoped_refptr<base::trace_event::ConvertableToTraceFormat> Scheduler::AsValue() 762 scoped_refptr<base::trace_event::ConvertableToTraceFormat> Scheduler::AsValue()
764 const { 763 const {
765 scoped_refptr<base::trace_event::TracedValue> state = 764 scoped_refptr<base::trace_event::TracedValue> state =
766 new base::trace_event::TracedValue(); 765 new base::trace_event::TracedValue();
767 AsValueInto(state.get()); 766 AsValueInto(state.get());
768 return state; 767 return state;
(...skipping 20 matching lines...) Expand all
789 (AnticipatedDrawTime() - Now()).InMillisecondsF()); 788 (AnticipatedDrawTime() - Now()).InMillisecondsF());
790 state->SetDouble("estimated_parent_draw_time_ms", 789 state->SetDouble("estimated_parent_draw_time_ms",
791 estimated_parent_draw_time_.InMillisecondsF()); 790 estimated_parent_draw_time_.InMillisecondsF());
792 state->SetBoolean("last_set_needs_begin_frame_", 791 state->SetBoolean("last_set_needs_begin_frame_",
793 frame_source_->NeedsBeginFrames()); 792 frame_source_->NeedsBeginFrames());
794 state->SetInteger("begin_retro_frame_args_", begin_retro_frame_args_.size()); 793 state->SetInteger("begin_retro_frame_args_", begin_retro_frame_args_.size());
795 state->SetBoolean("begin_retro_frame_task_", 794 state->SetBoolean("begin_retro_frame_task_",
796 !begin_retro_frame_task_.IsCancelled()); 795 !begin_retro_frame_task_.IsCancelled());
797 state->SetBoolean("begin_impl_frame_deadline_task_", 796 state->SetBoolean("begin_impl_frame_deadline_task_",
798 !begin_impl_frame_deadline_task_.IsCancelled()); 797 !begin_impl_frame_deadline_task_.IsCancelled());
799 state->SetBoolean("poll_for_draw_triggers_task_",
800 !poll_for_draw_triggers_task_.IsCancelled());
801 state->SetBoolean("advance_commit_state_task_", 798 state->SetBoolean("advance_commit_state_task_",
802 !advance_commit_state_task_.IsCancelled()); 799 !advance_commit_state_task_.IsCancelled());
803 state->BeginDictionary("begin_impl_frame_args"); 800 state->BeginDictionary("begin_impl_frame_args");
804 begin_impl_frame_args_.AsValueInto(state); 801 begin_impl_frame_args_.AsValueInto(state);
805 state->EndDictionary(); 802 state->EndDictionary();
806 803
807 base::TimeTicks now = Now(); 804 base::TimeTicks now = Now();
808 base::TimeTicks frame_time = begin_impl_frame_args_.frame_time; 805 base::TimeTicks frame_time = begin_impl_frame_args_.frame_time;
809 base::TimeTicks deadline = begin_impl_frame_args_.deadline; 806 base::TimeTicks deadline = begin_impl_frame_args_.deadline;
810 base::TimeDelta interval = begin_impl_frame_args_.interval; 807 base::TimeDelta interval = begin_impl_frame_args_.interval;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 } 852 }
856 853
857 bool Scheduler::IsBeginMainFrameSentOrStarted() const { 854 bool Scheduler::IsBeginMainFrameSentOrStarted() const {
858 return (state_machine_.commit_state() == 855 return (state_machine_.commit_state() ==
859 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || 856 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT ||
860 state_machine_.commit_state() == 857 state_machine_.commit_state() ==
861 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); 858 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED);
862 } 859 }
863 860
864 } // namespace cc 861 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/scheduler.h ('k') | cc/scheduler/scheduler_state_machine.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698