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

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

Issue 671653005: SetNeedsRedraw directly when updating a visible tile. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: pinchblurmerge-test: nits Created 6 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/debug/trace_event_argument.h" 8 #include "base/debug/trace_event_argument.h"
9 #include "base/format_macros.h" 9 #include "base/format_macros.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/strings/stringprintf.h" 11 #include "base/strings/stringprintf.h"
12 #include "base/values.h" 12 #include "base/values.h"
13 #include "ui/gfx/frame_time.h" 13 #include "ui/gfx/frame_time.h"
14 14
15 namespace cc { 15 namespace cc {
16 16
17 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) 17 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
18 : settings_(settings), 18 : settings_(settings),
19 output_surface_state_(OUTPUT_SURFACE_LOST), 19 output_surface_state_(OUTPUT_SURFACE_LOST),
20 begin_impl_frame_state_(BEGIN_IMPL_FRAME_STATE_IDLE), 20 begin_impl_frame_state_(BEGIN_IMPL_FRAME_STATE_IDLE),
21 commit_state_(COMMIT_STATE_IDLE), 21 commit_state_(COMMIT_STATE_IDLE),
22 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE), 22 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE),
23 commit_count_(0), 23 commit_count_(0),
24 current_frame_number_(0), 24 current_frame_number_(0),
25 last_frame_number_animate_performed_(-1), 25 last_frame_number_animate_performed_(-1),
26 last_frame_number_swap_performed_(-1), 26 last_frame_number_swap_performed_(-1),
27 last_frame_number_swap_requested_(-1), 27 last_frame_number_swap_requested_(-1),
28 last_frame_number_begin_main_frame_sent_(-1), 28 last_frame_number_begin_main_frame_sent_(-1),
29 last_frame_number_update_visible_tiles_was_called_(-1),
30 manage_tiles_funnel_(0), 29 manage_tiles_funnel_(0),
31 consecutive_checkerboard_animations_(0), 30 consecutive_checkerboard_animations_(0),
32 max_pending_swaps_(1), 31 max_pending_swaps_(1),
33 pending_swaps_(0), 32 pending_swaps_(0),
34 needs_redraw_(false), 33 needs_redraw_(false),
35 needs_animate_(false), 34 needs_animate_(false),
36 needs_manage_tiles_(false), 35 needs_manage_tiles_(false),
37 swap_used_incomplete_tile_(false),
38 needs_commit_(false), 36 needs_commit_(false),
39 inside_poll_for_anticipated_draw_triggers_(false), 37 inside_poll_for_anticipated_draw_triggers_(false),
40 visible_(false), 38 visible_(false),
41 can_start_(false), 39 can_start_(false),
42 can_draw_(false), 40 can_draw_(false),
43 has_pending_tree_(false), 41 has_pending_tree_(false),
44 pending_tree_is_ready_for_activation_(false), 42 pending_tree_is_ready_for_activation_(false),
45 active_tree_needs_first_draw_(false), 43 active_tree_needs_first_draw_(false),
46 did_commit_after_animating_(false), 44 did_commit_after_animating_(false),
47 did_create_and_initialize_first_output_surface_(false), 45 did_create_and_initialize_first_output_surface_(false),
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 const char* SchedulerStateMachine::ActionToString(Action action) { 120 const char* SchedulerStateMachine::ActionToString(Action action) {
123 switch (action) { 121 switch (action) {
124 case ACTION_NONE: 122 case ACTION_NONE:
125 return "ACTION_NONE"; 123 return "ACTION_NONE";
126 case ACTION_ANIMATE: 124 case ACTION_ANIMATE:
127 return "ACTION_ANIMATE"; 125 return "ACTION_ANIMATE";
128 case ACTION_SEND_BEGIN_MAIN_FRAME: 126 case ACTION_SEND_BEGIN_MAIN_FRAME:
129 return "ACTION_SEND_BEGIN_MAIN_FRAME"; 127 return "ACTION_SEND_BEGIN_MAIN_FRAME";
130 case ACTION_COMMIT: 128 case ACTION_COMMIT:
131 return "ACTION_COMMIT"; 129 return "ACTION_COMMIT";
132 case ACTION_UPDATE_VISIBLE_TILES:
133 return "ACTION_UPDATE_VISIBLE_TILES";
134 case ACTION_ACTIVATE_SYNC_TREE: 130 case ACTION_ACTIVATE_SYNC_TREE:
135 return "ACTION_ACTIVATE_SYNC_TREE"; 131 return "ACTION_ACTIVATE_SYNC_TREE";
136 case ACTION_DRAW_AND_SWAP_IF_POSSIBLE: 132 case ACTION_DRAW_AND_SWAP_IF_POSSIBLE:
137 return "ACTION_DRAW_AND_SWAP_IF_POSSIBLE"; 133 return "ACTION_DRAW_AND_SWAP_IF_POSSIBLE";
138 case ACTION_DRAW_AND_SWAP_FORCED: 134 case ACTION_DRAW_AND_SWAP_FORCED:
139 return "ACTION_DRAW_AND_SWAP_FORCED"; 135 return "ACTION_DRAW_AND_SWAP_FORCED";
140 case ACTION_DRAW_AND_SWAP_ABORT: 136 case ACTION_DRAW_AND_SWAP_ABORT:
141 return "ACTION_DRAW_AND_SWAP_ABORT"; 137 return "ACTION_DRAW_AND_SWAP_ABORT";
142 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION: 138 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
143 return "ACTION_BEGIN_OUTPUT_SURFACE_CREATION"; 139 return "ACTION_BEGIN_OUTPUT_SURFACE_CREATION";
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 state->SetInteger("current_frame_number", current_frame_number_); 195 state->SetInteger("current_frame_number", current_frame_number_);
200 196
201 state->SetInteger("last_frame_number_animate_performed", 197 state->SetInteger("last_frame_number_animate_performed",
202 last_frame_number_animate_performed_); 198 last_frame_number_animate_performed_);
203 state->SetInteger("last_frame_number_swap_performed", 199 state->SetInteger("last_frame_number_swap_performed",
204 last_frame_number_swap_performed_); 200 last_frame_number_swap_performed_);
205 state->SetInteger("last_frame_number_swap_requested", 201 state->SetInteger("last_frame_number_swap_requested",
206 last_frame_number_swap_requested_); 202 last_frame_number_swap_requested_);
207 state->SetInteger("last_frame_number_begin_main_frame_sent", 203 state->SetInteger("last_frame_number_begin_main_frame_sent",
208 last_frame_number_begin_main_frame_sent_); 204 last_frame_number_begin_main_frame_sent_);
209 state->SetInteger("last_frame_number_update_visible_tiles_was_called",
210 last_frame_number_update_visible_tiles_was_called_);
211 205
212 state->SetInteger("manage_tiles_funnel", manage_tiles_funnel_); 206 state->SetInteger("manage_tiles_funnel", manage_tiles_funnel_);
213 state->SetInteger("consecutive_checkerboard_animations", 207 state->SetInteger("consecutive_checkerboard_animations",
214 consecutive_checkerboard_animations_); 208 consecutive_checkerboard_animations_);
215 state->SetInteger("max_pending_swaps_", max_pending_swaps_); 209 state->SetInteger("max_pending_swaps_", max_pending_swaps_);
216 state->SetInteger("pending_swaps_", pending_swaps_); 210 state->SetInteger("pending_swaps_", pending_swaps_);
217 state->SetBoolean("needs_redraw", needs_redraw_); 211 state->SetBoolean("needs_redraw", needs_redraw_);
218 state->SetBoolean("needs_animate_", needs_animate_); 212 state->SetBoolean("needs_animate_", needs_animate_);
219 state->SetBoolean("needs_manage_tiles", needs_manage_tiles_); 213 state->SetBoolean("needs_manage_tiles", needs_manage_tiles_);
220 state->SetBoolean("swap_used_incomplete_tile", swap_used_incomplete_tile_);
221 state->SetBoolean("needs_commit", needs_commit_); 214 state->SetBoolean("needs_commit", needs_commit_);
222 state->SetBoolean("visible", visible_); 215 state->SetBoolean("visible", visible_);
223 state->SetBoolean("can_start", can_start_); 216 state->SetBoolean("can_start", can_start_);
224 state->SetBoolean("can_draw", can_draw_); 217 state->SetBoolean("can_draw", can_draw_);
225 state->SetBoolean("has_pending_tree", has_pending_tree_); 218 state->SetBoolean("has_pending_tree", has_pending_tree_);
226 state->SetBoolean("pending_tree_is_ready_for_activation", 219 state->SetBoolean("pending_tree_is_ready_for_activation",
227 pending_tree_is_ready_for_activation_); 220 pending_tree_is_ready_for_activation_);
228 state->SetBoolean("active_tree_needs_first_draw", 221 state->SetBoolean("active_tree_needs_first_draw",
229 active_tree_needs_first_draw_); 222 active_tree_needs_first_draw_);
230 state->SetBoolean("did_commit_after_animating", did_commit_after_animating_); 223 state->SetBoolean("did_commit_after_animating", did_commit_after_animating_);
(...skipping 27 matching lines...) Expand all
258 251
259 bool SchedulerStateMachine::HasAnimatedThisFrame() const { 252 bool SchedulerStateMachine::HasAnimatedThisFrame() const {
260 return last_frame_number_animate_performed_ == current_frame_number_; 253 return last_frame_number_animate_performed_ == current_frame_number_;
261 } 254 }
262 255
263 bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const { 256 bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const {
264 return current_frame_number_ == 257 return current_frame_number_ ==
265 last_frame_number_begin_main_frame_sent_; 258 last_frame_number_begin_main_frame_sent_;
266 } 259 }
267 260
268 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const {
269 return current_frame_number_ ==
270 last_frame_number_update_visible_tiles_was_called_;
271 }
272
273 bool SchedulerStateMachine::HasSwappedThisFrame() const { 261 bool SchedulerStateMachine::HasSwappedThisFrame() const {
274 return current_frame_number_ == last_frame_number_swap_performed_; 262 return current_frame_number_ == last_frame_number_swap_performed_;
275 } 263 }
276 264
277 bool SchedulerStateMachine::HasRequestedSwapThisFrame() const { 265 bool SchedulerStateMachine::HasRequestedSwapThisFrame() const {
278 return current_frame_number_ == last_frame_number_swap_requested_; 266 return current_frame_number_ == last_frame_number_swap_requested_;
279 } 267 }
280 268
281 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const { 269 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const {
282 // These are all the cases where we normally cannot or do not want to draw 270 // These are all the cases where we normally cannot or do not want to draw
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 return false; 375 return false;
388 376
389 // If we want to force activation, do so ASAP. 377 // If we want to force activation, do so ASAP.
390 if (PendingActivationsShouldBeForced()) 378 if (PendingActivationsShouldBeForced())
391 return true; 379 return true;
392 380
393 // At this point, only activate if we are ready to activate. 381 // At this point, only activate if we are ready to activate.
394 return pending_tree_is_ready_for_activation_; 382 return pending_tree_is_ready_for_activation_;
395 } 383 }
396 384
397 bool SchedulerStateMachine::ShouldUpdateVisibleTiles() const {
398 if (!settings_.impl_side_painting)
399 return false;
400 if (HasUpdatedVisibleTilesThisFrame())
401 return false;
402
403 // We don't want to update visible tiles right after drawing.
404 if (HasRequestedSwapThisFrame())
405 return false;
406
407 // There's no reason to check for tiles if we don't have an output surface.
408 if (!HasInitializedOutputSurface())
409 return false;
410
411 // We should not check for visible tiles until we've entered the deadline so
412 // we check as late as possible and give the tiles more time to initialize.
413 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
414 return false;
415
416 // If the last swap drew with checkerboard or missing tiles, we should
417 // poll for any new visible tiles so we can be notified to draw again
418 // when there are.
419 if (swap_used_incomplete_tile_)
420 return true;
421
422 return false;
423 }
424
425 bool SchedulerStateMachine::ShouldAnimate() const { 385 bool SchedulerStateMachine::ShouldAnimate() const {
426 if (!can_draw_) 386 if (!can_draw_)
427 return false; 387 return false;
428 388
429 // If a commit occurred after our last call, we need to do animation again. 389 // If a commit occurred after our last call, we need to do animation again.
430 if (HasAnimatedThisFrame() && !did_commit_after_animating_) 390 if (HasAnimatedThisFrame() && !did_commit_after_animating_)
431 return false; 391 return false;
432 392
433 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING && 393 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING &&
434 begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) 394 begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 // Limiting to once per-frame is not enough, since we only want to 490 // Limiting to once per-frame is not enough, since we only want to
531 // manage tiles _after_ draws. Polling for draw triggers and 491 // manage tiles _after_ draws. Polling for draw triggers and
532 // begin-frame are mutually exclusive, so we limit to these two cases. 492 // begin-frame are mutually exclusive, so we limit to these two cases.
533 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE && 493 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE &&
534 !inside_poll_for_anticipated_draw_triggers_) 494 !inside_poll_for_anticipated_draw_triggers_)
535 return false; 495 return false;
536 return needs_manage_tiles_; 496 return needs_manage_tiles_;
537 } 497 }
538 498
539 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { 499 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const {
540 if (ShouldUpdateVisibleTiles())
541 return ACTION_UPDATE_VISIBLE_TILES;
542 if (ShouldActivatePendingTree()) 500 if (ShouldActivatePendingTree())
543 return ACTION_ACTIVATE_SYNC_TREE; 501 return ACTION_ACTIVATE_SYNC_TREE;
544 if (ShouldCommit()) 502 if (ShouldCommit())
545 return ACTION_COMMIT; 503 return ACTION_COMMIT;
546 if (ShouldAnimate()) 504 if (ShouldAnimate())
547 return ACTION_ANIMATE; 505 return ACTION_ANIMATE;
548 if (ShouldDraw()) { 506 if (ShouldDraw()) {
549 if (PendingDrawsShouldBeAborted()) 507 if (PendingDrawsShouldBeAborted())
550 return ACTION_DRAW_AND_SWAP_ABORT; 508 return ACTION_DRAW_AND_SWAP_ABORT;
551 else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) 509 else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
552 return ACTION_DRAW_AND_SWAP_FORCED; 510 return ACTION_DRAW_AND_SWAP_FORCED;
553 else 511 else
554 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE; 512 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
555 } 513 }
556 if (ShouldManageTiles()) 514 if (ShouldManageTiles())
557 return ACTION_MANAGE_TILES; 515 return ACTION_MANAGE_TILES;
558 if (ShouldSendBeginMainFrame()) 516 if (ShouldSendBeginMainFrame())
559 return ACTION_SEND_BEGIN_MAIN_FRAME; 517 return ACTION_SEND_BEGIN_MAIN_FRAME;
560 if (ShouldBeginOutputSurfaceCreation()) 518 if (ShouldBeginOutputSurfaceCreation())
561 return ACTION_BEGIN_OUTPUT_SURFACE_CREATION; 519 return ACTION_BEGIN_OUTPUT_SURFACE_CREATION;
562 return ACTION_NONE; 520 return ACTION_NONE;
563 } 521 }
564 522
565 void SchedulerStateMachine::UpdateState(Action action) { 523 void SchedulerStateMachine::UpdateState(Action action) {
566 switch (action) { 524 switch (action) {
567 case ACTION_NONE: 525 case ACTION_NONE:
568 return; 526 return;
569 527
570 case ACTION_UPDATE_VISIBLE_TILES:
571 last_frame_number_update_visible_tiles_was_called_ =
572 current_frame_number_;
573 return;
574
575 case ACTION_ACTIVATE_SYNC_TREE: 528 case ACTION_ACTIVATE_SYNC_TREE:
576 UpdateStateOnActivation(); 529 UpdateStateOnActivation();
577 return; 530 return;
578 531
579 case ACTION_ANIMATE: 532 case ACTION_ANIMATE:
580 last_frame_number_animate_performed_ = current_frame_number_; 533 last_frame_number_animate_performed_ = current_frame_number_;
581 needs_animate_ = false; 534 needs_animate_ = false;
582 did_commit_after_animating_ = false; 535 did_commit_after_animating_ = false;
583 // TODO(skyostil): Instead of assuming this, require the client to tell 536 // TODO(skyostil): Instead of assuming this, require the client to tell
584 // us. 537 // us.
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 724
772 // The forced draw respects our normal draw scheduling, so we need to 725 // The forced draw respects our normal draw scheduling, so we need to
773 // request a BeginImplFrame for it. 726 // request a BeginImplFrame for it.
774 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) 727 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
775 return true; 728 return true;
776 729
777 // There's no need to produce frames if we are not visible. 730 // There's no need to produce frames if we are not visible.
778 if (!visible_) 731 if (!visible_)
779 return false; 732 return false;
780 733
781 // We need to draw a more complete frame than we did the last BeginImplFrame,
782 // so request another BeginImplFrame in anticipation that we will have
783 // additional visible tiles.
784 if (swap_used_incomplete_tile_)
785 return true;
786
787 if (needs_animate_) 734 if (needs_animate_)
788 return true; 735 return true;
789 736
790 return needs_redraw_; 737 return needs_redraw_;
791 } 738 }
792 739
793 // These are cases where we are very likely to draw soon, but might not 740 // These are cases where we are very likely to draw soon, but might not
794 // actually have a new frame to draw when we receive the next BeginImplFrame. 741 // actually have a new frame to draw when we receive the next BeginImplFrame.
795 // Proactively requesting the BeginImplFrame helps hide the round trip latency 742 // Proactively requesting the BeginImplFrame helps hide the round trip latency
796 // of the SetNeedsBeginFrame request that has to go to the Browser. 743 // of the SetNeedsBeginFrame request that has to go to the Browser.
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 max_pending_swaps_ = max; 917 max_pending_swaps_ = max;
971 } 918 }
972 919
973 void SchedulerStateMachine::DidSwapBuffers() { 920 void SchedulerStateMachine::DidSwapBuffers() {
974 pending_swaps_++; 921 pending_swaps_++;
975 DCHECK_LE(pending_swaps_, max_pending_swaps_); 922 DCHECK_LE(pending_swaps_, max_pending_swaps_);
976 923
977 last_frame_number_swap_performed_ = current_frame_number_; 924 last_frame_number_swap_performed_ = current_frame_number_;
978 } 925 }
979 926
980 void SchedulerStateMachine::SetSwapUsedIncompleteTile(
981 bool used_incomplete_tile) {
982 swap_used_incomplete_tile_ = used_incomplete_tile;
983 }
984
985 void SchedulerStateMachine::DidSwapBuffersComplete() { 927 void SchedulerStateMachine::DidSwapBuffersComplete() {
986 DCHECK_GT(pending_swaps_, 0); 928 DCHECK_GT(pending_swaps_, 0);
987 pending_swaps_--; 929 pending_swaps_--;
988 } 930 }
989 931
990 void SchedulerStateMachine::SetImplLatencyTakesPriority( 932 void SchedulerStateMachine::SetImplLatencyTakesPriority(
991 bool impl_latency_takes_priority) { 933 bool impl_latency_takes_priority) {
992 impl_latency_takes_priority_ = impl_latency_takes_priority; 934 impl_latency_takes_priority_ = impl_latency_takes_priority;
993 } 935 }
994 936
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1115 static_cast<int>(begin_impl_frame_state_), 1057 static_cast<int>(begin_impl_frame_state_),
1116 static_cast<int>(commit_state_), 1058 static_cast<int>(commit_state_),
1117 has_pending_tree_ ? 'T' : 'F', 1059 has_pending_tree_ ? 'T' : 'F',
1118 pending_tree_is_ready_for_activation_ ? 'T' : 'F', 1060 pending_tree_is_ready_for_activation_ ? 'T' : 'F',
1119 active_tree_needs_first_draw_ ? 'T' : 'F', 1061 active_tree_needs_first_draw_ ? 'T' : 'F',
1120 max_pending_swaps_, 1062 max_pending_swaps_,
1121 pending_swaps_); 1063 pending_swaps_);
1122 } 1064 }
1123 1065
1124 } // namespace cc 1066 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698