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 3 // found in the LICENSE file. 4 5 #ifndef CC_SCHEDULER_SCHEDULER_H_ 6 #define CC_SCHEDULER_SCHEDULER_H_ 7 8 #include <deque> 9 #include <string> 10 11 #include "base/basictypes.h" 12 #include "base/cancelable_callback.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/time/time.h" 15 #include "cc/base/cc_export.h" 16 #include "cc/output/begin_frame_args.h" 17 #include "cc/scheduler/delay_based_time_source.h" 18 #include "cc/scheduler/draw_result.h" 19 #include "cc/scheduler/scheduler_settings.h" 20 #include "cc/scheduler/scheduler_state_machine.h" 21 22 namespace base { 23 namespace debug { 24 class ConvertableToTraceFormat; 25 } 26 class SingleThreadTaskRunner; 27 } 28 29 namespace cc { 30 31 class SchedulerClient { 32 public: 33 virtual void SetNeedsBeginFrame(bool enable) = 0; 34 virtual void WillBeginImplFrame(const BeginFrameArgs& args) = 0; 35 virtual void ScheduledActionSendBeginMainFrame() = 0; 36 virtual DrawResult ScheduledActionDrawAndSwapIfPossible() = 0; 37 virtual DrawResult ScheduledActionDrawAndSwapForced() = 0; 38 virtual void ScheduledActionAnimate() = 0; 39 virtual void ScheduledActionCommit() = 0; 40 virtual void ScheduledActionUpdateVisibleTiles() = 0; 41 virtual void ScheduledActionActivateSyncTree() = 0; 42 virtual void ScheduledActionBeginOutputSurfaceCreation() = 0; 43 virtual void ScheduledActionManageTiles() = 0; 44 virtual void DidAnticipatedDrawTimeChange(base::TimeTicks time) = 0; 45 virtual base::TimeDelta DrawDurationEstimate() = 0; 46 virtual base::TimeDelta BeginMainFrameToCommitDurationEstimate() = 0; 47 virtual base::TimeDelta CommitToActivateDurationEstimate() = 0; 48 virtual void DidBeginImplFrameDeadline() = 0; 49 50 protected: 51 virtual ~SchedulerClient() {} 52 }; 53 54 class CC_EXPORT Scheduler { 55 public: 56 static scoped_ptr<Scheduler> Create( 57 SchedulerClient* client, 58 const SchedulerSettings& scheduler_settings, 59 int layer_tree_host_id, 60 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) { 61 return make_scoped_ptr(new Scheduler( 62 client, scheduler_settings, layer_tree_host_id, task_runner)); 63 } 64 65 virtual ~Scheduler(); 66 67 const SchedulerSettings& settings() const { return settings_; } 68 69 void CommitVSyncParameters(base::TimeTicks timebase, 70 base::TimeDelta interval); 71 void SetEstimatedParentDrawTime(base::TimeDelta draw_time); 72 73 void SetCanStart(); 74 75 void SetVisible(bool visible); 76 void SetCanDraw(bool can_draw); 77 void NotifyReadyToActivate(); 78 79 void SetNeedsCommit(); 80 81 void SetNeedsRedraw(); 82 83 void SetNeedsAnimate(); 84 85 void SetNeedsManageTiles(); 86 87 void SetMaxSwapsPending(int max); 88 void DidSwapBuffers(); 89 void SetSwapUsedIncompleteTile(bool used_incomplete_tile); 90 void DidSwapBuffersComplete(); 91 92 void SetImplLatencyTakesPriority(bool impl_latency_takes_priority); 93 94 void NotifyReadyToCommit(); 95 void BeginMainFrameAborted(bool did_handle); 96 97 void DidManageTiles(); 98 void DidLoseOutputSurface(); 99 void DidCreateAndInitializeOutputSurface(); 100 101 // Tests do not want to shut down until all possible BeginMainFrames have 102 // occured to prevent flakiness. 103 bool MainFrameForTestingWillHappen() const { 104 return state_machine_.CommitPending() || 105 state_machine_.CouldSendBeginMainFrame(); 106 } 107 108 bool CommitPending() const { return state_machine_.CommitPending(); } 109 bool RedrawPending() const { return state_machine_.RedrawPending(); } 110 bool ManageTilesPending() const { 111 return state_machine_.ManageTilesPending(); 112 } 113 bool MainThreadIsInHighLatencyMode() const { 114 return state_machine_.MainThreadIsInHighLatencyMode(); 115 } 116 bool BeginImplFrameDeadlinePending() const { 117 return !begin_impl_frame_deadline_task_.IsCancelled(); 118 } 119 120 bool WillDrawIfNeeded() const; 121 122 base::TimeTicks AnticipatedDrawTime() const; 123 124 void NotifyBeginMainFrameStarted(); 125 126 base::TimeTicks LastBeginImplFrameTime(); 127 128 void BeginFrame(const BeginFrameArgs& args); 129 130 scoped_refptr<base::debug::ConvertableToTraceFormat> AsValue() const; 131 void AsValueInto(base::debug::TracedValue* state) const; 132 133 void SetContinuousPainting(bool continuous_painting) { 134 state_machine_.SetContinuousPainting(continuous_painting); 135 } 136 137 protected: 138 class CC_EXPORT SyntheticBeginFrameSource : public TimeSourceClient { 139 public: 140 SyntheticBeginFrameSource(Scheduler* scheduler, 141 scoped_refptr<DelayBasedTimeSource> time_source); 142 virtual ~SyntheticBeginFrameSource(); 143 144 // Updates the phase and frequency of the timer. 145 void CommitVSyncParameters(base::TimeTicks timebase, 146 base::TimeDelta interval); 147 148 // Activates future BeginFrames and, if activating, pushes the most 149 // recently missed BeginFrame to the back of a retroactive queue. 150 void SetNeedsBeginFrame(bool needs_begin_frame, 151 std::deque<BeginFrameArgs>* begin_retro_frame_args); 152 153 bool IsActive() const; 154 155 // TimeSourceClient implementation of OnTimerTick triggers a BeginFrame. 156 virtual void OnTimerTick() OVERRIDE; 157 158 void AsValueInto(base::debug::TracedValue* dict) const; 159 160 private: 161 BeginFrameArgs CreateSyntheticBeginFrameArgs(base::TimeTicks frame_time); 162 163 Scheduler* scheduler_; 164 scoped_refptr<DelayBasedTimeSource> time_source_; 165 }; 166 167 Scheduler(SchedulerClient* client, 168 const SchedulerSettings& scheduler_settings, 169 int layer_tree_host_id, 170 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner); 171 172 virtual base::TimeTicks Now() const; 173 174 const SchedulerSettings settings_; 175 SchedulerClient* client_; 176 int layer_tree_host_id_; 177 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 178 179 base::TimeDelta vsync_interval_; 180 base::TimeDelta estimated_parent_draw_time_; 181 182 bool last_set_needs_begin_frame_; 183 bool begin_unthrottled_frame_posted_; 184 bool begin_retro_frame_posted_; 185 std::deque<BeginFrameArgs> begin_retro_frame_args_; 186 BeginFrameArgs begin_impl_frame_args_; 187 188 scoped_ptr<SyntheticBeginFrameSource> synthetic_begin_frame_source_; 189 190 base::Closure begin_retro_frame_closure_; 191 base::Closure begin_unthrottled_frame_closure_; 192 193 base::Closure begin_impl_frame_deadline_closure_; 194 base::Closure poll_for_draw_triggers_closure_; 195 base::Closure advance_commit_state_closure_; 196 base::CancelableClosure begin_impl_frame_deadline_task_; 197 base::CancelableClosure poll_for_draw_triggers_task_; 198 base::CancelableClosure advance_commit_state_task_; 199 200 SchedulerStateMachine state_machine_; 201 bool inside_process_scheduled_actions_; 202 SchedulerStateMachine::Action inside_action_; 203 204 base::TimeDelta VSyncInterval() { return vsync_interval_; } 205 206 private: 207 base::TimeTicks AdjustedBeginImplFrameDeadline( 208 const BeginFrameArgs& args, 209 base::TimeDelta draw_duration_estimate) const; 210 void ScheduleBeginImplFrameDeadline(base::TimeTicks deadline); 211 void SetupNextBeginFrameIfNeeded(); 212 void PostBeginRetroFrameIfNeeded(); 213 void SetupNextBeginFrameWhenVSyncThrottlingEnabled(bool needs_begin_frame); 214 void SetupNextBeginFrameWhenVSyncThrottlingDisabled(bool needs_begin_frame); 215 void SetupPollingMechanisms(bool needs_begin_frame); 216 void DrawAndSwapIfPossible(); 217 void ProcessScheduledActions(); 218 bool CanCommitAndActivateBeforeDeadline() const; 219 void AdvanceCommitStateIfPossible(); 220 bool IsBeginMainFrameSentOrStarted() const; 221 void SetupSyntheticBeginFrames(); 222 void BeginRetroFrame(); 223 void BeginUnthrottledFrame(); 224 void BeginImplFrame(const BeginFrameArgs& args); 225 void OnBeginImplFrameDeadline(); 226 void PollForAnticipatedDrawTriggers(); 227 void PollToAdvanceCommitState(); 228 229 base::TimeDelta EstimatedParentDrawTime() { 230 return estimated_parent_draw_time_; 231 } 232 233 bool IsInsideAction(SchedulerStateMachine::Action action) { 234 return inside_action_ == action; 235 } 236 237 base::WeakPtrFactory<Scheduler> weak_factory_; 238 239 DISALLOW_COPY_AND_ASSIGN(Scheduler); 240 }; 241 242 } // namespace cc 243 244 #endif // CC_SCHEDULER_SCHEDULER_H_ 245