OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #ifndef CC_SCHEDULER_BEGIN_FRAME_SOURCE_H_ | 5 #ifndef CC_SCHEDULER_BEGIN_FRAME_SOURCE_H_ |
6 #define CC_SCHEDULER_BEGIN_FRAME_SOURCE_H_ | 6 #define CC_SCHEDULER_BEGIN_FRAME_SOURCE_H_ |
7 | 7 |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
11 #include <set> | 11 #include <set> |
12 #include <string> | 12 #include <string> |
| 13 #include <unordered_set> |
13 | 14 |
14 #include "base/logging.h" | 15 #include "base/logging.h" |
15 #include "base/macros.h" | 16 #include "base/macros.h" |
16 #include "base/trace_event/trace_event.h" | 17 #include "base/trace_event/trace_event.h" |
17 #include "cc/output/begin_frame_args.h" | 18 #include "cc/output/begin_frame_args.h" |
18 #include "cc/scheduler/delay_based_time_source.h" | 19 #include "cc/scheduler/delay_based_time_source.h" |
19 | 20 |
20 namespace cc { | 21 namespace cc { |
21 | 22 |
22 // (Pure) Interface for observing BeginFrame messages from BeginFrameSource | 23 // (Pure) Interface for observing BeginFrame messages from BeginFrameSource |
23 // objects. | 24 // objects. |
24 class CC_EXPORT BeginFrameObserver { | 25 class CC_EXPORT BeginFrameObserver { |
25 public: | 26 public: |
26 virtual ~BeginFrameObserver() {} | 27 virtual ~BeginFrameObserver() {} |
27 | 28 |
28 // The |args| given to OnBeginFrame is guaranteed to have | 29 // The |args| given to OnBeginFrame is guaranteed to have |
29 // |args|.IsValid()==true and have |args|.frame_time | 30 // |args|.IsValid()==true. If |args|.source_id did not change between |
30 // field be strictly greater than the previous call. | 31 // invocations, |args|.sequence_number is guaranteed to be be strictly greater |
| 32 // than the previous call. Further, |args|.frame_time is guaranteed to be |
| 33 // greater than or equal to the previous call even if the source_id changes. |
31 // | 34 // |
32 // Side effects: This function can (and most of the time *will*) change the | 35 // Side effects: This function can (and most of the time *will*) change the |
33 // return value of the LastUsedBeginFrameArgs method. See the documentation | 36 // return value of the LastUsedBeginFrameArgs method. See the documentation |
34 // on that method for more information. | 37 // on that method for more information. |
35 virtual void OnBeginFrame(const BeginFrameArgs& args) = 0; | 38 virtual void OnBeginFrame(const BeginFrameArgs& args) = 0; |
36 | 39 |
37 // Returns the last BeginFrameArgs used by the observer. This method's return | 40 // Returns the last BeginFrameArgs used by the observer. This method's return |
38 // value is affected by the OnBeginFrame method! | 41 // value is affected by the OnBeginFrame method! |
39 // | 42 // |
40 // - Before the first call of OnBeginFrame, this method should return a | 43 // - Before the first call of OnBeginFrame, this method should return a |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 // BeginFrameObserver. | 95 // BeginFrameObserver. |
93 // | 96 // |
94 // BeginFrame calls *normally* occur just after a vsync interrupt when input | 97 // BeginFrame calls *normally* occur just after a vsync interrupt when input |
95 // processing has been finished and provide information about the time values | 98 // processing has been finished and provide information about the time values |
96 // of the vsync times. *However*, these values can be heavily modified or even | 99 // of the vsync times. *However*, these values can be heavily modified or even |
97 // plain made up (when no vsync signal is available or vsync throttling is | 100 // plain made up (when no vsync signal is available or vsync throttling is |
98 // turned off). See the BeginFrameObserver for information about the guarantees | 101 // turned off). See the BeginFrameObserver for information about the guarantees |
99 // all BeginFrameSources *must* provide. | 102 // all BeginFrameSources *must* provide. |
100 class CC_EXPORT BeginFrameSource { | 103 class CC_EXPORT BeginFrameSource { |
101 public: | 104 public: |
| 105 BeginFrameSource(); |
102 virtual ~BeginFrameSource() {} | 106 virtual ~BeginFrameSource() {} |
103 | 107 |
104 // DidFinishFrame provides back pressure to a frame source about frame | 108 // BeginFrameObservers use DidFinishFrame to acknowledge that they have |
105 // processing (rather than toggling SetNeedsBeginFrames every frame). It is | 109 // completed handling a BeginFrame. |
106 // used by systems like the BackToBackFrameSource to make sure only one frame | 110 // |
107 // is pending at a time. | 111 // The DisplayScheduler uses these acknowledgments to trigger an early |
| 112 // deadline once all BeginFrameObservers have completed a frame. |
| 113 // |
| 114 // They also provide back pressure to a frame source about frame processing |
| 115 // (rather than toggling SetNeedsBeginFrames every frame). For example, the |
| 116 // BackToBackFrameSource uses them to make sure only one frame is pending at a |
| 117 // time. |
108 virtual void DidFinishFrame(BeginFrameObserver* obs, | 118 virtual void DidFinishFrame(BeginFrameObserver* obs, |
109 size_t remaining_frames) = 0; | 119 const BeginFrameAck& ack) = 0; |
110 | 120 |
111 // Add/Remove an observer from the source. When no observers are added the BFS | 121 // Add/Remove an observer from the source. When no observers are added the BFS |
112 // should shut down its timers, disable vsync, etc. | 122 // should shut down its timers, disable vsync, etc. |
113 virtual void AddObserver(BeginFrameObserver* obs) = 0; | 123 virtual void AddObserver(BeginFrameObserver* obs) = 0; |
114 virtual void RemoveObserver(BeginFrameObserver* obs) = 0; | 124 virtual void RemoveObserver(BeginFrameObserver* obs) = 0; |
115 | 125 |
116 // Returns false if the begin frame source will just continue to produce | 126 // Returns false if the begin frame source will just continue to produce |
117 // begin frames without waiting. | 127 // begin frames without waiting. |
118 virtual bool IsThrottled() const = 0; | 128 virtual bool IsThrottled() const = 0; |
| 129 |
| 130 // Returns an identifier for this BeginFrameSource. Guaranteed unique within a |
| 131 // process, but not across processes. This is used to create BeginFrames that |
| 132 // originate at this source. Note that BeginFrameSources may pass on |
| 133 // BeginFrames created by other sources, with different IDs. |
| 134 uint64_t source_id() const; |
| 135 |
| 136 private: |
| 137 uint64_t source_id_; |
119 }; | 138 }; |
120 | 139 |
121 // A BeginFrameSource that does nothing. | 140 // A BeginFrameSource that does nothing. |
122 class CC_EXPORT StubBeginFrameSource : public BeginFrameSource { | 141 class CC_EXPORT StubBeginFrameSource : public BeginFrameSource { |
123 public: | 142 public: |
124 void DidFinishFrame(BeginFrameObserver* obs, | 143 void DidFinishFrame(BeginFrameObserver* obs, |
125 size_t remaining_frames) override {} | 144 const BeginFrameAck& ack) override {} |
126 void AddObserver(BeginFrameObserver* obs) override {} | 145 void AddObserver(BeginFrameObserver* obs) override {} |
127 void RemoveObserver(BeginFrameObserver* obs) override {} | 146 void RemoveObserver(BeginFrameObserver* obs) override {} |
128 bool IsThrottled() const override; | 147 bool IsThrottled() const override; |
129 }; | 148 }; |
130 | 149 |
131 // A frame source which ticks itself independently. | 150 // A frame source which ticks itself independently. |
132 class CC_EXPORT SyntheticBeginFrameSource : public BeginFrameSource { | 151 class CC_EXPORT SyntheticBeginFrameSource : public BeginFrameSource { |
133 public: | 152 public: |
134 ~SyntheticBeginFrameSource() override; | 153 ~SyntheticBeginFrameSource() override; |
135 | 154 |
136 virtual void OnUpdateVSyncParameters(base::TimeTicks timebase, | 155 virtual void OnUpdateVSyncParameters(base::TimeTicks timebase, |
137 base::TimeDelta interval) = 0; | 156 base::TimeDelta interval) = 0; |
138 // This overrides any past or future interval from updating vsync parameters. | 157 // This overrides any past or future interval from updating vsync parameters. |
139 virtual void SetAuthoritativeVSyncInterval(base::TimeDelta interval) = 0; | 158 virtual void SetAuthoritativeVSyncInterval(base::TimeDelta interval) = 0; |
140 }; | 159 }; |
141 | 160 |
142 // A frame source which calls BeginFrame (at the next possible time) as soon as | 161 // A frame source which calls BeginFrame (at the next possible time) as soon as |
143 // remaining frames reaches zero. | 162 // remaining frames reaches zero. |
144 class CC_EXPORT BackToBackBeginFrameSource : public SyntheticBeginFrameSource, | 163 class CC_EXPORT BackToBackBeginFrameSource : public SyntheticBeginFrameSource, |
145 public DelayBasedTimeSourceClient { | 164 public DelayBasedTimeSourceClient { |
146 public: | 165 public: |
147 explicit BackToBackBeginFrameSource( | 166 explicit BackToBackBeginFrameSource( |
148 std::unique_ptr<DelayBasedTimeSource> time_source); | 167 std::unique_ptr<DelayBasedTimeSource> time_source); |
149 ~BackToBackBeginFrameSource() override; | 168 ~BackToBackBeginFrameSource() override; |
150 | 169 |
151 // BeginFrameSource implementation. | 170 // BeginFrameSource implementation. |
152 void AddObserver(BeginFrameObserver* obs) override; | 171 void AddObserver(BeginFrameObserver* obs) override; |
153 void RemoveObserver(BeginFrameObserver* obs) override; | 172 void RemoveObserver(BeginFrameObserver* obs) override; |
154 void DidFinishFrame(BeginFrameObserver* obs, | 173 void DidFinishFrame(BeginFrameObserver* obs, |
155 size_t remaining_frames) override; | 174 const BeginFrameAck& ack) override; |
156 bool IsThrottled() const override; | 175 bool IsThrottled() const override; |
157 | 176 |
158 // SyntheticBeginFrameSource implementation. | 177 // SyntheticBeginFrameSource implementation. |
159 void OnUpdateVSyncParameters(base::TimeTicks timebase, | 178 void OnUpdateVSyncParameters(base::TimeTicks timebase, |
160 base::TimeDelta interval) override {} | 179 base::TimeDelta interval) override {} |
161 void SetAuthoritativeVSyncInterval(base::TimeDelta interval) override {} | 180 void SetAuthoritativeVSyncInterval(base::TimeDelta interval) override {} |
162 | 181 |
163 // DelayBasedTimeSourceClient implementation. | 182 // DelayBasedTimeSourceClient implementation. |
164 void OnTimerTick() override; | 183 void OnTimerTick() override; |
165 | 184 |
166 private: | 185 private: |
167 std::unique_ptr<DelayBasedTimeSource> time_source_; | 186 std::unique_ptr<DelayBasedTimeSource> time_source_; |
168 std::unordered_set<BeginFrameObserver*> observers_; | 187 std::unordered_set<BeginFrameObserver*> observers_; |
169 std::unordered_set<BeginFrameObserver*> pending_begin_frame_observers_; | 188 std::unordered_set<BeginFrameObserver*> pending_begin_frame_observers_; |
| 189 uint64_t next_sequence_number_; |
170 base::WeakPtrFactory<BackToBackBeginFrameSource> weak_factory_; | 190 base::WeakPtrFactory<BackToBackBeginFrameSource> weak_factory_; |
171 | 191 |
172 DISALLOW_COPY_AND_ASSIGN(BackToBackBeginFrameSource); | 192 DISALLOW_COPY_AND_ASSIGN(BackToBackBeginFrameSource); |
173 }; | 193 }; |
174 | 194 |
175 // A frame source which is locked to an external parameters provides from a | 195 // A frame source which is locked to an external parameters provides from a |
176 // vsync source and generates BeginFrameArgs for it. | 196 // vsync source and generates BeginFrameArgs for it. |
177 class CC_EXPORT DelayBasedBeginFrameSource : public SyntheticBeginFrameSource, | 197 class CC_EXPORT DelayBasedBeginFrameSource : public SyntheticBeginFrameSource, |
178 public DelayBasedTimeSourceClient { | 198 public DelayBasedTimeSourceClient { |
179 public: | 199 public: |
180 explicit DelayBasedBeginFrameSource( | 200 explicit DelayBasedBeginFrameSource( |
181 std::unique_ptr<DelayBasedTimeSource> time_source); | 201 std::unique_ptr<DelayBasedTimeSource> time_source); |
182 ~DelayBasedBeginFrameSource() override; | 202 ~DelayBasedBeginFrameSource() override; |
183 | 203 |
184 // BeginFrameSource implementation. | 204 // BeginFrameSource implementation. |
185 void AddObserver(BeginFrameObserver* obs) override; | 205 void AddObserver(BeginFrameObserver* obs) override; |
186 void RemoveObserver(BeginFrameObserver* obs) override; | 206 void RemoveObserver(BeginFrameObserver* obs) override; |
187 void DidFinishFrame(BeginFrameObserver* obs, | 207 void DidFinishFrame(BeginFrameObserver* obs, |
188 size_t remaining_frames) override {} | 208 const BeginFrameAck& ack) override {} |
189 bool IsThrottled() const override; | 209 bool IsThrottled() const override; |
190 | 210 |
191 // SyntheticBeginFrameSource implementation. | 211 // SyntheticBeginFrameSource implementation. |
192 void OnUpdateVSyncParameters(base::TimeTicks timebase, | 212 void OnUpdateVSyncParameters(base::TimeTicks timebase, |
193 base::TimeDelta interval) override; | 213 base::TimeDelta interval) override; |
194 void SetAuthoritativeVSyncInterval(base::TimeDelta interval) override; | 214 void SetAuthoritativeVSyncInterval(base::TimeDelta interval) override; |
195 | 215 |
196 // DelayBasedTimeSourceClient implementation. | 216 // DelayBasedTimeSourceClient implementation. |
197 void OnTimerTick() override; | 217 void OnTimerTick() override; |
198 | 218 |
199 private: | 219 private: |
200 BeginFrameArgs CreateBeginFrameArgs(base::TimeTicks frame_time, | 220 BeginFrameArgs CreateBeginFrameArgs(uint64_t sequence_number, |
| 221 base::TimeTicks frame_time, |
201 BeginFrameArgs::BeginFrameArgsType type); | 222 BeginFrameArgs::BeginFrameArgsType type); |
202 | 223 |
203 std::unique_ptr<DelayBasedTimeSource> time_source_; | 224 std::unique_ptr<DelayBasedTimeSource> time_source_; |
204 std::unordered_set<BeginFrameObserver*> observers_; | 225 std::unordered_set<BeginFrameObserver*> observers_; |
205 base::TimeTicks last_timebase_; | 226 base::TimeTicks last_timebase_; |
206 base::TimeDelta authoritative_interval_; | 227 base::TimeDelta authoritative_interval_; |
| 228 BeginFrameArgs current_begin_frame_args_; |
207 | 229 |
208 DISALLOW_COPY_AND_ASSIGN(DelayBasedBeginFrameSource); | 230 DISALLOW_COPY_AND_ASSIGN(DelayBasedBeginFrameSource); |
209 }; | 231 }; |
210 | 232 |
| 233 // Helper class that tracks outstanding acknowledgments from |
| 234 // BeginFrameObservers. |
| 235 class CC_EXPORT BeginFrameObserverAckTracker { |
| 236 public: |
| 237 BeginFrameObserverAckTracker(); |
| 238 virtual ~BeginFrameObserverAckTracker(); |
| 239 |
| 240 // The BeginFrameSource uses these methods to notify us when a BeginFrame was |
| 241 // started and sent to a specific observer, an observer finished a frame, or |
| 242 // an observer was added/removed. |
| 243 void OnBeginFrame(const BeginFrameArgs& args); |
| 244 void OnObserverBeginFrame(BeginFrameObserver* obs, |
| 245 const BeginFrameArgs& args); |
| 246 void OnObserverFinishedFrame(BeginFrameObserver* obs, |
| 247 const BeginFrameAck& ack); |
| 248 void OnObserverAdded(BeginFrameObserver* obs); |
| 249 void OnObserverRemoved(BeginFrameObserver* obs); |
| 250 |
| 251 // Returns |true| if all the source's observers completed the current frame. |
| 252 bool AllObserversFinishedFrame() const; |
| 253 |
| 254 // Returns |true| if any observer had damage during the current frame. |
| 255 bool AnyObserversHadDamage() const; |
| 256 |
| 257 // Returns the sequence number of the latest_confirmed_frame that any of |
| 258 // the observers have contributed for the latest frame. |
| 259 uint64_t LatestConfirmedFrame() const; |
| 260 |
| 261 private: |
| 262 void SourceChanged(const BeginFrameArgs& args); |
| 263 |
| 264 uint64_t current_source_id_; |
| 265 uint64_t current_sequence_number_; |
| 266 std::set<BeginFrameObserver*> observers_; |
| 267 std::set<BeginFrameObserver*> finished_observers_; |
| 268 bool observers_had_damage_; |
| 269 std::unordered_map<BeginFrameObserver*, uint64_t> latest_confirmed_frames_; |
| 270 }; |
| 271 |
211 class CC_EXPORT ExternalBeginFrameSourceClient { | 272 class CC_EXPORT ExternalBeginFrameSourceClient { |
212 public: | 273 public: |
213 // Only called when changed. Assumed false by default. | 274 // Only called when changed. Assumed false by default. |
214 virtual void OnNeedsBeginFrames(bool needs_begin_frames) = 0; | 275 virtual void OnNeedsBeginFrames(bool needs_begin_frames) = 0; |
| 276 // Called when all observers have completed a frame. |
| 277 virtual void OnDidFinishFrame(const BeginFrameAck& ack) = 0; |
215 }; | 278 }; |
216 | 279 |
217 // A BeginFrameSource that is only ticked manually. Usually the endpoint | 280 // A BeginFrameSource that is only ticked manually. Usually the endpoint |
218 // of messages from some other thread/process that send OnBeginFrame and | 281 // of messages from some other thread/process that send OnBeginFrame and |
219 // receive SetNeedsBeginFrame messages. This turns such messages back into | 282 // receive SetNeedsBeginFrame messages. This turns such messages back into |
220 // an observable BeginFrameSource. | 283 // an observable BeginFrameSource. |
221 class CC_EXPORT ExternalBeginFrameSource : public BeginFrameSource { | 284 class CC_EXPORT ExternalBeginFrameSource : public BeginFrameSource { |
222 public: | 285 public: |
223 // Client lifetime must be preserved by owner past the lifetime of this class. | 286 // Client lifetime must be preserved by owner past the lifetime of this class. |
224 explicit ExternalBeginFrameSource(ExternalBeginFrameSourceClient* client); | 287 explicit ExternalBeginFrameSource(ExternalBeginFrameSourceClient* client); |
225 ~ExternalBeginFrameSource() override; | 288 ~ExternalBeginFrameSource() override; |
226 | 289 |
227 // BeginFrameSource implementation. | 290 // BeginFrameSource implementation. |
228 void AddObserver(BeginFrameObserver* obs) override; | 291 void AddObserver(BeginFrameObserver* obs) override; |
229 void RemoveObserver(BeginFrameObserver* obs) override; | 292 void RemoveObserver(BeginFrameObserver* obs) override; |
230 void DidFinishFrame(BeginFrameObserver* obs, | 293 void DidFinishFrame(BeginFrameObserver* obs, |
231 size_t remaining_frames) override {} | 294 const BeginFrameAck& ack) override; |
232 bool IsThrottled() const override; | 295 bool IsThrottled() const override; |
233 | 296 |
234 void OnSetBeginFrameSourcePaused(bool paused); | 297 void OnSetBeginFrameSourcePaused(bool paused); |
235 void OnBeginFrame(const BeginFrameArgs& args); | 298 void OnBeginFrame(const BeginFrameArgs& args); |
236 | 299 |
237 protected: | 300 protected: |
| 301 void MaybeFinishFrame(); |
| 302 void FinishFrame(); |
| 303 |
238 BeginFrameArgs missed_begin_frame_args_; | 304 BeginFrameArgs missed_begin_frame_args_; |
239 std::unordered_set<BeginFrameObserver*> observers_; | 305 std::unordered_set<BeginFrameObserver*> observers_; |
240 ExternalBeginFrameSourceClient* client_; | 306 ExternalBeginFrameSourceClient* client_; |
241 bool paused_ = false; | 307 bool paused_ = false; |
| 308 bool frame_active_ = false; |
| 309 BeginFrameObserverAckTracker ack_tracker_; |
242 | 310 |
243 private: | 311 private: |
244 DISALLOW_COPY_AND_ASSIGN(ExternalBeginFrameSource); | 312 DISALLOW_COPY_AND_ASSIGN(ExternalBeginFrameSource); |
245 }; | 313 }; |
246 | 314 |
| 315 // A BeginFrameSource that delegates to another given source. |
| 316 class CC_EXPORT DelegatingBeginFrameSource : public BeginFrameSource { |
| 317 public: |
| 318 // |delegate| lifetime must be preserved past the lifetime of this class. |
| 319 explicit DelegatingBeginFrameSource(BeginFrameSource* delegate); |
| 320 ~DelegatingBeginFrameSource() override {} |
| 321 |
| 322 // BeginFrameSource implementation. |
| 323 void DidFinishFrame(BeginFrameObserver* obs, |
| 324 const BeginFrameAck& ack) override; |
| 325 void AddObserver(BeginFrameObserver* obs) override; |
| 326 void RemoveObserver(BeginFrameObserver* obs) override; |
| 327 bool IsThrottled() const override; |
| 328 |
| 329 private: |
| 330 BeginFrameSource* delegate_; // Not owned. |
| 331 }; |
| 332 |
247 } // namespace cc | 333 } // namespace cc |
248 | 334 |
249 #endif // CC_SCHEDULER_BEGIN_FRAME_SOURCE_H_ | 335 #endif // CC_SCHEDULER_BEGIN_FRAME_SOURCE_H_ |
OLD | NEW |