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 } | 52 } |
52 | 53 |
53 const char* SchedulerStateMachine::OutputSurfaceStateToString( | 54 const char* SchedulerStateMachine::OutputSurfaceStateToString( |
54 OutputSurfaceState state) { | 55 OutputSurfaceState state) { |
55 switch (state) { | 56 switch (state) { |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 state->SetBoolean("swap_used_incomplete_tile", swap_used_incomplete_tile_); | 219 state->SetBoolean("swap_used_incomplete_tile", swap_used_incomplete_tile_); |
219 state->SetBoolean("needs_commit", needs_commit_); | 220 state->SetBoolean("needs_commit", needs_commit_); |
220 state->SetBoolean("visible", visible_); | 221 state->SetBoolean("visible", visible_); |
221 state->SetBoolean("can_start", can_start_); | 222 state->SetBoolean("can_start", can_start_); |
222 state->SetBoolean("can_draw", can_draw_); | 223 state->SetBoolean("can_draw", can_draw_); |
223 state->SetBoolean("has_pending_tree", has_pending_tree_); | 224 state->SetBoolean("has_pending_tree", has_pending_tree_); |
224 state->SetBoolean("pending_tree_is_ready_for_activation", | 225 state->SetBoolean("pending_tree_is_ready_for_activation", |
225 pending_tree_is_ready_for_activation_); | 226 pending_tree_is_ready_for_activation_); |
226 state->SetBoolean("active_tree_needs_first_draw", | 227 state->SetBoolean("active_tree_needs_first_draw", |
227 active_tree_needs_first_draw_); | 228 active_tree_needs_first_draw_); |
| 229 state->SetBoolean("did_commit_after_animating", did_commit_after_animating_); |
228 state->SetBoolean("did_create_and_initialize_first_output_surface", | 230 state->SetBoolean("did_create_and_initialize_first_output_surface", |
229 did_create_and_initialize_first_output_surface_); | 231 did_create_and_initialize_first_output_surface_); |
230 state->SetBoolean("impl_latency_takes_priority", | 232 state->SetBoolean("impl_latency_takes_priority", |
231 impl_latency_takes_priority_); | 233 impl_latency_takes_priority_); |
232 state->SetBoolean("main_thread_is_in_high_latency_mode", | 234 state->SetBoolean("main_thread_is_in_high_latency_mode", |
233 MainThreadIsInHighLatencyMode()); | 235 MainThreadIsInHighLatencyMode()); |
234 state->SetBoolean("skip_begin_main_frame_to_reduce_latency", | 236 state->SetBoolean("skip_begin_main_frame_to_reduce_latency", |
235 skip_begin_main_frame_to_reduce_latency_); | 237 skip_begin_main_frame_to_reduce_latency_); |
236 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", | 238 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", |
237 skip_next_begin_main_frame_to_reduce_latency_); | 239 skip_next_begin_main_frame_to_reduce_latency_); |
238 state->SetBoolean("continuous_painting", continuous_painting_); | 240 state->SetBoolean("continuous_painting", continuous_painting_); |
239 state->EndDictionary(); | 241 state->EndDictionary(); |
240 } | 242 } |
241 | 243 |
242 void SchedulerStateMachine::AdvanceCurrentFrameNumber() { | 244 void SchedulerStateMachine::AdvanceCurrentFrameNumber() { |
243 current_frame_number_++; | 245 current_frame_number_++; |
244 | 246 |
245 // "Drain" the ManageTiles funnel. | 247 // "Drain" the ManageTiles funnel. |
246 if (manage_tiles_funnel_ > 0) | 248 if (manage_tiles_funnel_ > 0) |
247 manage_tiles_funnel_--; | 249 manage_tiles_funnel_--; |
248 | 250 |
249 skip_begin_main_frame_to_reduce_latency_ = | 251 skip_begin_main_frame_to_reduce_latency_ = |
250 skip_next_begin_main_frame_to_reduce_latency_; | 252 skip_next_begin_main_frame_to_reduce_latency_; |
251 skip_next_begin_main_frame_to_reduce_latency_ = false; | 253 skip_next_begin_main_frame_to_reduce_latency_ = false; |
252 } | 254 } |
253 | 255 |
| 256 bool SchedulerStateMachine::HasAnimatedThisFrame() const { |
| 257 return last_frame_number_animate_performed_ == current_frame_number_; |
| 258 } |
| 259 |
254 bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const { | 260 bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const { |
255 return current_frame_number_ == | 261 return current_frame_number_ == |
256 last_frame_number_begin_main_frame_sent_; | 262 last_frame_number_begin_main_frame_sent_; |
257 } | 263 } |
258 | 264 |
259 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const { | 265 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const { |
260 return current_frame_number_ == | 266 return current_frame_number_ == |
261 last_frame_number_update_visible_tiles_was_called_; | 267 last_frame_number_update_visible_tiles_was_called_; |
262 } | 268 } |
263 | 269 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 | 340 |
335 bool SchedulerStateMachine::ShouldDraw() const { | 341 bool SchedulerStateMachine::ShouldDraw() const { |
336 // If we need to abort draws, we should do so ASAP since the draw could | 342 // If we need to abort draws, we should do so ASAP since the draw could |
337 // be blocking other important actions (like output surface initialization), | 343 // be blocking other important actions (like output surface initialization), |
338 // from occuring. If we are waiting for the first draw, then perfom the | 344 // from occuring. If we are waiting for the first draw, then perfom the |
339 // aborted draw to keep things moving. If we are not waiting for the first | 345 // aborted draw to keep things moving. If we are not waiting for the first |
340 // draw however, we don't want to abort for no reason. | 346 // draw however, we don't want to abort for no reason. |
341 if (PendingDrawsShouldBeAborted()) | 347 if (PendingDrawsShouldBeAborted()) |
342 return active_tree_needs_first_draw_; | 348 return active_tree_needs_first_draw_; |
343 | 349 |
| 350 // If a commit has occurred after the animate call, we need to call animate |
| 351 // again before we should draw. |
| 352 if (did_commit_after_animating_) |
| 353 return false; |
| 354 |
344 // After this line, we only want to send a swap request once per frame. | 355 // After this line, we only want to send a swap request once per frame. |
345 if (HasRequestedSwapThisFrame()) | 356 if (HasRequestedSwapThisFrame()) |
346 return false; | 357 return false; |
347 | 358 |
348 // Do not queue too many swaps. | 359 // Do not queue too many swaps. |
349 if (pending_swaps_ >= max_pending_swaps_) | 360 if (pending_swaps_ >= max_pending_swaps_) |
350 return false; | 361 return false; |
351 | 362 |
352 // Except for the cases above, do not draw outside of the BeginImplFrame | 363 // Except for the cases above, do not draw outside of the BeginImplFrame |
353 // deadline. | 364 // deadline. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 if (swap_used_incomplete_tile_) | 416 if (swap_used_incomplete_tile_) |
406 return true; | 417 return true; |
407 | 418 |
408 return false; | 419 return false; |
409 } | 420 } |
410 | 421 |
411 bool SchedulerStateMachine::ShouldAnimate() const { | 422 bool SchedulerStateMachine::ShouldAnimate() const { |
412 if (!can_draw_) | 423 if (!can_draw_) |
413 return false; | 424 return false; |
414 | 425 |
415 if (last_frame_number_animate_performed_ == current_frame_number_) | 426 // If a commit occurred after our last call, we need to do animation again. |
| 427 if (HasAnimatedThisFrame() && !did_commit_after_animating_) |
416 return false; | 428 return false; |
417 | 429 |
418 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING && | 430 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING && |
419 begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) | 431 begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) |
420 return false; | 432 return false; |
421 | 433 |
422 return needs_redraw_ || needs_animate_; | 434 return needs_redraw_ || needs_animate_; |
423 } | 435 } |
424 | 436 |
425 bool SchedulerStateMachine::CouldSendBeginMainFrame() const { | 437 bool SchedulerStateMachine::CouldSendBeginMainFrame() const { |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 current_frame_number_; | 569 current_frame_number_; |
558 return; | 570 return; |
559 | 571 |
560 case ACTION_ACTIVATE_SYNC_TREE: | 572 case ACTION_ACTIVATE_SYNC_TREE: |
561 UpdateStateOnActivation(); | 573 UpdateStateOnActivation(); |
562 return; | 574 return; |
563 | 575 |
564 case ACTION_ANIMATE: | 576 case ACTION_ANIMATE: |
565 last_frame_number_animate_performed_ = current_frame_number_; | 577 last_frame_number_animate_performed_ = current_frame_number_; |
566 needs_animate_ = false; | 578 needs_animate_ = false; |
| 579 did_commit_after_animating_ = false; |
567 // TODO(skyostil): Instead of assuming this, require the client to tell | 580 // TODO(skyostil): Instead of assuming this, require the client to tell |
568 // us. | 581 // us. |
569 SetNeedsRedraw(); | 582 SetNeedsRedraw(); |
570 return; | 583 return; |
571 | 584 |
572 case ACTION_SEND_BEGIN_MAIN_FRAME: | 585 case ACTION_SEND_BEGIN_MAIN_FRAME: |
573 DCHECK(!has_pending_tree_ || | 586 DCHECK(!has_pending_tree_ || |
574 settings_.main_frame_before_activation_enabled); | 587 settings_.main_frame_before_activation_enabled); |
575 DCHECK(visible_); | 588 DCHECK(visible_); |
576 commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_SENT; | 589 commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_SENT; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 | 625 |
613 case ACTION_MANAGE_TILES: | 626 case ACTION_MANAGE_TILES: |
614 UpdateStateOnManageTiles(); | 627 UpdateStateOnManageTiles(); |
615 return; | 628 return; |
616 } | 629 } |
617 } | 630 } |
618 | 631 |
619 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { | 632 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { |
620 commit_count_++; | 633 commit_count_++; |
621 | 634 |
| 635 if (!commit_was_aborted && HasAnimatedThisFrame()) |
| 636 did_commit_after_animating_ = true; |
| 637 |
622 if (commit_was_aborted || settings_.main_frame_before_activation_enabled) { | 638 if (commit_was_aborted || settings_.main_frame_before_activation_enabled) { |
623 commit_state_ = COMMIT_STATE_IDLE; | 639 commit_state_ = COMMIT_STATE_IDLE; |
624 } else { | 640 } else { |
625 commit_state_ = settings_.impl_side_painting | 641 commit_state_ = settings_.impl_side_painting |
626 ? COMMIT_STATE_WAITING_FOR_ACTIVATION | 642 ? COMMIT_STATE_WAITING_FOR_ACTIVATION |
627 : COMMIT_STATE_IDLE; | 643 : COMMIT_STATE_IDLE; |
628 } | 644 } |
629 | 645 |
630 // If we are impl-side-painting but the commit was aborted, then we behave | 646 // If we are impl-side-painting but the commit was aborted, then we behave |
631 // mostly as if we are not impl-side-painting since there is no pending tree. | 647 // mostly as if we are not impl-side-painting since there is no pending tree. |
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1091 static_cast<int>(begin_impl_frame_state_), | 1107 static_cast<int>(begin_impl_frame_state_), |
1092 static_cast<int>(commit_state_), | 1108 static_cast<int>(commit_state_), |
1093 has_pending_tree_ ? 'T' : 'F', | 1109 has_pending_tree_ ? 'T' : 'F', |
1094 pending_tree_is_ready_for_activation_ ? 'T' : 'F', | 1110 pending_tree_is_ready_for_activation_ ? 'T' : 'F', |
1095 active_tree_needs_first_draw_ ? 'T' : 'F', | 1111 active_tree_needs_first_draw_ ? 'T' : 'F', |
1096 max_pending_swaps_, | 1112 max_pending_swaps_, |
1097 pending_swaps_); | 1113 pending_swaps_); |
1098 } | 1114 } |
1099 | 1115 |
1100 } // namespace cc | 1116 } // namespace cc |
OLD | NEW |