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

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

Issue 199523002: cc: Throttle swaps in Scheduler instead of OutputSurface (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: rebase; DidSwapBuffersComplete 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"
11 #include "base/values.h" 11 #include "base/values.h"
12 #include "ui/gfx/frame_time.h" 12 #include "ui/gfx/frame_time.h"
13 13
14 namespace cc { 14 namespace cc {
15 15
16 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) 16 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
17 : settings_(settings), 17 : settings_(settings),
18 output_surface_state_(OUTPUT_SURFACE_LOST), 18 output_surface_state_(OUTPUT_SURFACE_LOST),
19 begin_impl_frame_state_(BEGIN_IMPL_FRAME_STATE_IDLE), 19 begin_impl_frame_state_(BEGIN_IMPL_FRAME_STATE_IDLE),
20 commit_state_(COMMIT_STATE_IDLE), 20 commit_state_(COMMIT_STATE_IDLE),
21 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE), 21 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE),
22 readback_state_(READBACK_STATE_IDLE), 22 readback_state_(READBACK_STATE_IDLE),
23 commit_count_(0), 23 commit_count_(0),
24 current_frame_number_(0), 24 current_frame_number_(0),
25 last_frame_number_swap_performed_(-1), 25 last_frame_number_swap_performed_(-1),
26 last_frame_number_begin_main_frame_sent_(-1), 26 last_frame_number_begin_main_frame_sent_(-1),
27 last_frame_number_update_visible_tiles_was_called_(-1), 27 last_frame_number_update_visible_tiles_was_called_(-1),
28 manage_tiles_funnel_(0), 28 manage_tiles_funnel_(0),
29 consecutive_checkerboard_animations_(0), 29 consecutive_checkerboard_animations_(0),
30 max_pending_swaps_(1),
31 pending_swaps_(0),
30 needs_redraw_(false), 32 needs_redraw_(false),
31 needs_manage_tiles_(false), 33 needs_manage_tiles_(false),
32 swap_used_incomplete_tile_(false), 34 swap_used_incomplete_tile_(false),
33 needs_commit_(false), 35 needs_commit_(false),
34 inside_poll_for_anticipated_draw_triggers_(false), 36 inside_poll_for_anticipated_draw_triggers_(false),
35 visible_(false), 37 visible_(false),
36 can_start_(false), 38 can_start_(false),
37 can_draw_(false), 39 can_draw_(false),
38 has_pending_tree_(false), 40 has_pending_tree_(false),
39 pending_tree_is_ready_for_activation_(false), 41 pending_tree_is_ready_for_activation_(false),
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 minor_state->SetInteger( 221 minor_state->SetInteger(
220 "last_frame_number_begin_main_frame_sent", 222 "last_frame_number_begin_main_frame_sent",
221 last_frame_number_begin_main_frame_sent_); 223 last_frame_number_begin_main_frame_sent_);
222 minor_state->SetInteger( 224 minor_state->SetInteger(
223 "last_frame_number_update_visible_tiles_was_called", 225 "last_frame_number_update_visible_tiles_was_called",
224 last_frame_number_update_visible_tiles_was_called_); 226 last_frame_number_update_visible_tiles_was_called_);
225 227
226 minor_state->SetInteger("manage_tiles_funnel", manage_tiles_funnel_); 228 minor_state->SetInteger("manage_tiles_funnel", manage_tiles_funnel_);
227 minor_state->SetInteger("consecutive_checkerboard_animations", 229 minor_state->SetInteger("consecutive_checkerboard_animations",
228 consecutive_checkerboard_animations_); 230 consecutive_checkerboard_animations_);
231 minor_state->SetInteger("max_pending_swaps_", max_pending_swaps_);
232 minor_state->SetInteger("pending_swaps_", pending_swaps_);
229 minor_state->SetBoolean("needs_redraw", needs_redraw_); 233 minor_state->SetBoolean("needs_redraw", needs_redraw_);
230 minor_state->SetBoolean("needs_manage_tiles", needs_manage_tiles_); 234 minor_state->SetBoolean("needs_manage_tiles", needs_manage_tiles_);
231 minor_state->SetBoolean("swap_used_incomplete_tile", 235 minor_state->SetBoolean("swap_used_incomplete_tile",
232 swap_used_incomplete_tile_); 236 swap_used_incomplete_tile_);
233 minor_state->SetBoolean("needs_commit", needs_commit_); 237 minor_state->SetBoolean("needs_commit", needs_commit_);
234 minor_state->SetBoolean("visible", visible_); 238 minor_state->SetBoolean("visible", visible_);
235 minor_state->SetBoolean("can_start", can_start_); 239 minor_state->SetBoolean("can_start", can_start_);
236 minor_state->SetBoolean("can_draw", can_draw_); 240 minor_state->SetBoolean("can_draw", can_draw_);
237 minor_state->SetBoolean("has_pending_tree", has_pending_tree_); 241 minor_state->SetBoolean("has_pending_tree", has_pending_tree_);
238 minor_state->SetBoolean("pending_tree_is_ready_for_activation", 242 minor_state->SetBoolean("pending_tree_is_ready_for_activation",
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 // from occuring. If we are waiting for the first draw, then perfom the 361 // from occuring. If we are waiting for the first draw, then perfom the
358 // aborted draw to keep things moving. If we are not waiting for the first 362 // aborted draw to keep things moving. If we are not waiting for the first
359 // draw however, we don't want to abort for no reason. 363 // draw however, we don't want to abort for no reason.
360 if (PendingDrawsShouldBeAborted()) 364 if (PendingDrawsShouldBeAborted())
361 return active_tree_needs_first_draw_; 365 return active_tree_needs_first_draw_;
362 366
363 // After this line, we only want to swap once per frame. 367 // After this line, we only want to swap once per frame.
364 if (HasSwappedThisFrame()) 368 if (HasSwappedThisFrame())
365 return false; 369 return false;
366 370
371 // Do not queue too many swaps.
372 if (pending_swaps_ >= max_pending_swaps_)
373 return false;
374
367 // Except for the cases above, do not draw outside of the BeginImplFrame 375 // Except for the cases above, do not draw outside of the BeginImplFrame
368 // deadline. 376 // deadline.
369 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) 377 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
370 return false; 378 return false;
371 379
372 // Only handle forced redraws due to timeouts on the regular deadline. 380 // Only handle forced redraws due to timeouts on the regular deadline.
373 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) 381 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
374 return true; 382 return true;
375 383
376 return needs_redraw_; 384 return needs_redraw_;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 return true; 473 return true;
466 474
467 // After this point, we only start a commit once per frame. 475 // After this point, we only start a commit once per frame.
468 if (HasSentBeginMainFrameThisFrame()) 476 if (HasSentBeginMainFrameThisFrame())
469 return false; 477 return false;
470 478
471 // We shouldn't normally accept commits if there isn't an OutputSurface. 479 // We shouldn't normally accept commits if there isn't an OutputSurface.
472 if (!HasInitializedOutputSurface()) 480 if (!HasInitializedOutputSurface())
473 return false; 481 return false;
474 482
483 // SwapAck throttle the BeginMainFrames
484 // TODO(brianderson): Remove this restriction to improve throughput.
485 if (pending_swaps_ >= max_pending_swaps_)
486 return false;
487
475 if (skip_begin_main_frame_to_reduce_latency_) 488 if (skip_begin_main_frame_to_reduce_latency_)
476 return false; 489 return false;
477 490
478 return true; 491 return true;
479 } 492 }
480 493
481 bool SchedulerStateMachine::ShouldCommit() const { 494 bool SchedulerStateMachine::ShouldCommit() const {
482 if (commit_state_ != COMMIT_STATE_READY_TO_COMMIT) 495 if (commit_state_ != COMMIT_STATE_READY_TO_COMMIT)
483 return false; 496 return false;
484 497
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 798
786 // Non synchronous compositors should rely on 799 // Non synchronous compositors should rely on
787 // ProactiveBeginFrameWanted to poll for state instead. 800 // ProactiveBeginFrameWanted to poll for state instead.
788 return false; 801 return false;
789 } 802 }
790 803
791 bool SchedulerStateMachine::SupportsProactiveBeginFrame() const { 804 bool SchedulerStateMachine::SupportsProactiveBeginFrame() const {
792 // Both the synchronous compositor and disabled vsync settings 805 // Both the synchronous compositor and disabled vsync settings
793 // make it undesirable to proactively request BeginImplFrames. 806 // make it undesirable to proactively request BeginImplFrames.
794 // If this is true, the scheduler should poll. 807 // If this is true, the scheduler should poll.
795 return !settings_.using_synchronous_renderer_compositor && 808 return !settings_.using_synchronous_renderer_compositor;
796 settings_.throttle_frame_production;
797 } 809 }
798 810
799 // These are the cases where we definitely (or almost definitely) have a 811 // These are the cases where we definitely (or almost definitely) have a
800 // new frame to draw and can draw. 812 // new frame to draw and can draw.
801 bool SchedulerStateMachine::BeginFrameNeededToDraw() const { 813 bool SchedulerStateMachine::BeginFrameNeededToDraw() const {
802 // The output surface is the provider of BeginImplFrames, so we are not going 814 // The output surface is the provider of BeginImplFrames, so we are not going
803 // to get them even if we ask for them. 815 // to get them even if we ask for them.
804 if (!HasInitializedOutputSurface()) 816 if (!HasInitializedOutputSurface())
805 return false; 817 return false;
806 818
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 return false; 913 return false;
902 914
903 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) 915 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)
904 return false; 916 return false;
905 917
906 // If we've lost the output surface, end the current BeginImplFrame ASAP 918 // If we've lost the output surface, end the current BeginImplFrame ASAP
907 // so we can start creating the next output surface. 919 // so we can start creating the next output surface.
908 if (output_surface_state_ == OUTPUT_SURFACE_LOST) 920 if (output_surface_state_ == OUTPUT_SURFACE_LOST)
909 return true; 921 return true;
910 922
923 // SwapAck throttle the deadline since we wont draw and swap anyway.
924 if (pending_swaps_ >= max_pending_swaps_)
925 return false;
926
911 if (active_tree_needs_first_draw_) 927 if (active_tree_needs_first_draw_)
912 return true; 928 return true;
913 929
914 if (!needs_redraw_) 930 if (!needs_redraw_)
915 return false; 931 return false;
916 932
917 // This is used to prioritize impl-thread draws when the main thread isn't 933 // This is used to prioritize impl-thread draws when the main thread isn't
918 // producing anything, e.g., after an aborted commit. We also check that we 934 // producing anything, e.g., after an aborted commit. We also check that we
919 // don't have a pending tree -- otherwise we should give it a chance to 935 // don't have a pending tree -- otherwise we should give it a chance to
920 // activate. 936 // activate.
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } 1005 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; }
990 1006
991 void SchedulerStateMachine::SetNeedsManageTiles() { 1007 void SchedulerStateMachine::SetNeedsManageTiles() {
992 if (!needs_manage_tiles_) { 1008 if (!needs_manage_tiles_) {
993 TRACE_EVENT0("cc", 1009 TRACE_EVENT0("cc",
994 "SchedulerStateMachine::SetNeedsManageTiles"); 1010 "SchedulerStateMachine::SetNeedsManageTiles");
995 needs_manage_tiles_ = true; 1011 needs_manage_tiles_ = true;
996 } 1012 }
997 } 1013 }
998 1014
1015 void SchedulerStateMachine::SetMaxSwapsPending(int max) {
1016 max_pending_swaps_ = max;
1017 }
1018
1019 void SchedulerStateMachine::DidSwapBuffers() {
1020 pending_swaps_++;
1021 DCHECK_LE(pending_swaps_, max_pending_swaps_);
1022 }
1023
999 void SchedulerStateMachine::SetSwapUsedIncompleteTile( 1024 void SchedulerStateMachine::SetSwapUsedIncompleteTile(
1000 bool used_incomplete_tile) { 1025 bool used_incomplete_tile) {
1001 swap_used_incomplete_tile_ = used_incomplete_tile; 1026 swap_used_incomplete_tile_ = used_incomplete_tile;
1002 } 1027 }
1003 1028
1029 void SchedulerStateMachine::DidSwapBuffersComplete() {
1030 DCHECK(HasInitializedOutputSurface());
1031 DCHECK_GT(pending_swaps_, 0);
1032 pending_swaps_--;
1033 }
1034
1004 void SchedulerStateMachine::SetSmoothnessTakesPriority( 1035 void SchedulerStateMachine::SetSmoothnessTakesPriority(
1005 bool smoothness_takes_priority) { 1036 bool smoothness_takes_priority) {
1006 smoothness_takes_priority_ = smoothness_takes_priority; 1037 smoothness_takes_priority_ = smoothness_takes_priority;
1007 } 1038 }
1008 1039
1009 void SchedulerStateMachine::DidDrawIfPossibleCompleted( 1040 void SchedulerStateMachine::DidDrawIfPossibleCompleted(
1010 DrawSwapReadbackResult::DrawResult result) { 1041 DrawSwapReadbackResult::DrawResult result) {
1011 switch (result) { 1042 switch (result) {
1012 case DrawSwapReadbackResult::INVALID_RESULT: 1043 case DrawSwapReadbackResult::INVALID_RESULT:
1013 NOTREACHED() << "Uninitialized DrawSwapReadbackResult."; 1044 NOTREACHED() << "Uninitialized DrawSwapReadbackResult.";
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1108 // "Fill" the ManageTiles funnel. 1139 // "Fill" the ManageTiles funnel.
1109 manage_tiles_funnel_++; 1140 manage_tiles_funnel_++;
1110 } 1141 }
1111 1142
1112 void SchedulerStateMachine::DidLoseOutputSurface() { 1143 void SchedulerStateMachine::DidLoseOutputSurface() {
1113 if (output_surface_state_ == OUTPUT_SURFACE_LOST || 1144 if (output_surface_state_ == OUTPUT_SURFACE_LOST ||
1114 output_surface_state_ == OUTPUT_SURFACE_CREATING) 1145 output_surface_state_ == OUTPUT_SURFACE_CREATING)
1115 return; 1146 return;
1116 output_surface_state_ = OUTPUT_SURFACE_LOST; 1147 output_surface_state_ = OUTPUT_SURFACE_LOST;
1117 needs_redraw_ = false; 1148 needs_redraw_ = false;
1149 pending_swaps_ = 0;
1118 } 1150 }
1119 1151
1120 void SchedulerStateMachine::NotifyReadyToActivate() { 1152 void SchedulerStateMachine::NotifyReadyToActivate() {
1121 if (has_pending_tree_) 1153 if (has_pending_tree_)
1122 pending_tree_is_ready_for_activation_ = true; 1154 pending_tree_is_ready_for_activation_ = true;
1123 } 1155 }
1124 1156
1125 void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() { 1157 void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() {
1126 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING); 1158 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING);
1127 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT; 1159 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT;
(...skipping 25 matching lines...) Expand all
1153 case OUTPUT_SURFACE_ACTIVE: 1185 case OUTPUT_SURFACE_ACTIVE:
1154 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: 1186 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT:
1155 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: 1187 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION:
1156 return true; 1188 return true;
1157 } 1189 }
1158 NOTREACHED(); 1190 NOTREACHED();
1159 return false; 1191 return false;
1160 } 1192 }
1161 1193
1162 } // namespace cc 1194 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698