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

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

Powered by Google App Engine
This is Rietveld 408576698