Chromium Code Reviews| 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. | |
| 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, |
|
Sami
2016/12/07 16:59:40
Idle thought: should we have some debug safeguard
Eric Seckler
2016/12/08 17:54:28
Good question. Not sure if a check is easily enfor
| |
| 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, and very likely unique across processes. | |
| 132 virtual uint64_t source_id() const; | |
| 133 | |
| 134 private: | |
| 135 uint64_t source_id_; | |
| 119 }; | 136 }; |
| 120 | 137 |
| 121 // A BeginFrameSource that does nothing. | 138 // A BeginFrameSource that does nothing. |
| 122 class CC_EXPORT StubBeginFrameSource : public BeginFrameSource { | 139 class CC_EXPORT StubBeginFrameSource : public BeginFrameSource { |
| 123 public: | 140 public: |
| 124 void DidFinishFrame(BeginFrameObserver* obs, | 141 void DidFinishFrame(BeginFrameObserver* obs, |
| 125 size_t remaining_frames) override {} | 142 const BeginFrameAck& ack) override {} |
| 126 void AddObserver(BeginFrameObserver* obs) override {} | 143 void AddObserver(BeginFrameObserver* obs) override {} |
| 127 void RemoveObserver(BeginFrameObserver* obs) override {} | 144 void RemoveObserver(BeginFrameObserver* obs) override {} |
| 128 bool IsThrottled() const override; | 145 bool IsThrottled() const override; |
| 129 }; | 146 }; |
| 130 | 147 |
| 131 // A frame source which ticks itself independently. | 148 // A frame source which ticks itself independently. |
| 132 class CC_EXPORT SyntheticBeginFrameSource : public BeginFrameSource { | 149 class CC_EXPORT SyntheticBeginFrameSource : public BeginFrameSource { |
| 133 public: | 150 public: |
| 134 ~SyntheticBeginFrameSource() override; | 151 ~SyntheticBeginFrameSource() override; |
| 135 | 152 |
| 136 virtual void OnUpdateVSyncParameters(base::TimeTicks timebase, | 153 virtual void OnUpdateVSyncParameters(base::TimeTicks timebase, |
| 137 base::TimeDelta interval) = 0; | 154 base::TimeDelta interval) = 0; |
| 138 // This overrides any past or future interval from updating vsync parameters. | 155 // This overrides any past or future interval from updating vsync parameters. |
| 139 virtual void SetAuthoritativeVSyncInterval(base::TimeDelta interval) = 0; | 156 virtual void SetAuthoritativeVSyncInterval(base::TimeDelta interval) = 0; |
| 140 }; | 157 }; |
| 141 | 158 |
| 142 // A frame source which calls BeginFrame (at the next possible time) as soon as | 159 // A frame source which calls BeginFrame (at the next possible time) as soon as |
| 143 // remaining frames reaches zero. | 160 // remaining frames reaches zero. |
| 144 class CC_EXPORT BackToBackBeginFrameSource : public SyntheticBeginFrameSource, | 161 class CC_EXPORT BackToBackBeginFrameSource : public SyntheticBeginFrameSource, |
| 145 public DelayBasedTimeSourceClient { | 162 public DelayBasedTimeSourceClient { |
| 146 public: | 163 public: |
| 147 explicit BackToBackBeginFrameSource( | 164 explicit BackToBackBeginFrameSource( |
| 148 std::unique_ptr<DelayBasedTimeSource> time_source); | 165 std::unique_ptr<DelayBasedTimeSource> time_source); |
| 149 ~BackToBackBeginFrameSource() override; | 166 ~BackToBackBeginFrameSource() override; |
| 150 | 167 |
| 151 // BeginFrameSource implementation. | 168 // BeginFrameSource implementation. |
| 152 void AddObserver(BeginFrameObserver* obs) override; | 169 void AddObserver(BeginFrameObserver* obs) override; |
| 153 void RemoveObserver(BeginFrameObserver* obs) override; | 170 void RemoveObserver(BeginFrameObserver* obs) override; |
| 154 void DidFinishFrame(BeginFrameObserver* obs, | 171 void DidFinishFrame(BeginFrameObserver* obs, |
| 155 size_t remaining_frames) override; | 172 const BeginFrameAck& ack) override; |
| 156 bool IsThrottled() const override; | 173 bool IsThrottled() const override; |
| 157 | 174 |
| 158 // SyntheticBeginFrameSource implementation. | 175 // SyntheticBeginFrameSource implementation. |
| 159 void OnUpdateVSyncParameters(base::TimeTicks timebase, | 176 void OnUpdateVSyncParameters(base::TimeTicks timebase, |
| 160 base::TimeDelta interval) override {} | 177 base::TimeDelta interval) override {} |
| 161 void SetAuthoritativeVSyncInterval(base::TimeDelta interval) override {} | 178 void SetAuthoritativeVSyncInterval(base::TimeDelta interval) override {} |
| 162 | 179 |
| 163 // DelayBasedTimeSourceClient implementation. | 180 // DelayBasedTimeSourceClient implementation. |
| 164 void OnTimerTick() override; | 181 void OnTimerTick() override; |
| 165 | 182 |
| 166 private: | 183 private: |
| 167 std::unique_ptr<DelayBasedTimeSource> time_source_; | 184 std::unique_ptr<DelayBasedTimeSource> time_source_; |
| 168 std::unordered_set<BeginFrameObserver*> observers_; | 185 std::unordered_set<BeginFrameObserver*> observers_; |
| 169 std::unordered_set<BeginFrameObserver*> pending_begin_frame_observers_; | 186 std::unordered_set<BeginFrameObserver*> pending_begin_frame_observers_; |
| 187 uint64_t next_sequence_number_; | |
| 170 base::WeakPtrFactory<BackToBackBeginFrameSource> weak_factory_; | 188 base::WeakPtrFactory<BackToBackBeginFrameSource> weak_factory_; |
| 171 | 189 |
| 172 DISALLOW_COPY_AND_ASSIGN(BackToBackBeginFrameSource); | 190 DISALLOW_COPY_AND_ASSIGN(BackToBackBeginFrameSource); |
| 173 }; | 191 }; |
| 174 | 192 |
| 175 // A frame source which is locked to an external parameters provides from a | 193 // A frame source which is locked to an external parameters provides from a |
| 176 // vsync source and generates BeginFrameArgs for it. | 194 // vsync source and generates BeginFrameArgs for it. |
| 177 class CC_EXPORT DelayBasedBeginFrameSource : public SyntheticBeginFrameSource, | 195 class CC_EXPORT DelayBasedBeginFrameSource : public SyntheticBeginFrameSource, |
| 178 public DelayBasedTimeSourceClient { | 196 public DelayBasedTimeSourceClient { |
| 179 public: | 197 public: |
| 180 explicit DelayBasedBeginFrameSource( | 198 explicit DelayBasedBeginFrameSource( |
| 181 std::unique_ptr<DelayBasedTimeSource> time_source); | 199 std::unique_ptr<DelayBasedTimeSource> time_source); |
| 182 ~DelayBasedBeginFrameSource() override; | 200 ~DelayBasedBeginFrameSource() override; |
| 183 | 201 |
| 184 // BeginFrameSource implementation. | 202 // BeginFrameSource implementation. |
| 185 void AddObserver(BeginFrameObserver* obs) override; | 203 void AddObserver(BeginFrameObserver* obs) override; |
| 186 void RemoveObserver(BeginFrameObserver* obs) override; | 204 void RemoveObserver(BeginFrameObserver* obs) override; |
| 187 void DidFinishFrame(BeginFrameObserver* obs, | 205 void DidFinishFrame(BeginFrameObserver* obs, |
| 188 size_t remaining_frames) override {} | 206 const BeginFrameAck& ack) override {} |
| 189 bool IsThrottled() const override; | 207 bool IsThrottled() const override; |
| 190 | 208 |
| 191 // SyntheticBeginFrameSource implementation. | 209 // SyntheticBeginFrameSource implementation. |
| 192 void OnUpdateVSyncParameters(base::TimeTicks timebase, | 210 void OnUpdateVSyncParameters(base::TimeTicks timebase, |
| 193 base::TimeDelta interval) override; | 211 base::TimeDelta interval) override; |
| 194 void SetAuthoritativeVSyncInterval(base::TimeDelta interval) override; | 212 void SetAuthoritativeVSyncInterval(base::TimeDelta interval) override; |
| 195 | 213 |
| 196 // DelayBasedTimeSourceClient implementation. | 214 // DelayBasedTimeSourceClient implementation. |
| 197 void OnTimerTick() override; | 215 void OnTimerTick() override; |
| 198 | 216 |
| 199 private: | 217 private: |
| 200 BeginFrameArgs CreateBeginFrameArgs(base::TimeTicks frame_time, | 218 BeginFrameArgs CreateBeginFrameArgs(uint64_t sequence_number, |
| 219 base::TimeTicks frame_time, | |
| 201 BeginFrameArgs::BeginFrameArgsType type); | 220 BeginFrameArgs::BeginFrameArgsType type); |
| 202 | 221 |
| 203 std::unique_ptr<DelayBasedTimeSource> time_source_; | 222 std::unique_ptr<DelayBasedTimeSource> time_source_; |
| 204 std::unordered_set<BeginFrameObserver*> observers_; | 223 std::unordered_set<BeginFrameObserver*> observers_; |
| 205 base::TimeTicks last_timebase_; | 224 base::TimeTicks last_timebase_; |
| 206 base::TimeDelta authoritative_interval_; | 225 base::TimeDelta authoritative_interval_; |
| 226 uint64_t current_sequence_number_; | |
| 227 base::TimeTicks current_begin_frame_time_; | |
| 207 | 228 |
| 208 DISALLOW_COPY_AND_ASSIGN(DelayBasedBeginFrameSource); | 229 DISALLOW_COPY_AND_ASSIGN(DelayBasedBeginFrameSource); |
| 209 }; | 230 }; |
| 210 | 231 |
| 232 // Helper class that tracks outstanding acknowledgments from | |
| 233 // BeginFrameObservers. | |
| 234 class CC_EXPORT BeginFrameObserverAckTracker { | |
| 235 public: | |
| 236 BeginFrameObserverAckTracker(); | |
| 237 virtual ~BeginFrameObserverAckTracker(); | |
| 238 | |
| 239 // The BeginFrameSource uses these methods to notify us when a BeginFrame was | |
| 240 // started and sent to a specific observer, an observer finished a frame, or | |
| 241 // an observer was added/removed. | |
| 242 void OnBeginFrame(const BeginFrameArgs& args); | |
| 243 void OnObserverBeginFrame(BeginFrameObserver* obs, | |
| 244 const BeginFrameArgs& args); | |
| 245 void OnObserverFinishedFrame(BeginFrameObserver* obs, | |
| 246 const BeginFrameAck& ack); | |
| 247 void OnObserverAdded(BeginFrameObserver* obs); | |
| 248 void OnObserverRemoved(BeginFrameObserver* obs); | |
| 249 | |
| 250 // Returns |true| if all the source's observers completed the current frame. | |
| 251 bool AllObserversFinishedFrame() const; | |
| 252 | |
| 253 // Returns |true| if any observer had updates during the current frame. | |
| 254 bool AnyObserversHadUpdates() const; | |
| 255 | |
| 256 // Returns the sequence number of the oldest_incorporated_frame that any of | |
| 257 // the observers have contributed for the latest frame. | |
| 258 uint64_t OldestIncorporatedFrame() const; | |
| 259 | |
| 260 private: | |
| 261 void SourceChanged(const BeginFrameArgs& args); | |
| 262 | |
| 263 uint64_t current_source_id_; | |
| 264 uint64_t current_sequence_number_; | |
| 265 std::set<BeginFrameObserver*> observers_; | |
| 266 std::set<BeginFrameObserver*> finished_observers_; | |
| 267 bool observers_had_updates_; | |
| 268 std::unordered_map<BeginFrameObserver*, uint64_t> oldest_incorporated_frames_; | |
| 269 }; | |
| 270 | |
| 211 class CC_EXPORT ExternalBeginFrameSourceClient { | 271 class CC_EXPORT ExternalBeginFrameSourceClient { |
| 212 public: | 272 public: |
| 213 // Only called when changed. Assumed false by default. | 273 // Only called when changed. Assumed false by default. |
| 214 virtual void OnNeedsBeginFrames(bool needs_begin_frames) = 0; | 274 virtual void OnNeedsBeginFrames(bool needs_begin_frames) = 0; |
| 275 // Called when all observers have completed a frame. | |
| 276 virtual void OnDidFinishFrame(const BeginFrameAck& ack) = 0; | |
| 215 }; | 277 }; |
| 216 | 278 |
| 217 // A BeginFrameSource that is only ticked manually. Usually the endpoint | 279 // A BeginFrameSource that is only ticked manually. Usually the endpoint |
| 218 // of messages from some other thread/process that send OnBeginFrame and | 280 // of messages from some other thread/process that send OnBeginFrame and |
| 219 // receive SetNeedsBeginFrame messages. This turns such messages back into | 281 // receive SetNeedsBeginFrame messages. This turns such messages back into |
| 220 // an observable BeginFrameSource. | 282 // an observable BeginFrameSource. |
| 221 class CC_EXPORT ExternalBeginFrameSource : public BeginFrameSource { | 283 class CC_EXPORT ExternalBeginFrameSource : public BeginFrameSource { |
| 222 public: | 284 public: |
| 223 // Client lifetime must be preserved by owner past the lifetime of this class. | 285 // Client lifetime must be preserved by owner past the lifetime of this class. |
| 224 explicit ExternalBeginFrameSource(ExternalBeginFrameSourceClient* client); | 286 explicit ExternalBeginFrameSource(ExternalBeginFrameSourceClient* client); |
| 225 ~ExternalBeginFrameSource() override; | 287 ~ExternalBeginFrameSource() override; |
| 226 | 288 |
| 227 // BeginFrameSource implementation. | 289 // BeginFrameSource implementation. |
| 228 void AddObserver(BeginFrameObserver* obs) override; | 290 void AddObserver(BeginFrameObserver* obs) override; |
| 229 void RemoveObserver(BeginFrameObserver* obs) override; | 291 void RemoveObserver(BeginFrameObserver* obs) override; |
| 230 void DidFinishFrame(BeginFrameObserver* obs, | 292 void DidFinishFrame(BeginFrameObserver* obs, |
| 231 size_t remaining_frames) override {} | 293 const BeginFrameAck& ack) override; |
| 232 bool IsThrottled() const override; | 294 bool IsThrottled() const override; |
| 233 | 295 |
| 234 void OnSetBeginFrameSourcePaused(bool paused); | 296 void OnSetBeginFrameSourcePaused(bool paused); |
| 235 void OnBeginFrame(const BeginFrameArgs& args); | 297 void OnBeginFrame(const BeginFrameArgs& args); |
| 236 | 298 |
| 237 protected: | 299 protected: |
| 300 void MaybeFinishFrame(); | |
| 301 void FinishFrame(); | |
| 302 | |
| 238 BeginFrameArgs missed_begin_frame_args_; | 303 BeginFrameArgs missed_begin_frame_args_; |
| 239 std::unordered_set<BeginFrameObserver*> observers_; | 304 std::unordered_set<BeginFrameObserver*> observers_; |
| 240 ExternalBeginFrameSourceClient* client_; | 305 ExternalBeginFrameSourceClient* client_; |
| 241 bool paused_ = false; | 306 bool paused_ = false; |
| 307 bool frame_active_ = false; | |
| 308 BeginFrameObserverAckTracker ack_tracker_; | |
| 242 | 309 |
| 243 private: | 310 private: |
| 244 DISALLOW_COPY_AND_ASSIGN(ExternalBeginFrameSource); | 311 DISALLOW_COPY_AND_ASSIGN(ExternalBeginFrameSource); |
| 245 }; | 312 }; |
| 246 | 313 |
| 314 // A BeginFrameSource that delegates to another given source. | |
| 315 class CC_EXPORT DelegatingBeginFrameSource : public BeginFrameSource { | |
| 316 public: | |
| 317 // |delegate| lifetime must be preserved past the lifetime of this class. | |
| 318 explicit DelegatingBeginFrameSource(BeginFrameSource* delegate); | |
| 319 ~DelegatingBeginFrameSource() override {} | |
| 320 | |
| 321 // BeginFrameSource implementation. | |
| 322 void DidFinishFrame(BeginFrameObserver* obs, | |
| 323 const BeginFrameAck& ack) override; | |
| 324 void AddObserver(BeginFrameObserver* obs) override; | |
| 325 void RemoveObserver(BeginFrameObserver* obs) override; | |
| 326 bool IsThrottled() const override; | |
| 327 uint64_t source_id() 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 |