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_state_machine.h" | 5 #include "cc/scheduler/scheduler_state_machine.h" |
6 | 6 |
7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "base/debug/trace_event_argument.h" | 8 #include "base/debug/trace_event_argument.h" |
9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 29 matching lines...) Expand all Loading... |
40 can_draw_(false), | 40 can_draw_(false), |
41 has_pending_tree_(false), | 41 has_pending_tree_(false), |
42 pending_tree_is_ready_for_activation_(false), | 42 pending_tree_is_ready_for_activation_(false), |
43 active_tree_needs_first_draw_(false), | 43 active_tree_needs_first_draw_(false), |
44 did_commit_after_animating_(false), | 44 did_commit_after_animating_(false), |
45 did_create_and_initialize_first_output_surface_(false), | 45 did_create_and_initialize_first_output_surface_(false), |
46 impl_latency_takes_priority_(false), | 46 impl_latency_takes_priority_(false), |
47 skip_next_begin_main_frame_to_reduce_latency_(false), | 47 skip_next_begin_main_frame_to_reduce_latency_(false), |
48 skip_begin_main_frame_to_reduce_latency_(false), | 48 skip_begin_main_frame_to_reduce_latency_(false), |
49 continuous_painting_(false), | 49 continuous_painting_(false), |
50 impl_latency_takes_priority_on_battery_(false) { | 50 impl_latency_takes_priority_on_battery_(false), |
| 51 children_need_begin_frames_(false) { |
51 } | 52 } |
52 | 53 |
53 const char* SchedulerStateMachine::OutputSurfaceStateToString( | 54 const char* SchedulerStateMachine::OutputSurfaceStateToString( |
54 OutputSurfaceState state) { | 55 OutputSurfaceState state) { |
55 switch (state) { | 56 switch (state) { |
56 case OUTPUT_SURFACE_ACTIVE: | 57 case OUTPUT_SURFACE_ACTIVE: |
57 return "OUTPUT_SURFACE_ACTIVE"; | 58 return "OUTPUT_SURFACE_ACTIVE"; |
58 case OUTPUT_SURFACE_LOST: | 59 case OUTPUT_SURFACE_LOST: |
59 return "OUTPUT_SURFACE_LOST"; | 60 return "OUTPUT_SURFACE_LOST"; |
60 case OUTPUT_SURFACE_CREATING: | 61 case OUTPUT_SURFACE_CREATING: |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 impl_latency_takes_priority_); | 228 impl_latency_takes_priority_); |
228 state->SetBoolean("main_thread_is_in_high_latency_mode", | 229 state->SetBoolean("main_thread_is_in_high_latency_mode", |
229 MainThreadIsInHighLatencyMode()); | 230 MainThreadIsInHighLatencyMode()); |
230 state->SetBoolean("skip_begin_main_frame_to_reduce_latency", | 231 state->SetBoolean("skip_begin_main_frame_to_reduce_latency", |
231 skip_begin_main_frame_to_reduce_latency_); | 232 skip_begin_main_frame_to_reduce_latency_); |
232 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", | 233 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", |
233 skip_next_begin_main_frame_to_reduce_latency_); | 234 skip_next_begin_main_frame_to_reduce_latency_); |
234 state->SetBoolean("continuous_painting", continuous_painting_); | 235 state->SetBoolean("continuous_painting", continuous_painting_); |
235 state->SetBoolean("impl_latency_takes_priority_on_battery", | 236 state->SetBoolean("impl_latency_takes_priority_on_battery", |
236 impl_latency_takes_priority_on_battery_); | 237 impl_latency_takes_priority_on_battery_); |
| 238 state->SetBoolean("children_need_begin_frames", children_need_begin_frames_); |
237 state->EndDictionary(); | 239 state->EndDictionary(); |
238 } | 240 } |
239 | 241 |
240 void SchedulerStateMachine::AdvanceCurrentFrameNumber() { | 242 void SchedulerStateMachine::AdvanceCurrentFrameNumber() { |
241 current_frame_number_++; | 243 current_frame_number_++; |
242 | 244 |
243 // "Drain" the ManageTiles funnel. | 245 // "Drain" the ManageTiles funnel. |
244 if (manage_tiles_funnel_ > 0) | 246 if (manage_tiles_funnel_ > 0) |
245 manage_tiles_funnel_--; | 247 manage_tiles_funnel_--; |
246 | 248 |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
665 needs_manage_tiles_ = false; | 667 needs_manage_tiles_ = false; |
666 } | 668 } |
667 | 669 |
668 void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() { | 670 void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() { |
669 TRACE_EVENT_INSTANT0("cc", | 671 TRACE_EVENT_INSTANT0("cc", |
670 "Scheduler: SkipNextBeginMainFrameToReduceLatency", | 672 "Scheduler: SkipNextBeginMainFrameToReduceLatency", |
671 TRACE_EVENT_SCOPE_THREAD); | 673 TRACE_EVENT_SCOPE_THREAD); |
672 skip_next_begin_main_frame_to_reduce_latency_ = true; | 674 skip_next_begin_main_frame_to_reduce_latency_ = true; |
673 } | 675 } |
674 | 676 |
| 677 bool SchedulerStateMachine::BeginFrameNeededForChildren() const { |
| 678 if (HasInitializedOutputSurface()) |
| 679 return children_need_begin_frames_; |
| 680 |
| 681 return false; |
| 682 } |
| 683 |
675 bool SchedulerStateMachine::BeginFrameNeeded() const { | 684 bool SchedulerStateMachine::BeginFrameNeeded() const { |
| 685 if (SupportsProactiveBeginFrame()) { |
| 686 return (BeginFrameNeededToAnimateOrDraw() || |
| 687 BeginFrameNeededForChildren() || |
| 688 ProactiveBeginFrameWanted()); |
| 689 } |
| 690 |
676 // Proactive BeginFrames are bad for the synchronous compositor because we | 691 // Proactive BeginFrames are bad for the synchronous compositor because we |
677 // have to draw when we get the BeginFrame and could end up drawing many | 692 // have to draw when we get the BeginFrame and could end up drawing many |
678 // duplicate frames if our new frame isn't ready in time. | 693 // duplicate frames if our new frame isn't ready in time. |
679 // To poll for state with the synchronous compositor without having to draw, | 694 // To poll for state with the synchronous compositor without having to draw, |
680 // we rely on ShouldPollForAnticipatedDrawTriggers instead. | 695 // we rely on ShouldPollForAnticipatedDrawTriggers instead. |
681 if (!SupportsProactiveBeginFrame()) | 696 // Synchronous compositor doesn't have a browser. |
682 return BeginFrameNeededToAnimateOrDraw(); | 697 DCHECK(!children_need_begin_frames_); |
683 | 698 return BeginFrameNeededToAnimateOrDraw(); |
684 return BeginFrameNeededToAnimateOrDraw() || ProactiveBeginFrameWanted(); | |
685 } | 699 } |
686 | 700 |
687 bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const { | 701 bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const { |
688 // ShouldPollForAnticipatedDrawTriggers is what we use in place of | 702 // ShouldPollForAnticipatedDrawTriggers is what we use in place of |
689 // ProactiveBeginFrameWanted when we are using the synchronous | 703 // ProactiveBeginFrameWanted when we are using the synchronous |
690 // compositor. | 704 // compositor. |
691 if (!SupportsProactiveBeginFrame()) { | 705 if (!SupportsProactiveBeginFrame()) { |
692 return !BeginFrameNeededToAnimateOrDraw() && ProactiveBeginFrameWanted(); | 706 return !BeginFrameNeededToAnimateOrDraw() && ProactiveBeginFrameWanted(); |
693 } | 707 } |
694 | 708 |
695 // Non synchronous compositors should rely on | 709 // Non synchronous compositors should rely on |
696 // ProactiveBeginFrameWanted to poll for state instead. | 710 // ProactiveBeginFrameWanted to poll for state instead. |
697 return false; | 711 return false; |
698 } | 712 } |
699 | 713 |
700 // Note: If SupportsProactiveBeginFrame is false, the scheduler should poll | 714 // Note: If SupportsProactiveBeginFrame is false, the scheduler should poll |
701 // for changes in it's draw state so it can request a BeginFrame when it's | 715 // for changes in it's draw state so it can request a BeginFrame when it's |
702 // actually ready. | 716 // actually ready. |
703 bool SchedulerStateMachine::SupportsProactiveBeginFrame() const { | 717 bool SchedulerStateMachine::SupportsProactiveBeginFrame() const { |
704 // It is undesirable to proactively request BeginFrames if we are | 718 // It is undesirable to proactively request BeginFrames if we are |
705 // using a synchronous compositor because we *must* draw for every | 719 // using a synchronous compositor because we *must* draw for every |
706 // BeginFrame, which could cause duplicate draws. | 720 // BeginFrame, which could cause duplicate draws. |
707 return !settings_.using_synchronous_renderer_compositor; | 721 return !settings_.using_synchronous_renderer_compositor; |
708 } | 722 } |
709 | 723 |
| 724 void SchedulerStateMachine::SetChildrenNeedBeginFrames( |
| 725 bool children_need_begin_frames) { |
| 726 DCHECK(settings_.forward_begin_frames_to_children); |
| 727 children_need_begin_frames_ = children_need_begin_frames; |
| 728 } |
| 729 |
710 // These are the cases where we definitely (or almost definitely) have a | 730 // These are the cases where we definitely (or almost definitely) have a |
711 // new frame to animate and/or draw and can draw. | 731 // new frame to animate and/or draw and can draw. |
712 bool SchedulerStateMachine::BeginFrameNeededToAnimateOrDraw() const { | 732 bool SchedulerStateMachine::BeginFrameNeededToAnimateOrDraw() const { |
713 // The output surface is the provider of BeginImplFrames, so we are not going | 733 // The output surface is the provider of BeginImplFrames, so we are not going |
714 // to get them even if we ask for them. | 734 // to get them even if we ask for them. |
715 if (!HasInitializedOutputSurface()) | 735 if (!HasInitializedOutputSurface()) |
716 return false; | 736 return false; |
717 | 737 |
718 // The forced draw respects our normal draw scheduling, so we need to | 738 // The forced draw respects our normal draw scheduling, so we need to |
719 // request a BeginImplFrame for it. | 739 // request a BeginImplFrame for it. |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1043 static_cast<int>(begin_impl_frame_state_), | 1063 static_cast<int>(begin_impl_frame_state_), |
1044 static_cast<int>(commit_state_), | 1064 static_cast<int>(commit_state_), |
1045 has_pending_tree_ ? 'T' : 'F', | 1065 has_pending_tree_ ? 'T' : 'F', |
1046 pending_tree_is_ready_for_activation_ ? 'T' : 'F', | 1066 pending_tree_is_ready_for_activation_ ? 'T' : 'F', |
1047 active_tree_needs_first_draw_ ? 'T' : 'F', | 1067 active_tree_needs_first_draw_ ? 'T' : 'F', |
1048 max_pending_swaps_, | 1068 max_pending_swaps_, |
1049 pending_swaps_); | 1069 pending_swaps_); |
1050 } | 1070 } |
1051 | 1071 |
1052 } // namespace cc | 1072 } // namespace cc |
OLD | NEW |