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

Unified 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, 3 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 side-by-side diff with in-line comments
Download patch
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..de4a286b0a18875a5cad076264765b5c49a6ca07
--- /dev/null
+++ b/cc/scheduler/begin_frame_source.h
@@ -0,0 +1,285 @@
+// 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:
+ // Used to indicate what happened to the |args| value given to OnBeginFrame.
+ enum BeginFrameArgsStatus {
+ // The |args| value was discarded and not used. Hence
+ // LastUsedBeginFrameArgs will not have changed.
+ DROPPED,
+ // The |args| value was queued to be processed later.
+ // LastUsedBeginFrameArgs will have been updated to match |args|.
+ USED,
+ };
+
+ // 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 BeginFrameArgsStatus OnBeginFrame(const BeginFrameArgs& args) = 0;
+
+ // Some frame sources *may* provide the last missed begin frame when
+ // SetNeedsBeginFrames is set true (such as the SyntheticBeginFrameSource).
+ //
+ // **Don't** depend on this function ever being called.
+ virtual BeginFrameArgsStatus OnMissedBeginFrame(
+ 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 OnBeginFrame will return USED this method's return value
+ // should become the |args| given to OnBeginFrame.
+ //
+ // - If the |args| passed to OnBeginFrame is dropped, then OnBeginFrame will
+ // return DROPPED and this method's 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;
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
+
+ // 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 ProcessBeginFrameArgs function.
+// - Recommended (but not required) to call
+// BeginFrameObserverMixIn::OnValueInto in their overridden OnValueInto
+// function.
+//
+// Advance observers may also wish to override the OnMissedBeginFrame method.
+class CC_EXPORT BeginFrameObserverMixIn : public BeginFrameObserver {
+ public:
+ // BeginFrameObserver
+ BeginFrameObserverMixIn();
+
+ // Traces |args| and DCHECK |args| satisfies pre-conditions then calls
+ // ProcessBeginFrameArgs and updates the last_begin_frame_args_ value on true.
+ virtual BeginFrameObserver::BeginFrameArgsStatus OnBeginFrame(
+ const BeginFrameArgs& args) OVERRIDE;
+
+ // Forwards call to the OnBeginFrame callback.
+ virtual BeginFrameObserver::BeginFrameArgsStatus OnMissedBeginFrame(
+ 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 BeginFrameObserver::BeginFrameArgsStatus ProcessBeginFrameArgs(
+ 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 CallOn(Missed)BeginFrame 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 and 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.
+ BeginFrameObserver::BeginFrameArgsStatus CallOnBeginFrame(
+ const BeginFrameArgs& args);
+ BeginFrameObserver::BeginFrameArgsStatus CallOnMissedBeginFrame(
+ 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);
+
+ void SendBeginFrameFromTick(base::TimeTicks frame_time);
+
+ 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 BeginFrameObserver::BeginFrameArgsStatus OnBeginFrame(
+ const BeginFrameArgs& args) OVERRIDE;
+ virtual BeginFrameObserver::BeginFrameArgsStatus OnMissedBeginFrame(
+ 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_

Powered by Google App Engine
This is Rietveld 408576698