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

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

Issue 2527283003: cc: Introduce BeginFrame sequence numbers and acknowledgements.
Patch Set: Address Sami's comments, DisplayScheduler observes while BFSObservers exist. Created 4 years 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
OLDNEW
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698