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

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

Issue 267783004: Refactoring the way begin frame sources inside scheduler work. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixing for review comments. Created 6 years, 2 months 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 | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #ifndef CC_SCHEDULER_BEGIN_FRAME_SOURCE_H_
6 #define CC_SCHEDULER_BEGIN_FRAME_SOURCE_H_
7
8 #include <set>
9 #include <string>
10
11 #include "base/debug/trace_event.h"
12 #include "base/logging.h"
13 #include "cc/output/begin_frame_args.h"
14 #include "cc/output/vsync_parameter_observer.h"
15 #include "cc/scheduler/delay_based_time_source.h"
16
17 namespace cc {
18
19 // (Pure) Interface for observing BeginFrame messages from BeginFrameSource
20 // objects.
21 class CC_EXPORT BeginFrameObserver {
22 public:
23 // Used to indicate what happened to the |args| value given to OnBeginFrame.
24 enum BeginFrameArgsStatus {
25 // The |args| value was discarded and not used. Hence
26 // LastUsedBeginFrameArgs will not have changed.
27 DROPPED,
28 // The |args| value was queued to be processed later.
29 // LastUsedBeginFrameArgs will have been updated to match |args|.
30 USED,
31 };
32
33 // The |args| given to OnBeginFrame is guaranteed to have
34 // |args|.IsValid()==true and have |args|.frame_time
35 // field be strictly greater than the previous call.
36 //
37 // Side effects: This function can (and most of the time *will*) change the
38 // return value of the LastUsedBeginFrameArgs method. See the documentation
39 // on that method for more information.
40 virtual BeginFrameArgsStatus OnBeginFrame(const BeginFrameArgs& args) = 0;
41
42 // Some frame sources *may* provide the last missed begin frame when
43 // SetNeedsBeginFrames is set true (such as the SyntheticBeginFrameSource).
44 //
45 // **Don't** depend on this function ever being called.
46 virtual BeginFrameArgsStatus OnMissedBeginFrame(
47 const BeginFrameArgs& args) = 0;
48
49 // Returns the last BeginFrameArgs used by the observer. This method's return
50 // value is affected by the OnBeginFrame method!
51 //
52 // - Before the first call of OnBeginFrame, this method should return a
53 // BeginFrameArgs on which IsValid() returns false.
54 //
55 // - If the |args| passed to OnBeginFrame is (or *will be*)
56 // used, then OnBeginFrame will return USED this method's return value
57 // should become the |args| given to OnBeginFrame.
58 //
59 // - If the |args| passed to OnBeginFrame is dropped, then OnBeginFrame will
60 // return DROPPED and this method's return value should *not* change.
61 //
62 // These requirements are designed to allow chaining and nesting of
63 // BeginFrameObservers which filter the incoming BeginFrame messages while
64 // preventing "double dropping" and other bad side effects.
65 virtual const BeginFrameArgs LastUsedBeginFrameArgs() const = 0;
brianderson 2014/09/24 06:03:05 const BeginFrameArgs&
mithro-old 2014/09/24 17:14:55 Can't be a reference until C++11 as we need to be
66
67 // Tracing support
68 virtual void AsValueInto(base::debug::TracedValue* dict) const = 0;
69 };
70
71 // Simple mix in which implements a BeginFrameObserver which checks the
72 // incoming values meet the BeginFrameObserver requirements and implements the
73 // required LastUsedBeginFrameArgs behaviour.
74 //
75 // Users of this mix in should;
76 // - Implement the ProcessBeginFrameArgs function.
77 // - Recommended (but not required) to call
78 // BeginFrameObserverMixIn::OnValueInto in their overridden OnValueInto
79 // function.
80 //
81 // Advance observers may also wish to override the OnMissedBeginFrame method.
82 class CC_EXPORT BeginFrameObserverMixIn : public BeginFrameObserver {
83 public:
84 // BeginFrameObserver
85 BeginFrameObserverMixIn();
86
87 // Traces |args| and DCHECK |args| satisfies pre-conditions then calls
88 // ProcessBeginFrameArgs and updates the last_begin_frame_args_ value on true.
89 virtual BeginFrameObserver::BeginFrameArgsStatus OnBeginFrame(
90 const BeginFrameArgs& args) OVERRIDE;
91
92 // Forwards call to the OnBeginFrame callback.
93 virtual BeginFrameObserver::BeginFrameArgsStatus OnMissedBeginFrame(
94 const BeginFrameArgs& args) OVERRIDE;
95
96 virtual const BeginFrameArgs LastUsedBeginFrameArgs() const OVERRIDE;
97
98 // Outputs last_begin_frame_args_
99 virtual void AsValueInto(base::debug::TracedValue* dict) const OVERRIDE;
100
101 protected:
102 // Subclasses should override this method!
103 // Return true if the given argument is (or will be) used.
104 virtual BeginFrameObserver::BeginFrameArgsStatus ProcessBeginFrameArgs(
105 const BeginFrameArgs& args) = 0;
106
107 BeginFrameArgs last_begin_frame_args_;
108 int64_t dropped_begin_frame_args_;
109 };
110
111 // Interface for a class which produces BeginFrame calls to a
112 // BeginFrameObserver.
113 //
114 // BeginFrame calls *normally* occur just after a vsync interrupt when input
115 // processing has been finished and provide information about the time values
116 // of the vsync times. *However*, these values can be heavily modified or even
117 // plain made up (when no vsync signal is available or vsync throttling is
118 // turned off). See the BeginFrameObserver for information about the guarantees
119 // all BeginFrameSources *must* provide.
120 //
121 // Implementation classes should:
122 // - Use the CallOn(Missed)BeginFrame method to call to the observer(s).
123 // - Implement the pure virtual methods.
124 // - Recommend (but not required) to call BeginFrameSource::AsValueInto in
125 // their own AsValueInto implementation.
126 class CC_EXPORT BeginFrameSource {
127 public:
128 virtual ~BeginFrameSource() {}
129
130 // SetNeedsBeginFrames is the on/off "switch" for the BeginFrameSource. When
131 // set to false no more BeginFrame messages should be sent to observer.
132 virtual bool NeedsBeginFrames() const = 0;
133 virtual void SetNeedsBeginFrames(bool needs_begin_frames) = 0;
134
135 // DidFinishFrame provides back pressure to a frame source about frame
136 // processing (rather than toggling SetNeedsBeginFrames every frame). It is
137 // used by systems like the BackToBackFrameSource to make sure only one frame
138 // is pending at a time.
139 virtual void DidFinishFrame(size_t remaining_frames) = 0;
140
141 // Add/Remove and observer from the source.
142 // *At the moment* only a single observer can be added to the source, however
143 // in the future this may be extended to allow multiple observers.
144 // If making this change, please use base::ObserverList to do so.
145 void AddObserver(BeginFrameObserver* obs);
146 void RemoveObserver(BeginFrameObserver* obs);
147
148 // Tracing support - Recommend (but not required) to call this implementation
149 // in any override.
150 virtual void AsValueInto(base::debug::TracedValue* dict) const;
151
152 protected:
153 BeginFrameSource();
154
155 // These methods should be used by subclasses to make the call to the
156 // observers.
157 BeginFrameObserver::BeginFrameArgsStatus CallOnBeginFrame(
158 const BeginFrameArgs& args);
159 BeginFrameObserver::BeginFrameArgsStatus CallOnMissedBeginFrame(
160 const BeginFrameArgs& args);
161
162 BeginFrameObserver* observer_;
163
164 private:
165 bool inside_as_value_into_;
166 };
167
168 // A frame source which calls BeginFrame (at the next possible time) as soon as
169 // remaining frames reaches zero.
170 class CC_EXPORT BackToBackBeginFrameSource : public BeginFrameSource {
171 public:
172 static scoped_ptr<BackToBackBeginFrameSource> Create(
173 base::SingleThreadTaskRunner* task_runner);
174 virtual ~BackToBackBeginFrameSource();
175
176 // BeginFrameSource
177 virtual bool NeedsBeginFrames() const OVERRIDE;
178 virtual void SetNeedsBeginFrames(bool needs_begin_frames) OVERRIDE;
179 virtual void DidFinishFrame(size_t remaining_frames) OVERRIDE;
180
181 // Tracing
182 virtual void AsValueInto(base::debug::TracedValue* dict) const OVERRIDE;
183
184 protected:
185 explicit BackToBackBeginFrameSource(
186 base::SingleThreadTaskRunner* task_runner);
187 virtual base::TimeTicks Now(); // Now overridable for testing
188
189 base::WeakPtrFactory<BackToBackBeginFrameSource> weak_factory_;
190 base::SingleThreadTaskRunner* task_runner_;
191
192 bool needs_begin_frames_;
193 bool send_begin_frame_posted_;
194
195 void ScheduleBeginFrame();
196 void BeginFrame();
197 };
198
199 // A frame source which is locked to an external parameters provides from a
200 // vsync source and generates BeginFrameArgs for it.
201 class CC_EXPORT SyntheticBeginFrameSource : public BeginFrameSource,
202 public VSyncParameterObserver,
203 public TimeSourceClient {
204 public:
205 static scoped_ptr<SyntheticBeginFrameSource> Create(
206 base::SingleThreadTaskRunner* task_runner,
207 base::TimeTicks initial_vsync_timebase,
208 base::TimeDelta initial_vsync_interval);
209 virtual ~SyntheticBeginFrameSource();
210
211 // BeginFrameSource
212 virtual bool NeedsBeginFrames() const OVERRIDE;
213 virtual void SetNeedsBeginFrames(bool needs_begin_frames) OVERRIDE;
214 virtual void DidFinishFrame(size_t remaining_frames) OVERRIDE{};
215
216 // Tracing
217 virtual void AsValueInto(base::debug::TracedValue* dict) const OVERRIDE;
218
219 // VSyncParameterObserver
220 virtual void OnUpdateVSyncParameters(
221 base::TimeTicks new_vsync_timebase,
222 base::TimeDelta new_vsync_interval) OVERRIDE;
223
224 // TimeSourceClient
225 virtual void OnTimerTick() OVERRIDE;
226
227 protected:
228 explicit SyntheticBeginFrameSource(
229 scoped_refptr<DelayBasedTimeSource> time_source);
230
231 void SendBeginFrameFromTick(base::TimeTicks frame_time);
232
233 scoped_refptr<DelayBasedTimeSource> time_source_;
234 };
235
236 // A "virtual" frame source which lets you switch between multiple other frame
237 // sources while making sure the BeginFrameArgs stays increasing (possibly
238 // enforcing minimum boundry between BeginFrameArgs messages).
239 class CC_EXPORT BeginFrameSourceMultiplexer : public BeginFrameSource,
240 public BeginFrameObserver {
241 public:
242 static scoped_ptr<BeginFrameSourceMultiplexer> Create();
243 virtual ~BeginFrameSourceMultiplexer();
244
245 void SetMinimumInterval(base::TimeDelta new_minimum_interval);
246
247 void AddSource(BeginFrameSource* new_source);
248 void RemoveSource(BeginFrameSource* existing_source);
249 void SetActiveSource(BeginFrameSource* new_source);
250 const BeginFrameSource* ActiveSource();
251
252 // BeginFrameObserver
253 // The mux is an BeginFrameObserver as it needs to proxy the OnBeginFrame
254 // calls to preserve the monotonicity of the BeginFrameArgs when switching
255 // sources.
256 virtual BeginFrameObserver::BeginFrameArgsStatus OnBeginFrame(
257 const BeginFrameArgs& args) OVERRIDE;
258 virtual BeginFrameObserver::BeginFrameArgsStatus OnMissedBeginFrame(
259 const BeginFrameArgs& args) OVERRIDE;
260 virtual const BeginFrameArgs LastUsedBeginFrameArgs() const OVERRIDE;
261
262 // BeginFrameSource
263 virtual bool NeedsBeginFrames() const OVERRIDE;
264 virtual void SetNeedsBeginFrames(bool needs_begin_frames) OVERRIDE;
265 virtual void DidFinishFrame(size_t remaining_frames) OVERRIDE;
266
267 // Tracing
268 virtual void AsValueInto(base::debug::TracedValue* dict) const OVERRIDE;
269
270 protected:
271 BeginFrameSourceMultiplexer();
272 explicit BeginFrameSourceMultiplexer(base::TimeDelta minimum_interval);
273
274 bool HasSource(BeginFrameSource* source);
275 bool IsIncreasing(const BeginFrameArgs& args);
276
277 base::TimeDelta minimum_interval_;
278
279 BeginFrameSource* active_source_;
280 std::set<BeginFrameSource*> source_list_;
281 };
282
283 } // namespace cc
284
285 #endif // CC_SCHEDULER_BEGIN_FRAME_SOURCE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698