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

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

Issue 206793003: cc: Split animating and drawing into separate actions (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments and rebased. 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 | Annotate | Revision Log
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_animate_performed_(-1),
25 last_frame_number_swap_performed_(-1), 26 last_frame_number_swap_performed_(-1),
26 last_frame_number_begin_main_frame_sent_(-1), 27 last_frame_number_begin_main_frame_sent_(-1),
27 last_frame_number_update_visible_tiles_was_called_(-1), 28 last_frame_number_update_visible_tiles_was_called_(-1),
28 manage_tiles_funnel_(0), 29 manage_tiles_funnel_(0),
29 consecutive_checkerboard_animations_(0), 30 consecutive_checkerboard_animations_(0),
30 needs_redraw_(false), 31 needs_redraw_(false),
32 needs_animate_(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),
40 active_tree_needs_first_draw_(false), 42 active_tree_needs_first_draw_(false),
41 draw_if_possible_failed_(false), 43 draw_if_possible_failed_(false),
42 did_create_and_initialize_first_output_surface_(false), 44 did_create_and_initialize_first_output_surface_(false),
43 smoothness_takes_priority_(false), 45 smoothness_takes_priority_(false),
44 skip_next_begin_main_frame_to_reduce_latency_(false), 46 skip_next_begin_main_frame_to_reduce_latency_(false),
45 skip_begin_main_frame_to_reduce_latency_(false), 47 skip_begin_main_frame_to_reduce_latency_(false),
46 continuous_painting_(false), 48 continuous_painting_(false),
47 needs_back_to_back_readback_(false) {} 49 needs_back_to_back_readback_(false) {
50 }
48 51
49 const char* SchedulerStateMachine::OutputSurfaceStateToString( 52 const char* SchedulerStateMachine::OutputSurfaceStateToString(
50 OutputSurfaceState state) { 53 OutputSurfaceState state) {
51 switch (state) { 54 switch (state) {
52 case OUTPUT_SURFACE_ACTIVE: 55 case OUTPUT_SURFACE_ACTIVE:
53 return "OUTPUT_SURFACE_ACTIVE"; 56 return "OUTPUT_SURFACE_ACTIVE";
54 case OUTPUT_SURFACE_LOST: 57 case OUTPUT_SURFACE_LOST:
55 return "OUTPUT_SURFACE_LOST"; 58 return "OUTPUT_SURFACE_LOST";
56 case OUTPUT_SURFACE_CREATING: 59 case OUTPUT_SURFACE_CREATING:
57 return "OUTPUT_SURFACE_CREATING"; 60 return "OUTPUT_SURFACE_CREATING";
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 return "FORCED_REDRAW_STATE_WAITING_FOR_DRAW"; 137 return "FORCED_REDRAW_STATE_WAITING_FOR_DRAW";
135 } 138 }
136 NOTREACHED(); 139 NOTREACHED();
137 return "???"; 140 return "???";
138 } 141 }
139 142
140 const char* SchedulerStateMachine::ActionToString(Action action) { 143 const char* SchedulerStateMachine::ActionToString(Action action) {
141 switch (action) { 144 switch (action) {
142 case ACTION_NONE: 145 case ACTION_NONE:
143 return "ACTION_NONE"; 146 return "ACTION_NONE";
147 case ACTION_ANIMATE:
148 return "ACTION_ANIMATE";
144 case ACTION_SEND_BEGIN_MAIN_FRAME: 149 case ACTION_SEND_BEGIN_MAIN_FRAME:
145 return "ACTION_SEND_BEGIN_MAIN_FRAME"; 150 return "ACTION_SEND_BEGIN_MAIN_FRAME";
146 case ACTION_COMMIT: 151 case ACTION_COMMIT:
147 return "ACTION_COMMIT"; 152 return "ACTION_COMMIT";
148 case ACTION_UPDATE_VISIBLE_TILES: 153 case ACTION_UPDATE_VISIBLE_TILES:
149 return "ACTION_UPDATE_VISIBLE_TILES"; 154 return "ACTION_UPDATE_VISIBLE_TILES";
150 case ACTION_ACTIVATE_PENDING_TREE: 155 case ACTION_ACTIVATE_PENDING_TREE:
151 return "ACTION_ACTIVATE_PENDING_TREE"; 156 return "ACTION_ACTIVATE_PENDING_TREE";
152 case ACTION_DRAW_AND_SWAP_IF_POSSIBLE: 157 case ACTION_DRAW_AND_SWAP_IF_POSSIBLE:
153 return "ACTION_DRAW_AND_SWAP_IF_POSSIBLE"; 158 return "ACTION_DRAW_AND_SWAP_IF_POSSIBLE";
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 timestamps_state->SetDouble( 212 timestamps_state->SetDouble(
208 "6_deadline", 213 "6_deadline",
209 (begin_impl_frame_args_.deadline - base::TimeTicks()).InMicroseconds() / 214 (begin_impl_frame_args_.deadline - base::TimeTicks()).InMicroseconds() /
210 1000.0L); 215 1000.0L);
211 state->Set("major_timestamps_in_ms", timestamps_state.release()); 216 state->Set("major_timestamps_in_ms", timestamps_state.release());
212 217
213 scoped_ptr<base::DictionaryValue> minor_state(new base::DictionaryValue); 218 scoped_ptr<base::DictionaryValue> minor_state(new base::DictionaryValue);
214 minor_state->SetInteger("commit_count", commit_count_); 219 minor_state->SetInteger("commit_count", commit_count_);
215 minor_state->SetInteger("current_frame_number", current_frame_number_); 220 minor_state->SetInteger("current_frame_number", current_frame_number_);
216 221
222 minor_state->SetInteger("last_frame_number_animate_performed",
223 last_frame_number_animate_performed_);
217 minor_state->SetInteger("last_frame_number_swap_performed", 224 minor_state->SetInteger("last_frame_number_swap_performed",
218 last_frame_number_swap_performed_); 225 last_frame_number_swap_performed_);
219 minor_state->SetInteger( 226 minor_state->SetInteger(
220 "last_frame_number_begin_main_frame_sent", 227 "last_frame_number_begin_main_frame_sent",
221 last_frame_number_begin_main_frame_sent_); 228 last_frame_number_begin_main_frame_sent_);
222 minor_state->SetInteger( 229 minor_state->SetInteger(
223 "last_frame_number_update_visible_tiles_was_called", 230 "last_frame_number_update_visible_tiles_was_called",
224 last_frame_number_update_visible_tiles_was_called_); 231 last_frame_number_update_visible_tiles_was_called_);
225 232
226 minor_state->SetInteger("manage_tiles_funnel", manage_tiles_funnel_); 233 minor_state->SetInteger("manage_tiles_funnel", manage_tiles_funnel_);
227 minor_state->SetInteger("consecutive_checkerboard_animations", 234 minor_state->SetInteger("consecutive_checkerboard_animations",
228 consecutive_checkerboard_animations_); 235 consecutive_checkerboard_animations_);
229 minor_state->SetBoolean("needs_redraw", needs_redraw_); 236 minor_state->SetBoolean("needs_redraw", needs_redraw_);
237 minor_state->SetBoolean("needs_animate_", needs_animate_);
230 minor_state->SetBoolean("needs_manage_tiles", needs_manage_tiles_); 238 minor_state->SetBoolean("needs_manage_tiles", needs_manage_tiles_);
231 minor_state->SetBoolean("swap_used_incomplete_tile", 239 minor_state->SetBoolean("swap_used_incomplete_tile",
232 swap_used_incomplete_tile_); 240 swap_used_incomplete_tile_);
233 minor_state->SetBoolean("needs_commit", needs_commit_); 241 minor_state->SetBoolean("needs_commit", needs_commit_);
234 minor_state->SetBoolean("visible", visible_); 242 minor_state->SetBoolean("visible", visible_);
235 minor_state->SetBoolean("can_start", can_start_); 243 minor_state->SetBoolean("can_start", can_start_);
236 minor_state->SetBoolean("can_draw", can_draw_); 244 minor_state->SetBoolean("can_draw", can_draw_);
237 minor_state->SetBoolean("has_pending_tree", has_pending_tree_); 245 minor_state->SetBoolean("has_pending_tree", has_pending_tree_);
238 minor_state->SetBoolean("pending_tree_is_ready_for_activation", 246 minor_state->SetBoolean("pending_tree_is_ready_for_activation",
239 pending_tree_is_ready_for_activation_); 247 pending_tree_is_ready_for_activation_);
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 420
413 // If the last swap drew with checkerboard or missing tiles, we should 421 // If the last swap drew with checkerboard or missing tiles, we should
414 // poll for any new visible tiles so we can be notified to draw again 422 // poll for any new visible tiles so we can be notified to draw again
415 // when there are. 423 // when there are.
416 if (swap_used_incomplete_tile_) 424 if (swap_used_incomplete_tile_)
417 return true; 425 return true;
418 426
419 return false; 427 return false;
420 } 428 }
421 429
430 bool SchedulerStateMachine::ShouldAnimate() const {
431 if (!can_draw_)
432 return false;
433
434 if (last_frame_number_animate_performed_ == current_frame_number_)
435 return false;
436
437 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING &&
438 begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
439 return false;
440
441 return needs_redraw_ || needs_animate_;
442 }
443
422 bool SchedulerStateMachine::ShouldSendBeginMainFrame() const { 444 bool SchedulerStateMachine::ShouldSendBeginMainFrame() const {
423 if (!needs_commit_) 445 if (!needs_commit_)
424 return false; 446 return false;
425 447
426 // Only send BeginMainFrame when there isn't another commit pending already. 448 // Only send BeginMainFrame when there isn't another commit pending already.
427 if (commit_state_ != COMMIT_STATE_IDLE) 449 if (commit_state_ != COMMIT_STATE_IDLE)
428 return false; 450 return false;
429 451
430 // Don't send BeginMainFrame early if we are prioritizing the active tree 452 // Don't send BeginMainFrame early if we are prioritizing the active tree
431 // because of smoothness_takes_priority. 453 // because of smoothness_takes_priority.
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 return needs_manage_tiles_; 533 return needs_manage_tiles_;
512 } 534 }
513 535
514 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { 536 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const {
515 if (ShouldUpdateVisibleTiles()) 537 if (ShouldUpdateVisibleTiles())
516 return ACTION_UPDATE_VISIBLE_TILES; 538 return ACTION_UPDATE_VISIBLE_TILES;
517 if (ShouldActivatePendingTree()) 539 if (ShouldActivatePendingTree())
518 return ACTION_ACTIVATE_PENDING_TREE; 540 return ACTION_ACTIVATE_PENDING_TREE;
519 if (ShouldCommit()) 541 if (ShouldCommit())
520 return ACTION_COMMIT; 542 return ACTION_COMMIT;
543 if (ShouldAnimate())
544 return ACTION_ANIMATE;
521 if (ShouldDraw()) { 545 if (ShouldDraw()) {
522 if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) 546 if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK)
523 return ACTION_DRAW_AND_READBACK; 547 return ACTION_DRAW_AND_READBACK;
524 else if (PendingDrawsShouldBeAborted()) 548 else if (PendingDrawsShouldBeAborted())
525 return ACTION_DRAW_AND_SWAP_ABORT; 549 return ACTION_DRAW_AND_SWAP_ABORT;
526 else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) 550 else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
527 return ACTION_DRAW_AND_SWAP_FORCED; 551 return ACTION_DRAW_AND_SWAP_FORCED;
528 else 552 else
529 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE; 553 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
530 } 554 }
(...skipping 20 matching lines...) Expand all
551 575
552 case ACTION_UPDATE_VISIBLE_TILES: 576 case ACTION_UPDATE_VISIBLE_TILES:
553 last_frame_number_update_visible_tiles_was_called_ = 577 last_frame_number_update_visible_tiles_was_called_ =
554 current_frame_number_; 578 current_frame_number_;
555 return; 579 return;
556 580
557 case ACTION_ACTIVATE_PENDING_TREE: 581 case ACTION_ACTIVATE_PENDING_TREE:
558 UpdateStateOnActivation(); 582 UpdateStateOnActivation();
559 return; 583 return;
560 584
585 case ACTION_ANIMATE:
586 last_frame_number_animate_performed_ = current_frame_number_;
587 needs_animate_ = false;
588 // TODO(skyostil): Instead of assuming this, require the client to tell
589 // us.
590 SetNeedsRedraw();
591 return;
592
561 case ACTION_SEND_BEGIN_MAIN_FRAME: 593 case ACTION_SEND_BEGIN_MAIN_FRAME:
562 DCHECK(!has_pending_tree_ || 594 DCHECK(!has_pending_tree_ ||
563 settings_.main_frame_before_activation_enabled); 595 settings_.main_frame_before_activation_enabled);
564 DCHECK(!active_tree_needs_first_draw_ || 596 DCHECK(!active_tree_needs_first_draw_ ||
565 settings_.main_frame_before_draw_enabled); 597 settings_.main_frame_before_draw_enabled);
566 DCHECK(visible_ || 598 DCHECK(visible_ ||
567 readback_state_ == READBACK_STATE_NEEDS_BEGIN_MAIN_FRAME); 599 readback_state_ == READBACK_STATE_NEEDS_BEGIN_MAIN_FRAME);
568 commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_SENT; 600 commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_SENT;
569 needs_commit_ = false; 601 needs_commit_ = false;
570 if (readback_state_ == READBACK_STATE_NEEDS_BEGIN_MAIN_FRAME) 602 if (readback_state_ == READBACK_STATE_NEEDS_BEGIN_MAIN_FRAME)
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 // There's no need to produce frames if we are not visible. 848 // There's no need to produce frames if we are not visible.
817 if (!visible_) 849 if (!visible_)
818 return false; 850 return false;
819 851
820 // We need to draw a more complete frame than we did the last BeginImplFrame, 852 // We need to draw a more complete frame than we did the last BeginImplFrame,
821 // so request another BeginImplFrame in anticipation that we will have 853 // so request another BeginImplFrame in anticipation that we will have
822 // additional visible tiles. 854 // additional visible tiles.
823 if (swap_used_incomplete_tile_) 855 if (swap_used_incomplete_tile_)
824 return true; 856 return true;
825 857
858 if (needs_animate_)
brianderson 2014/04/18 01:10:54 If the BeginFrame is needed to advance the animati
Sami 2014/04/22 10:34:33 It feels like an animation request is a stronger s
859 return true;
860
826 return needs_redraw_; 861 return needs_redraw_;
827 } 862 }
828 863
829 // These are cases where we are very likely to draw soon, but might not 864 // These are cases where we are very likely to draw soon, but might not
830 // actually have a new frame to draw when we receive the next BeginImplFrame. 865 // actually have a new frame to draw when we receive the next BeginImplFrame.
831 // Proactively requesting the BeginImplFrame helps hide the round trip latency 866 // Proactively requesting the BeginImplFrame helps hide the round trip latency
832 // of the SetNeedsBeginFrame request that has to go to the Browser. 867 // of the SetNeedsBeginFrame request that has to go to the Browser.
833 bool SchedulerStateMachine::ProactiveBeginFrameWanted() const { 868 bool SchedulerStateMachine::ProactiveBeginFrameWanted() const {
834 // The output surface is the provider of BeginImplFrames, 869 // The output surface is the provider of BeginImplFrames,
835 // so we are not going to get them even if we ask for them. 870 // so we are not going to get them even if we ask for them.
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
981 void SchedulerStateMachine::DidLeavePollForAnticipatedDrawTriggers() { 1016 void SchedulerStateMachine::DidLeavePollForAnticipatedDrawTriggers() {
982 inside_poll_for_anticipated_draw_triggers_ = false; 1017 inside_poll_for_anticipated_draw_triggers_ = false;
983 } 1018 }
984 1019
985 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } 1020 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; }
986 1021
987 void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; } 1022 void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; }
988 1023
989 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } 1024 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; }
990 1025
1026 void SchedulerStateMachine::SetNeedsAnimate() {
1027 needs_animate_ = true;
1028 }
1029
991 void SchedulerStateMachine::SetNeedsManageTiles() { 1030 void SchedulerStateMachine::SetNeedsManageTiles() {
992 if (!needs_manage_tiles_) { 1031 if (!needs_manage_tiles_) {
993 TRACE_EVENT0("cc", 1032 TRACE_EVENT0("cc",
994 "SchedulerStateMachine::SetNeedsManageTiles"); 1033 "SchedulerStateMachine::SetNeedsManageTiles");
995 needs_manage_tiles_ = true; 1034 needs_manage_tiles_ = true;
996 } 1035 }
997 } 1036 }
998 1037
999 void SchedulerStateMachine::SetSwapUsedIncompleteTile( 1038 void SchedulerStateMachine::SetSwapUsedIncompleteTile(
1000 bool used_incomplete_tile) { 1039 bool used_incomplete_tile) {
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
1153 case OUTPUT_SURFACE_ACTIVE: 1192 case OUTPUT_SURFACE_ACTIVE:
1154 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: 1193 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT:
1155 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: 1194 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION:
1156 return true; 1195 return true;
1157 } 1196 }
1158 NOTREACHED(); 1197 NOTREACHED();
1159 return false; 1198 return false;
1160 } 1199 }
1161 1200
1162 } // namespace cc 1201 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/scheduler_state_machine.h ('k') | cc/scheduler/scheduler_state_machine_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698