blob: f5239aa572edf526b884da2a3b30c002d96f6d4c [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
Alec Mouri9a29e672020-09-14 12:39:14 -070019#include <../TimeStats/TimeStats.h>
Ady Abraham22c7b5c2020-09-22 19:33:40 -070020#include <gui/ISurfaceComposer.h>
Jorim Jaggi5814ab82020-12-03 20:45:58 +010021#include <gui/JankInfo.h>
Adithya Srinivasan01189672020-10-20 14:23:05 -070022#include <perfetto/trace/android/frame_timeline_event.pbzero.h>
23#include <perfetto/tracing.h>
Adithya Srinivasanf279e042020-08-17 14:56:27 -070024#include <ui/FenceTime.h>
25#include <utils/RefBase.h>
Adithya Srinivasan8fc601d2020-09-25 13:51:09 -070026#include <utils/String16.h>
Adithya Srinivasanf279e042020-08-17 14:56:27 -070027#include <utils/Timers.h>
Adithya Srinivasan8fc601d2020-09-25 13:51:09 -070028#include <utils/Vector.h>
Adithya Srinivasanf279e042020-08-17 14:56:27 -070029
Alec Mouri9a29e672020-09-14 12:39:14 -070030#include <deque>
31#include <mutex>
Adithya Srinivasanf279e042020-08-17 14:56:27 -070032
Alec Mouri9a29e672020-09-14 12:39:14 -070033namespace android::frametimeline {
Adithya Srinivasan8fc601d2020-09-25 13:51:09 -070034
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -080035class FrameTimelineTest;
36
37using namespace std::chrono_literals;
38
39// Metadata indicating how the frame was presented w.r.t expected present time.
40enum class FramePresentMetadata : int8_t {
41 // Frame was presented on time
42 OnTimePresent,
43 // Frame was presented late
44 LatePresent,
45 // Frame was presented early
46 EarlyPresent,
47 // Unknown/initial state
48 UnknownPresent,
Adithya Srinivasan8fc601d2020-09-25 13:51:09 -070049};
50
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -080051// Metadata comparing the frame's actual finish time to the expected deadline.
52enum class FrameReadyMetadata : int8_t {
53 // App/SF finished on time. Early finish is treated as on time since the goal of any component
54 // is to finish before the deadline.
55 OnTimeFinish,
56 // App/SF finished work later than expected
57 LateFinish,
58 // Unknown/initial state
59 UnknownFinish,
60};
61
62// Metadata comparing the frame's actual start time to the expected start time.
63enum class FrameStartMetadata : int8_t {
64 // App/SF started on time
65 OnTimeStart,
66 // App/SF started later than expected
67 LateStart,
68 // App/SF started earlier than expected
69 EarlyStart,
70 // Unknown/initial state
71 UnknownStart,
72};
Adithya Srinivasanf279e042020-08-17 14:56:27 -070073
74/*
75 * Collection of timestamps that can be used for both predictions and actual times.
76 */
77struct TimelineItem {
78 TimelineItem(const nsecs_t startTime = 0, const nsecs_t endTime = 0,
79 const nsecs_t presentTime = 0)
80 : startTime(startTime), endTime(endTime), presentTime(presentTime) {}
81
82 nsecs_t startTime;
83 nsecs_t endTime;
84 nsecs_t presentTime;
Ady Abraham55fa7272020-09-30 19:19:27 -070085
86 bool operator==(const TimelineItem& other) const {
87 return startTime == other.startTime && endTime == other.endTime &&
88 presentTime == other.presentTime;
89 }
90
91 bool operator!=(const TimelineItem& other) const { return !(*this == other); }
Adithya Srinivasanf279e042020-08-17 14:56:27 -070092};
93
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -080094struct TokenManagerPrediction {
95 nsecs_t timestamp = 0;
96 TimelineItem predictions;
97};
98
99struct JankClassificationThresholds {
100 // The various thresholds for App and SF. If the actual timestamp falls within the threshold
101 // compared to prediction, we treat it as on time.
102 nsecs_t presentThreshold = std::chrono::duration_cast<std::chrono::nanoseconds>(2ms).count();
103 nsecs_t deadlineThreshold = std::chrono::duration_cast<std::chrono::nanoseconds>(2ms).count();
104 nsecs_t startThreshold = std::chrono::duration_cast<std::chrono::nanoseconds>(2ms).count();
105};
106
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700107/*
108 * TokenManager generates a running number token for a set of predictions made by VsyncPredictor. It
109 * saves these predictions for a short period of time and returns the predictions for a given token,
110 * if it hasn't expired.
111 */
112class TokenManager {
113public:
114 virtual ~TokenManager() = default;
115
116 // Generates a token for the given set of predictions. Stores the predictions for 120ms and
117 // destroys it later.
Adithya Srinivasan5f683cf2020-09-15 14:21:04 -0700118 virtual int64_t generateTokenForPredictions(TimelineItem&& prediction) = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800119
120 // Returns the stored predictions for a given token, if the predictions haven't expired.
121 virtual std::optional<TimelineItem> getPredictionsForToken(int64_t token) const = 0;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700122};
123
124enum class PredictionState {
125 Valid, // Predictions obtained successfully from the TokenManager
126 Expired, // TokenManager no longer has the predictions
127 None, // Predictions are either not present or didn't come from TokenManager
128};
129
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700130class SurfaceFrame {
131public:
132 enum class PresentState {
133 Presented, // Buffer was latched and presented by SurfaceFlinger
134 Dropped, // Buffer was dropped by SurfaceFlinger
135 Unknown, // Initial state, SurfaceFlinger hasn't seen this buffer yet
136 };
137
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800138 // Only FrameTimeline can construct a SurfaceFrame as it provides Predictions(through
139 // TokenManager), Thresholds and TimeStats pointer.
140 SurfaceFrame(int64_t token, pid_t ownerPid, uid_t ownerUid, std::string layerName,
141 std::string debugName, PredictionState predictionState, TimelineItem&& predictions,
142 std::shared_ptr<TimeStats> timeStats, JankClassificationThresholds thresholds);
143 ~SurfaceFrame() = default;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700144
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800145 // Returns std::nullopt if the frame hasn't been classified yet.
146 // Used by both SF and FrameTimeline.
147 std::optional<int32_t> getJankType() const;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700148
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800149 // Functions called by SF
150 int64_t getToken() const { return mToken; };
151 TimelineItem getPredictions() const { return mPredictions; };
Adithya Srinivasan5f683cf2020-09-15 14:21:04 -0700152 // Actual timestamps of the app are set individually at different functions.
153 // Start time (if the app provides) and Queue time are accessible after queueing the frame,
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700154 // whereas Acquire Fence time is available only during latch.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800155 void setActualStartTime(nsecs_t actualStartTime);
156 void setActualQueueTime(nsecs_t actualQueueTime);
157 void setAcquireFenceTime(nsecs_t acquireFenceTime);
158 void setPresentState(PresentState presentState, nsecs_t lastLatchTime = 0);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100159
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800160 // Functions called by FrameTimeline
161 // BaseTime is the smallest timestamp in this SurfaceFrame.
162 // Used for dumping all timestamps relative to the oldest, making it easy to read.
163 nsecs_t getBaseTime() const;
164 // Sets the actual present time, appropriate metadata and classifies the jank.
165 void onPresent(nsecs_t presentTime, int32_t displayFrameJankType, nsecs_t vsyncPeriod);
166 // All the timestamps are dumped relative to the baseTime
167 void dump(std::string& result, const std::string& indent, nsecs_t baseTime) const;
168 // Emits a packet for perfetto tracing. The function body will be executed only if tracing is
169 // enabled. The displayFrameToken is needed to link the SurfaceFrame to the corresponding
170 // DisplayFrame at the trace processor side.
171 void trace(int64_t displayFrameToken);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100172
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800173 // Getter functions used only by FrameTimelineTests
174 TimelineItem getActuals() const;
175 pid_t getOwnerPid() const { return mOwnerPid; };
176 PredictionState getPredictionState() const { return mPredictionState; };
177 PresentState getPresentState() const;
178 FrameReadyMetadata getFrameReadyMetadata() const;
179 FramePresentMetadata getFramePresentMetadata() const;
180
181private:
182 const int64_t mToken;
183 const pid_t mOwnerPid;
184 const uid_t mOwnerUid;
185 const std::string mLayerName;
186 const std::string mDebugName;
187 PresentState mPresentState GUARDED_BY(mMutex);
188 const PredictionState mPredictionState;
189 const TimelineItem mPredictions;
190 TimelineItem mActuals GUARDED_BY(mMutex);
191 std::shared_ptr<TimeStats> mTimeStats;
192 const JankClassificationThresholds mJankClassificationThresholds;
193 nsecs_t mActualQueueTime GUARDED_BY(mMutex) = 0;
194 mutable std::mutex mMutex;
195 // Bitmask for the type of jank
196 int32_t mJankType GUARDED_BY(mMutex) = JankType::None;
197 // Indicates if this frame was composited by the GPU or not
198 bool mGpuComposition GUARDED_BY(mMutex) = false;
199 // Enum for the type of present
200 FramePresentMetadata mFramePresentMetadata GUARDED_BY(mMutex) =
201 FramePresentMetadata::UnknownPresent;
202 // Enum for the type of finish
203 FrameReadyMetadata mFrameReadyMetadata GUARDED_BY(mMutex) = FrameReadyMetadata::UnknownFinish;
204 // Time when the previous buffer from the same layer was latched by SF. This is used in checking
205 // for BufferStuffing where the current buffer is expected to be ready but the previous buffer
206 // was latched instead.
207 nsecs_t mLastLatchTime GUARDED_BY(mMutex) = 0;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700208};
209
210/*
211 * Maintains a history of SurfaceFrames grouped together by the vsync time in which they were
212 * presented
213 */
214class FrameTimeline {
215public:
216 virtual ~FrameTimeline() = default;
Adithya Srinivasan5f683cf2020-09-15 14:21:04 -0700217 virtual TokenManager* getTokenManager() = 0;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700218
Adithya Srinivasan01189672020-10-20 14:23:05 -0700219 // Initializes the Perfetto DataSource that emits DisplayFrame and SurfaceFrame events. Test
220 // classes can avoid double registration by mocking this function.
221 virtual void onBootFinished() = 0;
222
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700223 // Create a new surface frame, set the predictions based on a token and return it to the caller.
Alec Mouri9a29e672020-09-14 12:39:14 -0700224 // Debug name is the human-readable debugging string for dumpsys.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800225 virtual std::shared_ptr<SurfaceFrame> createSurfaceFrameForToken(std::optional<int64_t> token,
226 pid_t ownerPid, uid_t ownerUid,
227 std::string layerName,
228 std::string debugName) = 0;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700229
230 // Adds a new SurfaceFrame to the current DisplayFrame. Frames from multiple layers can be
231 // composited into one display frame.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800232 virtual void addSurfaceFrame(std::shared_ptr<SurfaceFrame> surfaceFrame) = 0;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700233
234 // The first function called by SF for the current DisplayFrame. Fetches SF predictions based on
235 // the token and sets the actualSfWakeTime for the current DisplayFrame.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800236 virtual void setSfWakeUp(int64_t token, nsecs_t wakeupTime, nsecs_t vsyncPeriod) = 0;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700237
238 // Sets the sfPresentTime and finalizes the current DisplayFrame. Tracks the given present fence
239 // until it's signaled, and updates the present timestamps of all presented SurfaceFrames in
240 // that vsync.
241 virtual void setSfPresent(nsecs_t sfPresentTime,
242 const std::shared_ptr<FenceTime>& presentFence) = 0;
Adithya Srinivasan5f683cf2020-09-15 14:21:04 -0700243
Adithya Srinivasan8fc601d2020-09-25 13:51:09 -0700244 // Args:
245 // -jank : Dumps only the Display Frames that are either janky themselves
246 // or contain janky Surface Frames.
247 // -all : Dumps the entire list of DisplayFrames and the SurfaceFrames contained within
248 virtual void parseArgs(const Vector<String16>& args, std::string& result) = 0;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700249
250 // Sets the max number of display frames that can be stored. Called by SF backdoor.
251 virtual void setMaxDisplayFrames(uint32_t size);
252
253 // Restores the max number of display frames to default. Called by SF backdoor.
254 virtual void reset() = 0;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700255};
256
257namespace impl {
258
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700259class TokenManager : public android::frametimeline::TokenManager {
260public:
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700261 TokenManager() : mCurrentToken(ISurfaceComposer::INVALID_VSYNC_ID + 1) {}
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700262 ~TokenManager() = default;
263
264 int64_t generateTokenForPredictions(TimelineItem&& predictions) override;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800265 std::optional<TimelineItem> getPredictionsForToken(int64_t token) const override;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700266
267private:
268 // Friend class for testing
269 friend class android::frametimeline::FrameTimelineTest;
270
271 void flushTokens(nsecs_t flushTime) REQUIRES(mMutex);
272
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800273 std::map<int64_t, TokenManagerPrediction> mPredictions GUARDED_BY(mMutex);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700274 int64_t mCurrentToken GUARDED_BY(mMutex);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800275 mutable std::mutex mMutex;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700276 static constexpr nsecs_t kMaxRetentionTime =
277 std::chrono::duration_cast<std::chrono::nanoseconds>(120ms).count();
278};
279
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700280class FrameTimeline : public android::frametimeline::FrameTimeline {
281public:
Adithya Srinivasan01189672020-10-20 14:23:05 -0700282 class FrameTimelineDataSource : public perfetto::DataSource<FrameTimelineDataSource> {
283 void OnSetup(const SetupArgs&) override{};
284 void OnStart(const StartArgs&) override{};
285 void OnStop(const StopArgs&) override{};
286 };
287
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800288 /*
289 * DisplayFrame should be used only internally within FrameTimeline. All members and methods are
290 * guarded by FrameTimeline's mMutex.
291 */
292 class DisplayFrame {
293 public:
294 DisplayFrame(std::shared_ptr<TimeStats> timeStats, JankClassificationThresholds thresholds);
295 virtual ~DisplayFrame() = default;
296 // Dumpsys interface - dumps only if the DisplayFrame itself is janky or is at least one
297 // SurfaceFrame is janky.
298 void dumpJank(std::string& result, nsecs_t baseTime, int displayFrameCount) const;
299 // Dumpsys interface - dumps all data irrespective of jank
300 void dumpAll(std::string& result, nsecs_t baseTime) const;
301 // Emits a packet for perfetto tracing. The function body will be executed only if tracing
302 // is enabled.
303 void trace(pid_t surfaceFlingerPid) const;
304 // Sets the token, vsyncPeriod, predictions and SF start time.
305 void onSfWakeUp(int64_t token, nsecs_t vsyncPeriod, std::optional<TimelineItem> predictions,
306 nsecs_t wakeUpTime);
307 // Sets the appropriate metadata, classifies the jank and returns the classified jankType.
308 void onPresent(nsecs_t signalTime);
309 // Adds the provided SurfaceFrame to the current display frame.
310 void addSurfaceFrame(std::shared_ptr<SurfaceFrame> surfaceFrame);
311
312 void setTokenAndVsyncPeriod(int64_t token, nsecs_t vsyncPeriod);
313 void setPredictions(PredictionState predictionState, TimelineItem predictions);
314 void setActualStartTime(nsecs_t actualStartTime);
315 void setActualEndTime(nsecs_t actualEndTime);
316
317 // BaseTime is the smallest timestamp in a DisplayFrame.
318 // Used for dumping all timestamps relative to the oldest, making it easy to read.
319 nsecs_t getBaseTime() const;
320
321 // Functions to be used only in testing.
322 TimelineItem getActuals() const { return mSurfaceFlingerActuals; };
323 TimelineItem getPredictions() const { return mSurfaceFlingerPredictions; };
324 FramePresentMetadata getFramePresentMetadata() const { return mFramePresentMetadata; };
325 FrameReadyMetadata getFrameReadyMetadata() const { return mFrameReadyMetadata; };
326 int32_t getJankType() const { return mJankType; }
327 const std::vector<std::shared_ptr<SurfaceFrame>>& getSurfaceFrames() const {
328 return mSurfaceFrames;
329 }
330
331 private:
332 void dump(std::string& result, nsecs_t baseTime) const;
333
334 int64_t mToken = ISurfaceComposer::INVALID_VSYNC_ID;
335
336 /* Usage of TimelineItem w.r.t SurfaceFlinger
337 * startTime Time when SurfaceFlinger wakes up to handle transactions and buffer updates
338 * endTime Time when SurfaceFlinger sends a composited frame to Display
339 * presentTime Time when the composited frame was presented on screen
340 */
341 TimelineItem mSurfaceFlingerPredictions;
342 TimelineItem mSurfaceFlingerActuals;
343 std::shared_ptr<TimeStats> mTimeStats;
344 const JankClassificationThresholds mJankClassificationThresholds;
345
346 // Collection of predictions and actual values sent over by Layers
347 std::vector<std::shared_ptr<SurfaceFrame>> mSurfaceFrames;
348
349 PredictionState mPredictionState = PredictionState::None;
350 // Bitmask for the type of jank
351 int32_t mJankType = JankType::None;
352 // Indicates if this frame was composited by the GPU or not
353 bool mGpuComposition = false;
354 // Enum for the type of present
355 FramePresentMetadata mFramePresentMetadata = FramePresentMetadata::UnknownPresent;
356 // Enum for the type of finish
357 FrameReadyMetadata mFrameReadyMetadata = FrameReadyMetadata::UnknownFinish;
358 // Enum for the type of start
359 FrameStartMetadata mFrameStartMetadata = FrameStartMetadata::UnknownStart;
360 // The refresh rate (vsync period) in nanoseconds as seen by SF during this DisplayFrame's
361 // timeline
362 nsecs_t mVsyncPeriod = 0;
363 };
364
365 FrameTimeline(std::shared_ptr<TimeStats> timeStats, pid_t surfaceFlingerPid,
366 JankClassificationThresholds thresholds = {});
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700367 ~FrameTimeline() = default;
368
Adithya Srinivasan5f683cf2020-09-15 14:21:04 -0700369 frametimeline::TokenManager* getTokenManager() override { return &mTokenManager; }
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800370 std::shared_ptr<SurfaceFrame> createSurfaceFrameForToken(std::optional<int64_t> token,
371 pid_t ownerPid, uid_t ownerUid,
372 std::string layerName,
373 std::string debugName) override;
374 void addSurfaceFrame(std::shared_ptr<frametimeline::SurfaceFrame> surfaceFrame) override;
375 void setSfWakeUp(int64_t token, nsecs_t wakeupTime, nsecs_t vsyncPeriod) override;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700376 void setSfPresent(nsecs_t sfPresentTime,
377 const std::shared_ptr<FenceTime>& presentFence) override;
Adithya Srinivasan8fc601d2020-09-25 13:51:09 -0700378 void parseArgs(const Vector<String16>& args, std::string& result) override;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700379 void setMaxDisplayFrames(uint32_t size) override;
380 void reset() override;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700381
Adithya Srinivasan01189672020-10-20 14:23:05 -0700382 // Sets up the perfetto tracing backend and data source.
383 void onBootFinished() override;
384 // Registers the data source with the perfetto backend. Called as part of onBootFinished()
385 // and should not be called manually outside of tests.
386 void registerDataSource();
387
388 static constexpr char kFrameTimelineDataSource[] = "android.surfaceflinger.frametimeline";
389
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700390private:
391 // Friend class for testing
392 friend class android::frametimeline::FrameTimelineTest;
393
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700394 void flushPendingPresentFences() REQUIRES(mMutex);
395 void finalizeCurrentDisplayFrame() REQUIRES(mMutex);
Adithya Srinivasan8fc601d2020-09-25 13:51:09 -0700396 void dumpAll(std::string& result);
397 void dumpJank(std::string& result);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700398
399 // Sliding window of display frames. TODO(b/168072834): compare perf with fixed size array
400 std::deque<std::shared_ptr<DisplayFrame>> mDisplayFrames GUARDED_BY(mMutex);
401 std::vector<std::pair<std::shared_ptr<FenceTime>, std::shared_ptr<DisplayFrame>>>
402 mPendingPresentFences GUARDED_BY(mMutex);
403 std::shared_ptr<DisplayFrame> mCurrentDisplayFrame GUARDED_BY(mMutex);
404 TokenManager mTokenManager;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800405 mutable std::mutex mMutex;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700406 uint32_t mMaxDisplayFrames;
Alec Mouri9a29e672020-09-14 12:39:14 -0700407 std::shared_ptr<TimeStats> mTimeStats;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800408 const pid_t mSurfaceFlingerPid;
409 const JankClassificationThresholds mJankClassificationThresholds;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700410 static constexpr uint32_t kDefaultMaxDisplayFrames = 64;
Adithya Srinivasan01189672020-10-20 14:23:05 -0700411 // The initial container size for the vector<SurfaceFrames> inside display frame. Although
412 // this number doesn't represent any bounds on the number of surface frames that can go in a
413 // display frame, this is a good starting size for the vector so that we can avoid the
414 // internal vector resizing that happens with push_back.
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700415 static constexpr uint32_t kNumSurfaceFramesInitial = 10;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700416};
417
418} // namespace impl
419} // namespace android::frametimeline