Chromium Code Reviews| 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 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 453 state_machine_.MainThreadIsInHighLatencyMode(); | 453 state_machine_.MainThreadIsInHighLatencyMode(); |
| 454 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args", | 454 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args", |
| 455 args.AsValue(), "main_thread_is_high_latency", | 455 args.AsValue(), "main_thread_is_high_latency", |
| 456 main_thread_is_in_high_latency_mode); | 456 main_thread_is_in_high_latency_mode); |
| 457 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | 457 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), |
| 458 "MainThreadLatency", main_thread_is_in_high_latency_mode); | 458 "MainThreadLatency", main_thread_is_in_high_latency_mode); |
| 459 | 459 |
| 460 BeginFrameArgs adjusted_args = args; | 460 BeginFrameArgs adjusted_args = args; |
| 461 adjusted_args.deadline -= compositor_timing_history_->DrawDurationEstimate(); | 461 adjusted_args.deadline -= compositor_timing_history_->DrawDurationEstimate(); |
| 462 | 462 |
| 463 if (!state_machine_.impl_latency_takes_priority() && | 463 if (ShouldRecoverMainLatency(adjusted_args)) { |
| 464 main_thread_is_in_high_latency_mode && | 464 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", |
| 465 CanCommitAndActivateBeforeDeadline()) { | 465 TRACE_EVENT_SCOPE_THREAD); |
| 466 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); | 466 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); |
| 467 } else if (ShouldRecoverImplLatency(adjusted_args)) { | |
| 468 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", | |
| 469 TRACE_EVENT_SCOPE_THREAD); | |
| 470 frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); | |
| 471 return; | |
| 467 } | 472 } |
| 468 | 473 |
| 469 BeginImplFrame(adjusted_args); | 474 BeginImplFrame(adjusted_args); |
| 470 | 475 |
| 471 // The deadline will be scheduled in ProcessScheduledActions. | 476 // The deadline will be scheduled in ProcessScheduledActions. |
| 472 state_machine_.OnBeginImplFrameDeadlinePending(); | 477 state_machine_.OnBeginImplFrameDeadlinePending(); |
| 473 ProcessScheduledActions(); | 478 ProcessScheduledActions(); |
| 474 } | 479 } |
| 475 | 480 |
| 476 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { | 481 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 508 | 513 |
| 509 void Scheduler::ScheduleBeginImplFrameDeadline() { | 514 void Scheduler::ScheduleBeginImplFrameDeadline() { |
| 510 // The synchronous compositor does not post a deadline task. | 515 // The synchronous compositor does not post a deadline task. |
| 511 DCHECK(!settings_.using_synchronous_renderer_compositor); | 516 DCHECK(!settings_.using_synchronous_renderer_compositor); |
| 512 | 517 |
| 513 begin_impl_frame_deadline_task_.Cancel(); | 518 begin_impl_frame_deadline_task_.Cancel(); |
| 514 begin_impl_frame_deadline_task_.Reset(begin_impl_frame_deadline_closure_); | 519 begin_impl_frame_deadline_task_.Reset(begin_impl_frame_deadline_closure_); |
| 515 | 520 |
| 516 begin_impl_frame_deadline_mode_ = | 521 begin_impl_frame_deadline_mode_ = |
| 517 state_machine_.CurrentBeginImplFrameDeadlineMode(); | 522 state_machine_.CurrentBeginImplFrameDeadlineMode(); |
| 518 | |
| 519 base::TimeTicks deadline; | 523 base::TimeTicks deadline; |
| 520 switch (begin_impl_frame_deadline_mode_) { | 524 switch (begin_impl_frame_deadline_mode_) { |
| 521 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE: | 525 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE: |
| 522 // No deadline. | 526 // No deadline. |
| 523 return; | 527 return; |
| 524 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE: | 528 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE: |
| 525 // We are ready to draw a new active tree immediately. | 529 // We are ready to draw a new active tree immediately. |
| 526 // We don't use Now() here because it's somewhat expensive to call. | 530 // We don't use Now() here because it's somewhat expensive to call. |
| 527 deadline = base::TimeTicks(); | 531 deadline = base::TimeTicks(); |
| 528 break; | 532 break; |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 690 | 694 |
| 691 scoped_refptr<base::trace_event::ConvertableToTraceFormat> Scheduler::AsValue() | 695 scoped_refptr<base::trace_event::ConvertableToTraceFormat> Scheduler::AsValue() |
| 692 const { | 696 const { |
| 693 scoped_refptr<base::trace_event::TracedValue> state = | 697 scoped_refptr<base::trace_event::TracedValue> state = |
| 694 new base::trace_event::TracedValue(); | 698 new base::trace_event::TracedValue(); |
| 695 AsValueInto(state.get()); | 699 AsValueInto(state.get()); |
| 696 return state; | 700 return state; |
| 697 } | 701 } |
| 698 | 702 |
| 699 void Scheduler::AsValueInto(base::trace_event::TracedValue* state) const { | 703 void Scheduler::AsValueInto(base::trace_event::TracedValue* state) const { |
| 704 base::TimeTicks now = Now(); | |
| 705 | |
| 700 state->BeginDictionary("state_machine"); | 706 state->BeginDictionary("state_machine"); |
| 701 state_machine_.AsValueInto(state); | 707 state_machine_.AsValueInto(state); |
| 702 state->EndDictionary(); | 708 state->EndDictionary(); |
| 703 | 709 |
| 704 // Only trace frame sources when explicitly enabled - http://crbug.com/420607 | 710 // Only trace frame sources when explicitly enabled - http://crbug.com/420607 |
| 705 bool frame_tracing_enabled = false; | 711 bool frame_tracing_enabled = false; |
| 706 TRACE_EVENT_CATEGORY_GROUP_ENABLED( | 712 TRACE_EVENT_CATEGORY_GROUP_ENABLED( |
| 707 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), | 713 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), |
| 708 &frame_tracing_enabled); | 714 &frame_tracing_enabled); |
| 709 if (frame_tracing_enabled) { | 715 if (frame_tracing_enabled) { |
| 710 state->BeginDictionary("frame_source_"); | 716 state->BeginDictionary("frame_source_"); |
| 711 frame_source_->AsValueInto(state); | 717 frame_source_->AsValueInto(state); |
| 712 state->EndDictionary(); | 718 state->EndDictionary(); |
| 713 } | 719 } |
| 714 | 720 |
| 715 state->BeginDictionary("scheduler_state"); | 721 state->BeginDictionary("scheduler_state"); |
| 716 state->SetDouble("estimated_parent_draw_time_ms", | 722 state->SetDouble("estimated_parent_draw_time_ms", |
| 717 estimated_parent_draw_time_.InMillisecondsF()); | 723 estimated_parent_draw_time_.InMillisecondsF()); |
| 718 state->SetBoolean("last_set_needs_begin_frame_", | 724 state->SetBoolean("last_set_needs_begin_frame_", |
| 719 frame_source_->NeedsBeginFrames()); | 725 frame_source_->NeedsBeginFrames()); |
| 720 state->SetInteger("begin_retro_frame_args", | 726 state->SetInteger("begin_retro_frame_args", |
| 721 static_cast<int>(begin_retro_frame_args_.size())); | 727 static_cast<int>(begin_retro_frame_args_.size())); |
| 722 state->SetBoolean("begin_retro_frame_task", | 728 state->SetBoolean("begin_retro_frame_task", |
| 723 !begin_retro_frame_task_.IsCancelled()); | 729 !begin_retro_frame_task_.IsCancelled()); |
| 724 state->SetBoolean("begin_impl_frame_deadline_task", | 730 state->SetBoolean("begin_impl_frame_deadline_task", |
| 725 !begin_impl_frame_deadline_task_.IsCancelled()); | 731 !begin_impl_frame_deadline_task_.IsCancelled()); |
| 726 state->SetString("inside_action", | 732 state->SetString("inside_action", |
| 727 SchedulerStateMachine::ActionToString(inside_action_)); | 733 SchedulerStateMachine::ActionToString(inside_action_)); |
| 734 | |
| 728 state->BeginDictionary("begin_impl_frame_args"); | 735 state->BeginDictionary("begin_impl_frame_args"); |
| 729 begin_impl_frame_tracker_.AsValueInto(Now(), state); | 736 begin_impl_frame_tracker_.AsValueInto(now, state); |
| 730 state->EndDictionary(); | 737 state->EndDictionary(); |
| 738 | |
| 739 state->SetString("begin_impl_frame_deadline_mode_", | |
| 740 SchedulerStateMachine::BeginImplFrameDeadlineModeToString( | |
| 741 begin_impl_frame_deadline_mode_)); | |
| 731 state->EndDictionary(); | 742 state->EndDictionary(); |
| 732 | 743 |
| 733 state->BeginDictionary("compositor_timing_history"); | 744 state->BeginDictionary("compositor_timing_history"); |
| 734 compositor_timing_history_->AsValueInto(state); | 745 compositor_timing_history_->AsValueInto(state); |
| 735 state->EndDictionary(); | 746 state->EndDictionary(); |
| 736 } | 747 } |
| 737 | 748 |
| 738 void Scheduler::UpdateCompositorTimingHistoryRecordingEnabled() { | 749 void Scheduler::UpdateCompositorTimingHistoryRecordingEnabled() { |
| 739 compositor_timing_history_->SetRecordingEnabled( | 750 compositor_timing_history_->SetRecordingEnabled( |
| 740 state_machine_.HasInitializedOutputSurface() && state_machine_.visible()); | 751 state_machine_.HasInitializedOutputSurface() && state_machine_.visible()); |
| 741 } | 752 } |
| 742 | 753 |
| 743 bool Scheduler::CanCommitAndActivateBeforeDeadline() const { | 754 bool Scheduler::ShouldRecoverMainLatency(const BeginFrameArgs& args) const { |
| 744 BeginFrameArgs args = | 755 DCHECK(!settings_.using_synchronous_renderer_compositor); |
| 745 begin_impl_frame_tracker_.DangerousMethodCurrentOrLast(); | |
| 746 | 756 |
| 757 if (!state_machine_.MainThreadIsInHighLatencyMode()) | |
| 758 return false; | |
| 759 | |
| 760 // When prioritizing impl thread latency, we currently put the | |
| 761 // main thread in a high latency mode. Don't try to fight it. | |
| 762 if (state_machine_.impl_latency_takes_priority()) | |
| 763 return false; | |
| 764 | |
| 765 return CanCommitAndActivateBeforeDeadline(args); | |
| 766 } | |
| 767 | |
| 768 bool Scheduler::ShouldRecoverImplLatency(const BeginFrameArgs& args) const { | |
| 769 DCHECK(!settings_.using_synchronous_renderer_compositor); | |
| 770 | |
| 771 // If we are swap throttled at the BeginFrame, that means the impl thread is | |
| 772 // very likely in a high latency mode. | |
| 773 bool impl_thread_is_likely_high_latency = state_machine_.SwapThrottled(); | |
| 774 if (!impl_thread_is_likely_high_latency) | |
| 775 return false; | |
| 776 | |
| 777 // The deadline may be in the past if our draw time is too long. | |
| 778 bool frame_time_is_before_deadline = args.frame_time < args.deadline; | |
| 779 | |
| 780 // When prioritizing impl thread latency, the deadline doesn't wait | |
| 781 // for the main thread. | |
| 782 if (state_machine_.impl_latency_takes_priority()) | |
| 783 return frame_time_is_before_deadline; | |
| 784 | |
| 785 // If we only have impl-side updates, the deadline doesn't wait for | |
| 786 // the main thread. | |
| 787 if (state_machine_.OnlyImplSideUpdatesExpected()) | |
| 788 return frame_time_is_before_deadline; | |
| 789 | |
| 790 // If the active tree hasn't been drawn at the BeginFrame, it means | |
| 791 // the main thread is in a high latency mode but was still | |
| 792 // fast enough to give us a new active tree before this BeginFrame. | |
| 793 if (state_machine_.active_tree_needs_first_draw()) | |
|
brianderson
2015/07/09 05:44:06
Hmm. I think there are a lot of issues with this c
brianderson
2015/07/09 17:55:37
Removed.
| |
| 794 return frame_time_is_before_deadline; | |
| 795 | |
| 796 // If we get here, we know the main thread is in a low-latency mode relative | |
| 797 // to the impl thread. In this case, only try to also recover impl thread | |
| 798 // latency if both the main and impl threads can run serially before the | |
| 799 // deadline. | |
| 800 return CanCommitAndActivateBeforeDeadline(args); | |
| 801 } | |
| 802 | |
| 803 bool Scheduler::CanCommitAndActivateBeforeDeadline( | |
| 804 const BeginFrameArgs& args) const { | |
| 747 // Check if the main thread computation and commit can be finished before the | 805 // Check if the main thread computation and commit can be finished before the |
| 748 // impl thread's deadline. | 806 // impl thread's deadline. |
| 749 base::TimeTicks estimated_draw_time = | 807 base::TimeTicks estimated_draw_time = |
| 750 args.frame_time + | 808 args.frame_time + |
| 751 compositor_timing_history_->BeginMainFrameToCommitDurationEstimate() + | 809 compositor_timing_history_->BeginMainFrameToCommitDurationEstimate() + |
| 752 compositor_timing_history_->CommitToReadyToActivateDurationEstimate() + | 810 compositor_timing_history_->CommitToReadyToActivateDurationEstimate() + |
| 753 compositor_timing_history_->ActivateDurationEstimate(); | 811 compositor_timing_history_->ActivateDurationEstimate(); |
| 754 | 812 |
| 755 TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | |
| 756 "CanCommitAndActivateBeforeDeadline", | |
| 757 "time_left_after_drawing_ms", | |
| 758 (args.deadline - estimated_draw_time).InMillisecondsF(), "state", | |
| 759 AsValue()); | |
| 760 | |
| 761 return estimated_draw_time < args.deadline; | 813 return estimated_draw_time < args.deadline; |
| 762 } | 814 } |
| 763 | 815 |
| 764 bool Scheduler::IsBeginMainFrameSentOrStarted() const { | 816 bool Scheduler::IsBeginMainFrameSentOrStarted() const { |
| 765 return (state_machine_.commit_state() == | 817 return (state_machine_.commit_state() == |
| 766 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || | 818 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || |
| 767 state_machine_.commit_state() == | 819 state_machine_.commit_state() == |
| 768 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); | 820 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); |
| 769 } | 821 } |
| 770 | 822 |
| 771 } // namespace cc | 823 } // namespace cc |
| OLD | NEW |