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

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

Issue 1012853003: Add DisplayScheduler for Surfaces (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: change Browser references to root surfce 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
« no previous file with comments | « cc/scheduler/scheduler.h ('k') | cc/scheduler/scheduler_state_machine.h » ('j') | 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.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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 122
123 base::TimeTicks Scheduler::Now() const { 123 base::TimeTicks Scheduler::Now() const {
124 base::TimeTicks now = gfx::FrameTime::Now(); 124 base::TimeTicks now = gfx::FrameTime::Now();
125 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.now"), 125 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.now"),
126 "Scheduler::Now", 126 "Scheduler::Now",
127 "now", 127 "now",
128 now); 128 now);
129 return now; 129 return now;
130 } 130 }
131 131
132 void Scheduler::SetAuthoritativeVSyncInterval(const base::TimeDelta& interval) {
133 authoritative_vsync_interval_ = interval;
134 if (vsync_observer_)
135 vsync_observer_->OnUpdateVSyncParameters(last_vsync_timebase_, interval);
136 }
137
132 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase, 138 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase,
133 base::TimeDelta interval) { 139 base::TimeDelta interval) {
140 TRACE_EVENT2("cc", "Scheduler::CommitVSyncParameters", "timebase",
141 (timebase - base::TimeTicks()).InSecondsF(), "interval",
142 interval.InSecondsF());
143
134 if (authoritative_vsync_interval_ != base::TimeDelta()) { 144 if (authoritative_vsync_interval_ != base::TimeDelta()) {
135 interval = authoritative_vsync_interval_; 145 interval = authoritative_vsync_interval_;
136 } else if (interval == base::TimeDelta()) { 146 } else if (interval == base::TimeDelta()) {
137 // TODO(brianderson): We should not be receiving 0 intervals. 147 // TODO(brianderson): We should not be receiving 0 intervals.
138 interval = BeginFrameArgs::DefaultInterval(); 148 interval = BeginFrameArgs::DefaultInterval();
139 } 149 }
140 150
141 last_vsync_timebase_ = timebase; 151 last_vsync_timebase_ = timebase;
142 152
143 if (vsync_observer_) 153 if (vsync_observer_)
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 BeginImplFrameWithDeadline(adjusted_args); 398 BeginImplFrameWithDeadline(adjusted_args);
389 } 399 }
390 return true; 400 return true;
391 } 401 }
392 402
393 void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) { 403 void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) {
394 state_machine_.SetChildrenNeedBeginFrames(children_need_begin_frames); 404 state_machine_.SetChildrenNeedBeginFrames(children_need_begin_frames);
395 ProcessScheduledActions(); 405 ProcessScheduledActions();
396 } 406 }
397 407
398 void Scheduler::SetAuthoritativeVSyncInterval(const base::TimeDelta& interval) {
399 authoritative_vsync_interval_ = interval;
400 if (vsync_observer_)
401 vsync_observer_->OnUpdateVSyncParameters(last_vsync_timebase_, interval);
402 }
403
404 void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) { 408 void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) {
405 state_machine_.SetVideoNeedsBeginFrames(video_needs_begin_frames); 409 state_machine_.SetVideoNeedsBeginFrames(video_needs_begin_frames);
406 ProcessScheduledActions(); 410 ProcessScheduledActions();
407 } 411 }
408 412
409 void Scheduler::OnDrawForOutputSurface() { 413 void Scheduler::OnDrawForOutputSurface() {
410 DCHECK(settings_.using_synchronous_renderer_compositor); 414 DCHECK(settings_.using_synchronous_renderer_compositor);
411 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 415 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
412 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 416 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
413 DCHECK(!BeginImplFrameDeadlinePending()); 417 DCHECK(!BeginImplFrameDeadlinePending());
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 args.AsValue(), "main_thread_is_high_latency", 503 args.AsValue(), "main_thread_is_high_latency",
500 main_thread_is_in_high_latency_mode); 504 main_thread_is_in_high_latency_mode);
501 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 505 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
502 "MainThreadLatency", main_thread_is_in_high_latency_mode); 506 "MainThreadLatency", main_thread_is_in_high_latency_mode);
503 507
504 advance_commit_state_task_.Cancel(); 508 advance_commit_state_task_.Cancel();
505 509
506 begin_impl_frame_args_ = args; 510 begin_impl_frame_args_ = args;
507 begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate(); 511 begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate();
508 512
513 // Prioritize skipping the main thread's latency first so we can keep the
514 // main and impl threads synchronized. Then skip an impl frame if it makes
515 // sense. This avoids skipping both at the same time to avoid strange
516 // interactions/oscillations since CanDrawBeforeDeadline() depends on
517 // whether the main thread is in a high latency mode or not.
509 if (!state_machine_.impl_latency_takes_priority() && 518 if (!state_machine_.impl_latency_takes_priority() &&
510 main_thread_is_in_high_latency_mode && 519 main_thread_is_in_high_latency_mode &&
511 CanCommitAndActivateBeforeDeadline()) { 520 CanCommitAndActivateBeforeDeadline()) {
512 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); 521 state_machine_.SetSkipNextBeginMainFrameToReduceLatency();
522 } else if (CanDrawBeforeDeadline() &&
523 state_machine_.last_swap_ack_came_after_begin_impl_frame()) {
524 // Skip this BeginImplFrame by returning early.
525 state_machine_.DidSkipBeginImplFrameToReduceLatency();
526 return;
513 } 527 }
514 528
515 BeginImplFrame(); 529 BeginImplFrame();
516 530
517 // The deadline will be scheduled in ProcessScheduledActions. 531 // The deadline will be scheduled in ProcessScheduledActions.
518 state_machine_.OnBeginImplFrameDeadlinePending(); 532 state_machine_.OnBeginImplFrameDeadlinePending();
519 ProcessScheduledActions(); 533 ProcessScheduledActions();
520 } 534 }
521 535
522 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { 536 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) {
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
814 bool Scheduler::CanCommitAndActivateBeforeDeadline() const { 828 bool Scheduler::CanCommitAndActivateBeforeDeadline() const {
815 // Check if the main thread computation and commit can be finished before the 829 // Check if the main thread computation and commit can be finished before the
816 // impl thread's deadline. 830 // impl thread's deadline.
817 base::TimeTicks estimated_draw_time = 831 base::TimeTicks estimated_draw_time =
818 begin_impl_frame_args_.frame_time + 832 begin_impl_frame_args_.frame_time +
819 client_->BeginMainFrameToCommitDurationEstimate() + 833 client_->BeginMainFrameToCommitDurationEstimate() +
820 client_->CommitToActivateDurationEstimate(); 834 client_->CommitToActivateDurationEstimate();
821 835
822 TRACE_EVENT2( 836 TRACE_EVENT2(
823 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 837 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
824 "CanCommitAndActivateBeforeDeadline", 838 "CanCommitAndActivateBeforeDeadline", "est_time_left_after_drawing_ms",
825 "time_left_after_drawing_ms",
826 (begin_impl_frame_args_.deadline - estimated_draw_time).InMillisecondsF(), 839 (begin_impl_frame_args_.deadline - estimated_draw_time).InMillisecondsF(),
827 "state", 840 "state", AsValue());
828 AsValue());
829 841
830 return estimated_draw_time < begin_impl_frame_args_.deadline; 842 return estimated_draw_time < begin_impl_frame_args_.deadline;
831 } 843 }
832 844
845 bool Scheduler::CanDrawBeforeDeadline() const {
846 bool main_thread_is_in_high_latency_mode =
847 state_machine_.MainThreadIsInHighLatencyMode();
848
849 // Check if the main thread computation and commit can be finished before the
850 // impl thread's deadline.
851 base::TimeTicks estimated_draw_time = begin_impl_frame_args_.frame_time;
852 if (!main_thread_is_in_high_latency_mode) {
853 estimated_draw_time += client_->BeginMainFrameToCommitDurationEstimate() +
854 client_->CommitToActivateDurationEstimate();
855 }
856
857 base::TimeDelta time_left_after_drawing =
858 begin_impl_frame_args_.deadline - estimated_draw_time;
859
860 TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
861 "CanDrawBeforeDeadline", "time_left_after_drawing_ms",
862 time_left_after_drawing.InMillisecondsF(), "state", AsValue());
863
864 // Ideally we could use a threshold of 0, but our deadlines are currently
865 // just estimates, so we are extra careful not to skip frames if we aren't
866 // absolutely sure the Impl thread can run in a low latency mode.
867 // TODO(mithro): Replace this with SwapNack logic.
868 base::TimeDelta threshold = BeginFrameArgs::DefaultEstimatedParentDrawTime();
869
870 return time_left_after_drawing > threshold;
871 }
872
833 bool Scheduler::IsBeginMainFrameSentOrStarted() const { 873 bool Scheduler::IsBeginMainFrameSentOrStarted() const {
834 return (state_machine_.commit_state() == 874 return (state_machine_.commit_state() ==
835 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || 875 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT ||
836 state_machine_.commit_state() == 876 state_machine_.commit_state() ==
837 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); 877 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED);
838 } 878 }
839 879
840 } // namespace cc 880 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/scheduler.h ('k') | cc/scheduler/scheduler_state_machine.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698