| 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_
|
|
|