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

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

Issue 54913003: Scheduler: Switch from high to low latency mode if possible. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update MainThreadIsInHighLatencyMode() and comments. Created 7 years, 1 month 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 23 matching lines...) Expand all
34 main_thread_needs_layer_textures_(false), 34 main_thread_needs_layer_textures_(false),
35 inside_poll_for_anticipated_draw_triggers_(false), 35 inside_poll_for_anticipated_draw_triggers_(false),
36 visible_(false), 36 visible_(false),
37 can_start_(false), 37 can_start_(false),
38 can_draw_(false), 38 can_draw_(false),
39 has_pending_tree_(false), 39 has_pending_tree_(false),
40 pending_tree_is_ready_for_activation_(false), 40 pending_tree_is_ready_for_activation_(false),
41 active_tree_needs_first_draw_(false), 41 active_tree_needs_first_draw_(false),
42 draw_if_possible_failed_(false), 42 draw_if_possible_failed_(false),
43 did_create_and_initialize_first_output_surface_(false), 43 did_create_and_initialize_first_output_surface_(false),
44 smoothness_takes_priority_(false) {} 44 smoothness_takes_priority_(false),
45 skip_begin_main_frame_to_reduce_latency_(false) {}
45 46
46 const char* SchedulerStateMachine::OutputSurfaceStateToString( 47 const char* SchedulerStateMachine::OutputSurfaceStateToString(
47 OutputSurfaceState state) { 48 OutputSurfaceState state) {
48 switch (state) { 49 switch (state) {
49 case OUTPUT_SURFACE_ACTIVE: 50 case OUTPUT_SURFACE_ACTIVE:
50 return "OUTPUT_SURFACE_ACTIVE"; 51 return "OUTPUT_SURFACE_ACTIVE";
51 case OUTPUT_SURFACE_LOST: 52 case OUTPUT_SURFACE_LOST:
52 return "OUTPUT_SURFACE_LOST"; 53 return "OUTPUT_SURFACE_LOST";
53 case OUTPUT_SURFACE_CREATING: 54 case OUTPUT_SURFACE_CREATING:
54 return "OUTPUT_SURFACE_CREATING"; 55 return "OUTPUT_SURFACE_CREATING";
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 minor_state->SetBoolean("has_pending_tree", has_pending_tree_); 253 minor_state->SetBoolean("has_pending_tree", has_pending_tree_);
253 minor_state->SetBoolean("pending_tree_is_ready_for_activation", 254 minor_state->SetBoolean("pending_tree_is_ready_for_activation",
254 pending_tree_is_ready_for_activation_); 255 pending_tree_is_ready_for_activation_);
255 minor_state->SetBoolean("active_tree_needs_first_draw", 256 minor_state->SetBoolean("active_tree_needs_first_draw",
256 active_tree_needs_first_draw_); 257 active_tree_needs_first_draw_);
257 minor_state->SetBoolean("draw_if_possible_failed", draw_if_possible_failed_); 258 minor_state->SetBoolean("draw_if_possible_failed", draw_if_possible_failed_);
258 minor_state->SetBoolean("did_create_and_initialize_first_output_surface", 259 minor_state->SetBoolean("did_create_and_initialize_first_output_surface",
259 did_create_and_initialize_first_output_surface_); 260 did_create_and_initialize_first_output_surface_);
260 minor_state->SetBoolean("smoothness_takes_priority", 261 minor_state->SetBoolean("smoothness_takes_priority",
261 smoothness_takes_priority_); 262 smoothness_takes_priority_);
263 minor_state->SetBoolean("main_thread_is_in_high_latency_mode",
264 MainThreadIsInHighLatencyMode());
265 minor_state->SetBoolean("skip_begin_main_frame_to_reduce_latency",
266 skip_begin_main_frame_to_reduce_latency_);
262 state->Set("minor_state", minor_state.release()); 267 state->Set("minor_state", minor_state.release());
263 268
264 return state.PassAs<base::Value>(); 269 return state.PassAs<base::Value>();
265 } 270 }
266 271
267 bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const { 272 bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const {
268 return current_frame_number_ == 273 return current_frame_number_ ==
269 last_frame_number_begin_main_frame_sent_; 274 last_frame_number_begin_main_frame_sent_;
270 } 275 }
271 276
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 return true; 483 return true;
479 484
480 // After this point, we only start a commit once per frame. 485 // After this point, we only start a commit once per frame.
481 if (HasSentBeginMainFrameThisFrame()) 486 if (HasSentBeginMainFrameThisFrame())
482 return false; 487 return false;
483 488
484 // We shouldn't normally accept commits if there isn't an OutputSurface. 489 // We shouldn't normally accept commits if there isn't an OutputSurface.
485 if (!HasInitializedOutputSurface()) 490 if (!HasInitializedOutputSurface())
486 return false; 491 return false;
487 492
493 if (skip_begin_main_frame_to_reduce_latency_)
494 return false;
495
488 return true; 496 return true;
489 } 497 }
490 498
491 bool SchedulerStateMachine::ShouldCommit() const { 499 bool SchedulerStateMachine::ShouldCommit() const {
492 return commit_state_ == COMMIT_STATE_READY_TO_COMMIT; 500 return commit_state_ == COMMIT_STATE_READY_TO_COMMIT;
493 } 501 }
494 502
495 bool SchedulerStateMachine::ShouldManageTiles() const { 503 bool SchedulerStateMachine::ShouldManageTiles() const {
496 // Limiting to once per-frame is not enough, since we only want to 504 // Limiting to once per-frame is not enough, since we only want to
497 // manage tiles _after_ draws. Polling for draw triggers and 505 // manage tiles _after_ draws. Polling for draw triggers and
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 void SchedulerStateMachine::UpdateStateOnManageTiles() { 757 void SchedulerStateMachine::UpdateStateOnManageTiles() {
750 needs_manage_tiles_ = false; 758 needs_manage_tiles_ = false;
751 } 759 }
752 760
753 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() { 761 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() {
754 DCHECK(!main_thread_needs_layer_textures_); 762 DCHECK(!main_thread_needs_layer_textures_);
755 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD); 763 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD);
756 main_thread_needs_layer_textures_ = true; 764 main_thread_needs_layer_textures_ = true;
757 } 765 }
758 766
767 void SchedulerStateMachine::SetSkipBeginMainFrameToReduceLatency(bool skip) {
768 skip_begin_main_frame_to_reduce_latency_ = skip;
769 }
770
759 bool SchedulerStateMachine::BeginImplFrameNeeded() const { 771 bool SchedulerStateMachine::BeginImplFrameNeeded() const {
760 // Proactive BeginImplFrames are bad for the synchronous compositor because we 772 // Proactive BeginImplFrames are bad for the synchronous compositor because we
761 // have to draw when we get the BeginImplFrame and could end up drawing many 773 // have to draw when we get the BeginImplFrame and could end up drawing many
762 // duplicate frames if our new frame isn't ready in time. 774 // duplicate frames if our new frame isn't ready in time.
763 // To poll for state with the synchronous compositor without having to draw, 775 // To poll for state with the synchronous compositor without having to draw,
764 // we rely on ShouldPollForAnticipatedDrawTriggers instead. 776 // we rely on ShouldPollForAnticipatedDrawTriggers instead.
765 if (!SupportsProactiveBeginImplFrame()) 777 if (!SupportsProactiveBeginImplFrame())
766 return BeginImplFrameNeededToDraw(); 778 return BeginImplFrameNeededToDraw();
767 779
768 return BeginImplFrameNeededToDraw() || 780 return BeginImplFrameNeededToDraw() ||
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 if (commit_state_ == COMMIT_STATE_IDLE && !has_pending_tree_) 924 if (commit_state_ == COMMIT_STATE_IDLE && !has_pending_tree_)
913 return true; 925 return true;
914 926
915 // Prioritize impl-thread draws in smoothness mode. 927 // Prioritize impl-thread draws in smoothness mode.
916 if (smoothness_takes_priority_) 928 if (smoothness_takes_priority_)
917 return true; 929 return true;
918 930
919 return false; 931 return false;
920 } 932 }
921 933
934 bool SchedulerStateMachine::MainThreadIsInHighLatencyMode() const {
935 // If we just sent a BeginMainFrame and haven't hit the deadline yet, the main
936 // thread is in a low latency mode.
937 if (last_frame_number_begin_main_frame_sent_ == current_frame_number_ &&
938 (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING ||
939 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME))
940 return false;
941
942 // If there's a commit in progress it must either be from the previous frame
943 // or it started after the impl thread's deadline. In either case the main
944 // thread is in high latency mode.
945 if (commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS ||
946 commit_state_ == COMMIT_STATE_READY_TO_COMMIT)
947 return true;
948
949 // Similarly, if there's a pending tree the main thread is in high latency
950 // mode, because either
951 // it's from the previous frame
952 // or
953 // we're currently drawing the active tree and the pending tree will thus
954 // only be drawn in the next frame.
955 if (has_pending_tree_)
956 return true;
957
958 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) {
959 // Even if there's a new active tree to draw at the deadline or we've just
960 // drawn it, it may have been triggered by a previous BeginImplFrame, in
961 // which case the main thread is in a high latency mode.
962 return (active_tree_needs_first_draw_ ||
963 last_frame_number_swap_performed_ == current_frame_number_) &&
brianderson 2013/11/05 00:24:17 Ah, good catch here.
964 last_frame_number_begin_main_frame_sent_ != current_frame_number_;
965 } else {
966 // If the active tree needs its first draw in any other state, we know the
967 // main thread is in a high latency mode.
968 return active_tree_needs_first_draw_;
969 }
970
971 return false;
brianderson 2013/11/05 00:24:17 Hmm, this will never be reached. Maybe we can just
Dominik Grewe 2013/11/05 12:24:20 Done.
972 }
973
922 void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() { 974 void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() {
923 current_frame_number_++; 975 current_frame_number_++;
924 inside_poll_for_anticipated_draw_triggers_ = true; 976 inside_poll_for_anticipated_draw_triggers_ = true;
925 } 977 }
926 978
927 void SchedulerStateMachine::DidLeavePollForAnticipatedDrawTriggers() { 979 void SchedulerStateMachine::DidLeavePollForAnticipatedDrawTriggers() {
928 inside_poll_for_anticipated_draw_triggers_ = false; 980 inside_poll_for_anticipated_draw_triggers_ = false;
929 } 981 }
930 982
931 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } 983 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; }
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1053 case OUTPUT_SURFACE_ACTIVE: 1105 case OUTPUT_SURFACE_ACTIVE:
1054 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: 1106 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT:
1055 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: 1107 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION:
1056 return true; 1108 return true;
1057 } 1109 }
1058 NOTREACHED(); 1110 NOTREACHED();
1059 return false; 1111 return false;
1060 } 1112 }
1061 1113
1062 } // namespace cc 1114 } // namespace cc
OLDNEW
« cc/scheduler/scheduler.h ('K') | « cc/scheduler/scheduler_state_machine.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698