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