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

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

Issue 1131633003: cc: Use multiple PrepareTiles approaches Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 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/format_macros.h" 7 #include "base/format_macros.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/strings/stringprintf.h" 9 #include "base/strings/stringprintf.h"
10 #include "base/trace_event/trace_event.h" 10 #include "base/trace_event/trace_event.h"
11 #include "base/trace_event/trace_event_argument.h" 11 #include "base/trace_event/trace_event_argument.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 prepare_tiles_approach_(PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY),
23 prepare_tiles_reason_(PREPARE_TILES_NOT_NEEDED),
23 commit_count_(0), 24 commit_count_(0),
24 current_frame_number_(0), 25 current_frame_number_(0),
25 last_frame_number_animate_performed_(-1), 26 last_frame_number_animate_performed_(-1),
26 last_frame_number_swap_performed_(-1), 27 last_frame_number_swap_performed_(-1),
27 last_frame_number_swap_requested_(-1), 28 last_frame_number_swap_requested_(-1),
28 last_frame_number_begin_main_frame_sent_(-1), 29 last_frame_number_begin_main_frame_sent_(-1),
29 last_frame_number_invalidate_output_surface_performed_(-1), 30 last_frame_number_invalidate_output_surface_performed_(-1),
30 animate_funnel_(false), 31 animate_funnel_(false),
31 request_swap_funnel_(false), 32 request_swap_funnel_(false),
32 send_begin_main_frame_funnel_(false), 33 send_begin_main_frame_funnel_(false),
33 invalidate_output_surface_funnel_(false), 34 invalidate_output_surface_funnel_(false),
34 prepare_tiles_funnel_(0), 35 prepare_tiles_funnel_(0),
35 consecutive_checkerboard_animations_(0),
36 max_pending_swaps_(1), 36 max_pending_swaps_(1),
37 pending_swaps_(0), 37 pending_swaps_(0),
38 needs_redraw_(false), 38 needs_redraw_(false),
39 last_draw_result_(DRAW_SUCCESS),
39 needs_animate_(false), 40 needs_animate_(false),
40 needs_prepare_tiles_(false),
41 needs_commit_(false), 41 needs_commit_(false),
42 visible_(false), 42 visible_(false),
43 can_start_(false), 43 can_start_(false),
44 can_draw_(false), 44 can_draw_(false),
45 has_pending_tree_(false), 45 has_pending_tree_(false),
46 pending_tree_is_ready_for_activation_(false), 46 pending_tree_is_ready_for_activation_(false),
47 requires_high_res_to_draw_(false),
47 active_tree_needs_first_draw_(false), 48 active_tree_needs_first_draw_(false),
48 did_create_and_initialize_first_output_surface_(false), 49 did_create_and_initialize_first_output_surface_(false),
49 impl_latency_takes_priority_(false), 50 impl_latency_takes_priority_(false),
50 skip_next_begin_main_frame_to_reduce_latency_(false), 51 skip_next_begin_main_frame_to_reduce_latency_(false),
51 skip_begin_main_frame_to_reduce_latency_(false), 52 skip_begin_main_frame_to_reduce_latency_(false),
52 continuous_painting_(false), 53 continuous_painting_(false),
53 children_need_begin_frames_(false), 54 children_need_begin_frames_(false),
54 defer_commits_(false), 55 defer_commits_(false),
55 video_needs_begin_frames_(false), 56 video_needs_begin_frames_(false),
56 last_commit_had_no_updates_(false), 57 last_commit_had_no_updates_(false),
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 BeginImplFrameDeadlineMode mode) { 98 BeginImplFrameDeadlineMode mode) {
98 switch (mode) { 99 switch (mode) {
99 case BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE: 100 case BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE:
100 return "BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE"; 101 return "BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE";
101 case BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE: 102 case BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE:
102 return "BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE"; 103 return "BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE";
103 case BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR: 104 case BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR:
104 return "BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR"; 105 return "BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR";
105 case BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE: 106 case BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE:
106 return "BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE"; 107 return "BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE";
108 case BEGIN_IMPL_FRAME_DEADLINE_MODE_TRY_TO_AVOID_CHECKERBOARD:
109 return "BEGIN_IMPL_FRAME_DEADLINE_MODE_TRY_TO_AVOID_CHECKERBOARD";
107 case BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW: 110 case BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW:
108 return "BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW"; 111 return "BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW";
109 } 112 }
110 NOTREACHED(); 113 NOTREACHED();
111 return "???"; 114 return "???";
112 } 115 }
113 116
114 const char* SchedulerStateMachine::CommitStateToString(CommitState state) { 117 const char* SchedulerStateMachine::CommitStateToString(CommitState state) {
115 switch (state) { 118 switch (state) {
116 case COMMIT_STATE_IDLE: 119 case COMMIT_STATE_IDLE:
117 return "COMMIT_STATE_IDLE"; 120 return "COMMIT_STATE_IDLE";
118 case COMMIT_STATE_BEGIN_MAIN_FRAME_SENT: 121 case COMMIT_STATE_BEGIN_MAIN_FRAME_SENT:
119 return "COMMIT_STATE_BEGIN_MAIN_FRAME_SENT"; 122 return "COMMIT_STATE_BEGIN_MAIN_FRAME_SENT";
120 case COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED: 123 case COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED:
121 return "COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED"; 124 return "COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED";
122 case COMMIT_STATE_READY_TO_COMMIT: 125 case COMMIT_STATE_READY_TO_COMMIT:
123 return "COMMIT_STATE_READY_TO_COMMIT"; 126 return "COMMIT_STATE_READY_TO_COMMIT";
124 case COMMIT_STATE_WAITING_FOR_ACTIVATION: 127 case COMMIT_STATE_WAITING_FOR_ACTIVATION:
125 return "COMMIT_STATE_WAITING_FOR_ACTIVATION"; 128 return "COMMIT_STATE_WAITING_FOR_ACTIVATION";
126 case COMMIT_STATE_WAITING_FOR_DRAW: 129 case COMMIT_STATE_WAITING_FOR_DRAW:
127 return "COMMIT_STATE_WAITING_FOR_DRAW"; 130 return "COMMIT_STATE_WAITING_FOR_DRAW";
128 } 131 }
129 NOTREACHED(); 132 NOTREACHED();
130 return "???"; 133 return "???";
131 } 134 }
132 135
133 const char* SchedulerStateMachine::ForcedRedrawOnTimeoutStateToString( 136 const char* SchedulerStateMachine::PrepareTilesApproachToString(
134 ForcedRedrawOnTimeoutState state) { 137 PrepareTilesApproach approach) {
135 switch (state) { 138 switch (approach) {
136 case FORCED_REDRAW_STATE_IDLE: 139 case PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY:
137 return "FORCED_REDRAW_STATE_IDLE"; 140 return "PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY";
138 case FORCED_REDRAW_STATE_WAITING_FOR_COMMIT: 141 case PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_WORK:
139 return "FORCED_REDRAW_STATE_WAITING_FOR_COMMIT"; 142 return "PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_WORK";
140 case FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION: 143 case PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_PENDING_WORK:
141 return "FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION"; 144 return "PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_PENDING_WORK";
142 case FORCED_REDRAW_STATE_WAITING_FOR_DRAW: 145 case PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_PENDING_CANCELED_WORK:
143 return "FORCED_REDRAW_STATE_WAITING_FOR_DRAW"; 146 return "PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_PENDING_CANCELED_WORK";
144 } 147 }
145 NOTREACHED(); 148 NOTREACHED();
146 return "???"; 149 return "???";
150 }
151
152 const char* SchedulerStateMachine::PrepareTilesReasonToString(
153 PrepareTilesReason reason) {
154 switch (reason) {
155 case PREPARE_TILES_NOT_NEEDED:
156 return "PREPARE_TILES_NOT_NEEDED";
157 case PREPARE_TILES_REQUESTED:
158 return "PREPARE_TILES_REQUESTED";
159 case PREPARE_TILES_NEEDED_FOR_COMMIT:
160 return "PREPARE_TILES_NEEDED_FOR_COMMIT";
161 case PREPARE_TILES_NEEDED_FOR_ACTIVATION:
162 return "PREPARE_TILES_NEEDED_FOR_ACTIVATION";
163 case PREPARE_TILES_NEEDED_FOR_ABORTED_DRAW:
164 return "PREPARE_TILES_NEEDED_FOR_ABORTED_DRAW";
165 case PREPARE_TILES_NEEDED_TO_EVICT_TILES:
166 return "PREPARE_TILES_NEEDED_TO_EVICT_TILES";
167 }
168 NOTREACHED();
169 return "???";
147 } 170 }
148 171
149 const char* SchedulerStateMachine::ActionToString(Action action) { 172 const char* SchedulerStateMachine::ActionToString(Action action) {
150 switch (action) { 173 switch (action) {
151 case ACTION_NONE: 174 case ACTION_NONE:
152 return "ACTION_NONE"; 175 return "ACTION_NONE";
153 case ACTION_ANIMATE: 176 case ACTION_ANIMATE:
154 return "ACTION_ANIMATE"; 177 return "ACTION_ANIMATE";
155 case ACTION_SEND_BEGIN_MAIN_FRAME: 178 case ACTION_SEND_BEGIN_MAIN_FRAME:
156 return "ACTION_SEND_BEGIN_MAIN_FRAME"; 179 return "ACTION_SEND_BEGIN_MAIN_FRAME";
(...skipping 26 matching lines...) Expand all
183 return state; 206 return state;
184 } 207 }
185 208
186 void SchedulerStateMachine::AsValueInto( 209 void SchedulerStateMachine::AsValueInto(
187 base::trace_event::TracedValue* state) const { 210 base::trace_event::TracedValue* state) const {
188 state->BeginDictionary("major_state"); 211 state->BeginDictionary("major_state");
189 state->SetString("next_action", ActionToString(NextAction())); 212 state->SetString("next_action", ActionToString(NextAction()));
190 state->SetString("begin_impl_frame_state", 213 state->SetString("begin_impl_frame_state",
191 BeginImplFrameStateToString(begin_impl_frame_state_)); 214 BeginImplFrameStateToString(begin_impl_frame_state_));
192 state->SetString("commit_state", CommitStateToString(commit_state_)); 215 state->SetString("commit_state", CommitStateToString(commit_state_));
193 state->SetString("output_surface_state_", 216 state->SetString("prepare_tiles_approach",
217 PrepareTilesApproachToString(prepare_tiles_approach_));
218 state->SetString("prepare_tiles_reason",
219 PrepareTilesReasonToString(prepare_tiles_reason_));
220 state->SetString("output_surface_state",
194 OutputSurfaceStateToString(output_surface_state_)); 221 OutputSurfaceStateToString(output_surface_state_));
195 state->SetString("forced_redraw_state",
196 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_));
197 state->EndDictionary(); 222 state->EndDictionary();
198 223
199 state->BeginDictionary("minor_state"); 224 state->BeginDictionary("minor_state");
200 state->SetInteger("commit_count", commit_count_); 225 state->SetInteger("commit_count", commit_count_);
201 state->SetInteger("current_frame_number", current_frame_number_); 226 state->SetInteger("current_frame_number", current_frame_number_);
202 state->SetInteger("last_frame_number_animate_performed", 227 state->SetInteger("last_frame_number_animate_performed",
203 last_frame_number_animate_performed_); 228 last_frame_number_animate_performed_);
204 state->SetInteger("last_frame_number_swap_performed", 229 state->SetInteger("last_frame_number_swap_performed",
205 last_frame_number_swap_performed_); 230 last_frame_number_swap_performed_);
206 state->SetInteger("last_frame_number_swap_requested", 231 state->SetInteger("last_frame_number_swap_requested",
207 last_frame_number_swap_requested_); 232 last_frame_number_swap_requested_);
208 state->SetInteger("last_frame_number_begin_main_frame_sent", 233 state->SetInteger("last_frame_number_begin_main_frame_sent",
209 last_frame_number_begin_main_frame_sent_); 234 last_frame_number_begin_main_frame_sent_);
210 state->SetBoolean("funnel: animate_funnel", animate_funnel_); 235 state->SetBoolean("funnel: animate_funnel", animate_funnel_);
211 state->SetBoolean("funnel: request_swap_funnel", request_swap_funnel_); 236 state->SetBoolean("funnel: request_swap_funnel", request_swap_funnel_);
212 state->SetBoolean("funnel: send_begin_main_frame_funnel", 237 state->SetBoolean("funnel: send_begin_main_frame_funnel",
213 send_begin_main_frame_funnel_); 238 send_begin_main_frame_funnel_);
214 state->SetInteger("funnel: prepare_tiles_funnel", prepare_tiles_funnel_); 239 state->SetInteger("funnel: prepare_tiles_funnel", prepare_tiles_funnel_);
215 state->SetBoolean("funnel: invalidate_output_surface_funnel", 240 state->SetBoolean("funnel: invalidate_output_surface_funnel",
216 invalidate_output_surface_funnel_); 241 invalidate_output_surface_funnel_);
217 state->SetInteger("consecutive_checkerboard_animations",
218 consecutive_checkerboard_animations_);
219 state->SetInteger("max_pending_swaps_", max_pending_swaps_); 242 state->SetInteger("max_pending_swaps_", max_pending_swaps_);
220 state->SetInteger("pending_swaps_", pending_swaps_); 243 state->SetInteger("pending_swaps_", pending_swaps_);
221 state->SetBoolean("needs_redraw", needs_redraw_); 244 state->SetBoolean("needs_redraw", needs_redraw_);
222 state->SetBoolean("needs_animate_", needs_animate_); 245 state->SetBoolean("needs_animate_", needs_animate_);
223 state->SetBoolean("needs_prepare_tiles", needs_prepare_tiles_);
224 state->SetBoolean("needs_commit", needs_commit_); 246 state->SetBoolean("needs_commit", needs_commit_);
225 state->SetBoolean("visible", visible_); 247 state->SetBoolean("visible", visible_);
226 state->SetBoolean("can_start", can_start_); 248 state->SetBoolean("can_start", can_start_);
227 state->SetBoolean("can_draw", can_draw_); 249 state->SetBoolean("can_draw", can_draw_);
228 state->SetBoolean("has_pending_tree", has_pending_tree_); 250 state->SetBoolean("has_pending_tree", has_pending_tree_);
229 state->SetBoolean("pending_tree_is_ready_for_activation", 251 state->SetBoolean("pending_tree_is_ready_for_activation",
230 pending_tree_is_ready_for_activation_); 252 pending_tree_is_ready_for_activation_);
231 state->SetBoolean("active_tree_needs_first_draw", 253 state->SetBoolean("active_tree_needs_first_draw",
232 active_tree_needs_first_draw_); 254 active_tree_needs_first_draw_);
233 state->SetBoolean("wait_for_active_tree_ready_to_draw", 255 state->SetBoolean("wait_for_active_tree_ready_to_draw",
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 360
339 // Do not queue too many swaps. 361 // Do not queue too many swaps.
340 if (pending_swaps_ >= max_pending_swaps_) 362 if (pending_swaps_ >= max_pending_swaps_)
341 return false; 363 return false;
342 364
343 // Except for the cases above, do not draw outside of the BeginImplFrame 365 // Except for the cases above, do not draw outside of the BeginImplFrame
344 // deadline. 366 // deadline.
345 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) 367 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
346 return false; 368 return false;
347 369
348 // Only handle forced redraws due to timeouts on the regular deadline.
349 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
350 return true;
351
352 return needs_redraw_; 370 return needs_redraw_;
353 } 371 }
354 372
355 bool SchedulerStateMachine::ShouldActivatePendingTree() const { 373 bool SchedulerStateMachine::ShouldActivatePendingTree() const {
356 // There is nothing to activate. 374 // There is nothing to activate.
357 if (!has_pending_tree_) 375 if (!has_pending_tree_)
358 return false; 376 return false;
359 377
360 // We should not activate a second tree before drawing the first one. 378 // We should not activate a second tree before drawing the first one.
361 // Even if we need to force activation of the pending tree, we should abort 379 // Even if we need to force activation of the pending tree, we should abort
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 441
424 // We should not send BeginMainFrame while we are in 442 // We should not send BeginMainFrame while we are in
425 // BEGIN_IMPL_FRAME_STATE_IDLE since we might have new 443 // BEGIN_IMPL_FRAME_STATE_IDLE since we might have new
426 // user input arriving soon. 444 // user input arriving soon.
427 // TODO(brianderson): Allow sending BeginMainFrame while idle when the main 445 // TODO(brianderson): Allow sending BeginMainFrame while idle when the main
428 // thread isn't consuming user input. 446 // thread isn't consuming user input.
429 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE && 447 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE &&
430 BeginFrameNeeded()) 448 BeginFrameNeeded())
431 return false; 449 return false;
432 450
433 // We need a new commit for the forced redraw. This honors the
434 // single commit per interval because the result will be swapped to screen.
435 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT)
436 return true;
437
438 // We shouldn't normally accept commits if there isn't an OutputSurface. 451 // We shouldn't normally accept commits if there isn't an OutputSurface.
439 if (!HasInitializedOutputSurface()) 452 if (!HasInitializedOutputSurface())
440 return false; 453 return false;
441 454
442 // SwapAck throttle the BeginMainFrames unless we just swapped. 455 // SwapAck throttle the BeginMainFrames unless we just swapped.
443 // TODO(brianderson): Remove this restriction to improve throughput. 456 // TODO(brianderson): Remove this restriction to improve throughput.
444 bool just_swapped_in_deadline = 457 bool just_swapped_in_deadline =
445 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE && 458 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE &&
446 did_perform_swap_in_last_draw_; 459 did_perform_swap_in_last_draw_;
447 if (pending_swaps_ >= max_pending_swaps_ && !just_swapped_in_deadline) 460 if (pending_swaps_ >= max_pending_swaps_ && !just_swapped_in_deadline)
(...skipping 16 matching lines...) Expand all
464 } 477 }
465 478
466 // Prioritize drawing the previous commit before finishing the next commit. 479 // Prioritize drawing the previous commit before finishing the next commit.
467 if (active_tree_needs_first_draw_) 480 if (active_tree_needs_first_draw_)
468 return false; 481 return false;
469 482
470 return true; 483 return true;
471 } 484 }
472 485
473 bool SchedulerStateMachine::ShouldPrepareTiles() const { 486 bool SchedulerStateMachine::ShouldPrepareTiles() const {
474 // PrepareTiles only really needs to be called immediately after commit 487 // Handle the clear cut cases.
475 // and then periodically after that. Use a funnel to make sure we average 488 switch (prepare_tiles_reason_) {
476 // one PrepareTiles per BeginImplFrame in the long run. 489 case PREPARE_TILES_NOT_NEEDED:
477 if (prepare_tiles_funnel_ > 0) 490 return false;
478 return false; 491 case PREPARE_TILES_NEEDED_FOR_COMMIT:
492 case PREPARE_TILES_NEEDED_FOR_ACTIVATION:
493 case PREPARE_TILES_NEEDED_FOR_ABORTED_DRAW:
494 case PREPARE_TILES_NEEDED_TO_EVICT_TILES:
495 return true;
496 case PREPARE_TILES_REQUESTED:
497 break;
498 }
479 499
480 // Limiting to once per-frame is not enough, since we only want to 500 switch (prepare_tiles_approach_) {
481 // prepare tiles _after_ draws. 501 case PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_WORK:
482 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) 502 case PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_PENDING_WORK:
483 return false; 503 case PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_PENDING_CANCELED_WORK:
504 // All of these approaches only handle requested PrepareTiles at the
505 // start of a frame.
506 return begin_impl_frame_state_ ==
507 BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING;
508 case PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY:
509 break;
510 }
484 511
485 return needs_prepare_tiles_; 512 DCHECK_EQ(PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY, prepare_tiles_approach_);
513 DCHECK_EQ(PREPARE_TILES_REQUESTED, prepare_tiles_reason_);
514
515 // Only PrepareTiles after a draw if we haven't already PreparedTiles this
516 // frame. This takes PrepareTiles out of the critical path, but wil make the
517 // NotifyReadyToDraw and NotifyReadyToActivate signals liars.
518 bool did_not_prepare_tiles_at_end_of_frame =
519 prepare_tiles_funnel_ == 0 &&
520 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE;
521 return did_not_prepare_tiles_at_end_of_frame;
486 } 522 }
487 523
488 bool SchedulerStateMachine::ShouldInvalidateOutputSurface() const { 524 bool SchedulerStateMachine::ShouldInvalidateOutputSurface() const {
489 // Do not invalidate too many times in a frame. 525 // Do not invalidate too many times in a frame.
490 if (invalidate_output_surface_funnel_) 526 if (invalidate_output_surface_funnel_)
491 return false; 527 return false;
492 528
493 // Only the synchronous compositor requires invalidations. 529 // Only the synchronous compositor requires invalidations.
494 if (!settings_.using_synchronous_renderer_compositor) 530 if (!settings_.using_synchronous_renderer_compositor)
495 return false; 531 return false;
496 532
497 // Invalidations are only performed inside a BeginFrame. 533 // Invalidations are only performed inside a BeginFrame.
498 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) 534 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING)
499 return false; 535 return false;
500 536
537 // TODO(brianderson): Figure out what to do with this.
501 // TODO(sunnyps): needs_prepare_tiles_ is needed here because PrepareTiles is 538 // TODO(sunnyps): needs_prepare_tiles_ is needed here because PrepareTiles is
502 // called only inside the deadline / draw phase. We could remove this if we 539 // called only inside the deadline / draw phase. We could remove this if we
503 // allowed PrepareTiles to happen in OnBeginImplFrame. 540 // allowed PrepareTiles to happen in OnBeginImplFrame.
504 return needs_redraw_ || needs_prepare_tiles_; 541 return needs_redraw_ || PrepareTilesPending();
505 } 542 }
506 543
507 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { 544 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const {
508 if (ShouldActivatePendingTree()) 545 if (ShouldActivatePendingTree())
509 return ACTION_ACTIVATE_SYNC_TREE; 546 return ACTION_ACTIVATE_SYNC_TREE;
510 if (ShouldCommit()) 547 if (ShouldCommit())
511 return ACTION_COMMIT; 548 return ACTION_COMMIT;
512 if (ShouldAnimate()) 549 if (ShouldAnimate())
513 return ACTION_ANIMATE; 550 return ACTION_ANIMATE;
514 if (ShouldDraw()) { 551 if (ShouldDraw()) {
515 if (PendingDrawsShouldBeAborted()) 552 if (PendingDrawsShouldBeAborted())
516 return ACTION_DRAW_AND_SWAP_ABORT; 553 return ACTION_DRAW_AND_SWAP_ABORT;
517 else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) 554 else if (requires_high_res_to_draw_ ||
555 prepare_tiles_approach_ ==
556 PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY)
557 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
558 else
518 return ACTION_DRAW_AND_SWAP_FORCED; 559 return ACTION_DRAW_AND_SWAP_FORCED;
519 else
520 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
521 } 560 }
522 if (ShouldPrepareTiles()) 561 if (ShouldPrepareTiles())
523 return ACTION_PREPARE_TILES; 562 return ACTION_PREPARE_TILES;
524 if (ShouldSendBeginMainFrame()) 563 if (ShouldSendBeginMainFrame())
525 return ACTION_SEND_BEGIN_MAIN_FRAME; 564 return ACTION_SEND_BEGIN_MAIN_FRAME;
526 if (ShouldInvalidateOutputSurface()) 565 if (ShouldInvalidateOutputSurface())
527 return ACTION_INVALIDATE_OUTPUT_SURFACE; 566 return ACTION_INVALIDATE_OUTPUT_SURFACE;
528 if (ShouldBeginOutputSurfaceCreation()) 567 if (ShouldBeginOutputSurfaceCreation())
529 return ACTION_BEGIN_OUTPUT_SURFACE_CREATION; 568 return ACTION_BEGIN_OUTPUT_SURFACE_CREATION;
530 return ACTION_NONE; 569 return ACTION_NONE;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 } else { 652 } else {
614 commit_state_ = settings_.main_thread_should_always_be_low_latency 653 commit_state_ = settings_.main_thread_should_always_be_low_latency
615 ? COMMIT_STATE_WAITING_FOR_DRAW 654 ? COMMIT_STATE_WAITING_FOR_DRAW
616 : COMMIT_STATE_IDLE; 655 : COMMIT_STATE_IDLE;
617 } 656 }
618 657
619 // If we are impl-side-painting but the commit was aborted, then we behave 658 // If we are impl-side-painting but the commit was aborted, then we behave
620 // mostly as if we are not impl-side-painting since there is no pending tree. 659 // mostly as if we are not impl-side-painting since there is no pending tree.
621 has_pending_tree_ = settings_.impl_side_painting && !commit_has_no_updates; 660 has_pending_tree_ = settings_.impl_side_painting && !commit_has_no_updates;
622 661
623 // Update state related to forced draws.
624 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) {
625 forced_redraw_state_ = has_pending_tree_
626 ? FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
627 : FORCED_REDRAW_STATE_WAITING_FOR_DRAW;
628 }
629
630 // Update the output surface state. 662 // Update the output surface state.
631 DCHECK_NE(output_surface_state_, OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION); 663 DCHECK_NE(output_surface_state_, OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION);
632 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) { 664 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) {
633 if (has_pending_tree_) { 665 if (has_pending_tree_) {
634 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION; 666 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION;
635 } else { 667 } else {
636 output_surface_state_ = OUTPUT_SURFACE_ACTIVE; 668 output_surface_state_ = OUTPUT_SURFACE_ACTIVE;
637 needs_redraw_ = true; 669 needs_redraw_ = true;
638 } 670 }
639 } 671 }
640 672
641 // Update state if we have a new active tree to draw, or if the active tree 673 // Update state if we have a new active tree to draw.
642 // was unchanged but we need to do a forced draw. 674 if (!has_pending_tree_) {
643 if (!has_pending_tree_ &&
644 (!commit_has_no_updates ||
645 forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)) {
646 needs_redraw_ = true; 675 needs_redraw_ = true;
647 active_tree_needs_first_draw_ = true; 676 active_tree_needs_first_draw_ = true;
648 } 677 }
649 678
650 // This post-commit work is common to both completed and aborted commits. 679 // This post-commit work is common to both completed and aborted commits.
651 pending_tree_is_ready_for_activation_ = false; 680 pending_tree_is_ready_for_activation_ = false;
652 681
653 if (continuous_painting_) 682 if (continuous_painting_)
654 needs_commit_ = true; 683 needs_commit_ = true;
655 last_commit_had_no_updates_ = commit_has_no_updates; 684 last_commit_had_no_updates_ = commit_has_no_updates;
656 } 685 }
657 686
658 void SchedulerStateMachine::UpdateStateOnActivation() { 687 void SchedulerStateMachine::UpdateStateOnActivation() {
659 if (commit_state_ == COMMIT_STATE_WAITING_FOR_ACTIVATION) { 688 if (commit_state_ == COMMIT_STATE_WAITING_FOR_ACTIVATION) {
660 commit_state_ = settings_.main_thread_should_always_be_low_latency 689 commit_state_ = settings_.main_thread_should_always_be_low_latency
661 ? COMMIT_STATE_WAITING_FOR_DRAW 690 ? COMMIT_STATE_WAITING_FOR_DRAW
662 : COMMIT_STATE_IDLE; 691 : COMMIT_STATE_IDLE;
663 } 692 }
664 693
665 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION) 694 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION)
666 output_surface_state_ = OUTPUT_SURFACE_ACTIVE; 695 output_surface_state_ = OUTPUT_SURFACE_ACTIVE;
667 696
668 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION) 697 // Make sure to cancel any old active tree work if needed.
669 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_DRAW; 698 if (prepare_tiles_approach_ ==
699 PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_PENDING_CANCELED_WORK)
700 prepare_tiles_reason_ = PREPARE_TILES_NEEDED_FOR_ACTIVATION;
670 701
671 has_pending_tree_ = false; 702 has_pending_tree_ = false;
672 pending_tree_is_ready_for_activation_ = false; 703 pending_tree_is_ready_for_activation_ = false;
673 active_tree_needs_first_draw_ = true; 704 active_tree_needs_first_draw_ = true;
674 needs_redraw_ = true; 705 needs_redraw_ = true;
675 } 706 }
676 707
677 void SchedulerStateMachine::UpdateStateOnDraw(bool did_request_swap) { 708 void SchedulerStateMachine::UpdateStateOnDraw(bool did_request_swap) {
678 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
679 forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE;
680
681 if (commit_state_ == COMMIT_STATE_WAITING_FOR_DRAW) 709 if (commit_state_ == COMMIT_STATE_WAITING_FOR_DRAW)
682 commit_state_ = COMMIT_STATE_IDLE; 710 commit_state_ = COMMIT_STATE_IDLE;
683 711
684 needs_redraw_ = false; 712 needs_redraw_ = false;
685 active_tree_needs_first_draw_ = false; 713 active_tree_needs_first_draw_ = false;
686 714
687 if (did_request_swap) { 715 if (did_request_swap) {
688 DCHECK(!request_swap_funnel_); 716 DCHECK(!request_swap_funnel_);
689 request_swap_funnel_ = true; 717 request_swap_funnel_ = true;
690 did_request_swap_in_last_frame_ = true; 718 did_request_swap_in_last_frame_ = true;
691 last_frame_number_swap_requested_ = current_frame_number_; 719 last_frame_number_swap_requested_ = current_frame_number_;
692 } 720 }
721
722 switch (last_draw_result_) {
723 case INVALID_RESULT:
724 NOTREACHED() << "Uninitialized DrawResult.";
725 break;
726
727 case DRAW_ABORTED_CANT_DRAW:
728 case DRAW_ABORTED_CONTEXT_LOST:
729 NOTREACHED() << "Invalid return value from DrawAndSwapIfPossible:"
730 << last_draw_result_;
731 break;
732
733 case DRAW_SUCCESS:
734 break;
735
736 case DRAW_ABORTED_MISSING_RASTER_OUTPUT_HIGH_RES:
737 case DRAW_ABORTED_MISSING_RASTER_OUTPUT_ANY:
738 TRACE_EVENT_INSTANT0("cc", "Raster missing output.",
739 TRACE_EVENT_SCOPE_THREAD);
740 prepare_tiles_reason_ = PREPARE_TILES_NEEDED_FOR_ABORTED_DRAW;
741 if (prepare_tiles_approach_ ==
742 PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY) {
743 prepare_tiles_approach_ = PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_WORK;
744 }
745 needs_redraw_ = true;
746 // TODO(brianderson): reschedule the deadline.
747 break;
748
749 case DRAW_ABORTED_MISSING_RASTER_SOURCE:
750 TRACE_EVENT_INSTANT0("cc", "Raster missing source.",
751 TRACE_EVENT_SCOPE_THREAD);
752 prepare_tiles_reason_ = PREPARE_TILES_NEEDED_FOR_ABORTED_DRAW;
753 if (prepare_tiles_approach_ ==
754 PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY) {
755 prepare_tiles_approach_ = PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_WORK;
756 }
757 // This is one of the few cases where we actively avoid drawing a commit.
758 // Skipping draw of the commit can be better than a flash of checkerboard.
759 active_tree_needs_first_draw_ = false;
760 // We need a new commit to get an updated raster source.
761 needs_commit_ = true;
762 // TODO(brianderson): reschedule the deadline.
763 break;
764 }
693 } 765 }
694 766
695 void SchedulerStateMachine::UpdateStateOnPrepareTiles() { 767 void SchedulerStateMachine::UpdateStateOnPrepareTiles() {
696 needs_prepare_tiles_ = false; 768 prepare_tiles_reason_ = PREPARE_TILES_NOT_NEEDED;
769
770 active_tree_ready_to_draw_ = false;
771
772 if (prepare_tiles_approach_ == PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY)
773 prepare_tiles_funnel_++;
774 else
775 prepare_tiles_funnel_ = 0;
697 } 776 }
698 777
699 void SchedulerStateMachine::UpdateStateOnBeginOutputSurfaceCreation() { 778 void SchedulerStateMachine::UpdateStateOnBeginOutputSurfaceCreation() {
700 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_LOST); 779 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_LOST);
701 output_surface_state_ = OUTPUT_SURFACE_CREATING; 780 output_surface_state_ = OUTPUT_SURFACE_CREATING;
702 781
703 // The following DCHECKs make sure we are in the proper quiescent state. 782 // The following DCHECKs make sure we are in the proper quiescent state.
704 // The pipeline should be flushed entirely before we start output 783 // The pipeline should be flushed entirely before we start output
705 // surface creation to avoid complicated corner cases. 784 // surface creation to avoid complicated corner cases.
706 DCHECK_EQ(commit_state_, COMMIT_STATE_IDLE); 785 DCHECK_EQ(commit_state_, COMMIT_STATE_IDLE);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
751 void SchedulerStateMachine::SetChildrenNeedBeginFrames( 830 void SchedulerStateMachine::SetChildrenNeedBeginFrames(
752 bool children_need_begin_frames) { 831 bool children_need_begin_frames) {
753 children_need_begin_frames_ = children_need_begin_frames; 832 children_need_begin_frames_ = children_need_begin_frames;
754 } 833 }
755 834
756 void SchedulerStateMachine::SetVideoNeedsBeginFrames( 835 void SchedulerStateMachine::SetVideoNeedsBeginFrames(
757 bool video_needs_begin_frames) { 836 bool video_needs_begin_frames) {
758 video_needs_begin_frames_ = video_needs_begin_frames; 837 video_needs_begin_frames_ = video_needs_begin_frames;
759 } 838 }
760 839
840 void SchedulerStateMachine::NotifyBeginFrameSourceActive(bool active) {
841 // Upon becoming inactive, switch back to prioritizing latency.
842 if (!active &&
843 prepare_tiles_approach_ == PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_WORK)
844 prepare_tiles_approach_ = PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY;
845 }
846
761 void SchedulerStateMachine::SetDeferCommits(bool defer_commits) { 847 void SchedulerStateMachine::SetDeferCommits(bool defer_commits) {
762 defer_commits_ = defer_commits; 848 defer_commits_ = defer_commits;
763 } 849 }
764 850
765 // These are the cases where we require a BeginFrame message to make progress 851 // These are the cases where we require a BeginFrame message to make progress
766 // on requested actions. 852 // on requested actions.
767 bool SchedulerStateMachine::BeginFrameRequiredForAction() const { 853 bool SchedulerStateMachine::BeginFrameRequiredForAction() const {
768 // The forced draw respects our normal draw scheduling, so we need to
769 // request a BeginImplFrame for it.
770 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
771 return true;
772
773 return needs_animate_ || needs_redraw_ || (needs_commit_ && !defer_commits_); 854 return needs_animate_ || needs_redraw_ || (needs_commit_ && !defer_commits_);
774 } 855 }
775 856
776 // These are cases where we are very likely want a BeginFrame message in the 857 // These are cases where we are very likely want a BeginFrame message in the
777 // near future. Proactively requesting the BeginImplFrame helps hide the round 858 // near future. Proactively requesting the BeginImplFrame helps hide the round
778 // trip latency of the SetNeedsBeginFrame request that has to go to the 859 // trip latency of the SetNeedsBeginFrame request that has to go to the
779 // Browser. 860 // Browser.
780 // This includes things like drawing soon, but might not actually have a new 861 // This includes things like drawing soon, but might not actually have a new
781 // frame to draw when we receive the next BeginImplFrame. 862 // frame to draw when we receive the next BeginImplFrame.
782 bool SchedulerStateMachine::ProactiveBeginFrameWanted() const { 863 bool SchedulerStateMachine::ProactiveBeginFrameWanted() const {
783 // Do not be proactive when invisible. 864 // Do not be proactive when invisible.
784 if (!visible_) 865 if (!visible_)
785 return false; 866 return false;
786 867
787 // We should proactively request a BeginImplFrame if a commit is pending 868 // We should proactively request a BeginImplFrame if a commit is pending
788 // because we will want to draw if the commit completes quickly. Do not 869 // because we will want to draw if the commit completes quickly. Do not
789 // request frames when commits are disabled, because the frame requests will 870 // request frames when commits are disabled, because the frame requests will
790 // not provide the needed commit (and will wake up the process when it could 871 // not provide the needed commit (and will wake up the process when it could
791 // stay idle). 872 // stay idle).
792 if ((commit_state_ != COMMIT_STATE_IDLE) && !defer_commits_) 873 if ((commit_state_ != COMMIT_STATE_IDLE) && !defer_commits_)
793 return true; 874 return true;
794 875
795 // If the pending tree activates quickly, we'll want a BeginImplFrame soon 876 // If the pending tree activates quickly, we'll want a BeginImplFrame soon
796 // to draw the new active tree. 877 // to draw the new active tree.
797 if (has_pending_tree_) 878 if (has_pending_tree_)
798 return true; 879 return true;
799 880
800 // Changing priorities may allow us to activate (given the new priorities), 881 // Changing priorities may allow us to activate (given the new priorities),
801 // which may result in a new frame. 882 // which may result in a new frame.
802 if (needs_prepare_tiles_) 883 if (PrepareTilesPending())
803 return true; 884 return true;
804 885
805 // If we just sent a swap request, it's likely that we are going to produce 886 // If we just sent a swap request, it's likely that we are going to produce
806 // another frame soon. This helps avoid negative glitches in our 887 // another frame soon. This helps avoid negative glitches in our
807 // SetNeedsBeginFrame requests, which may propagate to the BeginImplFrame 888 // SetNeedsBeginFrame requests, which may propagate to the BeginImplFrame
808 // provider and get sampled at an inopportune time, delaying the next 889 // provider and get sampled at an inopportune time, delaying the next
809 // BeginImplFrame. 890 // BeginImplFrame.
810 if (did_request_swap_in_last_frame_) 891 if (did_request_swap_in_last_frame_)
811 return true; 892 return true;
812 893
(...skipping 14 matching lines...) Expand all
827 908
828 // Clear funnels for any actions we perform during the frame. 909 // Clear funnels for any actions we perform during the frame.
829 animate_funnel_ = false; 910 animate_funnel_ = false;
830 send_begin_main_frame_funnel_ = false; 911 send_begin_main_frame_funnel_ = false;
831 invalidate_output_surface_funnel_ = false; 912 invalidate_output_surface_funnel_ = false;
832 913
833 // "Drain" the PrepareTiles funnel. 914 // "Drain" the PrepareTiles funnel.
834 if (prepare_tiles_funnel_ > 0) 915 if (prepare_tiles_funnel_ > 0)
835 prepare_tiles_funnel_--; 916 prepare_tiles_funnel_--;
836 917
918 // PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_WORK doesn't work well in
919 // main thread low-latency mode. Transition back to
920 // PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY if we just recovered
921 // main-thread latency.
922 if (skip_begin_main_frame_to_reduce_latency_ &&
923 prepare_tiles_approach_ == PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_WORK) {
924 prepare_tiles_approach_ = PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY;
925 }
926
837 skip_begin_main_frame_to_reduce_latency_ = 927 skip_begin_main_frame_to_reduce_latency_ =
838 skip_next_begin_main_frame_to_reduce_latency_; 928 skip_next_begin_main_frame_to_reduce_latency_;
839 skip_next_begin_main_frame_to_reduce_latency_ = false; 929 skip_next_begin_main_frame_to_reduce_latency_ = false;
840 } 930 }
841 931
842 void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() { 932 void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() {
843 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME; 933 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME;
844 } 934 }
845 935
846 void SchedulerStateMachine::OnBeginImplFrameDeadline() { 936 void SchedulerStateMachine::OnBeginImplFrameDeadline() {
(...skipping 13 matching lines...) Expand all
860 SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const { 950 SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const {
861 if (settings_.using_synchronous_renderer_compositor) { 951 if (settings_.using_synchronous_renderer_compositor) {
862 // No deadline for synchronous compositor. 952 // No deadline for synchronous compositor.
863 return BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE; 953 return BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE;
864 } else if (wait_for_active_tree_ready_to_draw_) { 954 } else if (wait_for_active_tree_ready_to_draw_) {
865 // When we are waiting for ready to draw signal, we do not wait to post a 955 // When we are waiting for ready to draw signal, we do not wait to post a
866 // deadline yet. 956 // deadline yet.
867 return BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW; 957 return BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW;
868 } else if (ShouldTriggerBeginImplFrameDeadlineImmediately()) { 958 } else if (ShouldTriggerBeginImplFrameDeadlineImmediately()) {
869 return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE; 959 return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE;
870 } else if (needs_redraw_ && pending_swaps_ < max_pending_swaps_) {
871 // We have an animation or fast input path on the impl thread that wants
872 // to draw, so don't wait too long for a new active tree.
873 // If we are swap throttled we should wait until we are unblocked.
874 return BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR;
875 } else {
876 // The impl thread doesn't have anything it wants to draw and we are just
877 // waiting for a new active tree or we are swap throttled. In short we are
878 // blocked.
879 return BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE;
880 } 960 }
961
962 if (prepare_tiles_approach_ == PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY) {
963 if (needs_redraw_ && pending_swaps_ < max_pending_swaps_) {
964 // We have an animation or fast input path on the impl thread that wants
965 // to draw, so don't wait too long for a new active tree.
966 // If we are swap throttled we should wait until we are unblocked.
967 return BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR;
968 } else {
969 // The impl thread doesn't have anything it wants to draw and we are just
970 // waiting for a new active tree or we are swap throttled. In short we are
971 // blocked.
972 return BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE;
973 }
974 }
975
976 return BEGIN_IMPL_FRAME_DEADLINE_MODE_TRY_TO_AVOID_CHECKERBOARD;
881 } 977 }
882 978
883 bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately() 979 bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately()
884 const { 980 const {
885 // TODO(brianderson): This should take into account multiple commit sources. 981 // TODO(brianderson): This should take into account multiple commit sources.
886 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) 982 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)
887 return false; 983 return false;
888 984
889 // If we just forced activation, we should end the deadline right now. 985 // If we just forced activation, we should end the deadline right now.
890 if (PendingActivationsShouldBeForced() && !has_pending_tree_) 986 if (PendingActivationsShouldBeForced() && !has_pending_tree_)
891 return true; 987 return true;
892 988
893 // SwapAck throttle the deadline since we wont draw and swap anyway. 989 // SwapAck throttle the deadline since we wont draw and swap anyway.
894 if (pending_swaps_ >= max_pending_swaps_) 990 if (pending_swaps_ >= max_pending_swaps_)
895 return false; 991 return false;
896 992
993 // PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY is the only approach
994 // where we want to trigger the deadline before NotifyReadyToDraw.
995 if (prepare_tiles_approach_ != PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY)
996 return active_tree_ready_to_draw_;
997
897 if (active_tree_needs_first_draw_) 998 if (active_tree_needs_first_draw_)
898 return true; 999 return true;
899 1000
900 if (!needs_redraw_) 1001 if (!needs_redraw_)
901 return false; 1002 return false;
902 1003
903 // This is used to prioritize impl-thread draws when the main thread isn't 1004 // This is used to prioritize impl-thread draws when the main thread isn't
904 // producing anything, e.g., after an aborted commit. We also check that we 1005 // producing anything, e.g., after an aborted commit. We also check that we
905 // don't have a pending tree -- otherwise we should give it a chance to 1006 // don't have a pending tree -- otherwise we should give it a chance to
906 // activate. 1007 // activate.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
949 // which case the main thread is in a high latency mode. 1050 // which case the main thread is in a high latency mode.
950 return (active_tree_needs_first_draw_ || did_perform_swap_in_last_draw_) && 1051 return (active_tree_needs_first_draw_ || did_perform_swap_in_last_draw_) &&
951 !send_begin_main_frame_funnel_; 1052 !send_begin_main_frame_funnel_;
952 } 1053 }
953 1054
954 // If the active tree needs its first draw in any other state, we know the 1055 // If the active tree needs its first draw in any other state, we know the
955 // main thread is in a high latency mode. 1056 // main thread is in a high latency mode.
956 return active_tree_needs_first_draw_; 1057 return active_tree_needs_first_draw_;
957 } 1058 }
958 1059
959 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } 1060 void SchedulerStateMachine::SetVisible(bool visible) {
1061 visible_ = visible;
1062 if (!visible)
1063 prepare_tiles_reason_ = PREPARE_TILES_NEEDED_TO_EVICT_TILES;
1064 }
960 1065
961 void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; } 1066 void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; }
962 1067
963 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } 1068 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; }
964 1069
965 void SchedulerStateMachine::SetNeedsAnimate() { 1070 void SchedulerStateMachine::SetNeedsAnimate() {
966 needs_animate_ = true; 1071 needs_animate_ = true;
967 } 1072 }
968 1073
969 void SchedulerStateMachine::SetWaitForReadyToDraw() { 1074 void SchedulerStateMachine::SetWaitForReadyToDraw() {
970 DCHECK(settings_.impl_side_painting); 1075 DCHECK(settings_.impl_side_painting);
971 wait_for_active_tree_ready_to_draw_ = true; 1076 wait_for_active_tree_ready_to_draw_ = true;
972 } 1077 }
973 1078
974 void SchedulerStateMachine::SetNeedsPrepareTiles() { 1079 void SchedulerStateMachine::SetNeedsPrepareTiles(bool for_commit) {
975 if (!needs_prepare_tiles_) { 1080 TRACE_EVENT0("cc", "SchedulerStateMachine::SetNeedsPrepareTiles");
976 TRACE_EVENT0("cc", "SchedulerStateMachine::SetNeedsPrepareTiles"); 1081 switch (prepare_tiles_approach_) {
977 needs_prepare_tiles_ = true; 1082 case PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY:
1083 case PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_PENDING_WORK:
1084 case PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_PENDING_CANCELED_WORK:
1085 if (for_commit)
1086 prepare_tiles_reason_ = PREPARE_TILES_NEEDED_FOR_COMMIT;
1087 else if (prepare_tiles_reason_ == PREPARE_TILES_NOT_NEEDED)
1088 prepare_tiles_reason_ = PREPARE_TILES_REQUESTED;
1089 break;
1090
1091 case PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_WORK:
1092 // We don't uncondititionally PrepareTiles immediately after a commit with
1093 // this approach.
1094 if (prepare_tiles_reason_ == PREPARE_TILES_NOT_NEEDED)
1095 prepare_tiles_reason_ = PREPARE_TILES_REQUESTED;
1096 break;
978 } 1097 }
979 } 1098 }
980 1099
981 void SchedulerStateMachine::SetMaxSwapsPending(int max) { 1100 void SchedulerStateMachine::SetMaxSwapsPending(int max) {
982 max_pending_swaps_ = max; 1101 max_pending_swaps_ = max;
983 } 1102 }
984 1103
985 void SchedulerStateMachine::DidSwapBuffers() { 1104 void SchedulerStateMachine::DidSwapBuffers() {
986 pending_swaps_++; 1105 pending_swaps_++;
987 DCHECK_LE(pending_swaps_, max_pending_swaps_); 1106 DCHECK_LE(pending_swaps_, max_pending_swaps_);
988 1107
989 did_perform_swap_in_last_draw_ = true; 1108 did_perform_swap_in_last_draw_ = true;
990 last_frame_number_swap_performed_ = current_frame_number_; 1109 last_frame_number_swap_performed_ = current_frame_number_;
991 } 1110 }
992 1111
993 void SchedulerStateMachine::DidSwapBuffersComplete() { 1112 void SchedulerStateMachine::DidSwapBuffersComplete() {
994 DCHECK_GT(pending_swaps_, 0); 1113 DCHECK_GT(pending_swaps_, 0);
995 pending_swaps_--; 1114 pending_swaps_--;
996 } 1115 }
997 1116
998 void SchedulerStateMachine::SetImplLatencyTakesPriority( 1117 void SchedulerStateMachine::SetImplLatencyTakesPriority(
999 bool impl_latency_takes_priority) { 1118 bool impl_latency_takes_priority) {
1000 impl_latency_takes_priority_ = impl_latency_takes_priority; 1119 impl_latency_takes_priority_ = impl_latency_takes_priority;
1001 } 1120 }
1002 1121
1003 void SchedulerStateMachine::DidDrawIfPossibleCompleted(DrawResult result) { 1122 void SchedulerStateMachine::SetDrawResult(DrawResult result) {
1004 switch (result) { 1123 last_draw_result_ = result;
1005 case INVALID_RESULT:
1006 NOTREACHED() << "Uninitialized DrawResult.";
1007 break;
1008 case DRAW_ABORTED_CANT_DRAW:
1009 case DRAW_ABORTED_CONTEXT_LOST:
1010 NOTREACHED() << "Invalid return value from DrawAndSwapIfPossible:"
1011 << result;
1012 break;
1013 case DRAW_SUCCESS:
1014 consecutive_checkerboard_animations_ = 0;
1015 forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE;
1016 break;
1017 case DRAW_ABORTED_CHECKERBOARD_ANIMATIONS:
1018 needs_redraw_ = true;
1019
1020 // If we're already in the middle of a redraw, we don't need to
1021 // restart it.
1022 if (forced_redraw_state_ != FORCED_REDRAW_STATE_IDLE)
1023 return;
1024
1025 needs_commit_ = true;
1026 consecutive_checkerboard_animations_++;
1027 if (settings_.timeout_and_draw_when_animation_checkerboards &&
1028 consecutive_checkerboard_animations_ >=
1029 settings_.maximum_number_of_failed_draws_before_draw_is_forced_) {
1030 consecutive_checkerboard_animations_ = 0;
1031 // We need to force a draw, but it doesn't make sense to do this until
1032 // we've committed and have new textures.
1033 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_COMMIT;
1034 }
1035 break;
1036 case DRAW_ABORTED_MISSING_HIGH_RES_CONTENT:
1037 // It's not clear whether this missing content is because of missing
1038 // pictures (which requires a commit) or because of memory pressure
1039 // removing textures (which might not). To be safe, request a commit
1040 // anyway.
1041 needs_commit_ = true;
1042 break;
1043 }
1044 } 1124 }
1045 1125
1046 void SchedulerStateMachine::SetNeedsCommit() { 1126 void SchedulerStateMachine::SetNeedsCommit() {
1047 needs_commit_ = true; 1127 needs_commit_ = true;
1048 } 1128 }
1049 1129
1050 void SchedulerStateMachine::NotifyReadyToCommit() { 1130 void SchedulerStateMachine::NotifyReadyToCommit() {
1051 DCHECK(commit_state_ == COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED) 1131 DCHECK(commit_state_ == COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED)
1052 << AsValue()->ToString(); 1132 << AsValue()->ToString();
1053 commit_state_ = COMMIT_STATE_READY_TO_COMMIT; 1133 commit_state_ = COMMIT_STATE_READY_TO_COMMIT;
(...skipping 13 matching lines...) Expand all
1067 commit_state_ = COMMIT_STATE_IDLE; 1147 commit_state_ = COMMIT_STATE_IDLE;
1068 SetNeedsCommit(); 1148 SetNeedsCommit();
1069 return; 1149 return;
1070 case CommitEarlyOutReason::FINISHED_NO_UPDATES: 1150 case CommitEarlyOutReason::FINISHED_NO_UPDATES:
1071 bool commit_has_no_updates = true; 1151 bool commit_has_no_updates = true;
1072 UpdateStateOnCommit(commit_has_no_updates); 1152 UpdateStateOnCommit(commit_has_no_updates);
1073 return; 1153 return;
1074 } 1154 }
1075 } 1155 }
1076 1156
1077 void SchedulerStateMachine::DidPrepareTiles() {
1078 needs_prepare_tiles_ = false;
1079 // "Fill" the PrepareTiles funnel.
1080 prepare_tiles_funnel_++;
1081 }
1082
1083 void SchedulerStateMachine::DidLoseOutputSurface() { 1157 void SchedulerStateMachine::DidLoseOutputSurface() {
1084 if (output_surface_state_ == OUTPUT_SURFACE_LOST || 1158 if (output_surface_state_ == OUTPUT_SURFACE_LOST ||
1085 output_surface_state_ == OUTPUT_SURFACE_CREATING) 1159 output_surface_state_ == OUTPUT_SURFACE_CREATING)
1086 return; 1160 return;
1087 output_surface_state_ = OUTPUT_SURFACE_LOST; 1161 output_surface_state_ = OUTPUT_SURFACE_LOST;
1088 needs_redraw_ = false; 1162 needs_redraw_ = false;
1089 wait_for_active_tree_ready_to_draw_ = false; 1163 wait_for_active_tree_ready_to_draw_ = false;
1090 } 1164 }
1091 1165
1092 void SchedulerStateMachine::NotifyReadyToActivate() { 1166 void SchedulerStateMachine::NotifyReadyToActivate() {
1093 if (has_pending_tree_) 1167 if (has_pending_tree_)
1094 pending_tree_is_ready_for_activation_ = true; 1168 pending_tree_is_ready_for_activation_ = true;
1095 } 1169 }
1096 1170
1097 void SchedulerStateMachine::NotifyReadyToDraw() { 1171 void SchedulerStateMachine::NotifyReadyToDraw() {
1098 wait_for_active_tree_ready_to_draw_ = false; 1172 wait_for_active_tree_ready_to_draw_ = false;
1173 active_tree_ready_to_draw_ = true;
1174 }
1175
1176 void SchedulerStateMachine::SetRequiresHighResToDraw(bool required) {
1177 if (requires_high_res_to_draw_ == required)
1178 return;
1179 requires_high_res_to_draw_ = required;
1099 } 1180 }
1100 1181
1101 void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() { 1182 void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() {
1102 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING); 1183 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING);
1103 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT; 1184 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT;
1104 1185
1105 if (did_create_and_initialize_first_output_surface_) { 1186 if (did_create_and_initialize_first_output_surface_) {
1106 // TODO(boliu): See if we can remove this when impl-side painting is always 1187 // TODO(boliu): See if we can remove this when impl-side painting is always
1107 // on. Does anything on the main thread need to update after recreate? 1188 // on. Does anything on the main thread need to update after recreate?
1108 needs_commit_ = true; 1189 needs_commit_ = true;
(...skipping 29 matching lines...) Expand all
1138 static_cast<int>(begin_impl_frame_state_), 1219 static_cast<int>(begin_impl_frame_state_),
1139 static_cast<int>(commit_state_), 1220 static_cast<int>(commit_state_),
1140 has_pending_tree_ ? 'T' : 'F', 1221 has_pending_tree_ ? 'T' : 'F',
1141 pending_tree_is_ready_for_activation_ ? 'T' : 'F', 1222 pending_tree_is_ready_for_activation_ ? 'T' : 'F',
1142 active_tree_needs_first_draw_ ? 'T' : 'F', 1223 active_tree_needs_first_draw_ ? 'T' : 'F',
1143 max_pending_swaps_, 1224 max_pending_swaps_,
1144 pending_swaps_); 1225 pending_swaps_);
1145 } 1226 }
1146 1227
1147 } // namespace cc 1228 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698