blob: 9d7b5403444acfeaeae630f0dad5f265ca5ea248 [file] [log] [blame]
Adithya Srinivasanf279e042020-08-17 14:56:27 -07001/*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <deque>
20#include <mutex>
21
Ady Abraham22c7b5c2020-09-22 19:33:40 -070022#include <gui/ISurfaceComposer.h>
Adithya Srinivasanf279e042020-08-17 14:56:27 -070023#include <ui/FenceTime.h>
24#include <utils/RefBase.h>
25#include <utils/Timers.h>
26
27namespace android::frametimeline {
28
29class FrameTimelineTest;
30
31/*
32 * Collection of timestamps that can be used for both predictions and actual times.
33 */
34struct TimelineItem {
35 TimelineItem(const nsecs_t startTime = 0, const nsecs_t endTime = 0,
36 const nsecs_t presentTime = 0)
37 : startTime(startTime), endTime(endTime), presentTime(presentTime) {}
38
39 nsecs_t startTime;
40 nsecs_t endTime;
41 nsecs_t presentTime;
Ady Abraham55fa7272020-09-30 19:19:27 -070042
43 bool operator==(const TimelineItem& other) const {
44 return startTime == other.startTime && endTime == other.endTime &&
45 presentTime == other.presentTime;
46 }
47
48 bool operator!=(const TimelineItem& other) const { return !(*this == other); }
Adithya Srinivasanf279e042020-08-17 14:56:27 -070049};
50
51/*
52 * TokenManager generates a running number token for a set of predictions made by VsyncPredictor. It
53 * saves these predictions for a short period of time and returns the predictions for a given token,
54 * if it hasn't expired.
55 */
56class TokenManager {
57public:
58 virtual ~TokenManager() = default;
59
60 // Generates a token for the given set of predictions. Stores the predictions for 120ms and
61 // destroys it later.
Adithya Srinivasan5f683cf2020-09-15 14:21:04 -070062 virtual int64_t generateTokenForPredictions(TimelineItem&& prediction) = 0;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070063};
64
65enum class PredictionState {
66 Valid, // Predictions obtained successfully from the TokenManager
67 Expired, // TokenManager no longer has the predictions
68 None, // Predictions are either not present or didn't come from TokenManager
69};
70
71/*
72 * Stores a set of predictions and the corresponding actual timestamps pertaining to a single frame
73 * from the app
74 */
75class SurfaceFrame {
76public:
77 enum class PresentState {
78 Presented, // Buffer was latched and presented by SurfaceFlinger
79 Dropped, // Buffer was dropped by SurfaceFlinger
80 Unknown, // Initial state, SurfaceFlinger hasn't seen this buffer yet
81 };
82
83 virtual ~SurfaceFrame() = default;
84
85 virtual TimelineItem getPredictions() = 0;
86 virtual TimelineItem getActuals() = 0;
Adithya Srinivasan5f683cf2020-09-15 14:21:04 -070087 virtual nsecs_t getActualQueueTime() = 0;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070088 virtual PresentState getPresentState() = 0;
89 virtual PredictionState getPredictionState() = 0;
90
91 virtual void setPresentState(PresentState state) = 0;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070092
Adithya Srinivasan5f683cf2020-09-15 14:21:04 -070093 // Actual timestamps of the app are set individually at different functions.
94 // Start time (if the app provides) and Queue time are accessible after queueing the frame,
95 // whereas End time is available only during latch.
96 virtual void setActualStartTime(nsecs_t actualStartTime) = 0;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070097 virtual void setActualQueueTime(nsecs_t actualQueueTime) = 0;
Adithya Srinivasan5f683cf2020-09-15 14:21:04 -070098 virtual void setActualEndTime(nsecs_t actualEndTime) = 0;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070099};
100
101/*
102 * Maintains a history of SurfaceFrames grouped together by the vsync time in which they were
103 * presented
104 */
105class FrameTimeline {
106public:
107 virtual ~FrameTimeline() = default;
Adithya Srinivasan5f683cf2020-09-15 14:21:04 -0700108 virtual TokenManager* getTokenManager() = 0;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700109
110 // Create a new surface frame, set the predictions based on a token and return it to the caller.
111 // Sets the PredictionState of SurfaceFrame.
112 virtual std::unique_ptr<SurfaceFrame> createSurfaceFrameForToken(
113 const std::string& layerName, std::optional<int64_t> token) = 0;
114
115 // Adds a new SurfaceFrame to the current DisplayFrame. Frames from multiple layers can be
116 // composited into one display frame.
117 virtual void addSurfaceFrame(std::unique_ptr<SurfaceFrame> surfaceFrame,
118 SurfaceFrame::PresentState state) = 0;
119
120 // The first function called by SF for the current DisplayFrame. Fetches SF predictions based on
121 // the token and sets the actualSfWakeTime for the current DisplayFrame.
122 virtual void setSfWakeUp(int64_t token, nsecs_t wakeupTime) = 0;
123
124 // Sets the sfPresentTime and finalizes the current DisplayFrame. Tracks the given present fence
125 // until it's signaled, and updates the present timestamps of all presented SurfaceFrames in
126 // that vsync.
127 virtual void setSfPresent(nsecs_t sfPresentTime,
128 const std::shared_ptr<FenceTime>& presentFence) = 0;
Adithya Srinivasan5f683cf2020-09-15 14:21:04 -0700129
130 virtual void dump(std::string& result) = 0;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700131};
132
133namespace impl {
134
135using namespace std::chrono_literals;
136
137class TokenManager : public android::frametimeline::TokenManager {
138public:
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700139 TokenManager() : mCurrentToken(ISurfaceComposer::INVALID_VSYNC_ID + 1) {}
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700140 ~TokenManager() = default;
141
142 int64_t generateTokenForPredictions(TimelineItem&& predictions) override;
143 std::optional<TimelineItem> getPredictionsForToken(int64_t token);
144
145private:
146 // Friend class for testing
147 friend class android::frametimeline::FrameTimelineTest;
148
149 void flushTokens(nsecs_t flushTime) REQUIRES(mMutex);
150
151 std::unordered_map<int64_t, TimelineItem> mPredictions GUARDED_BY(mMutex);
152 std::vector<std::pair<int64_t, nsecs_t>> mTokens GUARDED_BY(mMutex);
153 int64_t mCurrentToken GUARDED_BY(mMutex);
154 std::mutex mMutex;
155 static constexpr nsecs_t kMaxRetentionTime =
156 std::chrono::duration_cast<std::chrono::nanoseconds>(120ms).count();
157};
158
159class SurfaceFrame : public android::frametimeline::SurfaceFrame {
160public:
161 SurfaceFrame(const std::string& layerName, PredictionState predictionState,
162 TimelineItem&& predictions);
163 ~SurfaceFrame() = default;
164
165 TimelineItem getPredictions() override { return mPredictions; };
166 TimelineItem getActuals() override;
Adithya Srinivasan5f683cf2020-09-15 14:21:04 -0700167 nsecs_t getActualQueueTime() override;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700168 PresentState getPresentState() override;
169 PredictionState getPredictionState() override;
Adithya Srinivasan5f683cf2020-09-15 14:21:04 -0700170
171 void setActualStartTime(nsecs_t actualStartTime) override;
172 void setActualQueueTime(nsecs_t actualQueueTime) override;
173 void setActualEndTime(nsecs_t actualEndTime) override;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700174 void setPresentState(PresentState state) override;
Adithya Srinivasan5f683cf2020-09-15 14:21:04 -0700175 void setActualPresentTime(nsecs_t presentTime);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700176 void dump(std::string& result);
177
178private:
179 const std::string mLayerName;
180 PresentState mPresentState GUARDED_BY(mMutex);
181 PredictionState mPredictionState GUARDED_BY(mMutex);
182 const TimelineItem mPredictions;
183 TimelineItem mActuals GUARDED_BY(mMutex);
184 nsecs_t mActualQueueTime;
185 std::mutex mMutex;
186};
187
188class FrameTimeline : public android::frametimeline::FrameTimeline {
189public:
190 FrameTimeline();
191 ~FrameTimeline() = default;
192
Adithya Srinivasan5f683cf2020-09-15 14:21:04 -0700193 frametimeline::TokenManager* getTokenManager() override { return &mTokenManager; }
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700194 std::unique_ptr<frametimeline::SurfaceFrame> createSurfaceFrameForToken(
195 const std::string& layerName, std::optional<int64_t> token) override;
196 void addSurfaceFrame(std::unique_ptr<frametimeline::SurfaceFrame> surfaceFrame,
197 SurfaceFrame::PresentState state) override;
198 void setSfWakeUp(int64_t token, nsecs_t wakeupTime) override;
199 void setSfPresent(nsecs_t sfPresentTime,
200 const std::shared_ptr<FenceTime>& presentFence) override;
Adithya Srinivasan5f683cf2020-09-15 14:21:04 -0700201 void dump(std::string& result) override;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700202
203private:
204 // Friend class for testing
205 friend class android::frametimeline::FrameTimelineTest;
206
207 /*
208 * DisplayFrame should be used only internally within FrameTimeline.
209 */
210 struct DisplayFrame {
211 DisplayFrame();
212
213 /* Usage of TimelineItem w.r.t SurfaceFlinger
214 * startTime Time when SurfaceFlinger wakes up to handle transactions and buffer updates
215 * endTime Time when SurfaceFlinger sends a composited frame to Display
216 * presentTime Time when the composited frame was presented on screen
217 */
218 TimelineItem surfaceFlingerPredictions;
219 TimelineItem surfaceFlingerActuals;
220
221 // Collection of predictions and actual values sent over by Layers
222 std::vector<std::unique_ptr<SurfaceFrame>> surfaceFrames;
223
224 PredictionState predictionState;
225 };
226
227 void flushPendingPresentFences() REQUIRES(mMutex);
228 void finalizeCurrentDisplayFrame() REQUIRES(mMutex);
229
230 // Sliding window of display frames. TODO(b/168072834): compare perf with fixed size array
231 std::deque<std::shared_ptr<DisplayFrame>> mDisplayFrames GUARDED_BY(mMutex);
232 std::vector<std::pair<std::shared_ptr<FenceTime>, std::shared_ptr<DisplayFrame>>>
233 mPendingPresentFences GUARDED_BY(mMutex);
234 std::shared_ptr<DisplayFrame> mCurrentDisplayFrame GUARDED_BY(mMutex);
235 TokenManager mTokenManager;
236 std::mutex mMutex;
237 static constexpr uint32_t kMaxDisplayFrames = 64;
238 // The initial container size for the vector<SurfaceFrames> inside display frame. Although this
239 // number doesn't represent any bounds on the number of surface frames that can go in a display
240 // frame, this is a good starting size for the vector so that we can avoid the internal vector
241 // resizing that happens with push_back.
242 static constexpr uint32_t kNumSurfaceFramesInitial = 10;
243};
244
245} // namespace impl
246} // namespace android::frametimeline