Index: cc/scheduler/begin_frame_source.h |
diff --git a/cc/scheduler/begin_frame_source.h b/cc/scheduler/begin_frame_source.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9d87e908d4278a62836ecf50ad2e9f234e22cc67 |
--- /dev/null |
+++ b/cc/scheduler/begin_frame_source.h |
@@ -0,0 +1,256 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef CC_SCHEDULER_BEGIN_FRAME_SOURCE_H_ |
+#define CC_SCHEDULER_BEGIN_FRAME_SOURCE_H_ |
+ |
+#include <set> |
+#include <string> |
+ |
+#include "base/debug/trace_event.h" |
+#include "base/logging.h" |
+#include "cc/output/begin_frame_args.h" |
+#include "cc/output/vsync_parameter_observer.h" |
+#include "cc/scheduler/delay_based_time_source.h" |
+ |
+namespace cc { |
+ |
+// (Pure) Interface for observing BeginFrame messages from BeginFrameSource |
+// objects. |
+class CC_EXPORT BeginFrameObserver { |
+ public: |
+ // The |args| given to OnBeginFrame is guaranteed to have |
+ // |args|.IsValid()==true and have |args|.frame_time |
+ // field be strictly greater than the previous call. |
+ // |
+ // Side effects: This function can (and most of the time *will*) change the |
+ // return value of the LastUsedBeginFrameArgs method. See the documentation |
+ // on that method for more information. |
+ virtual void OnBeginFrame(const BeginFrameArgs& args) = 0; |
+ |
+ // Returns the last BeginFrameArgs used by the observer. This method's return |
+ // value is affected by the OnBeginFrame method! |
+ // |
+ // - Before the first call of OnBeginFrame, this method should return a |
+ // BeginFrameArgs on which IsValid() returns false. |
+ // |
+ // - If the |args| passed to OnBeginFrame is (or *will be*) used, then |
+ // LastUsedBeginFrameArgs return value should become the |args| given to |
+ // OnBeginFrame. |
+ // |
+ // - If the |args| passed to OnBeginFrame is dropped, then |
+ // LastUsedBeginFrameArgs return value should *not* change. |
+ // |
+ // These requirements are designed to allow chaining and nesting of |
+ // BeginFrameObservers which filter the incoming BeginFrame messages while |
+ // preventing "double dropping" and other bad side effects. |
+ virtual const BeginFrameArgs LastUsedBeginFrameArgs() const = 0; |
+ |
+ // Tracing support |
+ virtual void AsValueInto(base::debug::TracedValue* dict) const = 0; |
+}; |
+ |
+// Simple mix in which implements a BeginFrameObserver which checks the |
+// incoming values meet the BeginFrameObserver requirements and implements the |
+// required LastUsedBeginFrameArgs behaviour. |
+// |
+// Users of this mix in should; |
+// - Implement the OnBeginFrameMixInDelegate function. |
+// - Recommended (but not required) to call |
+// BeginFrameObserverMixIn::OnValueInto in their overridden OnValueInto |
+// function. |
+class CC_EXPORT BeginFrameObserverMixIn : public BeginFrameObserver { |
+ public: |
+ BeginFrameObserverMixIn(); |
+ |
+ // BeginFrameObserver |
+ |
+ // Traces |args| and DCHECK |args| satisfies pre-conditions then calls |
+ // OnBeginFrameMixInDelegate and updates the last_begin_frame_args_ value on |
+ // true. |
+ virtual void OnBeginFrame(const BeginFrameArgs& args) OVERRIDE; |
+ virtual const BeginFrameArgs LastUsedBeginFrameArgs() const OVERRIDE; |
+ |
+ // Outputs last_begin_frame_args_ |
+ virtual void AsValueInto(base::debug::TracedValue* dict) const OVERRIDE; |
+ |
+ protected: |
+ // Subclasses should override this method! |
+ // Return true if the given argument is (or will be) used. |
+ virtual bool OnBeginFrameMixInDelegate(const BeginFrameArgs& args) = 0; |
+ |
+ BeginFrameArgs last_begin_frame_args_; |
+ int64_t dropped_begin_frame_args_; |
+}; |
+ |
+// Interface for a class which produces BeginFrame calls to a |
+// BeginFrameObserver. |
+// |
+// BeginFrame calls *normally* occur just after a vsync interrupt when input |
+// processing has been finished and provide information about the time values |
+// of the vsync times. *However*, these values can be heavily modified or even |
+// plain made up (when no vsync signal is available or vsync throttling is |
+// turned off). See the BeginFrameObserver for information about the guarantees |
+// all BeginFrameSources *must* provide. |
+// |
+// Implementation classes should: |
+// - Use the CallOnBeginFrame method to call to the observer(s). |
+// - Implement the pure virtual methods. |
+// - Recommend (but not required) to call BeginFrameSource::AsValueInto in |
+// their own AsValueInto implementation. |
+class CC_EXPORT BeginFrameSource { |
+ public: |
+ virtual ~BeginFrameSource() {} |
+ |
+ // SetNeedsBeginFrames is the on/off "switch" for the BeginFrameSource. When |
+ // set to false no more BeginFrame messages should be sent to observer. |
+ virtual bool NeedsBeginFrames() const = 0; |
+ virtual void SetNeedsBeginFrames(bool needs_begin_frames) = 0; |
+ |
+ // DidFinishFrame provides back pressure to a frame source about frame |
+ // processing (rather than toggling SetNeedsBeginFrames every frame). It is |
+ // used by systems like the BackToBackFrameSource to make sure only one frame |
+ // is pending at a time. |
+ virtual void DidFinishFrame(size_t remaining_frames) = 0; |
+ |
+ // Add/Remove an observer from the source. |
+ // *At the moment* only a single observer can be added to the source, however |
+ // in the future this may be extended to allow multiple observers. |
+ // If making this change, please use base::ObserverList to do so. |
+ void AddObserver(BeginFrameObserver* obs); |
+ void RemoveObserver(BeginFrameObserver* obs); |
+ |
+ // Tracing support - Recommend (but not required) to call this implementation |
+ // in any override. |
+ virtual void AsValueInto(base::debug::TracedValue* dict) const; |
+ |
+ protected: |
+ BeginFrameSource(); |
+ |
+ // These methods should be used by subclasses to make the call to the |
+ // observers. |
+ void CallOnBeginFrame(const BeginFrameArgs& args); |
+ |
+ BeginFrameObserver* observer_; |
+ |
+ private: |
+ bool inside_as_value_into_; |
+}; |
+ |
+// A frame source which calls BeginFrame (at the next possible time) as soon as |
+// remaining frames reaches zero. |
+class CC_EXPORT BackToBackBeginFrameSource : public BeginFrameSource { |
+ public: |
+ static scoped_ptr<BackToBackBeginFrameSource> Create( |
+ base::SingleThreadTaskRunner* task_runner); |
+ virtual ~BackToBackBeginFrameSource(); |
+ |
+ // BeginFrameSource |
+ virtual bool NeedsBeginFrames() const OVERRIDE; |
+ virtual void SetNeedsBeginFrames(bool needs_begin_frames) OVERRIDE; |
+ virtual void DidFinishFrame(size_t remaining_frames) OVERRIDE; |
+ |
+ // Tracing |
+ virtual void AsValueInto(base::debug::TracedValue* dict) const OVERRIDE; |
+ |
+ protected: |
+ explicit BackToBackBeginFrameSource( |
+ base::SingleThreadTaskRunner* task_runner); |
+ virtual base::TimeTicks Now(); // Now overridable for testing |
+ |
+ base::WeakPtrFactory<BackToBackBeginFrameSource> weak_factory_; |
+ base::SingleThreadTaskRunner* task_runner_; |
+ |
+ bool needs_begin_frames_; |
+ bool send_begin_frame_posted_; |
+ |
+ void ScheduleBeginFrame(); |
+ void BeginFrame(); |
+}; |
+ |
+// A frame source which is locked to an external parameters provides from a |
+// vsync source and generates BeginFrameArgs for it. |
+class CC_EXPORT SyntheticBeginFrameSource : public BeginFrameSource, |
+ public VSyncParameterObserver, |
+ public TimeSourceClient { |
+ public: |
+ static scoped_ptr<SyntheticBeginFrameSource> Create( |
+ base::SingleThreadTaskRunner* task_runner, |
+ base::TimeTicks initial_vsync_timebase, |
+ base::TimeDelta initial_vsync_interval); |
+ virtual ~SyntheticBeginFrameSource(); |
+ |
+ // BeginFrameSource |
+ virtual bool NeedsBeginFrames() const OVERRIDE; |
+ virtual void SetNeedsBeginFrames(bool needs_begin_frames) OVERRIDE; |
+ virtual void DidFinishFrame(size_t remaining_frames) OVERRIDE{}; |
+ |
+ // Tracing |
+ virtual void AsValueInto(base::debug::TracedValue* dict) const OVERRIDE; |
+ |
+ // VSyncParameterObserver |
+ virtual void OnUpdateVSyncParameters( |
+ base::TimeTicks new_vsync_timebase, |
+ base::TimeDelta new_vsync_interval) OVERRIDE; |
+ |
+ // TimeSourceClient |
+ virtual void OnTimerTick() OVERRIDE; |
+ |
+ protected: |
+ explicit SyntheticBeginFrameSource( |
+ scoped_refptr<DelayBasedTimeSource> time_source); |
+ |
+ BeginFrameArgs CreateBeginFrameArgs(base::TimeTicks frame_time, |
+ BeginFrameArgs::BeginFrameArgsType type); |
+ |
+ scoped_refptr<DelayBasedTimeSource> time_source_; |
+}; |
+ |
+// A "virtual" frame source which lets you switch between multiple other frame |
+// sources while making sure the BeginFrameArgs stays increasing (possibly |
+// enforcing minimum boundry between BeginFrameArgs messages). |
+class CC_EXPORT BeginFrameSourceMultiplexer : public BeginFrameSource, |
+ public BeginFrameObserver { |
+ public: |
+ static scoped_ptr<BeginFrameSourceMultiplexer> Create(); |
+ virtual ~BeginFrameSourceMultiplexer(); |
+ |
+ void SetMinimumInterval(base::TimeDelta new_minimum_interval); |
+ |
+ void AddSource(BeginFrameSource* new_source); |
+ void RemoveSource(BeginFrameSource* existing_source); |
+ void SetActiveSource(BeginFrameSource* new_source); |
+ const BeginFrameSource* ActiveSource(); |
+ |
+ // BeginFrameObserver |
+ // The mux is an BeginFrameObserver as it needs to proxy the OnBeginFrame |
+ // calls to preserve the monotonicity of the BeginFrameArgs when switching |
+ // sources. |
+ virtual void OnBeginFrame(const BeginFrameArgs& args) OVERRIDE; |
+ virtual const BeginFrameArgs LastUsedBeginFrameArgs() const OVERRIDE; |
+ |
+ // BeginFrameSource |
+ virtual bool NeedsBeginFrames() const OVERRIDE; |
+ virtual void SetNeedsBeginFrames(bool needs_begin_frames) OVERRIDE; |
+ virtual void DidFinishFrame(size_t remaining_frames) OVERRIDE; |
+ |
+ // Tracing |
+ virtual void AsValueInto(base::debug::TracedValue* dict) const OVERRIDE; |
+ |
+ protected: |
+ BeginFrameSourceMultiplexer(); |
+ explicit BeginFrameSourceMultiplexer(base::TimeDelta minimum_interval); |
+ |
+ bool HasSource(BeginFrameSource* source); |
+ bool IsIncreasing(const BeginFrameArgs& args); |
+ |
+ base::TimeDelta minimum_interval_; |
+ |
+ BeginFrameSource* active_source_; |
+ std::set<BeginFrameSource*> source_list_; |
+}; |
+ |
+} // namespace cc |
+ |
+#endif // CC_SCHEDULER_BEGIN_FRAME_SOURCE_H_ |