| 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.h" | 5 #include "cc/scheduler/scheduler.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 void Scheduler::SetCanDraw(bool can_draw) { | 162 void Scheduler::SetCanDraw(bool can_draw) { |
| 163 state_machine_.SetCanDraw(can_draw); | 163 state_machine_.SetCanDraw(can_draw); |
| 164 ProcessScheduledActions(); | 164 ProcessScheduledActions(); |
| 165 } | 165 } |
| 166 | 166 |
| 167 void Scheduler::NotifyReadyToActivate() { | 167 void Scheduler::NotifyReadyToActivate() { |
| 168 state_machine_.NotifyReadyToActivate(); | 168 state_machine_.NotifyReadyToActivate(); |
| 169 ProcessScheduledActions(); | 169 ProcessScheduledActions(); |
| 170 } | 170 } |
| 171 | 171 |
| 172 void Scheduler::SetRequiresHighResToDraw(bool required) { |
| 173 state_machine_.SetRequiresHighResToDraw(required); |
| 174 ProcessScheduledActions(); |
| 175 } |
| 176 |
| 172 void Scheduler::NotifyReadyToDraw() { | 177 void Scheduler::NotifyReadyToDraw() { |
| 173 // Future work might still needed for crbug.com/352894. | 178 // Future work might still needed for crbug.com/352894. |
| 174 state_machine_.NotifyReadyToDraw(); | 179 state_machine_.NotifyReadyToDraw(); |
| 175 ProcessScheduledActions(); | 180 ProcessScheduledActions(); |
| 176 } | 181 } |
| 177 | 182 |
| 178 void Scheduler::SetThrottleFrameProduction(bool throttle) { | 183 void Scheduler::SetThrottleFrameProduction(bool throttle) { |
| 179 throttle_frame_production_ = throttle; | 184 throttle_frame_production_ = throttle; |
| 180 if (throttle) { | 185 if (throttle) { |
| 181 frame_source_->SetActiveSource(primary_frame_source_); | 186 frame_source_->SetActiveSource(primary_frame_source_); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 193 void Scheduler::SetNeedsRedraw() { | 198 void Scheduler::SetNeedsRedraw() { |
| 194 state_machine_.SetNeedsRedraw(); | 199 state_machine_.SetNeedsRedraw(); |
| 195 ProcessScheduledActions(); | 200 ProcessScheduledActions(); |
| 196 } | 201 } |
| 197 | 202 |
| 198 void Scheduler::SetNeedsAnimate() { | 203 void Scheduler::SetNeedsAnimate() { |
| 199 state_machine_.SetNeedsAnimate(); | 204 state_machine_.SetNeedsAnimate(); |
| 200 ProcessScheduledActions(); | 205 ProcessScheduledActions(); |
| 201 } | 206 } |
| 202 | 207 |
| 203 void Scheduler::SetNeedsPrepareTiles() { | 208 void Scheduler::SetNeedsPrepareTiles(bool for_commit) { |
| 204 DCHECK(!IsInsideAction(SchedulerStateMachine::ACTION_PREPARE_TILES)); | 209 DCHECK(!IsInsideAction(SchedulerStateMachine::ACTION_PREPARE_TILES)); |
| 205 state_machine_.SetNeedsPrepareTiles(); | 210 state_machine_.SetNeedsPrepareTiles(for_commit); |
| 206 ProcessScheduledActions(); | 211 ProcessScheduledActions(); |
| 207 } | 212 } |
| 208 | 213 |
| 209 void Scheduler::SetWaitForReadyToDraw() { | 214 void Scheduler::SetWaitForReadyToDraw() { |
| 210 state_machine_.SetWaitForReadyToDraw(); | 215 state_machine_.SetWaitForReadyToDraw(); |
| 211 ProcessScheduledActions(); | 216 ProcessScheduledActions(); |
| 212 } | 217 } |
| 213 | 218 |
| 214 void Scheduler::SetMaxSwapsPending(int max) { | 219 void Scheduler::SetMaxSwapsPending(int max) { |
| 215 state_machine_.SetMaxSwapsPending(max); | 220 state_machine_.SetMaxSwapsPending(max); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 241 ProcessScheduledActions(); | 246 ProcessScheduledActions(); |
| 242 } | 247 } |
| 243 | 248 |
| 244 void Scheduler::BeginMainFrameAborted(CommitEarlyOutReason reason) { | 249 void Scheduler::BeginMainFrameAborted(CommitEarlyOutReason reason) { |
| 245 TRACE_EVENT1("cc", "Scheduler::BeginMainFrameAborted", "reason", | 250 TRACE_EVENT1("cc", "Scheduler::BeginMainFrameAborted", "reason", |
| 246 CommitEarlyOutReasonToString(reason)); | 251 CommitEarlyOutReasonToString(reason)); |
| 247 state_machine_.BeginMainFrameAborted(reason); | 252 state_machine_.BeginMainFrameAborted(reason); |
| 248 ProcessScheduledActions(); | 253 ProcessScheduledActions(); |
| 249 } | 254 } |
| 250 | 255 |
| 251 void Scheduler::DidPrepareTiles() { | |
| 252 state_machine_.DidPrepareTiles(); | |
| 253 } | |
| 254 | |
| 255 void Scheduler::DidLoseOutputSurface() { | 256 void Scheduler::DidLoseOutputSurface() { |
| 256 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); | 257 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); |
| 257 begin_retro_frame_args_.clear(); | 258 begin_retro_frame_args_.clear(); |
| 258 begin_retro_frame_task_.Cancel(); | 259 begin_retro_frame_task_.Cancel(); |
| 259 state_machine_.DidLoseOutputSurface(); | 260 state_machine_.DidLoseOutputSurface(); |
| 260 ProcessScheduledActions(); | 261 ProcessScheduledActions(); |
| 261 } | 262 } |
| 262 | 263 |
| 263 void Scheduler::DidCreateAndInitializeOutputSurface() { | 264 void Scheduler::DidCreateAndInitializeOutputSurface() { |
| 264 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); | 265 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 285 return timebase + (begin_impl_frame_args_.interval * intervals); | 286 return timebase + (begin_impl_frame_args_.interval * intervals); |
| 286 } | 287 } |
| 287 | 288 |
| 288 base::TimeTicks Scheduler::LastBeginImplFrameTime() { | 289 base::TimeTicks Scheduler::LastBeginImplFrameTime() { |
| 289 return begin_impl_frame_args_.frame_time; | 290 return begin_impl_frame_args_.frame_time; |
| 290 } | 291 } |
| 291 | 292 |
| 292 void Scheduler::SetupNextBeginFrameIfNeeded() { | 293 void Scheduler::SetupNextBeginFrameIfNeeded() { |
| 293 // Never call SetNeedsBeginFrames if the frame source already has the right | 294 // Never call SetNeedsBeginFrames if the frame source already has the right |
| 294 // value. | 295 // value. |
| 295 if (frame_source_->NeedsBeginFrames() != state_machine_.BeginFrameNeeded()) { | 296 bool begin_frames_needed = state_machine_.BeginFrameNeeded(); |
| 296 if (state_machine_.BeginFrameNeeded()) { | 297 if (frame_source_->NeedsBeginFrames() != begin_frames_needed) { |
| 298 if (begin_frames_needed) { |
| 297 // Call SetNeedsBeginFrames(true) as soon as possible. | 299 // Call SetNeedsBeginFrames(true) as soon as possible. |
| 298 frame_source_->SetNeedsBeginFrames(true); | 300 frame_source_->SetNeedsBeginFrames(true); |
| 299 } else if (state_machine_.begin_impl_frame_state() == | 301 } else if (state_machine_.begin_impl_frame_state() == |
| 300 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) { | 302 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) { |
| 301 // Call SetNeedsBeginFrames(false) in between frames only. | 303 // Call SetNeedsBeginFrames(false) in between frames only. |
| 302 frame_source_->SetNeedsBeginFrames(false); | 304 frame_source_->SetNeedsBeginFrames(false); |
| 303 client_->SendBeginMainFrameNotExpectedSoon(); | 305 client_->SendBeginMainFrameNotExpectedSoon(); |
| 304 } | 306 } |
| 307 state_machine_.NotifyBeginFrameSourceActive(begin_frames_needed); |
| 305 } | 308 } |
| 306 | 309 |
| 307 PostBeginRetroFrameIfNeeded(); | 310 PostBeginRetroFrameIfNeeded(); |
| 308 } | 311 } |
| 309 | 312 |
| 310 // We may need to poll when we can't rely on BeginFrame to advance certain | 313 // We may need to poll when we can't rely on BeginFrame to advance certain |
| 311 // state or to avoid deadlock. | 314 // state or to avoid deadlock. |
| 312 void Scheduler::SetupPollingMechanisms() { | 315 void Scheduler::SetupPollingMechanisms() { |
| 313 // At this point we'd prefer to advance through the commit flow by | 316 // At this point we'd prefer to advance through the commit flow by |
| 314 // drawing a frame, however it's possible that the frame rate controller | 317 // drawing a frame, however it's possible that the frame rate controller |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 deadline = begin_impl_frame_args_.deadline; | 572 deadline = begin_impl_frame_args_.deadline; |
| 570 break; | 573 break; |
| 571 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE: | 574 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE: |
| 572 // We are blocked for one reason or another and we should wait. | 575 // We are blocked for one reason or another and we should wait. |
| 573 // TODO(brianderson): Handle long deadlines (that are past the next | 576 // TODO(brianderson): Handle long deadlines (that are past the next |
| 574 // frame's frame time) properly instead of using this hack. | 577 // frame's frame time) properly instead of using this hack. |
| 575 deadline = | 578 deadline = |
| 576 begin_impl_frame_args_.frame_time + begin_impl_frame_args_.interval; | 579 begin_impl_frame_args_.frame_time + begin_impl_frame_args_.interval; |
| 577 break; | 580 break; |
| 578 case SchedulerStateMachine:: | 581 case SchedulerStateMachine:: |
| 582 BEGIN_IMPL_FRAME_DEADLINE_MODE_TRY_TO_AVOID_CHECKERBOARD: |
| 583 // We will wait up until this deadline for the ReadyToDraw signal. |
| 584 // TODO(brianderson): Use a different timeout for touch vs. mouse wheel. |
| 585 deadline = begin_impl_frame_args_.frame_time + |
| 586 (1 * begin_impl_frame_args_.interval); |
| 587 break; |
| 588 case SchedulerStateMachine:: |
| 579 BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW: | 589 BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW: |
| 580 // We are blocked because we are waiting for ReadyToDraw signal. We would | 590 // We are blocked because we are waiting for ReadyToDraw signal. We would |
| 581 // post deadline after we received ReadyToDraw singal. | 591 // post deadline after we received ReadyToDraw singal. |
| 582 TRACE_EVENT1("cc", "Scheduler::ScheduleBeginImplFrameDeadline", | 592 TRACE_EVENT1("cc", "Scheduler::ScheduleBeginImplFrameDeadline", |
| 583 "deadline_mode", "blocked_on_ready_to_draw"); | 593 "deadline_mode", "blocked_on_ready_to_draw"); |
| 584 return; | 594 return; |
| 585 } | 595 } |
| 586 | 596 |
| 587 TRACE_EVENT2("cc", "Scheduler::ScheduleBeginImplFrameDeadline", "mode", | 597 TRACE_EVENT2("cc", "Scheduler::ScheduleBeginImplFrameDeadline", "mode", |
| 588 SchedulerStateMachine::BeginImplFrameDeadlineModeToString( | 598 SchedulerStateMachine::BeginImplFrameDeadlineModeToString( |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 632 | 642 |
| 633 | 643 |
| 634 void Scheduler::PollToAdvanceCommitState() { | 644 void Scheduler::PollToAdvanceCommitState() { |
| 635 TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState"); | 645 TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState"); |
| 636 advance_commit_state_task_.Cancel(); | 646 advance_commit_state_task_.Cancel(); |
| 637 ProcessScheduledActions(); | 647 ProcessScheduledActions(); |
| 638 } | 648 } |
| 639 | 649 |
| 640 void Scheduler::DrawAndSwapIfPossible() { | 650 void Scheduler::DrawAndSwapIfPossible() { |
| 641 DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible(); | 651 DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible(); |
| 642 state_machine_.DidDrawIfPossibleCompleted(result); | 652 state_machine_.SetDrawResult(result); |
| 653 } |
| 654 |
| 655 void Scheduler::DrawAndSwapForced() { |
| 656 DrawResult result = client_->ScheduledActionDrawAndSwapForced(); |
| 657 state_machine_.SetDrawResult(result); |
| 643 } | 658 } |
| 644 | 659 |
| 645 void Scheduler::SetDeferCommits(bool defer_commits) { | 660 void Scheduler::SetDeferCommits(bool defer_commits) { |
| 646 TRACE_EVENT1("cc", "Scheduler::SetDeferCommits", | 661 TRACE_EVENT1("cc", "Scheduler::SetDeferCommits", |
| 647 "defer_commits", | 662 "defer_commits", |
| 648 defer_commits); | 663 defer_commits); |
| 649 state_machine_.SetDeferCommits(defer_commits); | 664 state_machine_.SetDeferCommits(defer_commits); |
| 650 ProcessScheduledActions(); | 665 ProcessScheduledActions(); |
| 651 } | 666 } |
| 652 | 667 |
| 653 void Scheduler::ProcessScheduledActions() { | 668 void Scheduler::ProcessScheduledActions() { |
| 654 // We do not allow ProcessScheduledActions to be recursive. | 669 // We do not allow ProcessScheduledActions to be recursive. |
| 655 // The top-level call will iteratively execute the next action for us anyway. | 670 // The top-level call will iteratively execute the next action for us anyway. |
| 656 if (inside_process_scheduled_actions_) | 671 if (inside_process_scheduled_actions_) |
| 657 return; | 672 return; |
| 658 | 673 |
| 659 base::AutoReset<bool> mark_inside(&inside_process_scheduled_actions_, true); | 674 base::AutoReset<bool> mark_inside(&inside_process_scheduled_actions_, true); |
| 660 | 675 |
| 661 SchedulerStateMachine::Action action; | 676 SchedulerStateMachine::Action action; |
| 662 do { | 677 do { |
| 663 action = state_machine_.NextAction(); | 678 action = state_machine_.NextAction(); |
| 664 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | 679 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), |
| 665 "SchedulerStateMachine", | 680 "SchedulerStateMachine", |
| 666 "state", | 681 "state", |
| 667 AsValue()); | 682 AsValue()); |
| 668 VLOG(2) << "Scheduler::ProcessScheduledActions: " | 683 VLOG(2) << "Scheduler::ProcessScheduledActions: " |
| 669 << SchedulerStateMachine::ActionToString(action) << " " | 684 << SchedulerStateMachine::ActionToString(action) << " " |
| 670 << state_machine_.GetStatesForDebugging(); | 685 << state_machine_.GetStatesForDebugging(); |
| 671 state_machine_.UpdateState(action); | 686 { |
| 672 base::AutoReset<SchedulerStateMachine::Action> | 687 base::AutoReset<SchedulerStateMachine::Action> mark_inside_action( |
| 673 mark_inside_action(&inside_action_, action); | 688 &inside_action_, action); |
| 674 switch (action) { | 689 switch (action) { |
| 675 case SchedulerStateMachine::ACTION_NONE: | 690 case SchedulerStateMachine::ACTION_NONE: |
| 676 break; | 691 break; |
| 677 case SchedulerStateMachine::ACTION_ANIMATE: | 692 case SchedulerStateMachine::ACTION_ANIMATE: |
| 678 client_->ScheduledActionAnimate(); | 693 client_->ScheduledActionAnimate(); |
| 679 break; | 694 break; |
| 680 case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME: | 695 case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME: |
| 681 client_->ScheduledActionSendBeginMainFrame(); | 696 client_->ScheduledActionSendBeginMainFrame(); |
| 682 break; | 697 break; |
| 683 case SchedulerStateMachine::ACTION_COMMIT: { | 698 case SchedulerStateMachine::ACTION_COMMIT: { |
| 684 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is | 699 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is |
| 685 // fixed. | 700 // fixed. |
| 686 tracked_objects::ScopedTracker tracking_profile4( | 701 tracked_objects::ScopedTracker tracking_profile4( |
| 687 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 702 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 688 "461509 Scheduler::ProcessScheduledActions4")); | 703 "461509 Scheduler::ProcessScheduledActions4")); |
| 689 client_->ScheduledActionCommit(); | 704 client_->ScheduledActionCommit(); |
| 690 break; | 705 break; |
| 706 } |
| 707 case SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE: |
| 708 client_->ScheduledActionActivateSyncTree(); |
| 709 break; |
| 710 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE: { |
| 711 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is |
| 712 // fixed. |
| 713 tracked_objects::ScopedTracker tracking_profile6( |
| 714 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 715 "461509 Scheduler::ProcessScheduledActions6")); |
| 716 DrawAndSwapIfPossible(); |
| 717 break; |
| 718 } |
| 719 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED: |
| 720 DrawAndSwapForced(); |
| 721 break; |
| 722 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT: |
| 723 // No action is actually performed, but this allows the state machine |
| 724 // to |
| 725 // advance out of its waiting to draw state without actually drawing. |
| 726 state_machine_.SetDrawResult(DRAW_SUCCESS); |
| 727 break; |
| 728 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION: |
| 729 client_->ScheduledActionBeginOutputSurfaceCreation(); |
| 730 break; |
| 731 case SchedulerStateMachine::ACTION_PREPARE_TILES: |
| 732 client_->ScheduledActionPrepareTiles(); |
| 733 break; |
| 734 case SchedulerStateMachine::ACTION_INVALIDATE_OUTPUT_SURFACE: { |
| 735 client_->ScheduledActionInvalidateOutputSurface(); |
| 736 break; |
| 737 } |
| 691 } | 738 } |
| 692 case SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE: | 739 state_machine_.UpdateState(action); |
| 693 client_->ScheduledActionActivateSyncTree(); | |
| 694 break; | |
| 695 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE: { | |
| 696 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is | |
| 697 // fixed. | |
| 698 tracked_objects::ScopedTracker tracking_profile6( | |
| 699 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
| 700 "461509 Scheduler::ProcessScheduledActions6")); | |
| 701 DrawAndSwapIfPossible(); | |
| 702 break; | |
| 703 } | |
| 704 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED: | |
| 705 client_->ScheduledActionDrawAndSwapForced(); | |
| 706 break; | |
| 707 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT: | |
| 708 // No action is actually performed, but this allows the state machine to | |
| 709 // advance out of its waiting to draw state without actually drawing. | |
| 710 break; | |
| 711 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION: | |
| 712 client_->ScheduledActionBeginOutputSurfaceCreation(); | |
| 713 break; | |
| 714 case SchedulerStateMachine::ACTION_PREPARE_TILES: | |
| 715 client_->ScheduledActionPrepareTiles(); | |
| 716 break; | |
| 717 case SchedulerStateMachine::ACTION_INVALIDATE_OUTPUT_SURFACE: { | |
| 718 client_->ScheduledActionInvalidateOutputSurface(); | |
| 719 break; | |
| 720 } | |
| 721 } | 740 } |
| 722 } while (action != SchedulerStateMachine::ACTION_NONE); | 741 } while (action != SchedulerStateMachine::ACTION_NONE); |
| 723 | 742 |
| 724 SetupPollingMechanisms(); | 743 SetupPollingMechanisms(); |
| 725 | 744 |
| 726 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime()); | 745 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime()); |
| 727 | 746 |
| 728 ScheduleBeginImplFrameDeadlineIfNeeded(); | 747 ScheduleBeginImplFrameDeadlineIfNeeded(); |
| 729 | 748 |
| 730 SetupNextBeginFrameIfNeeded(); | 749 SetupNextBeginFrameIfNeeded(); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 823 } | 842 } |
| 824 | 843 |
| 825 bool Scheduler::IsBeginMainFrameSentOrStarted() const { | 844 bool Scheduler::IsBeginMainFrameSentOrStarted() const { |
| 826 return (state_machine_.commit_state() == | 845 return (state_machine_.commit_state() == |
| 827 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || | 846 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || |
| 828 state_machine_.commit_state() == | 847 state_machine_.commit_state() == |
| 829 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); | 848 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); |
| 830 } | 849 } |
| 831 | 850 |
| 832 } // namespace cc | 851 } // namespace cc |
| OLD | NEW |