| Index: cc/scheduler/begin_frame_source.h
|
| diff --git a/cc/scheduler/begin_frame_source.h b/cc/scheduler/begin_frame_source.h
|
| index bde01afd79ec6bd72a1d525c85b9d6d49bafe9d0..57d305b027be491033948145e28b38b2ec382988 100644
|
| --- a/cc/scheduler/begin_frame_source.h
|
| +++ b/cc/scheduler/begin_frame_source.h
|
| @@ -10,6 +10,7 @@
|
|
|
| #include <set>
|
| #include <string>
|
| +#include <unordered_set>
|
|
|
| #include "base/logging.h"
|
| #include "base/macros.h"
|
| @@ -26,8 +27,10 @@ class CC_EXPORT BeginFrameObserver {
|
| virtual ~BeginFrameObserver() {}
|
|
|
| // 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.
|
| + // |args|.IsValid()==true. If |args|.source_id did not change between
|
| + // invocations, |args|.sequence_number is guaranteed to be be strictly greater
|
| + // than the previous call. Further, |args|.frame_time is guaranteed to be
|
| + // greater than or equal to the previous call even if the source_id changes.
|
| //
|
| // Side effects: This function can (and most of the time *will*) change the
|
| // return value of the LastUsedBeginFrameArgs method. See the documentation
|
| @@ -99,14 +102,21 @@ class CC_EXPORT BeginFrameObserverBase : public BeginFrameObserver {
|
| // all BeginFrameSources *must* provide.
|
| class CC_EXPORT BeginFrameSource {
|
| public:
|
| + BeginFrameSource();
|
| virtual ~BeginFrameSource() {}
|
|
|
| - // 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.
|
| + // BeginFrameObservers use DidFinishFrame to acknowledge that they have
|
| + // completed handling a BeginFrame.
|
| + //
|
| + // The DisplayScheduler uses these acknowledgments to trigger an early
|
| + // deadline once all BeginFrameObservers have completed a frame.
|
| + //
|
| + // They also provide back pressure to a frame source about frame processing
|
| + // (rather than toggling SetNeedsBeginFrames every frame). For example, the
|
| + // BackToBackFrameSource uses them to make sure only one frame is pending at a
|
| + // time.
|
| virtual void DidFinishFrame(BeginFrameObserver* obs,
|
| - size_t remaining_frames) = 0;
|
| + const BeginFrameAck& ack) = 0;
|
|
|
| // Add/Remove an observer from the source. When no observers are added the BFS
|
| // should shut down its timers, disable vsync, etc.
|
| @@ -116,13 +126,22 @@ class CC_EXPORT BeginFrameSource {
|
| // Returns false if the begin frame source will just continue to produce
|
| // begin frames without waiting.
|
| virtual bool IsThrottled() const = 0;
|
| +
|
| + // Returns an identifier for this BeginFrameSource. Guaranteed unique within a
|
| + // process, but not across processes. This is used to create BeginFrames that
|
| + // originate at this source. Note that BeginFrameSources may pass on
|
| + // BeginFrames created by other sources, with different IDs.
|
| + uint64_t source_id() const;
|
| +
|
| + private:
|
| + uint64_t source_id_;
|
| };
|
|
|
| // A BeginFrameSource that does nothing.
|
| class CC_EXPORT StubBeginFrameSource : public BeginFrameSource {
|
| public:
|
| void DidFinishFrame(BeginFrameObserver* obs,
|
| - size_t remaining_frames) override {}
|
| + const BeginFrameAck& ack) override {}
|
| void AddObserver(BeginFrameObserver* obs) override {}
|
| void RemoveObserver(BeginFrameObserver* obs) override {}
|
| bool IsThrottled() const override;
|
| @@ -152,7 +171,7 @@ class CC_EXPORT BackToBackBeginFrameSource : public SyntheticBeginFrameSource,
|
| void AddObserver(BeginFrameObserver* obs) override;
|
| void RemoveObserver(BeginFrameObserver* obs) override;
|
| void DidFinishFrame(BeginFrameObserver* obs,
|
| - size_t remaining_frames) override;
|
| + const BeginFrameAck& ack) override;
|
| bool IsThrottled() const override;
|
|
|
| // SyntheticBeginFrameSource implementation.
|
| @@ -167,6 +186,7 @@ class CC_EXPORT BackToBackBeginFrameSource : public SyntheticBeginFrameSource,
|
| std::unique_ptr<DelayBasedTimeSource> time_source_;
|
| std::unordered_set<BeginFrameObserver*> observers_;
|
| std::unordered_set<BeginFrameObserver*> pending_begin_frame_observers_;
|
| + uint64_t next_sequence_number_;
|
| base::WeakPtrFactory<BackToBackBeginFrameSource> weak_factory_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(BackToBackBeginFrameSource);
|
| @@ -185,7 +205,7 @@ class CC_EXPORT DelayBasedBeginFrameSource : public SyntheticBeginFrameSource,
|
| void AddObserver(BeginFrameObserver* obs) override;
|
| void RemoveObserver(BeginFrameObserver* obs) override;
|
| void DidFinishFrame(BeginFrameObserver* obs,
|
| - size_t remaining_frames) override {}
|
| + const BeginFrameAck& ack) override {}
|
| bool IsThrottled() const override;
|
|
|
| // SyntheticBeginFrameSource implementation.
|
| @@ -197,21 +217,64 @@ class CC_EXPORT DelayBasedBeginFrameSource : public SyntheticBeginFrameSource,
|
| void OnTimerTick() override;
|
|
|
| private:
|
| - BeginFrameArgs CreateBeginFrameArgs(base::TimeTicks frame_time,
|
| + BeginFrameArgs CreateBeginFrameArgs(uint64_t sequence_number,
|
| + base::TimeTicks frame_time,
|
| BeginFrameArgs::BeginFrameArgsType type);
|
|
|
| std::unique_ptr<DelayBasedTimeSource> time_source_;
|
| std::unordered_set<BeginFrameObserver*> observers_;
|
| base::TimeTicks last_timebase_;
|
| base::TimeDelta authoritative_interval_;
|
| + BeginFrameArgs current_begin_frame_args_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(DelayBasedBeginFrameSource);
|
| };
|
|
|
| +// Helper class that tracks outstanding acknowledgments from
|
| +// BeginFrameObservers.
|
| +class CC_EXPORT BeginFrameObserverAckTracker {
|
| + public:
|
| + BeginFrameObserverAckTracker();
|
| + virtual ~BeginFrameObserverAckTracker();
|
| +
|
| + // The BeginFrameSource uses these methods to notify us when a BeginFrame was
|
| + // started and sent to a specific observer, an observer finished a frame, or
|
| + // an observer was added/removed.
|
| + void OnBeginFrame(const BeginFrameArgs& args);
|
| + void OnObserverBeginFrame(BeginFrameObserver* obs,
|
| + const BeginFrameArgs& args);
|
| + void OnObserverFinishedFrame(BeginFrameObserver* obs,
|
| + const BeginFrameAck& ack);
|
| + void OnObserverAdded(BeginFrameObserver* obs);
|
| + void OnObserverRemoved(BeginFrameObserver* obs);
|
| +
|
| + // Returns |true| if all the source's observers completed the current frame.
|
| + bool AllObserversFinishedFrame() const;
|
| +
|
| + // Returns |true| if any observer had damage during the current frame.
|
| + bool AnyObserversHadDamage() const;
|
| +
|
| + // Returns the sequence number of the latest_confirmed_frame that any of
|
| + // the observers have contributed for the latest frame.
|
| + uint64_t LatestConfirmedFrame() const;
|
| +
|
| + private:
|
| + void SourceChanged(const BeginFrameArgs& args);
|
| +
|
| + uint64_t current_source_id_;
|
| + uint64_t current_sequence_number_;
|
| + std::set<BeginFrameObserver*> observers_;
|
| + std::set<BeginFrameObserver*> finished_observers_;
|
| + bool observers_had_damage_;
|
| + std::unordered_map<BeginFrameObserver*, uint64_t> latest_confirmed_frames_;
|
| +};
|
| +
|
| class CC_EXPORT ExternalBeginFrameSourceClient {
|
| public:
|
| // Only called when changed. Assumed false by default.
|
| virtual void OnNeedsBeginFrames(bool needs_begin_frames) = 0;
|
| + // Called when all observers have completed a frame.
|
| + virtual void OnDidFinishFrame(const BeginFrameAck& ack) = 0;
|
| };
|
|
|
| // A BeginFrameSource that is only ticked manually. Usually the endpoint
|
| @@ -228,22 +291,45 @@ class CC_EXPORT ExternalBeginFrameSource : public BeginFrameSource {
|
| void AddObserver(BeginFrameObserver* obs) override;
|
| void RemoveObserver(BeginFrameObserver* obs) override;
|
| void DidFinishFrame(BeginFrameObserver* obs,
|
| - size_t remaining_frames) override {}
|
| + const BeginFrameAck& ack) override;
|
| bool IsThrottled() const override;
|
|
|
| void OnSetBeginFrameSourcePaused(bool paused);
|
| void OnBeginFrame(const BeginFrameArgs& args);
|
|
|
| protected:
|
| + void MaybeFinishFrame();
|
| + void FinishFrame();
|
| +
|
| BeginFrameArgs missed_begin_frame_args_;
|
| std::unordered_set<BeginFrameObserver*> observers_;
|
| ExternalBeginFrameSourceClient* client_;
|
| bool paused_ = false;
|
| + bool frame_active_ = false;
|
| + BeginFrameObserverAckTracker ack_tracker_;
|
|
|
| private:
|
| DISALLOW_COPY_AND_ASSIGN(ExternalBeginFrameSource);
|
| };
|
|
|
| +// A BeginFrameSource that delegates to another given source.
|
| +class CC_EXPORT DelegatingBeginFrameSource : public BeginFrameSource {
|
| + public:
|
| + // |delegate| lifetime must be preserved past the lifetime of this class.
|
| + explicit DelegatingBeginFrameSource(BeginFrameSource* delegate);
|
| + ~DelegatingBeginFrameSource() override {}
|
| +
|
| + // BeginFrameSource implementation.
|
| + void DidFinishFrame(BeginFrameObserver* obs,
|
| + const BeginFrameAck& ack) override;
|
| + void AddObserver(BeginFrameObserver* obs) override;
|
| + void RemoveObserver(BeginFrameObserver* obs) override;
|
| + bool IsThrottled() const override;
|
| +
|
| + private:
|
| + BeginFrameSource* delegate_; // Not owned.
|
| +};
|
| +
|
| } // namespace cc
|
|
|
| #endif // CC_SCHEDULER_BEGIN_FRAME_SOURCE_H_
|
|
|