OLD | NEW |
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/scheduler/scheduler_state_machine.h" | 5 #include "cc/scheduler/scheduler_state_machine.h" |
6 | 6 |
7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "base/debug/trace_event_argument.h" | 8 #include "base/debug/trace_event_argument.h" |
9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 needs_manage_tiles_(false), | 36 needs_manage_tiles_(false), |
37 swap_used_incomplete_tile_(false), | 37 swap_used_incomplete_tile_(false), |
38 needs_commit_(false), | 38 needs_commit_(false), |
39 inside_poll_for_anticipated_draw_triggers_(false), | 39 inside_poll_for_anticipated_draw_triggers_(false), |
40 visible_(false), | 40 visible_(false), |
41 can_start_(false), | 41 can_start_(false), |
42 can_draw_(false), | 42 can_draw_(false), |
43 has_pending_tree_(false), | 43 has_pending_tree_(false), |
44 pending_tree_is_ready_for_activation_(false), | 44 pending_tree_is_ready_for_activation_(false), |
45 active_tree_needs_first_draw_(false), | 45 active_tree_needs_first_draw_(false), |
| 46 did_commit_after_animating_(false), |
46 did_create_and_initialize_first_output_surface_(false), | 47 did_create_and_initialize_first_output_surface_(false), |
47 impl_latency_takes_priority_(false), | 48 impl_latency_takes_priority_(false), |
48 skip_next_begin_main_frame_to_reduce_latency_(false), | 49 skip_next_begin_main_frame_to_reduce_latency_(false), |
49 skip_begin_main_frame_to_reduce_latency_(false), | 50 skip_begin_main_frame_to_reduce_latency_(false), |
50 continuous_painting_(false), | 51 continuous_painting_(false), |
51 impl_latency_takes_priority_on_battery_(false) { | 52 impl_latency_takes_priority_on_battery_(false) { |
52 } | 53 } |
53 | 54 |
54 const char* SchedulerStateMachine::OutputSurfaceStateToString( | 55 const char* SchedulerStateMachine::OutputSurfaceStateToString( |
55 OutputSurfaceState state) { | 56 OutputSurfaceState state) { |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 state->SetBoolean("swap_used_incomplete_tile", swap_used_incomplete_tile_); | 220 state->SetBoolean("swap_used_incomplete_tile", swap_used_incomplete_tile_); |
220 state->SetBoolean("needs_commit", needs_commit_); | 221 state->SetBoolean("needs_commit", needs_commit_); |
221 state->SetBoolean("visible", visible_); | 222 state->SetBoolean("visible", visible_); |
222 state->SetBoolean("can_start", can_start_); | 223 state->SetBoolean("can_start", can_start_); |
223 state->SetBoolean("can_draw", can_draw_); | 224 state->SetBoolean("can_draw", can_draw_); |
224 state->SetBoolean("has_pending_tree", has_pending_tree_); | 225 state->SetBoolean("has_pending_tree", has_pending_tree_); |
225 state->SetBoolean("pending_tree_is_ready_for_activation", | 226 state->SetBoolean("pending_tree_is_ready_for_activation", |
226 pending_tree_is_ready_for_activation_); | 227 pending_tree_is_ready_for_activation_); |
227 state->SetBoolean("active_tree_needs_first_draw", | 228 state->SetBoolean("active_tree_needs_first_draw", |
228 active_tree_needs_first_draw_); | 229 active_tree_needs_first_draw_); |
| 230 state->SetBoolean("did_commit_after_animating", did_commit_after_animating_); |
229 state->SetBoolean("did_create_and_initialize_first_output_surface", | 231 state->SetBoolean("did_create_and_initialize_first_output_surface", |
230 did_create_and_initialize_first_output_surface_); | 232 did_create_and_initialize_first_output_surface_); |
231 state->SetBoolean("impl_latency_takes_priority", | 233 state->SetBoolean("impl_latency_takes_priority", |
232 impl_latency_takes_priority_); | 234 impl_latency_takes_priority_); |
233 state->SetBoolean("main_thread_is_in_high_latency_mode", | 235 state->SetBoolean("main_thread_is_in_high_latency_mode", |
234 MainThreadIsInHighLatencyMode()); | 236 MainThreadIsInHighLatencyMode()); |
235 state->SetBoolean("skip_begin_main_frame_to_reduce_latency", | 237 state->SetBoolean("skip_begin_main_frame_to_reduce_latency", |
236 skip_begin_main_frame_to_reduce_latency_); | 238 skip_begin_main_frame_to_reduce_latency_); |
237 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", | 239 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", |
238 skip_next_begin_main_frame_to_reduce_latency_); | 240 skip_next_begin_main_frame_to_reduce_latency_); |
239 state->SetBoolean("continuous_painting", continuous_painting_); | 241 state->SetBoolean("continuous_painting", continuous_painting_); |
240 state->SetBoolean("impl_latency_takes_priority_on_battery", | 242 state->SetBoolean("impl_latency_takes_priority_on_battery", |
241 impl_latency_takes_priority_on_battery_); | 243 impl_latency_takes_priority_on_battery_); |
242 state->EndDictionary(); | 244 state->EndDictionary(); |
243 } | 245 } |
244 | 246 |
245 void SchedulerStateMachine::AdvanceCurrentFrameNumber() { | 247 void SchedulerStateMachine::AdvanceCurrentFrameNumber() { |
246 current_frame_number_++; | 248 current_frame_number_++; |
247 | 249 |
248 // "Drain" the ManageTiles funnel. | 250 // "Drain" the ManageTiles funnel. |
249 if (manage_tiles_funnel_ > 0) | 251 if (manage_tiles_funnel_ > 0) |
250 manage_tiles_funnel_--; | 252 manage_tiles_funnel_--; |
251 | 253 |
252 skip_begin_main_frame_to_reduce_latency_ = | 254 skip_begin_main_frame_to_reduce_latency_ = |
253 skip_next_begin_main_frame_to_reduce_latency_; | 255 skip_next_begin_main_frame_to_reduce_latency_; |
254 skip_next_begin_main_frame_to_reduce_latency_ = false; | 256 skip_next_begin_main_frame_to_reduce_latency_ = false; |
255 } | 257 } |
256 | 258 |
| 259 bool SchedulerStateMachine::HasAnimatedThisFrame() const { |
| 260 return last_frame_number_animate_performed_ == current_frame_number_; |
| 261 } |
| 262 |
257 bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const { | 263 bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const { |
258 return current_frame_number_ == | 264 return current_frame_number_ == |
259 last_frame_number_begin_main_frame_sent_; | 265 last_frame_number_begin_main_frame_sent_; |
260 } | 266 } |
261 | 267 |
262 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const { | 268 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const { |
263 return current_frame_number_ == | 269 return current_frame_number_ == |
264 last_frame_number_update_visible_tiles_was_called_; | 270 last_frame_number_update_visible_tiles_was_called_; |
265 } | 271 } |
266 | 272 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 | 343 |
338 bool SchedulerStateMachine::ShouldDraw() const { | 344 bool SchedulerStateMachine::ShouldDraw() const { |
339 // If we need to abort draws, we should do so ASAP since the draw could | 345 // If we need to abort draws, we should do so ASAP since the draw could |
340 // be blocking other important actions (like output surface initialization), | 346 // be blocking other important actions (like output surface initialization), |
341 // from occuring. If we are waiting for the first draw, then perfom the | 347 // from occuring. If we are waiting for the first draw, then perfom the |
342 // aborted draw to keep things moving. If we are not waiting for the first | 348 // aborted draw to keep things moving. If we are not waiting for the first |
343 // draw however, we don't want to abort for no reason. | 349 // draw however, we don't want to abort for no reason. |
344 if (PendingDrawsShouldBeAborted()) | 350 if (PendingDrawsShouldBeAborted()) |
345 return active_tree_needs_first_draw_; | 351 return active_tree_needs_first_draw_; |
346 | 352 |
| 353 // If a commit has occurred after the animate call, we need to call animate |
| 354 // again before we should draw. |
| 355 if (did_commit_after_animating_) |
| 356 return false; |
| 357 |
347 // After this line, we only want to send a swap request once per frame. | 358 // After this line, we only want to send a swap request once per frame. |
348 if (HasRequestedSwapThisFrame()) | 359 if (HasRequestedSwapThisFrame()) |
349 return false; | 360 return false; |
350 | 361 |
351 // Do not queue too many swaps. | 362 // Do not queue too many swaps. |
352 if (pending_swaps_ >= max_pending_swaps_) | 363 if (pending_swaps_ >= max_pending_swaps_) |
353 return false; | 364 return false; |
354 | 365 |
355 // Except for the cases above, do not draw outside of the BeginImplFrame | 366 // Except for the cases above, do not draw outside of the BeginImplFrame |
356 // deadline. | 367 // deadline. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 if (swap_used_incomplete_tile_) | 419 if (swap_used_incomplete_tile_) |
409 return true; | 420 return true; |
410 | 421 |
411 return false; | 422 return false; |
412 } | 423 } |
413 | 424 |
414 bool SchedulerStateMachine::ShouldAnimate() const { | 425 bool SchedulerStateMachine::ShouldAnimate() const { |
415 if (!can_draw_) | 426 if (!can_draw_) |
416 return false; | 427 return false; |
417 | 428 |
418 if (last_frame_number_animate_performed_ == current_frame_number_) | 429 // If a commit occurred after our last call, we need to do animation again. |
| 430 if (HasAnimatedThisFrame() && !did_commit_after_animating_) |
419 return false; | 431 return false; |
420 | 432 |
421 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING && | 433 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING && |
422 begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) | 434 begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) |
423 return false; | 435 return false; |
424 | 436 |
425 return needs_redraw_ || needs_animate_; | 437 return needs_redraw_ || needs_animate_; |
426 } | 438 } |
427 | 439 |
428 bool SchedulerStateMachine::CouldSendBeginMainFrame() const { | 440 bool SchedulerStateMachine::CouldSendBeginMainFrame() const { |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 current_frame_number_; | 572 current_frame_number_; |
561 return; | 573 return; |
562 | 574 |
563 case ACTION_ACTIVATE_SYNC_TREE: | 575 case ACTION_ACTIVATE_SYNC_TREE: |
564 UpdateStateOnActivation(); | 576 UpdateStateOnActivation(); |
565 return; | 577 return; |
566 | 578 |
567 case ACTION_ANIMATE: | 579 case ACTION_ANIMATE: |
568 last_frame_number_animate_performed_ = current_frame_number_; | 580 last_frame_number_animate_performed_ = current_frame_number_; |
569 needs_animate_ = false; | 581 needs_animate_ = false; |
| 582 did_commit_after_animating_ = false; |
570 // TODO(skyostil): Instead of assuming this, require the client to tell | 583 // TODO(skyostil): Instead of assuming this, require the client to tell |
571 // us. | 584 // us. |
572 SetNeedsRedraw(); | 585 SetNeedsRedraw(); |
573 return; | 586 return; |
574 | 587 |
575 case ACTION_SEND_BEGIN_MAIN_FRAME: | 588 case ACTION_SEND_BEGIN_MAIN_FRAME: |
576 DCHECK(!has_pending_tree_ || | 589 DCHECK(!has_pending_tree_ || |
577 settings_.main_frame_before_activation_enabled); | 590 settings_.main_frame_before_activation_enabled); |
578 DCHECK(visible_); | 591 DCHECK(visible_); |
579 commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_SENT; | 592 commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_SENT; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 | 628 |
616 case ACTION_MANAGE_TILES: | 629 case ACTION_MANAGE_TILES: |
617 UpdateStateOnManageTiles(); | 630 UpdateStateOnManageTiles(); |
618 return; | 631 return; |
619 } | 632 } |
620 } | 633 } |
621 | 634 |
622 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { | 635 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { |
623 commit_count_++; | 636 commit_count_++; |
624 | 637 |
| 638 if (!commit_was_aborted && HasAnimatedThisFrame()) |
| 639 did_commit_after_animating_ = true; |
| 640 |
625 if (commit_was_aborted || settings_.main_frame_before_activation_enabled) { | 641 if (commit_was_aborted || settings_.main_frame_before_activation_enabled) { |
626 commit_state_ = COMMIT_STATE_IDLE; | 642 commit_state_ = COMMIT_STATE_IDLE; |
627 } else { | 643 } else { |
628 commit_state_ = settings_.impl_side_painting | 644 commit_state_ = settings_.impl_side_painting |
629 ? COMMIT_STATE_WAITING_FOR_ACTIVATION | 645 ? COMMIT_STATE_WAITING_FOR_ACTIVATION |
630 : COMMIT_STATE_IDLE; | 646 : COMMIT_STATE_IDLE; |
631 } | 647 } |
632 | 648 |
633 // If we are impl-side-painting but the commit was aborted, then we behave | 649 // If we are impl-side-painting but the commit was aborted, then we behave |
634 // mostly as if we are not impl-side-painting since there is no pending tree. | 650 // mostly as if we are not impl-side-painting since there is no pending tree. |
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1099 static_cast<int>(begin_impl_frame_state_), | 1115 static_cast<int>(begin_impl_frame_state_), |
1100 static_cast<int>(commit_state_), | 1116 static_cast<int>(commit_state_), |
1101 has_pending_tree_ ? 'T' : 'F', | 1117 has_pending_tree_ ? 'T' : 'F', |
1102 pending_tree_is_ready_for_activation_ ? 'T' : 'F', | 1118 pending_tree_is_ready_for_activation_ ? 'T' : 'F', |
1103 active_tree_needs_first_draw_ ? 'T' : 'F', | 1119 active_tree_needs_first_draw_ ? 'T' : 'F', |
1104 max_pending_swaps_, | 1120 max_pending_swaps_, |
1105 pending_swaps_); | 1121 pending_swaps_); |
1106 } | 1122 } |
1107 | 1123 |
1108 } // namespace cc | 1124 } // namespace cc |
OLD | NEW |