Create shared timeline data structure and unit test cases

This change adds the necessary classes for the graphics shared timeline.

Bug: 162889810
Test: libsurfaceflinger_unittest --gtest_filter='FrameTimelineTest*'
Change-Id: I7310a8e0793b2d640d873814bb5a9ba83c76a196
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.h b/services/surfaceflinger/FrameTimeline/FrameTimeline.h
new file mode 100644
index 0000000..291e30e
--- /dev/null
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.h
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <deque>
+#include <mutex>
+
+#include <ui/FenceTime.h>
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+
+namespace android::frametimeline {
+
+class FrameTimelineTest;
+
+/*
+ * Collection of timestamps that can be used for both predictions and actual times.
+ */
+struct TimelineItem {
+    TimelineItem(const nsecs_t startTime = 0, const nsecs_t endTime = 0,
+                 const nsecs_t presentTime = 0)
+          : startTime(startTime), endTime(endTime), presentTime(presentTime) {}
+
+    nsecs_t startTime;
+    nsecs_t endTime;
+    nsecs_t presentTime;
+};
+
+/*
+ * TokenManager generates a running number token for a set of predictions made by VsyncPredictor. It
+ * saves these predictions for a short period of time and returns the predictions for a given token,
+ * if it hasn't expired.
+ */
+class TokenManager {
+public:
+    virtual ~TokenManager() = default;
+
+    // Generates a token for the given set of predictions. Stores the predictions for 120ms and
+    // destroys it later.
+    virtual int64_t generateTokenForPredictions(TimelineItem&& prediction);
+};
+
+enum class PredictionState {
+    Valid,   // Predictions obtained successfully from the TokenManager
+    Expired, // TokenManager no longer has the predictions
+    None,    // Predictions are either not present or didn't come from TokenManager
+};
+
+/*
+ * Stores a set of predictions and the corresponding actual timestamps pertaining to a single frame
+ * from the app
+ */
+class SurfaceFrame {
+public:
+    enum class PresentState {
+        Presented, // Buffer was latched and presented by SurfaceFlinger
+        Dropped,   // Buffer was dropped by SurfaceFlinger
+        Unknown,   // Initial state, SurfaceFlinger hasn't seen this buffer yet
+    };
+
+    virtual ~SurfaceFrame() = default;
+
+    virtual TimelineItem getPredictions() = 0;
+    virtual TimelineItem getActuals() = 0;
+    virtual PresentState getPresentState() = 0;
+    virtual PredictionState getPredictionState() = 0;
+
+    virtual void setPresentState(PresentState state) = 0;
+    virtual void setActuals(TimelineItem&& actuals) = 0;
+
+    // There is no prediction for Queue time and it is not a part of TimelineItem. Set it
+    // separately.
+    virtual void setActualQueueTime(nsecs_t actualQueueTime) = 0;
+};
+
+/*
+ * Maintains a history of SurfaceFrames grouped together by the vsync time in which they were
+ * presented
+ */
+class FrameTimeline {
+public:
+    virtual ~FrameTimeline() = default;
+    virtual TokenManager& getTokenManager() = 0;
+
+    // Create a new surface frame, set the predictions based on a token and return it to the caller.
+    // Sets the PredictionState of SurfaceFrame.
+    virtual std::unique_ptr<SurfaceFrame> createSurfaceFrameForToken(
+            const std::string& layerName, std::optional<int64_t> token) = 0;
+
+    // Adds a new SurfaceFrame to the current DisplayFrame. Frames from multiple layers can be
+    // composited into one display frame.
+    virtual void addSurfaceFrame(std::unique_ptr<SurfaceFrame> surfaceFrame,
+                                 SurfaceFrame::PresentState state) = 0;
+
+    // The first function called by SF for the current DisplayFrame. Fetches SF predictions based on
+    // the token and sets the actualSfWakeTime for the current DisplayFrame.
+    virtual void setSfWakeUp(int64_t token, nsecs_t wakeupTime) = 0;
+
+    // Sets the sfPresentTime and finalizes the current DisplayFrame. Tracks the given present fence
+    // until it's signaled, and updates the present timestamps of all presented SurfaceFrames in
+    // that vsync.
+    virtual void setSfPresent(nsecs_t sfPresentTime,
+                              const std::shared_ptr<FenceTime>& presentFence) = 0;
+};
+
+namespace impl {
+
+using namespace std::chrono_literals;
+
+class TokenManager : public android::frametimeline::TokenManager {
+public:
+    TokenManager() : mCurrentToken(0) {}
+    ~TokenManager() = default;
+
+    int64_t generateTokenForPredictions(TimelineItem&& predictions) override;
+    std::optional<TimelineItem> getPredictionsForToken(int64_t token);
+
+private:
+    // Friend class for testing
+    friend class android::frametimeline::FrameTimelineTest;
+
+    void flushTokens(nsecs_t flushTime) REQUIRES(mMutex);
+
+    std::unordered_map<int64_t, TimelineItem> mPredictions GUARDED_BY(mMutex);
+    std::vector<std::pair<int64_t, nsecs_t>> mTokens GUARDED_BY(mMutex);
+    int64_t mCurrentToken GUARDED_BY(mMutex);
+    std::mutex mMutex;
+    static constexpr nsecs_t kMaxRetentionTime =
+            std::chrono::duration_cast<std::chrono::nanoseconds>(120ms).count();
+};
+
+class SurfaceFrame : public android::frametimeline::SurfaceFrame {
+public:
+    SurfaceFrame(const std::string& layerName, PredictionState predictionState,
+                 TimelineItem&& predictions);
+    ~SurfaceFrame() = default;
+
+    TimelineItem getPredictions() override { return mPredictions; };
+    TimelineItem getActuals() override;
+    PresentState getPresentState() override;
+    PredictionState getPredictionState() override;
+    void setActuals(TimelineItem&& actuals) override;
+    void setActualQueueTime(nsecs_t actualQueueTime) override {
+        mActualQueueTime = actualQueueTime;
+    };
+    void setPresentState(PresentState state) override;
+    void setPresentTime(nsecs_t presentTime);
+    void dump(std::string& result);
+
+private:
+    const std::string mLayerName;
+    PresentState mPresentState GUARDED_BY(mMutex);
+    PredictionState mPredictionState GUARDED_BY(mMutex);
+    const TimelineItem mPredictions;
+    TimelineItem mActuals GUARDED_BY(mMutex);
+    nsecs_t mActualQueueTime;
+    std::mutex mMutex;
+};
+
+class FrameTimeline : public android::frametimeline::FrameTimeline {
+public:
+    FrameTimeline();
+    ~FrameTimeline() = default;
+
+    frametimeline::TokenManager& getTokenManager() override { return mTokenManager; }
+    std::unique_ptr<frametimeline::SurfaceFrame> createSurfaceFrameForToken(
+            const std::string& layerName, std::optional<int64_t> token) override;
+    void addSurfaceFrame(std::unique_ptr<frametimeline::SurfaceFrame> surfaceFrame,
+                         SurfaceFrame::PresentState state) override;
+    void setSfWakeUp(int64_t token, nsecs_t wakeupTime) override;
+    void setSfPresent(nsecs_t sfPresentTime,
+                      const std::shared_ptr<FenceTime>& presentFence) override;
+    void dump(std::string& result);
+
+private:
+    // Friend class for testing
+    friend class android::frametimeline::FrameTimelineTest;
+
+    /*
+     * DisplayFrame should be used only internally within FrameTimeline.
+     */
+    struct DisplayFrame {
+        DisplayFrame();
+
+        /* Usage of TimelineItem w.r.t SurfaceFlinger
+         * startTime    Time when SurfaceFlinger wakes up to handle transactions and buffer updates
+         * endTime      Time when SurfaceFlinger sends a composited frame to Display
+         * presentTime  Time when the composited frame was presented on screen
+         */
+        TimelineItem surfaceFlingerPredictions;
+        TimelineItem surfaceFlingerActuals;
+
+        // Collection of predictions and actual values sent over by Layers
+        std::vector<std::unique_ptr<SurfaceFrame>> surfaceFrames;
+
+        PredictionState predictionState;
+    };
+
+    void flushPendingPresentFences() REQUIRES(mMutex);
+    void finalizeCurrentDisplayFrame() REQUIRES(mMutex);
+
+    // Sliding window of display frames. TODO(b/168072834): compare perf with fixed size array
+    std::deque<std::shared_ptr<DisplayFrame>> mDisplayFrames GUARDED_BY(mMutex);
+    std::vector<std::pair<std::shared_ptr<FenceTime>, std::shared_ptr<DisplayFrame>>>
+            mPendingPresentFences GUARDED_BY(mMutex);
+    std::shared_ptr<DisplayFrame> mCurrentDisplayFrame GUARDED_BY(mMutex);
+    TokenManager mTokenManager;
+    std::mutex mMutex;
+    static constexpr uint32_t kMaxDisplayFrames = 64;
+    // The initial container size for the vector<SurfaceFrames> inside display frame. Although this
+    // number doesn't represent any bounds on the number of surface frames that can go in a display
+    // frame, this is a good starting size for the vector so that we can avoid the internal vector
+    // resizing that happens with push_back.
+    static constexpr uint32_t kNumSurfaceFramesInitial = 10;
+};
+
+} // namespace impl
+} // namespace android::frametimeline