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

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

Powered by Google App Engine
This is Rietveld 408576698