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

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

Issue 1002493006: cc: Do not use current frame number in state machine decisions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@no_begin_impl_frame_args_in_state_machine
Patch Set: Address comments. Created 5 years, 9 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
« no previous file with comments | « cc/scheduler/scheduler_state_machine.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 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 animate_funnel_(false),
30 perform_swap_funnel_(false),
31 request_swap_funnel_(false),
32 send_begin_main_frame_funnel_(false),
29 prepare_tiles_funnel_(0), 33 prepare_tiles_funnel_(0),
30 consecutive_checkerboard_animations_(0), 34 consecutive_checkerboard_animations_(0),
31 max_pending_swaps_(1), 35 max_pending_swaps_(1),
32 pending_swaps_(0), 36 pending_swaps_(0),
33 needs_redraw_(false), 37 needs_redraw_(false),
34 needs_animate_(false), 38 needs_animate_(false),
35 needs_prepare_tiles_(false), 39 needs_prepare_tiles_(false),
36 needs_commit_(false), 40 needs_commit_(false),
37 inside_poll_for_anticipated_draw_triggers_(false), 41 inside_poll_for_anticipated_draw_triggers_(false),
38 visible_(false), 42 visible_(false),
39 can_start_(false), 43 can_start_(false),
40 can_draw_(false), 44 can_draw_(false),
41 has_pending_tree_(false), 45 has_pending_tree_(false),
42 pending_tree_is_ready_for_activation_(false), 46 pending_tree_is_ready_for_activation_(false),
43 active_tree_needs_first_draw_(false), 47 active_tree_needs_first_draw_(false),
44 did_commit_after_animating_(false),
45 did_create_and_initialize_first_output_surface_(false), 48 did_create_and_initialize_first_output_surface_(false),
46 impl_latency_takes_priority_(false), 49 impl_latency_takes_priority_(false),
47 skip_next_begin_main_frame_to_reduce_latency_(false), 50 skip_next_begin_main_frame_to_reduce_latency_(false),
48 skip_begin_main_frame_to_reduce_latency_(false), 51 skip_begin_main_frame_to_reduce_latency_(false),
49 continuous_painting_(false), 52 continuous_painting_(false),
50 children_need_begin_frames_(false), 53 children_need_begin_frames_(false),
51 defer_commits_(false) { 54 defer_commits_(false) {
52 } 55 }
53 56
54 const char* SchedulerStateMachine::OutputSurfaceStateToString( 57 const char* SchedulerStateMachine::OutputSurfaceStateToString(
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 state->SetString("commit_state", CommitStateToString(commit_state_)); 167 state->SetString("commit_state", CommitStateToString(commit_state_));
165 state->SetString("output_surface_state_", 168 state->SetString("output_surface_state_",
166 OutputSurfaceStateToString(output_surface_state_)); 169 OutputSurfaceStateToString(output_surface_state_));
167 state->SetString("forced_redraw_state", 170 state->SetString("forced_redraw_state",
168 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_)); 171 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_));
169 state->EndDictionary(); 172 state->EndDictionary();
170 173
171 state->BeginDictionary("minor_state"); 174 state->BeginDictionary("minor_state");
172 state->SetInteger("commit_count", commit_count_); 175 state->SetInteger("commit_count", commit_count_);
173 state->SetInteger("current_frame_number", current_frame_number_); 176 state->SetInteger("current_frame_number", current_frame_number_);
174
175 state->SetInteger("last_frame_number_animate_performed", 177 state->SetInteger("last_frame_number_animate_performed",
176 last_frame_number_animate_performed_); 178 last_frame_number_animate_performed_);
177 state->SetInteger("last_frame_number_swap_performed", 179 state->SetInteger("last_frame_number_swap_performed",
178 last_frame_number_swap_performed_); 180 last_frame_number_swap_performed_);
179 state->SetInteger("last_frame_number_swap_requested", 181 state->SetInteger("last_frame_number_swap_requested",
180 last_frame_number_swap_requested_); 182 last_frame_number_swap_requested_);
181 state->SetInteger("last_frame_number_begin_main_frame_sent", 183 state->SetInteger("last_frame_number_begin_main_frame_sent",
182 last_frame_number_begin_main_frame_sent_); 184 last_frame_number_begin_main_frame_sent_);
183 185 state->SetBoolean("funnel: animate_funnel", animate_funnel_);
184 state->SetInteger("prepare_tiles_funnel", prepare_tiles_funnel_); 186 state->SetBoolean("funnel: perform_swap_funnel", perform_swap_funnel_);
187 state->SetBoolean("funnel: request_swap_funnel", request_swap_funnel_);
188 state->SetBoolean("funnel: send_begin_main_frame_funnel",
189 send_begin_main_frame_funnel_);
190 state->SetInteger("funnel: prepare_tiles_funnel", prepare_tiles_funnel_);
185 state->SetInteger("consecutive_checkerboard_animations", 191 state->SetInteger("consecutive_checkerboard_animations",
186 consecutive_checkerboard_animations_); 192 consecutive_checkerboard_animations_);
187 state->SetInteger("max_pending_swaps_", max_pending_swaps_); 193 state->SetInteger("max_pending_swaps_", max_pending_swaps_);
188 state->SetInteger("pending_swaps_", pending_swaps_); 194 state->SetInteger("pending_swaps_", pending_swaps_);
189 state->SetBoolean("needs_redraw", needs_redraw_); 195 state->SetBoolean("needs_redraw", needs_redraw_);
190 state->SetBoolean("needs_animate_", needs_animate_); 196 state->SetBoolean("needs_animate_", needs_animate_);
191 state->SetBoolean("needs_prepare_tiles", needs_prepare_tiles_); 197 state->SetBoolean("needs_prepare_tiles", needs_prepare_tiles_);
192 state->SetBoolean("needs_commit", needs_commit_); 198 state->SetBoolean("needs_commit", needs_commit_);
193 state->SetBoolean("visible", visible_); 199 state->SetBoolean("visible", visible_);
194 state->SetBoolean("can_start", can_start_); 200 state->SetBoolean("can_start", can_start_);
195 state->SetBoolean("can_draw", can_draw_); 201 state->SetBoolean("can_draw", can_draw_);
196 state->SetBoolean("has_pending_tree", has_pending_tree_); 202 state->SetBoolean("has_pending_tree", has_pending_tree_);
197 state->SetBoolean("pending_tree_is_ready_for_activation", 203 state->SetBoolean("pending_tree_is_ready_for_activation",
198 pending_tree_is_ready_for_activation_); 204 pending_tree_is_ready_for_activation_);
199 state->SetBoolean("active_tree_needs_first_draw", 205 state->SetBoolean("active_tree_needs_first_draw",
200 active_tree_needs_first_draw_); 206 active_tree_needs_first_draw_);
201 state->SetBoolean("did_commit_after_animating", did_commit_after_animating_);
202 state->SetBoolean("did_create_and_initialize_first_output_surface", 207 state->SetBoolean("did_create_and_initialize_first_output_surface",
203 did_create_and_initialize_first_output_surface_); 208 did_create_and_initialize_first_output_surface_);
204 state->SetBoolean("impl_latency_takes_priority", 209 state->SetBoolean("impl_latency_takes_priority",
205 impl_latency_takes_priority_); 210 impl_latency_takes_priority_);
206 state->SetBoolean("main_thread_is_in_high_latency_mode", 211 state->SetBoolean("main_thread_is_in_high_latency_mode",
207 MainThreadIsInHighLatencyMode()); 212 MainThreadIsInHighLatencyMode());
208 state->SetBoolean("skip_begin_main_frame_to_reduce_latency", 213 state->SetBoolean("skip_begin_main_frame_to_reduce_latency",
209 skip_begin_main_frame_to_reduce_latency_); 214 skip_begin_main_frame_to_reduce_latency_);
210 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", 215 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency",
211 skip_next_begin_main_frame_to_reduce_latency_); 216 skip_next_begin_main_frame_to_reduce_latency_);
212 state->SetBoolean("continuous_painting", continuous_painting_); 217 state->SetBoolean("continuous_painting", continuous_painting_);
213 state->SetBoolean("children_need_begin_frames", children_need_begin_frames_); 218 state->SetBoolean("children_need_begin_frames", children_need_begin_frames_);
214 state->SetBoolean("defer_commits", defer_commits_); 219 state->SetBoolean("defer_commits", defer_commits_);
215 state->EndDictionary(); 220 state->EndDictionary();
216 } 221 }
217 222
218 void SchedulerStateMachine::AdvanceCurrentFrameNumber() { 223 void SchedulerStateMachine::AdvanceCurrentFrameNumber() {
219 current_frame_number_++; 224 current_frame_number_++;
220 225
226 animate_funnel_ = false;
227 perform_swap_funnel_ = false;
228 request_swap_funnel_ = false;
229 send_begin_main_frame_funnel_ = false;
230
221 // "Drain" the PrepareTiles funnel. 231 // "Drain" the PrepareTiles funnel.
222 if (prepare_tiles_funnel_ > 0) 232 if (prepare_tiles_funnel_ > 0)
223 prepare_tiles_funnel_--; 233 prepare_tiles_funnel_--;
224 234
225 skip_begin_main_frame_to_reduce_latency_ = 235 skip_begin_main_frame_to_reduce_latency_ =
226 skip_next_begin_main_frame_to_reduce_latency_; 236 skip_next_begin_main_frame_to_reduce_latency_;
227 skip_next_begin_main_frame_to_reduce_latency_ = false; 237 skip_next_begin_main_frame_to_reduce_latency_ = false;
228 } 238 }
229 239
230 bool SchedulerStateMachine::HasAnimatedThisFrame() const {
231 return last_frame_number_animate_performed_ == current_frame_number_;
232 }
233
234 bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const {
235 return current_frame_number_ ==
236 last_frame_number_begin_main_frame_sent_;
237 }
238
239 bool SchedulerStateMachine::HasSwappedThisFrame() const {
240 return current_frame_number_ == last_frame_number_swap_performed_;
241 }
242
243 bool SchedulerStateMachine::HasRequestedSwapThisFrame() const {
244 return current_frame_number_ == last_frame_number_swap_requested_;
245 }
246
247 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const { 240 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const {
248 // These are all the cases where we normally cannot or do not want to draw 241 // These are all the cases where we normally cannot or do not want to draw
249 // but, if needs_redraw_ is true and we do not draw to make forward progress, 242 // but, if needs_redraw_ is true and we do not draw to make forward progress,
250 // we might deadlock with the main thread. 243 // we might deadlock with the main thread.
251 // This should be a superset of PendingActivationsShouldBeForced() since 244 // This should be a superset of PendingActivationsShouldBeForced() since
252 // activation of the pending tree is blocked by drawing of the active tree and 245 // activation of the pending tree is blocked by drawing of the active tree and
253 // the main thread might be blocked on activation of the most recent commit. 246 // the main thread might be blocked on activation of the most recent commit.
254 if (PendingActivationsShouldBeForced()) 247 if (PendingActivationsShouldBeForced())
255 return true; 248 return true;
256 249
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 302
310 bool SchedulerStateMachine::ShouldDraw() const { 303 bool SchedulerStateMachine::ShouldDraw() const {
311 // If we need to abort draws, we should do so ASAP since the draw could 304 // If we need to abort draws, we should do so ASAP since the draw could
312 // be blocking other important actions (like output surface initialization), 305 // be blocking other important actions (like output surface initialization),
313 // from occuring. If we are waiting for the first draw, then perfom the 306 // from occuring. If we are waiting for the first draw, then perfom the
314 // aborted draw to keep things moving. If we are not waiting for the first 307 // aborted draw to keep things moving. If we are not waiting for the first
315 // draw however, we don't want to abort for no reason. 308 // draw however, we don't want to abort for no reason.
316 if (PendingDrawsShouldBeAborted()) 309 if (PendingDrawsShouldBeAborted())
317 return active_tree_needs_first_draw_; 310 return active_tree_needs_first_draw_;
318 311
312 // Do not draw too many times in a single frame. It's okay that we don't check
313 // this before checking for aborted draws because aborted draws do not request
314 // a swap.
315 if (request_swap_funnel_)
316 return false;
317
319 // Don't draw if we are waiting on the first commit after a surface. 318 // Don't draw if we are waiting on the first commit after a surface.
320 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE) 319 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE)
321 return false; 320 return false;
322 321
323 // If a commit has occurred after the animate call, we need to call animate
324 // again before we should draw.
325 if (did_commit_after_animating_)
326 return false;
327
328 // After this line, we only want to send a swap request once per frame.
329 if (HasRequestedSwapThisFrame())
330 return false;
331
332 // Do not queue too many swaps. 322 // Do not queue too many swaps.
333 if (pending_swaps_ >= max_pending_swaps_) 323 if (pending_swaps_ >= max_pending_swaps_)
334 return false; 324 return false;
335 325
336 // Except for the cases above, do not draw outside of the BeginImplFrame 326 // Except for the cases above, do not draw outside of the BeginImplFrame
337 // deadline. 327 // deadline.
338 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) 328 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
339 return false; 329 return false;
340 330
341 // Only handle forced redraws due to timeouts on the regular deadline. 331 // Only handle forced redraws due to timeouts on the regular deadline.
(...skipping 16 matching lines...) Expand all
358 348
359 // If we want to force activation, do so ASAP. 349 // If we want to force activation, do so ASAP.
360 if (PendingActivationsShouldBeForced()) 350 if (PendingActivationsShouldBeForced())
361 return true; 351 return true;
362 352
363 // At this point, only activate if we are ready to activate. 353 // At this point, only activate if we are ready to activate.
364 return pending_tree_is_ready_for_activation_; 354 return pending_tree_is_ready_for_activation_;
365 } 355 }
366 356
367 bool SchedulerStateMachine::ShouldAnimate() const { 357 bool SchedulerStateMachine::ShouldAnimate() const {
358 // Do not animate too many times in a single frame.
359 if (animate_funnel_)
360 return false;
361
368 // Don't animate if we are waiting on the first commit after a surface. 362 // Don't animate if we are waiting on the first commit after a surface.
369 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE) 363 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE)
370 return false; 364 return false;
371 365
372 // If a commit occurred after our last call, we need to do animation again.
373 if (HasAnimatedThisFrame() && !did_commit_after_animating_)
374 return false;
375
376 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING && 366 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING &&
377 begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) 367 begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
378 return false; 368 return false;
379 369
380 return needs_redraw_ || needs_animate_; 370 return needs_redraw_ || needs_animate_;
381 } 371 }
382 372
383 bool SchedulerStateMachine::CouldSendBeginMainFrame() const { 373 bool SchedulerStateMachine::CouldSendBeginMainFrame() const {
374 // Do not send begin main frame too many times in a single frame.
375 if (send_begin_main_frame_funnel_)
376 return false;
377
384 if (!needs_commit_) 378 if (!needs_commit_)
385 return false; 379 return false;
386 380
387 // We can not perform commits if we are not visible. 381 // We can not perform commits if we are not visible.
388 if (!visible_) 382 if (!visible_)
389 return false; 383 return false;
390 384
391 // Do not make a new commits when it is deferred. 385 // Do not make a new commits when it is deferred.
392 if (defer_commits_) 386 if (defer_commits_)
393 return false; 387 return false;
(...skipping 23 matching lines...) Expand all
417 // thread isn't consuming user input. 411 // thread isn't consuming user input.
418 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE && 412 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE &&
419 BeginFrameNeeded()) 413 BeginFrameNeeded())
420 return false; 414 return false;
421 415
422 // We need a new commit for the forced redraw. This honors the 416 // We need a new commit for the forced redraw. This honors the
423 // single commit per interval because the result will be swapped to screen. 417 // single commit per interval because the result will be swapped to screen.
424 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) 418 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT)
425 return true; 419 return true;
426 420
427 // After this point, we only start a commit once per frame.
428 if (HasSentBeginMainFrameThisFrame())
429 return false;
430
431 // We shouldn't normally accept commits if there isn't an OutputSurface. 421 // We shouldn't normally accept commits if there isn't an OutputSurface.
432 if (!HasInitializedOutputSurface()) 422 if (!HasInitializedOutputSurface())
433 return false; 423 return false;
434 424
435 // SwapAck throttle the BeginMainFrames unless we just swapped. 425 // SwapAck throttle the BeginMainFrames unless we just swapped.
436 // TODO(brianderson): Remove this restriction to improve throughput. 426 // TODO(brianderson): Remove this restriction to improve throughput.
437 bool just_swapped_in_deadline = 427 bool just_swapped_in_deadline =
438 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE && 428 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE &&
439 HasSwappedThisFrame(); 429 perform_swap_funnel_;
440 if (pending_swaps_ >= max_pending_swaps_ && !just_swapped_in_deadline) 430 if (pending_swaps_ >= max_pending_swaps_ && !just_swapped_in_deadline)
441 return false; 431 return false;
442 432
443 if (skip_begin_main_frame_to_reduce_latency_) 433 if (skip_begin_main_frame_to_reduce_latency_)
444 return false; 434 return false;
445 435
446 return true; 436 return true;
447 } 437 }
448 438
449 bool SchedulerStateMachine::ShouldCommit() const { 439 bool SchedulerStateMachine::ShouldCommit() const {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 void SchedulerStateMachine::UpdateState(Action action) { 496 void SchedulerStateMachine::UpdateState(Action action) {
507 switch (action) { 497 switch (action) {
508 case ACTION_NONE: 498 case ACTION_NONE:
509 return; 499 return;
510 500
511 case ACTION_ACTIVATE_SYNC_TREE: 501 case ACTION_ACTIVATE_SYNC_TREE:
512 UpdateStateOnActivation(); 502 UpdateStateOnActivation();
513 return; 503 return;
514 504
515 case ACTION_ANIMATE: 505 case ACTION_ANIMATE:
506 DCHECK(!animate_funnel_);
516 last_frame_number_animate_performed_ = current_frame_number_; 507 last_frame_number_animate_performed_ = current_frame_number_;
508 animate_funnel_ = true;
517 needs_animate_ = false; 509 needs_animate_ = false;
518 did_commit_after_animating_ = false;
519 // TODO(skyostil): Instead of assuming this, require the client to tell 510 // TODO(skyostil): Instead of assuming this, require the client to tell
520 // us. 511 // us.
521 SetNeedsRedraw(); 512 SetNeedsRedraw();
522 return; 513 return;
523 514
524 case ACTION_SEND_BEGIN_MAIN_FRAME: 515 case ACTION_SEND_BEGIN_MAIN_FRAME:
525 DCHECK(!has_pending_tree_ || 516 DCHECK(!has_pending_tree_ ||
526 settings_.main_frame_before_activation_enabled); 517 settings_.main_frame_before_activation_enabled);
527 DCHECK(visible_); 518 DCHECK(visible_);
519 DCHECK(!send_begin_main_frame_funnel_);
528 commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_SENT; 520 commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_SENT;
529 needs_commit_ = false; 521 needs_commit_ = false;
522 send_begin_main_frame_funnel_ = true;
530 last_frame_number_begin_main_frame_sent_ = 523 last_frame_number_begin_main_frame_sent_ =
531 current_frame_number_; 524 current_frame_number_;
532 return; 525 return;
533 526
534 case ACTION_COMMIT: { 527 case ACTION_COMMIT: {
535 bool commit_has_no_updates = false; 528 bool commit_has_no_updates = false;
536 UpdateStateOnCommit(commit_has_no_updates); 529 UpdateStateOnCommit(commit_has_no_updates);
537 return; 530 return;
538 } 531 }
539 532
(...skipping 24 matching lines...) Expand all
564 557
565 case ACTION_PREPARE_TILES: 558 case ACTION_PREPARE_TILES:
566 UpdateStateOnPrepareTiles(); 559 UpdateStateOnPrepareTiles();
567 return; 560 return;
568 } 561 }
569 } 562 }
570 563
571 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_has_no_updates) { 564 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_has_no_updates) {
572 commit_count_++; 565 commit_count_++;
573 566
574 if (!commit_has_no_updates && HasAnimatedThisFrame()) 567 if (!commit_has_no_updates)
575 did_commit_after_animating_ = true; 568 animate_funnel_ = false;
576 569
577 if (commit_has_no_updates || settings_.main_frame_before_activation_enabled) { 570 if (commit_has_no_updates || settings_.main_frame_before_activation_enabled) {
578 commit_state_ = COMMIT_STATE_IDLE; 571 commit_state_ = COMMIT_STATE_IDLE;
579 } else if (settings_.impl_side_painting) { 572 } else if (settings_.impl_side_painting) {
580 commit_state_ = COMMIT_STATE_WAITING_FOR_ACTIVATION; 573 commit_state_ = COMMIT_STATE_WAITING_FOR_ACTIVATION;
581 } else { 574 } else {
582 commit_state_ = settings_.main_thread_should_always_be_low_latency 575 commit_state_ = settings_.main_thread_should_always_be_low_latency
583 ? COMMIT_STATE_WAITING_FOR_DRAW 576 ? COMMIT_STATE_WAITING_FOR_DRAW
584 : COMMIT_STATE_IDLE; 577 : COMMIT_STATE_IDLE;
585 } 578 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 void SchedulerStateMachine::UpdateStateOnDraw(bool did_request_swap) { 637 void SchedulerStateMachine::UpdateStateOnDraw(bool did_request_swap) {
645 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) 638 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
646 forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE; 639 forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE;
647 640
648 if (commit_state_ == COMMIT_STATE_WAITING_FOR_DRAW) 641 if (commit_state_ == COMMIT_STATE_WAITING_FOR_DRAW)
649 commit_state_ = COMMIT_STATE_IDLE; 642 commit_state_ = COMMIT_STATE_IDLE;
650 643
651 needs_redraw_ = false; 644 needs_redraw_ = false;
652 active_tree_needs_first_draw_ = false; 645 active_tree_needs_first_draw_ = false;
653 646
654 if (did_request_swap) 647 if (did_request_swap) {
648 DCHECK(!request_swap_funnel_);
649 request_swap_funnel_ = true;
655 last_frame_number_swap_requested_ = current_frame_number_; 650 last_frame_number_swap_requested_ = current_frame_number_;
651 }
656 } 652 }
657 653
658 void SchedulerStateMachine::UpdateStateOnPrepareTiles() { 654 void SchedulerStateMachine::UpdateStateOnPrepareTiles() {
659 needs_prepare_tiles_ = false; 655 needs_prepare_tiles_ = false;
660 } 656 }
661 657
662 void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() { 658 void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() {
663 TRACE_EVENT_INSTANT0("cc", 659 TRACE_EVENT_INSTANT0("cc",
664 "Scheduler: SkipNextBeginMainFrameToReduceLatency", 660 "Scheduler: SkipNextBeginMainFrameToReduceLatency",
665 TRACE_EVENT_SCOPE_THREAD); 661 TRACE_EVENT_SCOPE_THREAD);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 // Changing priorities may allow us to activate (given the new priorities), 756 // Changing priorities may allow us to activate (given the new priorities),
761 // which may result in a new frame. 757 // which may result in a new frame.
762 if (needs_prepare_tiles_) 758 if (needs_prepare_tiles_)
763 return true; 759 return true;
764 760
765 // If we just sent a swap request, it's likely that we are going to produce 761 // If we just sent a swap request, it's likely that we are going to produce
766 // another frame soon. This helps avoid negative glitches in our 762 // another frame soon. This helps avoid negative glitches in our
767 // SetNeedsBeginFrame requests, which may propagate to the BeginImplFrame 763 // SetNeedsBeginFrame requests, which may propagate to the BeginImplFrame
768 // provider and get sampled at an inopportune time, delaying the next 764 // provider and get sampled at an inopportune time, delaying the next
769 // BeginImplFrame. 765 // BeginImplFrame.
770 if (HasRequestedSwapThisFrame()) 766 if (request_swap_funnel_)
771 return true; 767 return true;
772 768
773 return false; 769 return false;
774 } 770 }
775 771
776 void SchedulerStateMachine::OnBeginImplFrame() { 772 void SchedulerStateMachine::OnBeginImplFrame() {
777 AdvanceCurrentFrameNumber(); 773 AdvanceCurrentFrameNumber();
778 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE) 774 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE)
779 << AsValue()->ToString(); 775 << AsValue()->ToString();
780 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING; 776 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
854 } 850 }
855 851
856 bool SchedulerStateMachine::MainThreadIsInHighLatencyMode() const { 852 bool SchedulerStateMachine::MainThreadIsInHighLatencyMode() const {
857 // If a commit is pending before the previous commit has been drawn, we 853 // If a commit is pending before the previous commit has been drawn, we
858 // are definitely in a high latency mode. 854 // are definitely in a high latency mode.
859 if (CommitPending() && (active_tree_needs_first_draw_ || has_pending_tree_)) 855 if (CommitPending() && (active_tree_needs_first_draw_ || has_pending_tree_))
860 return true; 856 return true;
861 857
862 // If we just sent a BeginMainFrame and haven't hit the deadline yet, the main 858 // If we just sent a BeginMainFrame and haven't hit the deadline yet, the main
863 // thread is in a low latency mode. 859 // thread is in a low latency mode.
864 if (HasSentBeginMainFrameThisFrame() && 860 if (send_begin_main_frame_funnel_ &&
865 (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING || 861 (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING ||
866 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)) 862 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME))
867 return false; 863 return false;
868 864
869 // If there's a commit in progress it must either be from the previous frame 865 // If there's a commit in progress it must either be from the previous frame
870 // or it started after the impl thread's deadline. In either case the main 866 // or it started after the impl thread's deadline. In either case the main
871 // thread is in high latency mode. 867 // thread is in high latency mode.
872 if (CommitPending()) 868 if (CommitPending())
873 return true; 869 return true;
874 870
875 // Similarly, if there's a pending tree the main thread is in high latency 871 // Similarly, if there's a pending tree the main thread is in high latency
876 // mode, because either 872 // mode, because either
877 // it's from the previous frame 873 // it's from the previous frame
878 // or 874 // or
879 // we're currently drawing the active tree and the pending tree will thus 875 // we're currently drawing the active tree and the pending tree will thus
880 // only be drawn in the next frame. 876 // only be drawn in the next frame.
881 if (has_pending_tree_) 877 if (has_pending_tree_)
882 return true; 878 return true;
883 879
884 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) { 880 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) {
885 // Even if there's a new active tree to draw at the deadline or we've just 881 // Even if there's a new active tree to draw at the deadline or we've just
886 // swapped it, it may have been triggered by a previous BeginImplFrame, in 882 // swapped it, it may have been triggered by a previous BeginImplFrame, in
887 // which case the main thread is in a high latency mode. 883 // which case the main thread is in a high latency mode.
888 return (active_tree_needs_first_draw_ || HasSwappedThisFrame()) && 884 return (active_tree_needs_first_draw_ || perform_swap_funnel_) &&
889 !HasSentBeginMainFrameThisFrame(); 885 !send_begin_main_frame_funnel_;
890 } 886 }
891 887
892 // If the active tree needs its first draw in any other state, we know the 888 // If the active tree needs its first draw in any other state, we know the
893 // main thread is in a high latency mode. 889 // main thread is in a high latency mode.
894 return active_tree_needs_first_draw_; 890 return active_tree_needs_first_draw_;
895 } 891 }
896 892
897 void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() { 893 void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() {
898 AdvanceCurrentFrameNumber(); 894 AdvanceCurrentFrameNumber();
899 inside_poll_for_anticipated_draw_triggers_ = true; 895 inside_poll_for_anticipated_draw_triggers_ = true;
(...skipping 20 matching lines...) Expand all
920 } 916 }
921 } 917 }
922 918
923 void SchedulerStateMachine::SetMaxSwapsPending(int max) { 919 void SchedulerStateMachine::SetMaxSwapsPending(int max) {
924 max_pending_swaps_ = max; 920 max_pending_swaps_ = max;
925 } 921 }
926 922
927 void SchedulerStateMachine::DidSwapBuffers() { 923 void SchedulerStateMachine::DidSwapBuffers() {
928 pending_swaps_++; 924 pending_swaps_++;
929 DCHECK_LE(pending_swaps_, max_pending_swaps_); 925 DCHECK_LE(pending_swaps_, max_pending_swaps_);
926 DCHECK(!perform_swap_funnel_);
930 927
928 perform_swap_funnel_ = true;
931 last_frame_number_swap_performed_ = current_frame_number_; 929 last_frame_number_swap_performed_ = current_frame_number_;
932 } 930 }
933 931
934 void SchedulerStateMachine::DidSwapBuffersComplete() { 932 void SchedulerStateMachine::DidSwapBuffersComplete() {
935 DCHECK_GT(pending_swaps_, 0); 933 DCHECK_GT(pending_swaps_, 0);
936 pending_swaps_--; 934 pending_swaps_--;
937 } 935 }
938 936
939 void SchedulerStateMachine::SetImplLatencyTakesPriority( 937 void SchedulerStateMachine::SetImplLatencyTakesPriority(
940 bool impl_latency_takes_priority) { 938 bool impl_latency_takes_priority) {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 static_cast<int>(begin_impl_frame_state_), 1072 static_cast<int>(begin_impl_frame_state_),
1075 static_cast<int>(commit_state_), 1073 static_cast<int>(commit_state_),
1076 has_pending_tree_ ? 'T' : 'F', 1074 has_pending_tree_ ? 'T' : 'F',
1077 pending_tree_is_ready_for_activation_ ? 'T' : 'F', 1075 pending_tree_is_ready_for_activation_ ? 'T' : 'F',
1078 active_tree_needs_first_draw_ ? 'T' : 'F', 1076 active_tree_needs_first_draw_ ? 'T' : 'F',
1079 max_pending_swaps_, 1077 max_pending_swaps_,
1080 pending_swaps_); 1078 pending_swaps_);
1081 } 1079 }
1082 1080
1083 } // namespace cc 1081 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/scheduler_state_machine.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698