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

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: sami's comments; rebase 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 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 major_state->SetString( 197 major_state->SetString(
198 "forced_redraw_state", 198 "forced_redraw_state",
199 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_)); 199 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_));
200 major_state->SetString("readback_state", 200 major_state->SetString("readback_state",
201 SynchronousReadbackStateToString(readback_state_)); 201 SynchronousReadbackStateToString(readback_state_));
202 state->Set("major_state", major_state.release()); 202 state->Set("major_state", major_state.release());
203 203
204 scoped_ptr<base::DictionaryValue> timestamps_state(new base::DictionaryValue); 204 scoped_ptr<base::DictionaryValue> timestamps_state(new base::DictionaryValue);
205 base::TimeTicks now = gfx::FrameTime::Now(); 205 base::TimeTicks now = gfx::FrameTime::Now();
206 timestamps_state->SetDouble( 206 timestamps_state->SetDouble(
207 "0_interval", 207 "0_interval", begin_impl_frame_args_.interval.InMicroseconds() / 1000.0L);
208 last_begin_impl_frame_args_.interval.InMicroseconds() / 1000.0L);
209 timestamps_state->SetDouble( 208 timestamps_state->SetDouble(
210 "1_now_to_deadline", 209 "1_now_to_deadline",
211 (last_begin_impl_frame_args_.deadline - now).InMicroseconds() / 1000.0L); 210 (begin_impl_frame_args_.deadline - now).InMicroseconds() / 1000.0L);
212 timestamps_state->SetDouble( 211 timestamps_state->SetDouble(
213 "2_frame_time_to_now", 212 "2_frame_time_to_now",
214 (now - last_begin_impl_frame_args_.frame_time).InMicroseconds() / 213 (now - begin_impl_frame_args_.frame_time).InMicroseconds() / 1000.0L);
215 1000.0L);
216 timestamps_state->SetDouble( 214 timestamps_state->SetDouble(
217 "3_frame_time_to_deadline", 215 "3_frame_time_to_deadline",
218 (last_begin_impl_frame_args_.deadline - 216 (begin_impl_frame_args_.deadline - begin_impl_frame_args_.frame_time)
219 last_begin_impl_frame_args_.frame_time).InMicroseconds() / 217 .InMicroseconds() /
220 1000.0L); 218 1000.0L);
221 timestamps_state->SetDouble( 219 timestamps_state->SetDouble(
222 "4_now", (now - base::TimeTicks()).InMicroseconds() / 1000.0L); 220 "4_now", (now - base::TimeTicks()).InMicroseconds() / 1000.0L);
223 timestamps_state->SetDouble( 221 timestamps_state->SetDouble(
224 "5_frame_time", 222 "5_frame_time",
225 (last_begin_impl_frame_args_.frame_time - base::TimeTicks()) 223 (begin_impl_frame_args_.frame_time - base::TimeTicks()).InMicroseconds() /
226 .InMicroseconds() /
227 1000.0L); 224 1000.0L);
228 timestamps_state->SetDouble( 225 timestamps_state->SetDouble(
229 "6_deadline", 226 "6_deadline",
230 (last_begin_impl_frame_args_.deadline - base::TimeTicks()) 227 (begin_impl_frame_args_.deadline - base::TimeTicks()).InMicroseconds() /
231 .InMicroseconds() /
232 1000.0L); 228 1000.0L);
233 state->Set("major_timestamps_in_ms", timestamps_state.release()); 229 state->Set("major_timestamps_in_ms", timestamps_state.release());
234 230
235 scoped_ptr<base::DictionaryValue> minor_state(new base::DictionaryValue); 231 scoped_ptr<base::DictionaryValue> minor_state(new base::DictionaryValue);
236 minor_state->SetInteger("commit_count", commit_count_); 232 minor_state->SetInteger("commit_count", commit_count_);
237 minor_state->SetInteger("current_frame_number", current_frame_number_); 233 minor_state->SetInteger("current_frame_number", current_frame_number_);
238 234
239 minor_state->SetInteger("last_frame_number_swap_performed", 235 minor_state->SetInteger("last_frame_number_swap_performed",
240 last_frame_number_swap_performed_); 236 last_frame_number_swap_performed_);
241 minor_state->SetInteger( 237 minor_state->SetInteger(
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 // We want to start the first commit after we get a new output surface ASAP. 483 // We want to start the first commit after we get a new output surface ASAP.
488 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) 484 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT)
489 return true; 485 return true;
490 486
491 // We should not send BeginMainFrame while we are in 487 // We should not send BeginMainFrame while we are in
492 // BEGIN_IMPL_FRAME_STATE_IDLE since we might have new 488 // BEGIN_IMPL_FRAME_STATE_IDLE since we might have new
493 // user input arriving soon. 489 // user input arriving soon.
494 // TODO(brianderson): Allow sending BeginMainFrame while idle when the main 490 // TODO(brianderson): Allow sending BeginMainFrame while idle when the main
495 // thread isn't consuming user input. 491 // thread isn't consuming user input.
496 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE && 492 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE &&
497 BeginImplFrameNeeded()) 493 BeginFrameNeeded())
498 return false; 494 return false;
499 495
500 // We need a new commit for the forced redraw. This honors the 496 // We need a new commit for the forced redraw. This honors the
501 // single commit per interval because the result will be swapped to screen. 497 // single commit per interval because the result will be swapped to screen.
502 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) 498 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT)
503 return true; 499 return true;
504 500
505 // After this point, we only start a commit once per frame. 501 // After this point, we only start a commit once per frame.
506 if (HasSentBeginMainFrameThisFrame()) 502 if (HasSentBeginMainFrameThisFrame())
507 return false; 503 return false;
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() { 802 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() {
807 DCHECK(!main_thread_needs_layer_textures_); 803 DCHECK(!main_thread_needs_layer_textures_);
808 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD); 804 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD);
809 main_thread_needs_layer_textures_ = true; 805 main_thread_needs_layer_textures_ = true;
810 } 806 }
811 807
812 void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() { 808 void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() {
813 skip_next_begin_main_frame_to_reduce_latency_ = true; 809 skip_next_begin_main_frame_to_reduce_latency_ = true;
814 } 810 }
815 811
816 bool SchedulerStateMachine::BeginImplFrameNeeded() const { 812 bool SchedulerStateMachine::BeginFrameNeeded() const {
817 // Proactive BeginImplFrames are bad for the synchronous compositor because we 813 // Proactive BeginFrames are bad for the synchronous compositor because we
818 // have to draw when we get the BeginImplFrame and could end up drawing many 814 // have to draw when we get the BeginFrame and could end up drawing many
819 // duplicate frames if our new frame isn't ready in time. 815 // duplicate frames if our new frame isn't ready in time.
820 // To poll for state with the synchronous compositor without having to draw, 816 // To poll for state with the synchronous compositor without having to draw,
821 // we rely on ShouldPollForAnticipatedDrawTriggers instead. 817 // we rely on ShouldPollForAnticipatedDrawTriggers instead.
822 if (!SupportsProactiveBeginImplFrame()) 818 if (!SupportsProactiveBeginFrame())
823 return BeginImplFrameNeededToDraw(); 819 return BeginFrameNeededToDraw();
824 820
825 return BeginImplFrameNeededToDraw() || 821 return BeginFrameNeededToDraw() || ProactiveBeginFrameWanted();
826 ProactiveBeginImplFrameWanted();
827 } 822 }
828 823
829 bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const { 824 bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const {
830 // ShouldPollForAnticipatedDrawTriggers is what we use in place of 825 // ShouldPollForAnticipatedDrawTriggers is what we use in place of
831 // ProactiveBeginImplFrameWanted when we are using the synchronous 826 // ProactiveBeginFrameWanted when we are using the synchronous
832 // compositor. 827 // compositor.
833 if (!SupportsProactiveBeginImplFrame()) { 828 if (!SupportsProactiveBeginFrame()) {
834 return !BeginImplFrameNeededToDraw() && 829 return !BeginFrameNeededToDraw() && ProactiveBeginFrameWanted();
835 ProactiveBeginImplFrameWanted();
836 } 830 }
837 831
838 // Non synchronous compositors should rely on 832 // Non synchronous compositors should rely on
839 // ProactiveBeginImplFrameWanted to poll for state instead. 833 // ProactiveBeginFrameWanted to poll for state instead.
840 return false; 834 return false;
841 } 835 }
842 836
843 bool SchedulerStateMachine::SupportsProactiveBeginImplFrame() const { 837 bool SchedulerStateMachine::SupportsProactiveBeginFrame() const {
844 // Both the synchronous compositor and disabled vsync settings 838 // Both the synchronous compositor and disabled vsync settings
845 // make it undesirable to proactively request BeginImplFrames. 839 // make it undesirable to proactively request BeginImplFrames.
846 // If this is true, the scheduler should poll. 840 // If this is true, the scheduler should poll.
847 return !settings_.using_synchronous_renderer_compositor && 841 return !settings_.using_synchronous_renderer_compositor &&
848 settings_.throttle_frame_production; 842 settings_.throttle_frame_production;
849 } 843 }
850 844
851 // These are the cases where we definitely (or almost definitely) have a 845 // These are the cases where we definitely (or almost definitely) have a
852 // new frame to draw and can draw. 846 // new frame to draw and can draw.
853 bool SchedulerStateMachine::BeginImplFrameNeededToDraw() const { 847 bool SchedulerStateMachine::BeginFrameNeededToDraw() const {
854 // The output surface is the provider of BeginImplFrames, so we are not going 848 // The output surface is the provider of BeginImplFrames, so we are not going
855 // to get them even if we ask for them. 849 // to get them even if we ask for them.
856 if (!HasInitializedOutputSurface()) 850 if (!HasInitializedOutputSurface())
857 return false; 851 return false;
858 852
859 // If we can't draw, don't tick until we are notified that we can draw again. 853 // If we can't draw, don't tick until we are notified that we can draw again.
860 if (!can_draw_) 854 if (!can_draw_)
861 return false; 855 return false;
862 856
863 // The forced draw respects our normal draw scheduling, so we need to 857 // The forced draw respects our normal draw scheduling, so we need to
(...skipping 10 matching lines...) Expand all
874 // additional visible tiles. 868 // additional visible tiles.
875 if (swap_used_incomplete_tile_) 869 if (swap_used_incomplete_tile_)
876 return true; 870 return true;
877 871
878 return needs_redraw_; 872 return needs_redraw_;
879 } 873 }
880 874
881 // These are cases where we are very likely to draw soon, but might not 875 // These are cases where we are very likely to draw soon, but might not
882 // actually have a new frame to draw when we receive the next BeginImplFrame. 876 // actually have a new frame to draw when we receive the next BeginImplFrame.
883 // Proactively requesting the BeginImplFrame helps hide the round trip latency 877 // Proactively requesting the BeginImplFrame helps hide the round trip latency
884 // of the SetNeedsBeginImplFrame request that has to go to the Browser. 878 // of the SetNeedsBeginFrame request that has to go to the Browser.
885 bool SchedulerStateMachine::ProactiveBeginImplFrameWanted() const { 879 bool SchedulerStateMachine::ProactiveBeginFrameWanted() const {
886 // The output surface is the provider of BeginImplFrames, 880 // The output surface is the provider of BeginImplFrames,
887 // so we are not going to get them even if we ask for them. 881 // so we are not going to get them even if we ask for them.
888 if (!HasInitializedOutputSurface()) 882 if (!HasInitializedOutputSurface())
889 return false; 883 return false;
890 884
891 // Do not be proactive when invisible. 885 // Do not be proactive when invisible.
892 if (!visible_) 886 if (!visible_)
893 return false; 887 return false;
894 888
895 // We should proactively request a BeginImplFrame if a commit is pending 889 // We should proactively request a BeginImplFrame if a commit is pending
896 // because we will want to draw if the commit completes quickly. 890 // because we will want to draw if the commit completes quickly.
897 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE) 891 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE)
898 return true; 892 return true;
899 893
900 // If the pending tree activates quickly, we'll want a BeginImplFrame soon 894 // If the pending tree activates quickly, we'll want a BeginImplFrame soon
901 // to draw the new active tree. 895 // to draw the new active tree.
902 if (has_pending_tree_) 896 if (has_pending_tree_)
903 return true; 897 return true;
904 898
905 // Changing priorities may allow us to activate (given the new priorities), 899 // Changing priorities may allow us to activate (given the new priorities),
906 // which may result in a new frame. 900 // which may result in a new frame.
907 if (needs_manage_tiles_) 901 if (needs_manage_tiles_)
908 return true; 902 return true;
909 903
910 // If we just swapped, it's likely that we are going to produce another 904 // If we just swapped, it's likely that we are going to produce another
911 // frame soon. This helps avoid negative glitches in our 905 // frame soon. This helps avoid negative glitches in our
912 // SetNeedsBeginImplFrame requests, which may propagate to the BeginImplFrame 906 // SetNeedsBeginFrame requests, which may propagate to the BeginImplFrame
913 // provider and get sampled at an inopportune time, delaying the next 907 // provider and get sampled at an inopportune time, delaying the next
914 // BeginImplFrame. 908 // BeginImplFrame.
915 if (last_frame_number_swap_performed_ == current_frame_number_) 909 if (last_frame_number_swap_performed_ == current_frame_number_)
916 return true; 910 return true;
917 911
918 return false; 912 return false;
919 } 913 }
920 914
921 void SchedulerStateMachine::OnBeginImplFrame(const BeginFrameArgs& args) { 915 void SchedulerStateMachine::OnBeginImplFrame(const BeginFrameArgs& args) {
922 AdvanceCurrentFrameNumber(); 916 AdvanceCurrentFrameNumber();
923 last_begin_impl_frame_args_ = args; 917 begin_impl_frame_args_ = args;
924 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE) << *AsValue(); 918 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE) << *AsValue();
925 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING; 919 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING;
926 } 920 }
927 921
928 void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() { 922 void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() {
929 DCHECK_EQ(begin_impl_frame_state_, 923 DCHECK_EQ(begin_impl_frame_state_,
930 BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) 924 BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING)
931 << *AsValue(); 925 << *AsValue();
932 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME; 926 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME;
933 } 927 }
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 case OUTPUT_SURFACE_ACTIVE: 1185 case OUTPUT_SURFACE_ACTIVE:
1192 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: 1186 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT:
1193 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: 1187 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION:
1194 return true; 1188 return true;
1195 } 1189 }
1196 NOTREACHED(); 1190 NOTREACHED();
1197 return false; 1191 return false;
1198 } 1192 }
1199 1193
1200 } // namespace cc 1194 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698