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.
5 #ifndef CC_SCHEDULER_BEGIN_FRAME_SOURCE_H_
6 #define CC_SCHEDULER_BEGIN_FRAME_SOURCE_H_
11 #include "base/logging.h"
12 #include "base/trace_event/trace_event.h"
13 #include "cc/output/begin_frame_args.h"
14 #include "cc/scheduler/delay_based_time_source.h"
18 // (Pure) Interface for observing BeginFrame messages from BeginFrameSource
20 class CC_EXPORT BeginFrameObserver
{
22 virtual ~BeginFrameObserver() {}
24 // The |args| given to OnBeginFrame is guaranteed to have
25 // |args|.IsValid()==true and have |args|.frame_time
26 // field be strictly greater than the previous call.
28 // Side effects: This function can (and most of the time *will*) change the
29 // return value of the LastUsedBeginFrameArgs method. See the documentation
30 // on that method for more information.
31 virtual void OnBeginFrame(const BeginFrameArgs
& args
) = 0;
33 // Returns the last BeginFrameArgs used by the observer. This method's return
34 // value is affected by the OnBeginFrame method!
36 // - Before the first call of OnBeginFrame, this method should return a
37 // BeginFrameArgs on which IsValid() returns false.
39 // - If the |args| passed to OnBeginFrame is (or *will be*) used, then
40 // LastUsedBeginFrameArgs return value should become the |args| given to
43 // - If the |args| passed to OnBeginFrame is dropped, then
44 // LastUsedBeginFrameArgs return value should *not* change.
46 // These requirements are designed to allow chaining and nesting of
47 // BeginFrameObservers which filter the incoming BeginFrame messages while
48 // preventing "double dropping" and other bad side effects.
49 virtual const BeginFrameArgs
LastUsedBeginFrameArgs() const = 0;
52 virtual void AsValueInto(base::trace_event::TracedValue
* dict
) const = 0;
55 // Simple base class which implements a BeginFrameObserver which checks the
56 // incoming values meet the BeginFrameObserver requirements and implements the
57 // required LastUsedBeginFrameArgs behaviour.
59 // Users of this class should;
60 // - Implement the OnBeginFrameDerivedImpl function.
61 // - Recommended (but not required) to call
62 // BeginFrameObserverBase::OnValueInto in their overridden OnValueInto
64 class CC_EXPORT BeginFrameObserverBase
: public BeginFrameObserver
{
66 BeginFrameObserverBase();
70 // Traces |args| and DCHECK |args| satisfies pre-conditions then calls
71 // OnBeginFrameDerivedImpl and updates the last_begin_frame_args_ value on
73 void OnBeginFrame(const BeginFrameArgs
& args
) override
;
74 const BeginFrameArgs
LastUsedBeginFrameArgs() const override
;
76 // Outputs last_begin_frame_args_
77 void AsValueInto(base::trace_event::TracedValue
* dict
) const override
;
80 // Subclasses should override this method!
81 // Return true if the given argument is (or will be) used.
82 virtual bool OnBeginFrameDerivedImpl(const BeginFrameArgs
& args
) = 0;
84 BeginFrameArgs last_begin_frame_args_
;
85 int64_t dropped_begin_frame_args_
;
88 DISALLOW_COPY_AND_ASSIGN(BeginFrameObserverBase
);
91 // Interface for a class which produces BeginFrame calls to a
92 // BeginFrameObserver.
94 // BeginFrame calls *normally* occur just after a vsync interrupt when input
95 // 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
97 // plain made up (when no vsync signal is available or vsync throttling is
98 // turned off). See the BeginFrameObserver for information about the guarantees
99 // all BeginFrameSources *must* provide.
100 class CC_EXPORT BeginFrameSource
{
102 virtual ~BeginFrameSource() {}
104 // SetNeedsBeginFrames is the on/off "switch" for the BeginFrameSource. When
105 // set to false no more BeginFrame messages should be sent to observer.
106 virtual bool NeedsBeginFrames() const = 0;
107 virtual void SetNeedsBeginFrames(bool needs_begin_frames
) = 0;
109 // DidFinishFrame provides back pressure to a frame source about frame
110 // processing (rather than toggling SetNeedsBeginFrames every frame). It is
111 // used by systems like the BackToBackFrameSource to make sure only one frame
112 // is pending at a time.
113 virtual void DidFinishFrame(size_t remaining_frames
) = 0;
115 // Add/Remove an observer from the source.
116 // *At the moment* only a single observer can be added to the source, however
117 // in the future this may be extended to allow multiple observers.
118 // If making this change, please use base::ObserverList to do so.
119 virtual void AddObserver(BeginFrameObserver
* obs
) = 0;
120 virtual void RemoveObserver(BeginFrameObserver
* obs
) = 0;
122 // Tells the Source that client is ready to handle BeginFrames messages.
123 virtual void SetClientReady() = 0;
125 // Tracing support - Recommend (but not required) to call this implementation
127 virtual void AsValueInto(base::trace_event::TracedValue
* dict
) const = 0;
130 // Simple base class which implements a BeginFrameSource.
131 // Implementation classes should:
132 // - Implement the pure virtual (Set)NeedsBeginFrames methods from
134 // - Use the CallOnBeginFrame method to call to the observer(s).
135 // - Recommended (but not required) to call BeginFrameSourceBase::AsValueInto
136 // in their own AsValueInto implementation.
137 class CC_EXPORT BeginFrameSourceBase
: public BeginFrameSource
{
139 ~BeginFrameSourceBase() override
{}
142 bool NeedsBeginFrames() const final
;
143 void SetNeedsBeginFrames(bool needs_begin_frames
) final
;
144 void DidFinishFrame(size_t remaining_frames
) override
{}
145 void AddObserver(BeginFrameObserver
* obs
) final
;
146 void RemoveObserver(BeginFrameObserver
* obs
) final
;
147 void SetClientReady() override
{}
149 // Tracing support - Recommend (but not required) to call this implementation
151 void AsValueInto(base::trace_event::TracedValue
* dict
) const override
;
154 BeginFrameSourceBase();
156 // These methods should be used by subclasses to make the call to the
158 void CallOnBeginFrame(const BeginFrameArgs
& args
);
160 // This method should be overridden if you want to change some behaviour on
161 // needs_begin_frames change.
162 virtual void OnNeedsBeginFramesChange(bool needs_begin_frames
) {}
164 BeginFrameObserver
* observer_
;
165 bool needs_begin_frames_
;
168 bool inside_as_value_into_
;
170 DISALLOW_COPY_AND_ASSIGN(BeginFrameSourceBase
);
173 // A frame source which calls BeginFrame (at the next possible time) as soon as
174 // remaining frames reaches zero.
175 class CC_EXPORT BackToBackBeginFrameSource
: public BeginFrameSourceBase
{
177 static scoped_ptr
<BackToBackBeginFrameSource
> Create(
178 base::SingleThreadTaskRunner
* task_runner
);
179 ~BackToBackBeginFrameSource() override
;
182 void DidFinishFrame(size_t remaining_frames
) override
;
185 void AsValueInto(base::trace_event::TracedValue
* dict
) const override
;
188 explicit BackToBackBeginFrameSource(
189 base::SingleThreadTaskRunner
* task_runner
);
190 virtual base::TimeTicks
Now(); // Now overridable for testing
192 base::SingleThreadTaskRunner
* task_runner_
;
194 bool send_begin_frame_posted_
;
196 // BeginFrameSourceBase
197 void OnNeedsBeginFramesChange(bool needs_begin_frames
) override
;
202 base::WeakPtrFactory
<BackToBackBeginFrameSource
> weak_factory_
;
204 DISALLOW_COPY_AND_ASSIGN(BackToBackBeginFrameSource
);
207 // A frame source which is locked to an external parameters provides from a
208 // vsync source and generates BeginFrameArgs for it.
209 class CC_EXPORT SyntheticBeginFrameSource
: public BeginFrameSourceBase
,
210 public DelayBasedTimeSourceClient
{
212 static scoped_ptr
<SyntheticBeginFrameSource
> Create(
213 base::SingleThreadTaskRunner
* task_runner
,
214 base::TimeDelta initial_vsync_interval
);
215 ~SyntheticBeginFrameSource() override
;
217 void OnUpdateVSyncParameters(base::TimeTicks new_vsync_timebase
,
218 base::TimeDelta new_vsync_interval
);
221 void AsValueInto(base::trace_event::TracedValue
* dict
) const override
;
223 // DelayBasedTimeSourceClient
224 void OnTimerTick() override
;
227 explicit SyntheticBeginFrameSource(
228 scoped_ptr
<DelayBasedTimeSource
> time_source
);
230 BeginFrameArgs
CreateBeginFrameArgs(base::TimeTicks frame_time
,
231 BeginFrameArgs::BeginFrameArgsType type
);
233 // BeginFrameSourceBase
234 void OnNeedsBeginFramesChange(bool needs_begin_frames
) override
;
236 scoped_ptr
<DelayBasedTimeSource
> time_source_
;
239 DISALLOW_COPY_AND_ASSIGN(SyntheticBeginFrameSource
);
242 // A "virtual" frame source which lets you switch between multiple other frame
243 // sources while making sure the BeginFrameArgs stays increasing (possibly
244 // enforcing minimum boundry between BeginFrameArgs messages).
245 class CC_EXPORT BeginFrameSourceMultiplexer
: public BeginFrameSourceBase
,
246 public BeginFrameObserver
{
248 static scoped_ptr
<BeginFrameSourceMultiplexer
> Create();
249 ~BeginFrameSourceMultiplexer() override
;
251 void SetMinimumInterval(base::TimeDelta new_minimum_interval
);
253 void AddSource(BeginFrameSource
* new_source
);
254 void RemoveSource(BeginFrameSource
* existing_source
);
255 void SetActiveSource(BeginFrameSource
* new_source
);
256 const BeginFrameSource
* ActiveSource();
258 // BeginFrameObserver
259 // The mux is an BeginFrameObserver as it needs to proxy the OnBeginFrame
260 // calls to preserve the monotonicity of the BeginFrameArgs when switching
262 void OnBeginFrame(const BeginFrameArgs
& args
) override
;
263 const BeginFrameArgs
LastUsedBeginFrameArgs() const override
;
266 void DidFinishFrame(size_t remaining_frames
) override
;
268 // BeginFrameSourceBase
269 void OnNeedsBeginFramesChange(bool needs_begin_frames
) override
;
272 void AsValueInto(base::trace_event::TracedValue
* dict
) const override
;
275 BeginFrameSourceMultiplexer();
276 explicit BeginFrameSourceMultiplexer(base::TimeDelta minimum_interval
);
278 bool HasSource(BeginFrameSource
* source
);
279 bool IsIncreasing(const BeginFrameArgs
& args
);
281 base::TimeDelta minimum_interval_
;
283 BeginFrameSource
* active_source_
;
284 std::set
<BeginFrameSource
*> source_list_
;
287 DISALLOW_COPY_AND_ASSIGN(BeginFrameSourceMultiplexer
);
292 #endif // CC_SCHEDULER_BEGIN_FRAME_SOURCE_H_