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

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

Issue 218633010: cc: Handle retroactive BeginFrames in the Scheduler. (Closed) Base URL: http://git.chromium.org/chromium/src.git@compositorVsyncDisable
Patch Set: fix comment typo Created 6 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
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_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/format_macros.h" 8 #include "base/format_macros.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/strings/stringprintf.h" 10 #include "base/strings/stringprintf.h"
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 major_state->SetString( 179 major_state->SetString(
180 "forced_redraw_state", 180 "forced_redraw_state",
181 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_)); 181 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_));
182 major_state->SetString("readback_state", 182 major_state->SetString("readback_state",
183 SynchronousReadbackStateToString(readback_state_)); 183 SynchronousReadbackStateToString(readback_state_));
184 state->Set("major_state", major_state.release()); 184 state->Set("major_state", major_state.release());
185 185
186 scoped_ptr<base::DictionaryValue> timestamps_state(new base::DictionaryValue); 186 scoped_ptr<base::DictionaryValue> timestamps_state(new base::DictionaryValue);
187 base::TimeTicks now = gfx::FrameTime::Now(); 187 base::TimeTicks now = gfx::FrameTime::Now();
188 timestamps_state->SetDouble( 188 timestamps_state->SetDouble(
189 "0_interval", 189 "0_interval", begin_impl_frame_args_.interval.InMicroseconds() / 1000.0L);
190 last_begin_impl_frame_args_.interval.InMicroseconds() / 1000.0L);
191 timestamps_state->SetDouble( 190 timestamps_state->SetDouble(
192 "1_now_to_deadline", 191 "1_now_to_deadline",
193 (last_begin_impl_frame_args_.deadline - now).InMicroseconds() / 1000.0L); 192 (begin_impl_frame_args_.deadline - now).InMicroseconds() / 1000.0L);
194 timestamps_state->SetDouble( 193 timestamps_state->SetDouble(
195 "2_frame_time_to_now", 194 "2_frame_time_to_now",
196 (now - last_begin_impl_frame_args_.frame_time).InMicroseconds() / 195 (now - begin_impl_frame_args_.frame_time).InMicroseconds() / 1000.0L);
197 1000.0L);
198 timestamps_state->SetDouble( 196 timestamps_state->SetDouble(
199 "3_frame_time_to_deadline", 197 "3_frame_time_to_deadline",
200 (last_begin_impl_frame_args_.deadline - 198 (begin_impl_frame_args_.deadline - begin_impl_frame_args_.frame_time)
201 last_begin_impl_frame_args_.frame_time).InMicroseconds() / 199 .InMicroseconds() /
202 1000.0L); 200 1000.0L);
203 timestamps_state->SetDouble( 201 timestamps_state->SetDouble(
204 "4_now", (now - base::TimeTicks()).InMicroseconds() / 1000.0L); 202 "4_now", (now - base::TimeTicks()).InMicroseconds() / 1000.0L);
205 timestamps_state->SetDouble( 203 timestamps_state->SetDouble(
206 "5_frame_time", 204 "5_frame_time",
207 (last_begin_impl_frame_args_.frame_time - base::TimeTicks()) 205 (begin_impl_frame_args_.frame_time - base::TimeTicks()).InMicroseconds() /
208 .InMicroseconds() /
209 1000.0L); 206 1000.0L);
210 timestamps_state->SetDouble( 207 timestamps_state->SetDouble(
211 "6_deadline", 208 "6_deadline",
212 (last_begin_impl_frame_args_.deadline - base::TimeTicks()) 209 (begin_impl_frame_args_.deadline - base::TimeTicks()).InMicroseconds() /
213 .InMicroseconds() /
214 1000.0L); 210 1000.0L);
215 state->Set("major_timestamps_in_ms", timestamps_state.release()); 211 state->Set("major_timestamps_in_ms", timestamps_state.release());
216 212
217 scoped_ptr<base::DictionaryValue> minor_state(new base::DictionaryValue); 213 scoped_ptr<base::DictionaryValue> minor_state(new base::DictionaryValue);
218 minor_state->SetInteger("commit_count", commit_count_); 214 minor_state->SetInteger("commit_count", commit_count_);
219 minor_state->SetInteger("current_frame_number", current_frame_number_); 215 minor_state->SetInteger("current_frame_number", current_frame_number_);
220 216
221 minor_state->SetInteger("last_frame_number_swap_performed", 217 minor_state->SetInteger("last_frame_number_swap_performed",
222 last_frame_number_swap_performed_); 218 last_frame_number_swap_performed_);
223 minor_state->SetInteger( 219 minor_state->SetInteger(
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 // We want to start the first commit after we get a new output surface ASAP. 449 // We want to start the first commit after we get a new output surface ASAP.
454 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) 450 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT)
455 return true; 451 return true;
456 452
457 // We should not send BeginMainFrame while we are in 453 // We should not send BeginMainFrame while we are in
458 // BEGIN_IMPL_FRAME_STATE_IDLE since we might have new 454 // BEGIN_IMPL_FRAME_STATE_IDLE since we might have new
459 // user input arriving soon. 455 // user input arriving soon.
460 // TODO(brianderson): Allow sending BeginMainFrame while idle when the main 456 // TODO(brianderson): Allow sending BeginMainFrame while idle when the main
461 // thread isn't consuming user input. 457 // thread isn't consuming user input.
462 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE && 458 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE &&
463 BeginImplFrameNeeded()) 459 BeginFrameNeeded())
464 return false; 460 return false;
465 461
466 // We need a new commit for the forced redraw. This honors the 462 // We need a new commit for the forced redraw. This honors the
467 // single commit per interval because the result will be swapped to screen. 463 // single commit per interval because the result will be swapped to screen.
468 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) 464 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT)
469 return true; 465 return true;
470 466
471 // After this point, we only start a commit once per frame. 467 // After this point, we only start a commit once per frame.
472 if (HasSentBeginMainFrameThisFrame()) 468 if (HasSentBeginMainFrameThisFrame())
473 return false; 469 return false;
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 } 756 }
761 757
762 void SchedulerStateMachine::UpdateStateOnManageTiles() { 758 void SchedulerStateMachine::UpdateStateOnManageTiles() {
763 needs_manage_tiles_ = false; 759 needs_manage_tiles_ = false;
764 } 760 }
765 761
766 void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() { 762 void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() {
767 skip_next_begin_main_frame_to_reduce_latency_ = true; 763 skip_next_begin_main_frame_to_reduce_latency_ = true;
768 } 764 }
769 765
770 bool SchedulerStateMachine::BeginImplFrameNeeded() const { 766 bool SchedulerStateMachine::BeginFrameNeeded() const {
771 // Proactive BeginImplFrames are bad for the synchronous compositor because we 767 // Proactive BeginFrames are bad for the synchronous compositor because we
772 // have to draw when we get the BeginImplFrame and could end up drawing many 768 // have to draw when we get the BeginFrame and could end up drawing many
773 // duplicate frames if our new frame isn't ready in time. 769 // duplicate frames if our new frame isn't ready in time.
774 // To poll for state with the synchronous compositor without having to draw, 770 // To poll for state with the synchronous compositor without having to draw,
775 // we rely on ShouldPollForAnticipatedDrawTriggers instead. 771 // we rely on ShouldPollForAnticipatedDrawTriggers instead.
776 if (!SupportsProactiveBeginImplFrame()) 772 if (!SupportsProactiveBeginFrame())
777 return BeginImplFrameNeededToDraw(); 773 return BeginFrameNeededToDraw();
778 774
779 return BeginImplFrameNeededToDraw() || 775 return BeginFrameNeededToDraw() || ProactiveBeginFrameWanted();
780 ProactiveBeginImplFrameWanted();
781 } 776 }
782 777
783 bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const { 778 bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const {
784 // ShouldPollForAnticipatedDrawTriggers is what we use in place of 779 // ShouldPollForAnticipatedDrawTriggers is what we use in place of
785 // ProactiveBeginImplFrameWanted when we are using the synchronous 780 // ProactiveBeginFrameWanted when we are using the synchronous
786 // compositor. 781 // compositor.
787 if (!SupportsProactiveBeginImplFrame()) { 782 if (!SupportsProactiveBeginFrame()) {
788 return !BeginImplFrameNeededToDraw() && 783 return !BeginFrameNeededToDraw() && ProactiveBeginFrameWanted();
789 ProactiveBeginImplFrameWanted();
790 } 784 }
791 785
792 // Non synchronous compositors should rely on 786 // Non synchronous compositors should rely on
793 // ProactiveBeginImplFrameWanted to poll for state instead. 787 // ProactiveBeginFrameWanted to poll for state instead.
794 return false; 788 return false;
795 } 789 }
796 790
797 bool SchedulerStateMachine::SupportsProactiveBeginImplFrame() const { 791 bool SchedulerStateMachine::SupportsProactiveBeginFrame() const {
798 // Both the synchronous compositor and disabled vsync settings 792 // Both the synchronous compositor and disabled vsync settings
799 // make it undesirable to proactively request BeginImplFrames. 793 // make it undesirable to proactively request BeginImplFrames.
800 // If this is true, the scheduler should poll. 794 // If this is true, the scheduler should poll.
801 return !settings_.using_synchronous_renderer_compositor && 795 return !settings_.using_synchronous_renderer_compositor &&
802 settings_.throttle_frame_production; 796 settings_.throttle_frame_production;
803 } 797 }
804 798
805 // These are the cases where we definitely (or almost definitely) have a 799 // These are the cases where we definitely (or almost definitely) have a
806 // new frame to draw and can draw. 800 // new frame to draw and can draw.
807 bool SchedulerStateMachine::BeginImplFrameNeededToDraw() const { 801 bool SchedulerStateMachine::BeginFrameNeededToDraw() const {
808 // The output surface is the provider of BeginImplFrames, so we are not going 802 // The output surface is the provider of BeginImplFrames, so we are not going
809 // to get them even if we ask for them. 803 // to get them even if we ask for them.
810 if (!HasInitializedOutputSurface()) 804 if (!HasInitializedOutputSurface())
811 return false; 805 return false;
812 806
813 // If we can't draw, don't tick until we are notified that we can draw again. 807 // If we can't draw, don't tick until we are notified that we can draw again.
814 if (!can_draw_) 808 if (!can_draw_)
815 return false; 809 return false;
816 810
817 // The forced draw respects our normal draw scheduling, so we need to 811 // The forced draw respects our normal draw scheduling, so we need to
(...skipping 10 matching lines...) Expand all
828 // additional visible tiles. 822 // additional visible tiles.
829 if (swap_used_incomplete_tile_) 823 if (swap_used_incomplete_tile_)
830 return true; 824 return true;
831 825
832 return needs_redraw_; 826 return needs_redraw_;
833 } 827 }
834 828
835 // These are cases where we are very likely to draw soon, but might not 829 // These are cases where we are very likely to draw soon, but might not
836 // actually have a new frame to draw when we receive the next BeginImplFrame. 830 // actually have a new frame to draw when we receive the next BeginImplFrame.
837 // Proactively requesting the BeginImplFrame helps hide the round trip latency 831 // Proactively requesting the BeginImplFrame helps hide the round trip latency
838 // of the SetNeedsBeginImplFrame request that has to go to the Browser. 832 // of the SetNeedsBeginFrame request that has to go to the Browser.
839 bool SchedulerStateMachine::ProactiveBeginImplFrameWanted() const { 833 bool SchedulerStateMachine::ProactiveBeginFrameWanted() const {
840 // The output surface is the provider of BeginImplFrames, 834 // The output surface is the provider of BeginImplFrames,
841 // so we are not going to get them even if we ask for them. 835 // so we are not going to get them even if we ask for them.
842 if (!HasInitializedOutputSurface()) 836 if (!HasInitializedOutputSurface())
843 return false; 837 return false;
844 838
845 // Do not be proactive when invisible. 839 // Do not be proactive when invisible.
846 if (!visible_) 840 if (!visible_)
847 return false; 841 return false;
848 842
849 // We should proactively request a BeginImplFrame if a commit is pending 843 // We should proactively request a BeginImplFrame if a commit is pending
850 // because we will want to draw if the commit completes quickly. 844 // because we will want to draw if the commit completes quickly.
851 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE) 845 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE)
852 return true; 846 return true;
853 847
854 // If the pending tree activates quickly, we'll want a BeginImplFrame soon 848 // If the pending tree activates quickly, we'll want a BeginImplFrame soon
855 // to draw the new active tree. 849 // to draw the new active tree.
856 if (has_pending_tree_) 850 if (has_pending_tree_)
857 return true; 851 return true;
858 852
859 // Changing priorities may allow us to activate (given the new priorities), 853 // Changing priorities may allow us to activate (given the new priorities),
860 // which may result in a new frame. 854 // which may result in a new frame.
861 if (needs_manage_tiles_) 855 if (needs_manage_tiles_)
862 return true; 856 return true;
863 857
864 // If we just swapped, it's likely that we are going to produce another 858 // If we just swapped, it's likely that we are going to produce another
865 // frame soon. This helps avoid negative glitches in our 859 // frame soon. This helps avoid negative glitches in our
866 // SetNeedsBeginImplFrame requests, which may propagate to the BeginImplFrame 860 // SetNeedsBeginFrame requests, which may propagate to the BeginImplFrame
867 // provider and get sampled at an inopportune time, delaying the next 861 // provider and get sampled at an inopportune time, delaying the next
868 // BeginImplFrame. 862 // BeginImplFrame.
869 if (last_frame_number_swap_performed_ == current_frame_number_) 863 if (last_frame_number_swap_performed_ == current_frame_number_)
870 return true; 864 return true;
871 865
872 return false; 866 return false;
873 } 867 }
874 868
875 void SchedulerStateMachine::OnBeginImplFrame(const BeginFrameArgs& args) { 869 void SchedulerStateMachine::OnBeginImplFrame(const BeginFrameArgs& args) {
876 AdvanceCurrentFrameNumber(); 870 AdvanceCurrentFrameNumber();
877 last_begin_impl_frame_args_ = args; 871 begin_impl_frame_args_ = args;
878 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE) << *AsValue(); 872 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE) << *AsValue();
879 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING; 873 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING;
880 } 874 }
881 875
882 void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() { 876 void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() {
883 DCHECK_EQ(begin_impl_frame_state_, 877 DCHECK_EQ(begin_impl_frame_state_,
884 BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) 878 BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING)
885 << *AsValue(); 879 << *AsValue();
886 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME; 880 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME;
887 } 881 }
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
1159 case OUTPUT_SURFACE_ACTIVE: 1153 case OUTPUT_SURFACE_ACTIVE:
1160 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: 1154 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT:
1161 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: 1155 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION:
1162 return true; 1156 return true;
1163 } 1157 }
1164 NOTREACHED(); 1158 NOTREACHED();
1165 return false; 1159 return false;
1166 } 1160 }
1167 1161
1168 } // namespace cc 1162 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/scheduler_state_machine.h ('k') | cc/scheduler/scheduler_state_machine_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698