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/format_macros.h" | 7 #include "base/format_macros.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
10 #include "base/trace_event/trace_event.h" | 10 #include "base/trace_event/trace_event.h" |
11 #include "base/trace_event/trace_event_argument.h" | 11 #include "base/trace_event/trace_event_argument.h" |
12 #include "base/values.h" | 12 #include "base/values.h" |
| 13 #include "cc/output/begin_frame_args.h" |
13 | 14 |
14 namespace cc { | 15 namespace cc { |
15 | 16 |
16 namespace { | 17 namespace { |
17 // Surfaces and CompositorTimingHistory don't support more than 1 pending swap. | 18 // Surfaces and CompositorTimingHistory don't support more than 1 pending swap. |
18 const int kMaxPendingSubmitFrames = 1; | 19 const int kMaxPendingSubmitFrames = 1; |
19 } // namespace | 20 } // namespace |
20 | 21 |
21 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) | 22 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) |
22 : settings_(settings), | 23 : settings_(settings), |
23 compositor_frame_sink_state_(COMPOSITOR_FRAME_SINK_NONE), | 24 compositor_frame_sink_state_(COMPOSITOR_FRAME_SINK_NONE), |
24 begin_impl_frame_state_(BEGIN_IMPL_FRAME_STATE_IDLE), | 25 begin_impl_frame_state_(BEGIN_IMPL_FRAME_STATE_IDLE), |
25 begin_main_frame_state_(BEGIN_MAIN_FRAME_STATE_IDLE), | 26 begin_main_frame_state_(BEGIN_MAIN_FRAME_STATE_IDLE), |
26 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE), | 27 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE), |
27 commit_count_(0), | 28 commit_count_(0), |
28 current_frame_number_(0), | 29 begin_frame_source_id_(0), |
29 last_frame_number_submit_performed_(-1), | 30 current_frame_number_(BeginFrameArgs::kStartingFrameNumber), |
30 last_frame_number_draw_performed_(-1), | 31 last_frame_number_submit_performed_(BeginFrameArgs::kInvalidFrameNumber), |
31 last_frame_number_begin_main_frame_sent_(-1), | 32 last_frame_number_draw_performed_(BeginFrameArgs::kInvalidFrameNumber), |
32 last_frame_number_invalidate_compositor_frame_sink_performed_(-1), | 33 last_frame_number_begin_main_frame_sent_( |
| 34 BeginFrameArgs::kInvalidFrameNumber), |
| 35 last_frame_number_invalidate_compositor_frame_sink_performed_( |
| 36 BeginFrameArgs::kInvalidFrameNumber), |
| 37 last_frame_number_pending_tree_was_fresh_( |
| 38 BeginFrameArgs::kInvalidFrameNumber), |
| 39 last_frame_number_active_tree_was_fresh_( |
| 40 BeginFrameArgs::kInvalidFrameNumber), |
| 41 last_frame_number_compositor_frame_was_fresh_( |
| 42 BeginFrameArgs::kInvalidFrameNumber), |
33 draw_funnel_(false), | 43 draw_funnel_(false), |
34 send_begin_main_frame_funnel_(true), | 44 send_begin_main_frame_funnel_(true), |
35 invalidate_compositor_frame_sink_funnel_(false), | 45 invalidate_compositor_frame_sink_funnel_(false), |
36 prepare_tiles_funnel_(0), | 46 prepare_tiles_funnel_(0), |
37 consecutive_checkerboard_animations_(0), | 47 consecutive_checkerboard_animations_(0), |
38 pending_submit_frames_(0), | 48 pending_submit_frames_(0), |
39 submit_frames_with_current_compositor_frame_sink_(0), | 49 submit_frames_with_current_compositor_frame_sink_(0), |
40 needs_redraw_(false), | 50 needs_redraw_(false), |
41 needs_prepare_tiles_(false), | 51 needs_prepare_tiles_(false), |
42 needs_begin_main_frame_(false), | 52 needs_begin_main_frame_(false), |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 BeginMainFrameStateToString(begin_main_frame_state_)); | 210 BeginMainFrameStateToString(begin_main_frame_state_)); |
201 state->SetString( | 211 state->SetString( |
202 "compositor_frame_sink_state_", | 212 "compositor_frame_sink_state_", |
203 CompositorFrameSinkStateToString(compositor_frame_sink_state_)); | 213 CompositorFrameSinkStateToString(compositor_frame_sink_state_)); |
204 state->SetString("forced_redraw_state", | 214 state->SetString("forced_redraw_state", |
205 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_)); | 215 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_)); |
206 state->EndDictionary(); | 216 state->EndDictionary(); |
207 | 217 |
208 state->BeginDictionary("minor_state"); | 218 state->BeginDictionary("minor_state"); |
209 state->SetInteger("commit_count", commit_count_); | 219 state->SetInteger("commit_count", commit_count_); |
| 220 state->SetInteger("begin_frame_source_id", begin_frame_source_id_); |
210 state->SetInteger("current_frame_number", current_frame_number_); | 221 state->SetInteger("current_frame_number", current_frame_number_); |
211 state->SetInteger("last_frame_number_submit_performed", | 222 state->SetInteger("last_frame_number_submit_performed", |
212 last_frame_number_submit_performed_); | 223 last_frame_number_submit_performed_); |
213 state->SetInteger("last_frame_number_draw_performed", | 224 state->SetInteger("last_frame_number_draw_performed", |
214 last_frame_number_draw_performed_); | 225 last_frame_number_draw_performed_); |
215 state->SetInteger("last_frame_number_begin_main_frame_sent", | 226 state->SetInteger("last_frame_number_begin_main_frame_sent", |
216 last_frame_number_begin_main_frame_sent_); | 227 last_frame_number_begin_main_frame_sent_); |
| 228 state->SetInteger("last_frame_number_pending_tree_was_fresh", |
| 229 last_frame_number_pending_tree_was_fresh_); |
| 230 state->SetInteger("last_frame_number_active_tree_was_fresh", |
| 231 last_frame_number_active_tree_was_fresh_); |
| 232 state->SetInteger("last_frame_number_compositor_frame_was_fresh", |
| 233 last_frame_number_compositor_frame_was_fresh_); |
217 state->SetBoolean("funnel: draw_funnel", draw_funnel_); | 234 state->SetBoolean("funnel: draw_funnel", draw_funnel_); |
218 state->SetBoolean("funnel: send_begin_main_frame_funnel", | 235 state->SetBoolean("funnel: send_begin_main_frame_funnel", |
219 send_begin_main_frame_funnel_); | 236 send_begin_main_frame_funnel_); |
220 state->SetInteger("funnel: prepare_tiles_funnel", prepare_tiles_funnel_); | 237 state->SetInteger("funnel: prepare_tiles_funnel", prepare_tiles_funnel_); |
221 state->SetBoolean("funnel: invalidate_compositor_frame_sink_funnel", | 238 state->SetBoolean("funnel: invalidate_compositor_frame_sink_funnel", |
222 invalidate_compositor_frame_sink_funnel_); | 239 invalidate_compositor_frame_sink_funnel_); |
223 state->SetInteger("consecutive_checkerboard_animations", | 240 state->SetInteger("consecutive_checkerboard_animations", |
224 consecutive_checkerboard_animations_); | 241 consecutive_checkerboard_animations_); |
225 state->SetInteger("pending_submit_frames_", pending_submit_frames_); | 242 state->SetInteger("pending_submit_frames_", pending_submit_frames_); |
226 state->SetInteger("submit_frames_with_current_compositor_frame_sink", | 243 state->SetInteger("submit_frames_with_current_compositor_frame_sink", |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 } | 599 } |
583 | 600 |
584 void SchedulerStateMachine::WillCommit(bool commit_has_no_updates) { | 601 void SchedulerStateMachine::WillCommit(bool commit_has_no_updates) { |
585 DCHECK(!has_pending_tree_ || | 602 DCHECK(!has_pending_tree_ || |
586 (settings_.main_frame_before_activation_enabled && | 603 (settings_.main_frame_before_activation_enabled && |
587 commit_has_no_updates)); | 604 commit_has_no_updates)); |
588 commit_count_++; | 605 commit_count_++; |
589 last_commit_had_no_updates_ = commit_has_no_updates; | 606 last_commit_had_no_updates_ = commit_has_no_updates; |
590 begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_IDLE; | 607 begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_IDLE; |
591 | 608 |
592 if (!commit_has_no_updates) { | 609 if (commit_has_no_updates) { |
593 // Pending tree only exists if commit had updates. | 610 // Pending tree might still exist from prior commit. |
| 611 if (has_pending_tree_) { |
| 612 DCHECK(settings_.main_frame_before_activation_enabled); |
| 613 last_frame_number_pending_tree_was_fresh_ = |
| 614 last_frame_number_begin_main_frame_sent_; |
| 615 } else { |
| 616 last_frame_number_active_tree_was_fresh_ = |
| 617 last_frame_number_begin_main_frame_sent_; |
| 618 } |
| 619 } else { |
| 620 // We have a new pending tree. |
594 has_pending_tree_ = true; | 621 has_pending_tree_ = true; |
595 pending_tree_is_ready_for_activation_ = false; | 622 pending_tree_is_ready_for_activation_ = false; |
| 623 last_frame_number_pending_tree_was_fresh_ = |
| 624 last_frame_number_begin_main_frame_sent_; |
596 wait_for_ready_to_draw_ = settings_.commit_to_active_tree; | 625 wait_for_ready_to_draw_ = settings_.commit_to_active_tree; |
597 } | 626 } |
598 | 627 |
599 // Update state related to forced draws. | 628 // Update state related to forced draws. |
600 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) { | 629 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) { |
601 forced_redraw_state_ = has_pending_tree_ | 630 forced_redraw_state_ = has_pending_tree_ |
602 ? FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION | 631 ? FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION |
603 : FORCED_REDRAW_STATE_WAITING_FOR_DRAW; | 632 : FORCED_REDRAW_STATE_WAITING_FOR_DRAW; |
604 } | 633 } |
605 | 634 |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
817 return true; | 846 return true; |
818 | 847 |
819 // If the last commit was aborted because of early out (no updates), we should | 848 // If the last commit was aborted because of early out (no updates), we should |
820 // still want a begin frame in case there is a commit coming again. | 849 // still want a begin frame in case there is a commit coming again. |
821 if (last_commit_had_no_updates_) | 850 if (last_commit_had_no_updates_) |
822 return true; | 851 return true; |
823 | 852 |
824 return false; | 853 return false; |
825 } | 854 } |
826 | 855 |
827 void SchedulerStateMachine::OnBeginImplFrame() { | 856 void SchedulerStateMachine::OnBeginImplFrame(uint64_t source_id, |
| 857 uint64_t sequence_number) { |
| 858 if (source_id != begin_frame_source_id_) { |
| 859 begin_frame_source_id_ = source_id; |
| 860 current_frame_number_ = sequence_number; |
| 861 |
| 862 // Consider us up to date up to the previous BeginFrame. |
| 863 DCHECK_LT(BeginFrameArgs::kInvalidFrameNumber, current_frame_number_); |
| 864 last_frame_number_active_tree_was_fresh_ = current_frame_number_ - 1; |
| 865 last_frame_number_pending_tree_was_fresh_ = |
| 866 last_frame_number_active_tree_was_fresh_; |
| 867 last_frame_number_compositor_frame_was_fresh_ = |
| 868 last_frame_number_active_tree_was_fresh_; |
| 869 } |
| 870 |
| 871 DCHECK_GE(sequence_number, current_frame_number_); |
| 872 |
828 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME; | 873 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME; |
829 current_frame_number_++; | 874 current_frame_number_ = sequence_number; |
830 | 875 |
831 last_commit_had_no_updates_ = false; | 876 last_commit_had_no_updates_ = false; |
832 did_draw_in_last_frame_ = false; | 877 did_draw_in_last_frame_ = false; |
833 did_submit_in_last_frame_ = false; | 878 did_submit_in_last_frame_ = false; |
834 needs_one_begin_impl_frame_ = false; | 879 needs_one_begin_impl_frame_ = false; |
835 | 880 |
836 // Clear funnels for any actions we perform during the frame. | 881 // Clear funnels for any actions we perform during the frame. |
837 send_begin_main_frame_funnel_ = false; | 882 send_begin_main_frame_funnel_ = false; |
838 invalidate_compositor_frame_sink_funnel_ = false; | 883 invalidate_compositor_frame_sink_funnel_ = false; |
839 | 884 |
840 // "Drain" the PrepareTiles funnel. | 885 // "Drain" the PrepareTiles funnel. |
841 if (prepare_tiles_funnel_ > 0) | 886 if (prepare_tiles_funnel_ > 0) |
842 prepare_tiles_funnel_--; | 887 prepare_tiles_funnel_--; |
| 888 |
| 889 // Update frame numbers for freshness if no updates are requested. |
| 890 if (!needs_begin_main_frame_) { |
| 891 if (has_pending_tree_) { |
| 892 last_frame_number_pending_tree_was_fresh_ = current_frame_number_; |
| 893 } else { |
| 894 last_frame_number_active_tree_was_fresh_ = current_frame_number_; |
| 895 |
| 896 if (!needs_redraw_) |
| 897 last_frame_number_compositor_frame_was_fresh_ = current_frame_number_; |
| 898 } |
| 899 } |
843 } | 900 } |
844 | 901 |
845 void SchedulerStateMachine::OnBeginImplFrameDeadline() { | 902 void SchedulerStateMachine::OnBeginImplFrameDeadline() { |
846 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; | 903 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; |
847 | 904 |
848 // Clear funnels for any actions we perform during the deadline. | 905 // Clear funnels for any actions we perform during the deadline. |
849 draw_funnel_ = false; | 906 draw_funnel_ = false; |
850 | 907 |
851 // Allow one PrepareTiles per draw for synchronous compositor. | 908 // Allow one PrepareTiles per draw for synchronous compositor. |
852 if (settings_.using_synchronous_renderer_compositor) { | 909 if (settings_.using_synchronous_renderer_compositor) { |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
978 void SchedulerStateMachine::DidSubmitCompositorFrame() { | 1035 void SchedulerStateMachine::DidSubmitCompositorFrame() { |
979 TRACE_EVENT_ASYNC_BEGIN1("cc", "Scheduler:pending_submit_frames", this, | 1036 TRACE_EVENT_ASYNC_BEGIN1("cc", "Scheduler:pending_submit_frames", this, |
980 "pending_frames", pending_submit_frames_); | 1037 "pending_frames", pending_submit_frames_); |
981 DCHECK_LT(pending_submit_frames_, kMaxPendingSubmitFrames); | 1038 DCHECK_LT(pending_submit_frames_, kMaxPendingSubmitFrames); |
982 | 1039 |
983 pending_submit_frames_++; | 1040 pending_submit_frames_++; |
984 submit_frames_with_current_compositor_frame_sink_++; | 1041 submit_frames_with_current_compositor_frame_sink_++; |
985 | 1042 |
986 did_submit_in_last_frame_ = true; | 1043 did_submit_in_last_frame_ = true; |
987 last_frame_number_submit_performed_ = current_frame_number_; | 1044 last_frame_number_submit_performed_ = current_frame_number_; |
| 1045 last_frame_number_compositor_frame_was_fresh_ = |
| 1046 last_frame_number_active_tree_was_fresh_; |
988 } | 1047 } |
989 | 1048 |
990 void SchedulerStateMachine::DidReceiveCompositorFrameAck() { | 1049 void SchedulerStateMachine::DidReceiveCompositorFrameAck() { |
991 TRACE_EVENT_ASYNC_END1("cc", "Scheduler:pending_submit_frames", this, | 1050 TRACE_EVENT_ASYNC_END1("cc", "Scheduler:pending_submit_frames", this, |
992 "pending_frames", pending_submit_frames_); | 1051 "pending_frames", pending_submit_frames_); |
993 pending_submit_frames_--; | 1052 pending_submit_frames_--; |
994 } | 1053 } |
995 | 1054 |
996 void SchedulerStateMachine::SetTreePrioritiesAndScrollState( | 1055 void SchedulerStateMachine::SetTreePrioritiesAndScrollState( |
997 TreePriority tree_priority, | 1056 TreePriority tree_priority, |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1112 case COMPOSITOR_FRAME_SINK_ACTIVE: | 1171 case COMPOSITOR_FRAME_SINK_ACTIVE: |
1113 case COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_COMMIT: | 1172 case COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_COMMIT: |
1114 case COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_ACTIVATION: | 1173 case COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_ACTIVATION: |
1115 return true; | 1174 return true; |
1116 } | 1175 } |
1117 NOTREACHED(); | 1176 NOTREACHED(); |
1118 return false; | 1177 return false; |
1119 } | 1178 } |
1120 | 1179 |
1121 } // namespace cc | 1180 } // namespace cc |
OLD | NEW |