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 #include "base/auto_reset.h" | 8 #include "base/auto_reset.h" |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 } else { | 387 } else { |
388 advance_commit_state_task_.Cancel(); | 388 advance_commit_state_task_.Cancel(); |
389 } | 389 } |
390 } | 390 } |
391 | 391 |
392 // BeginFrame is the mechanism that tells us that now is a good time to start | 392 // BeginFrame is the mechanism that tells us that now is a good time to start |
393 // making a frame. Usually this means that user input for the frame is complete. | 393 // making a frame. Usually this means that user input for the frame is complete. |
394 // If the scheduler is busy, we queue the BeginFrame to be handled later as | 394 // If the scheduler is busy, we queue the BeginFrame to be handled later as |
395 // a BeginRetroFrame. | 395 // a BeginRetroFrame. |
396 void Scheduler::BeginFrame(const BeginFrameArgs& args) { | 396 void Scheduler::BeginFrame(const BeginFrameArgs& args) { |
397 TRACE_EVENT1("cc", "Scheduler::BeginFrame", "frame_time", args.frame_time); | 397 TRACE_EVENT1("cc", "Scheduler::BeginFrame", "args", ToTrace(args)); |
398 DCHECK(settings_.throttle_frame_production); | 398 DCHECK(settings_.throttle_frame_production); |
399 | 399 |
400 bool should_defer_begin_frame; | 400 bool should_defer_begin_frame; |
401 if (settings_.using_synchronous_renderer_compositor) { | 401 if (settings_.using_synchronous_renderer_compositor) { |
402 should_defer_begin_frame = false; | 402 should_defer_begin_frame = false; |
403 } else { | 403 } else { |
404 should_defer_begin_frame = | 404 should_defer_begin_frame = |
405 !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ || | 405 !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ || |
406 !last_set_needs_begin_frame_ || | 406 !last_set_needs_begin_frame_ || |
407 (state_machine_.begin_impl_frame_state() != | 407 (state_machine_.begin_impl_frame_state() != |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 return; | 481 return; |
482 | 482 |
483 begin_retro_frame_posted_ = true; | 483 begin_retro_frame_posted_ = true; |
484 impl_task_runner_->PostTask(FROM_HERE, begin_retro_frame_closure_); | 484 impl_task_runner_->PostTask(FROM_HERE, begin_retro_frame_closure_); |
485 } | 485 } |
486 | 486 |
487 // BeginImplFrame starts a compositor frame that will wait up until a deadline | 487 // BeginImplFrame starts a compositor frame that will wait up until a deadline |
488 // for a BeginMainFrame+activation to complete before it times out and draws | 488 // for a BeginMainFrame+activation to complete before it times out and draws |
489 // any asynchronous animation and scroll/pinch updates. | 489 // any asynchronous animation and scroll/pinch updates. |
490 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { | 490 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { |
491 TRACE_EVENT1( | 491 TRACE_EVENT1("cc", "Scheduler::BeginImplFrame", "args", ToTrace(args)); |
492 "cc", "Scheduler::BeginImplFrame", "frame_time", args.frame_time); | |
493 DCHECK(state_machine_.begin_impl_frame_state() == | 492 DCHECK(state_machine_.begin_impl_frame_state() == |
494 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | 493 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
495 DCHECK(state_machine_.HasInitializedOutputSurface()); | 494 DCHECK(state_machine_.HasInitializedOutputSurface()); |
496 | 495 |
497 advance_commit_state_task_.Cancel(); | 496 advance_commit_state_task_.Cancel(); |
498 | 497 |
499 base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate(); | 498 base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate(); |
500 begin_impl_frame_args_ = args; | 499 begin_impl_frame_args_ = args; |
501 begin_impl_frame_args_.deadline -= draw_duration_estimate; | 500 begin_impl_frame_args_.deadline -= draw_duration_estimate; |
502 | 501 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
623 | 622 |
624 base::AutoReset<bool> mark_inside(&inside_process_scheduled_actions_, true); | 623 base::AutoReset<bool> mark_inside(&inside_process_scheduled_actions_, true); |
625 | 624 |
626 SchedulerStateMachine::Action action; | 625 SchedulerStateMachine::Action action; |
627 do { | 626 do { |
628 state_machine_.CheckInvariants(); | 627 state_machine_.CheckInvariants(); |
629 action = state_machine_.NextAction(); | 628 action = state_machine_.NextAction(); |
630 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | 629 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), |
631 "SchedulerStateMachine", | 630 "SchedulerStateMachine", |
632 "state", | 631 "state", |
633 TracedValue::FromValue(StateAsValue().release())); | 632 ToTrace(this)); |
634 state_machine_.UpdateState(action); | 633 state_machine_.UpdateState(action); |
635 base::AutoReset<SchedulerStateMachine::Action> | 634 base::AutoReset<SchedulerStateMachine::Action> |
636 mark_inside_action(&inside_action_, action); | 635 mark_inside_action(&inside_action_, action); |
637 switch (action) { | 636 switch (action) { |
638 case SchedulerStateMachine::ACTION_NONE: | 637 case SchedulerStateMachine::ACTION_NONE: |
639 break; | 638 break; |
640 case SchedulerStateMachine::ACTION_ANIMATE: | 639 case SchedulerStateMachine::ACTION_ANIMATE: |
641 client_->ScheduledActionAnimate(); | 640 client_->ScheduledActionAnimate(); |
642 break; | 641 break; |
643 case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME: | 642 case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME: |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
680 if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) { | 679 if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) { |
681 DCHECK(!settings_.using_synchronous_renderer_compositor); | 680 DCHECK(!settings_.using_synchronous_renderer_compositor); |
682 ScheduleBeginImplFrameDeadline(base::TimeTicks()); | 681 ScheduleBeginImplFrameDeadline(base::TimeTicks()); |
683 } | 682 } |
684 } | 683 } |
685 | 684 |
686 bool Scheduler::WillDrawIfNeeded() const { | 685 bool Scheduler::WillDrawIfNeeded() const { |
687 return !state_machine_.PendingDrawsShouldBeAborted(); | 686 return !state_machine_.PendingDrawsShouldBeAborted(); |
688 } | 687 } |
689 | 688 |
690 scoped_ptr<base::Value> Scheduler::StateAsValue() const { | 689 scoped_ptr<base::Value> Scheduler::AsValue() const { |
691 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); | 690 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); |
692 state->Set("state_machine", state_machine_.AsValue().release()); | 691 state->Set("state_machine", state_machine_.AsValue().release()); |
693 | 692 |
694 scoped_ptr<base::DictionaryValue> scheduler_state(new base::DictionaryValue); | 693 scoped_ptr<base::DictionaryValue> scheduler_state(new base::DictionaryValue); |
695 scheduler_state->SetDouble( | 694 scheduler_state->SetDouble( |
696 "time_until_anticipated_draw_time_ms", | 695 "time_until_anticipated_draw_time_ms", |
697 (AnticipatedDrawTime() - base::TimeTicks::Now()).InMillisecondsF()); | 696 (AnticipatedDrawTime() - base::TimeTicks::Now()).InMillisecondsF()); |
698 scheduler_state->SetDouble("vsync_interval_ms", | 697 scheduler_state->SetDouble("vsync_interval_ms", |
699 vsync_interval_.InMillisecondsF()); | 698 vsync_interval_.InMillisecondsF()); |
700 scheduler_state->SetDouble("estimated_parent_draw_time_ms", | 699 scheduler_state->SetDouble("estimated_parent_draw_time_ms", |
701 estimated_parent_draw_time_.InMillisecondsF()); | 700 estimated_parent_draw_time_.InMillisecondsF()); |
702 scheduler_state->SetBoolean("last_set_needs_begin_frame_", | 701 scheduler_state->SetBoolean("last_set_needs_begin_frame_", |
703 last_set_needs_begin_frame_); | 702 last_set_needs_begin_frame_); |
704 scheduler_state->SetBoolean("begin_unthrottled_frame_posted_", | 703 scheduler_state->SetBoolean("begin_unthrottled_frame_posted_", |
705 begin_unthrottled_frame_posted_); | 704 begin_unthrottled_frame_posted_); |
706 scheduler_state->SetBoolean("begin_retro_frame_posted_", | 705 scheduler_state->SetBoolean("begin_retro_frame_posted_", |
707 begin_retro_frame_posted_); | 706 begin_retro_frame_posted_); |
708 scheduler_state->SetInteger("begin_retro_frame_args_", | 707 scheduler_state->SetInteger("begin_retro_frame_args_", |
709 begin_retro_frame_args_.size()); | 708 begin_retro_frame_args_.size()); |
710 scheduler_state->SetBoolean("begin_impl_frame_deadline_task_", | 709 scheduler_state->SetBoolean("begin_impl_frame_deadline_task_", |
711 !begin_impl_frame_deadline_task_.IsCancelled()); | 710 !begin_impl_frame_deadline_task_.IsCancelled()); |
712 scheduler_state->SetBoolean("poll_for_draw_triggers_task_", | 711 scheduler_state->SetBoolean("poll_for_draw_triggers_task_", |
713 !poll_for_draw_triggers_task_.IsCancelled()); | 712 !poll_for_draw_triggers_task_.IsCancelled()); |
714 scheduler_state->SetBoolean("advance_commit_state_task_", | 713 scheduler_state->SetBoolean("advance_commit_state_task_", |
715 !advance_commit_state_task_.IsCancelled()); | 714 !advance_commit_state_task_.IsCancelled()); |
| 715 scheduler_state->Set("begin_impl_frame_args", |
| 716 begin_impl_frame_args_.AsValue().release()); |
| 717 |
716 state->Set("scheduler_state", scheduler_state.release()); | 718 state->Set("scheduler_state", scheduler_state.release()); |
717 | 719 |
718 scoped_ptr<base::DictionaryValue> client_state(new base::DictionaryValue); | 720 scoped_ptr<base::DictionaryValue> client_state(new base::DictionaryValue); |
719 client_state->SetDouble("draw_duration_estimate_ms", | 721 client_state->SetDouble("draw_duration_estimate_ms", |
720 client_->DrawDurationEstimate().InMillisecondsF()); | 722 client_->DrawDurationEstimate().InMillisecondsF()); |
721 client_state->SetDouble( | 723 client_state->SetDouble( |
722 "begin_main_frame_to_commit_duration_estimate_ms", | 724 "begin_main_frame_to_commit_duration_estimate_ms", |
723 client_->BeginMainFrameToCommitDurationEstimate().InMillisecondsF()); | 725 client_->BeginMainFrameToCommitDurationEstimate().InMillisecondsF()); |
724 client_state->SetDouble( | 726 client_state->SetDouble( |
725 "commit_to_activate_duration_estimate_ms", | 727 "commit_to_activate_duration_estimate_ms", |
726 client_->CommitToActivateDurationEstimate().InMillisecondsF()); | 728 client_->CommitToActivateDurationEstimate().InMillisecondsF()); |
727 state->Set("client_state", client_state.release()); | 729 state->Set("client_state", client_state.release()); |
728 return state.PassAs<base::Value>(); | 730 return state.PassAs<base::Value>(); |
729 } | 731 } |
730 | 732 |
731 bool Scheduler::CanCommitAndActivateBeforeDeadline() const { | 733 bool Scheduler::CanCommitAndActivateBeforeDeadline() const { |
732 // Check if the main thread computation and commit can be finished before the | 734 // Check if the main thread computation and commit can be finished before the |
733 // impl thread's deadline. | 735 // impl thread's deadline. |
734 base::TimeTicks estimated_draw_time = | 736 base::TimeTicks estimated_draw_time = |
735 begin_impl_frame_args_.frame_time + | 737 begin_impl_frame_args_.frame_time + |
736 client_->BeginMainFrameToCommitDurationEstimate() + | 738 client_->BeginMainFrameToCommitDurationEstimate() + |
737 client_->CommitToActivateDurationEstimate(); | 739 client_->CommitToActivateDurationEstimate(); |
738 | 740 |
739 TRACE_EVENT2( | 741 TRACE_EVENT2( |
740 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | 742 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), |
741 "CanCommitAndActivateBeforeDeadline", | 743 "CanCommitAndActivateBeforeDeadline", |
742 "time_left_after_drawing_ms", | 744 "time_left_after_drawing_ms", |
743 (begin_impl_frame_args_.deadline - estimated_draw_time).InMillisecondsF(), | 745 (begin_impl_frame_args_.deadline - estimated_draw_time).InMillisecondsF(), |
744 "state", | 746 "state", |
745 TracedValue::FromValue(StateAsValue().release())); | 747 ToTrace(this)); |
746 | 748 |
747 return estimated_draw_time < begin_impl_frame_args_.deadline; | 749 return estimated_draw_time < begin_impl_frame_args_.deadline; |
748 } | 750 } |
749 | 751 |
750 bool Scheduler::IsBeginMainFrameSentOrStarted() const { | 752 bool Scheduler::IsBeginMainFrameSentOrStarted() const { |
751 return (state_machine_.commit_state() == | 753 return (state_machine_.commit_state() == |
752 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || | 754 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || |
753 state_machine_.commit_state() == | 755 state_machine_.commit_state() == |
754 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); | 756 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); |
755 } | 757 } |
756 | 758 |
757 } // namespace cc | 759 } // namespace cc |
OLD | NEW |