xref: /aosp_15_r20/frameworks/native/services/surfaceflinger/TimeStats/TimeStats.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2018 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #pragma once
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <cstdint>
20*38e8c45fSAndroid Build Coastguard Worker #include <deque>
21*38e8c45fSAndroid Build Coastguard Worker #include <mutex>
22*38e8c45fSAndroid Build Coastguard Worker #include <optional>
23*38e8c45fSAndroid Build Coastguard Worker #include <unordered_map>
24*38e8c45fSAndroid Build Coastguard Worker #include <variant>
25*38e8c45fSAndroid Build Coastguard Worker 
26*38e8c45fSAndroid Build Coastguard Worker #include <android/hardware/graphics/composer/2.4/IComposerClient.h>
27*38e8c45fSAndroid Build Coastguard Worker #include <gui/JankInfo.h>
28*38e8c45fSAndroid Build Coastguard Worker #include <gui/LayerMetadata.h>
29*38e8c45fSAndroid Build Coastguard Worker #include <timestatsproto/TimeStatsHelper.h>
30*38e8c45fSAndroid Build Coastguard Worker #include <timestatsproto/TimeStatsProtoHeader.h>
31*38e8c45fSAndroid Build Coastguard Worker #include <ui/FenceTime.h>
32*38e8c45fSAndroid Build Coastguard Worker #include <utils/String16.h>
33*38e8c45fSAndroid Build Coastguard Worker #include <utils/Vector.h>
34*38e8c45fSAndroid Build Coastguard Worker 
35*38e8c45fSAndroid Build Coastguard Worker #include <scheduler/Fps.h>
36*38e8c45fSAndroid Build Coastguard Worker 
37*38e8c45fSAndroid Build Coastguard Worker using android::gui::GameMode;
38*38e8c45fSAndroid Build Coastguard Worker using android::gui::LayerMetadata;
39*38e8c45fSAndroid Build Coastguard Worker using namespace android::surfaceflinger;
40*38e8c45fSAndroid Build Coastguard Worker 
41*38e8c45fSAndroid Build Coastguard Worker namespace android {
42*38e8c45fSAndroid Build Coastguard Worker 
43*38e8c45fSAndroid Build Coastguard Worker class TimeStats {
44*38e8c45fSAndroid Build Coastguard Worker public:
45*38e8c45fSAndroid Build Coastguard Worker     using SetFrameRateVote = TimeStatsHelper::SetFrameRateVote;
46*38e8c45fSAndroid Build Coastguard Worker 
47*38e8c45fSAndroid Build Coastguard Worker     virtual ~TimeStats() = default;
48*38e8c45fSAndroid Build Coastguard Worker 
49*38e8c45fSAndroid Build Coastguard Worker     // Process a pull request from statsd.
50*38e8c45fSAndroid Build Coastguard Worker     virtual bool onPullAtom(const int atomId, std::vector<uint8_t>* pulledData) = 0;
51*38e8c45fSAndroid Build Coastguard Worker 
52*38e8c45fSAndroid Build Coastguard Worker     virtual void parseArgs(bool asProto, const Vector<String16>& args, std::string& result) = 0;
53*38e8c45fSAndroid Build Coastguard Worker     virtual bool isEnabled() = 0;
54*38e8c45fSAndroid Build Coastguard Worker     virtual std::string miniDump() = 0;
55*38e8c45fSAndroid Build Coastguard Worker 
56*38e8c45fSAndroid Build Coastguard Worker     virtual void incrementTotalFrames() = 0;
57*38e8c45fSAndroid Build Coastguard Worker     virtual void incrementMissedFrames() = 0;
58*38e8c45fSAndroid Build Coastguard Worker     // Increments the number of times the display refresh rate changed.
59*38e8c45fSAndroid Build Coastguard Worker     virtual void incrementRefreshRateSwitches() = 0;
60*38e8c45fSAndroid Build Coastguard Worker 
61*38e8c45fSAndroid Build Coastguard Worker     // Records the start and end times for a frame.
62*38e8c45fSAndroid Build Coastguard Worker     // The start time is the same as the beginning of a SurfaceFlinger
63*38e8c45fSAndroid Build Coastguard Worker     // invalidate message.
64*38e8c45fSAndroid Build Coastguard Worker     // The end time corresponds to when SurfaceFlinger finishes submitting the
65*38e8c45fSAndroid Build Coastguard Worker     // request to HWC to present a frame.
66*38e8c45fSAndroid Build Coastguard Worker     virtual void recordFrameDuration(nsecs_t startTime, nsecs_t endTime) = 0;
67*38e8c45fSAndroid Build Coastguard Worker     // Records the start time and end times for when RenderEngine begins work.
68*38e8c45fSAndroid Build Coastguard Worker     // The start time corresponds to the beginning of RenderEngine::drawLayers.
69*38e8c45fSAndroid Build Coastguard Worker     // The end time corresponds to when RenderEngine finishes rendering.
70*38e8c45fSAndroid Build Coastguard Worker     virtual void recordRenderEngineDuration(nsecs_t startTime, nsecs_t endTime) = 0;
71*38e8c45fSAndroid Build Coastguard Worker     // Same as above, but passes in a fence representing the end time.
72*38e8c45fSAndroid Build Coastguard Worker     virtual void recordRenderEngineDuration(nsecs_t startTime,
73*38e8c45fSAndroid Build Coastguard Worker                                             const std::shared_ptr<FenceTime>& readyFence) = 0;
74*38e8c45fSAndroid Build Coastguard Worker 
75*38e8c45fSAndroid Build Coastguard Worker     virtual void setPostTime(int32_t layerId, uint64_t frameNumber, const std::string& layerName,
76*38e8c45fSAndroid Build Coastguard Worker                              uid_t uid, nsecs_t postTime, GameMode) = 0;
77*38e8c45fSAndroid Build Coastguard Worker     virtual void setLatchTime(int32_t layerId, uint64_t frameNumber, nsecs_t latchTime) = 0;
78*38e8c45fSAndroid Build Coastguard Worker     // Reasons why latching a particular buffer may be skipped
79*38e8c45fSAndroid Build Coastguard Worker     enum class LatchSkipReason {
80*38e8c45fSAndroid Build Coastguard Worker         // If the acquire fence did not fire on some devices we skip latching
81*38e8c45fSAndroid Build Coastguard Worker         // the buffer until the fence fires.
82*38e8c45fSAndroid Build Coastguard Worker         LateAcquire,
83*38e8c45fSAndroid Build Coastguard Worker     };
84*38e8c45fSAndroid Build Coastguard Worker     // Increments the counter of skipped latch buffers.
85*38e8c45fSAndroid Build Coastguard Worker     virtual void incrementLatchSkipped(int32_t layerId, LatchSkipReason reason) = 0;
86*38e8c45fSAndroid Build Coastguard Worker     // Increments the counter of bad desired present times for this layer.
87*38e8c45fSAndroid Build Coastguard Worker     // Bad desired present times are "implausible" and cause SurfaceFlinger to
88*38e8c45fSAndroid Build Coastguard Worker     // latch a buffer immediately to avoid stalling.
89*38e8c45fSAndroid Build Coastguard Worker     virtual void incrementBadDesiredPresent(int32_t layerId) = 0;
90*38e8c45fSAndroid Build Coastguard Worker     virtual void setDesiredTime(int32_t layerId, uint64_t frameNumber, nsecs_t desiredTime) = 0;
91*38e8c45fSAndroid Build Coastguard Worker     virtual void setAcquireTime(int32_t layerId, uint64_t frameNumber, nsecs_t acquireTime) = 0;
92*38e8c45fSAndroid Build Coastguard Worker     virtual void setAcquireFence(int32_t layerId, uint64_t frameNumber,
93*38e8c45fSAndroid Build Coastguard Worker                                  const std::shared_ptr<FenceTime>& acquireFence) = 0;
94*38e8c45fSAndroid Build Coastguard Worker     // SetPresent{Time, Fence} are not expected to be called in the critical
95*38e8c45fSAndroid Build Coastguard Worker     // rendering path, as they flush prior fences if those fences have fired.
96*38e8c45fSAndroid Build Coastguard Worker     virtual void setPresentTime(int32_t layerId, uint64_t frameNumber, nsecs_t presentTime,
97*38e8c45fSAndroid Build Coastguard Worker                                 Fps displayRefreshRate, std::optional<Fps> renderRate,
98*38e8c45fSAndroid Build Coastguard Worker                                 SetFrameRateVote frameRateVote, GameMode) = 0;
99*38e8c45fSAndroid Build Coastguard Worker     virtual void setPresentFence(int32_t layerId, uint64_t frameNumber,
100*38e8c45fSAndroid Build Coastguard Worker                                  const std::shared_ptr<FenceTime>& presentFence,
101*38e8c45fSAndroid Build Coastguard Worker                                  Fps displayRefreshRate, std::optional<Fps> renderRate,
102*38e8c45fSAndroid Build Coastguard Worker                                  SetFrameRateVote frameRateVote, GameMode) = 0;
103*38e8c45fSAndroid Build Coastguard Worker 
104*38e8c45fSAndroid Build Coastguard Worker     // Increments janky frames, blamed to the provided {refreshRate, renderRate, uid, layerName}
105*38e8c45fSAndroid Build Coastguard Worker     // key, with JankMetadata as supplementary reasons for the jank. Because FrameTimeline is the
106*38e8c45fSAndroid Build Coastguard Worker     // infrastructure responsible for computing jank in the system, this is expected to be called
107*38e8c45fSAndroid Build Coastguard Worker     // from FrameTimeline, rather than directly from SurfaceFlinger or individual layers. If there
108*38e8c45fSAndroid Build Coastguard Worker     // are no jank reasons, then total frames are incremented but jank is not, for accurate
109*38e8c45fSAndroid Build Coastguard Worker     // accounting of janky frames.
110*38e8c45fSAndroid Build Coastguard Worker     // displayDeadlineDelta, displayPresentJitter, and appDeadlineDelta are also provided in order
111*38e8c45fSAndroid Build Coastguard Worker     // to provide contextual information about a janky frame. These values may only be uploaded if
112*38e8c45fSAndroid Build Coastguard Worker     // there was an associated valid jank reason, and they must be positive. When these frame counts
113*38e8c45fSAndroid Build Coastguard Worker     // are incremented, these are also aggregated into a global reporting packet to help with data
114*38e8c45fSAndroid Build Coastguard Worker     // validation and assessing of overall device health.
115*38e8c45fSAndroid Build Coastguard Worker     struct JankyFramesInfo {
116*38e8c45fSAndroid Build Coastguard Worker         Fps refreshRate;
117*38e8c45fSAndroid Build Coastguard Worker         std::optional<Fps> renderRate;
118*38e8c45fSAndroid Build Coastguard Worker         uid_t uid = 0;
119*38e8c45fSAndroid Build Coastguard Worker         std::string layerName;
120*38e8c45fSAndroid Build Coastguard Worker         GameMode gameMode = GameMode::Unsupported;
121*38e8c45fSAndroid Build Coastguard Worker         int32_t reasons = 0;
122*38e8c45fSAndroid Build Coastguard Worker         nsecs_t displayDeadlineDelta = 0;
123*38e8c45fSAndroid Build Coastguard Worker         nsecs_t displayPresentJitter = 0;
124*38e8c45fSAndroid Build Coastguard Worker         nsecs_t appDeadlineDelta = 0;
125*38e8c45fSAndroid Build Coastguard Worker 
isOptApproxEqualJankyFramesInfo126*38e8c45fSAndroid Build Coastguard Worker         static bool isOptApproxEqual(std::optional<Fps> lhs, std::optional<Fps> rhs) {
127*38e8c45fSAndroid Build Coastguard Worker             return (!lhs && !rhs) || (lhs && rhs && isApproxEqual(*lhs, *rhs));
128*38e8c45fSAndroid Build Coastguard Worker         }
129*38e8c45fSAndroid Build Coastguard Worker 
130*38e8c45fSAndroid Build Coastguard Worker         bool operator==(const JankyFramesInfo& o) const {
131*38e8c45fSAndroid Build Coastguard Worker             return isApproxEqual(refreshRate, o.refreshRate) &&
132*38e8c45fSAndroid Build Coastguard Worker                     isOptApproxEqual(renderRate, o.renderRate) && uid == o.uid &&
133*38e8c45fSAndroid Build Coastguard Worker                     layerName == o.layerName && gameMode == o.gameMode && reasons == o.reasons &&
134*38e8c45fSAndroid Build Coastguard Worker                     displayDeadlineDelta == o.displayDeadlineDelta &&
135*38e8c45fSAndroid Build Coastguard Worker                     displayPresentJitter == o.displayPresentJitter &&
136*38e8c45fSAndroid Build Coastguard Worker                     appDeadlineDelta == o.appDeadlineDelta;
137*38e8c45fSAndroid Build Coastguard Worker         }
138*38e8c45fSAndroid Build Coastguard Worker 
139*38e8c45fSAndroid Build Coastguard Worker         friend std::ostream& operator<<(std::ostream& os, const JankyFramesInfo& info) {
140*38e8c45fSAndroid Build Coastguard Worker             os << "JankyFramesInfo {";
141*38e8c45fSAndroid Build Coastguard Worker             os << "\n    .refreshRate = " << info.refreshRate;
142*38e8c45fSAndroid Build Coastguard Worker             os << "\n    .renderRate = "
143*38e8c45fSAndroid Build Coastguard Worker                << (info.renderRate ? to_string(*info.renderRate) : "nullopt");
144*38e8c45fSAndroid Build Coastguard Worker             os << "\n    .uid = " << info.uid;
145*38e8c45fSAndroid Build Coastguard Worker             os << "\n    .layerName = " << info.layerName;
146*38e8c45fSAndroid Build Coastguard Worker             os << "\n    .reasons = " << info.reasons;
147*38e8c45fSAndroid Build Coastguard Worker             os << "\n    .displayDeadlineDelta = " << info.displayDeadlineDelta;
148*38e8c45fSAndroid Build Coastguard Worker             os << "\n    .displayPresentJitter = " << info.displayPresentJitter;
149*38e8c45fSAndroid Build Coastguard Worker             os << "\n    .appDeadlineDelta = " << info.appDeadlineDelta;
150*38e8c45fSAndroid Build Coastguard Worker             return os << "\n}";
151*38e8c45fSAndroid Build Coastguard Worker         }
152*38e8c45fSAndroid Build Coastguard Worker     };
153*38e8c45fSAndroid Build Coastguard Worker 
154*38e8c45fSAndroid Build Coastguard Worker     struct ClientCompositionRecord {
155*38e8c45fSAndroid Build Coastguard Worker         // Frame had client composition or mixed composition
156*38e8c45fSAndroid Build Coastguard Worker         bool hadClientComposition = false;
157*38e8c45fSAndroid Build Coastguard Worker         // Composition changed between hw composition and mixed/client composition
158*38e8c45fSAndroid Build Coastguard Worker         bool changed = false;
159*38e8c45fSAndroid Build Coastguard Worker         // Frame reused the client composition result from a previous frame
160*38e8c45fSAndroid Build Coastguard Worker         bool reused = false;
161*38e8c45fSAndroid Build Coastguard Worker         // Composition strategy predicted for frame
162*38e8c45fSAndroid Build Coastguard Worker         bool predicted = false;
163*38e8c45fSAndroid Build Coastguard Worker         // Composition strategy prediction succeeded
164*38e8c45fSAndroid Build Coastguard Worker         bool predictionSucceeded = false;
165*38e8c45fSAndroid Build Coastguard Worker 
166*38e8c45fSAndroid Build Coastguard Worker         // Whether there is data we want to record.
hasInterestingDataClientCompositionRecord167*38e8c45fSAndroid Build Coastguard Worker         bool hasInterestingData() const {
168*38e8c45fSAndroid Build Coastguard Worker             return hadClientComposition || changed || reused || predicted;
169*38e8c45fSAndroid Build Coastguard Worker         }
170*38e8c45fSAndroid Build Coastguard Worker     };
171*38e8c45fSAndroid Build Coastguard Worker 
172*38e8c45fSAndroid Build Coastguard Worker     virtual void incrementJankyFrames(const JankyFramesInfo& info) = 0;
173*38e8c45fSAndroid Build Coastguard Worker     // Clean up the layer record
174*38e8c45fSAndroid Build Coastguard Worker     virtual void onDestroy(int32_t layerId) = 0;
175*38e8c45fSAndroid Build Coastguard Worker     // If SF skips or rejects a buffer, remove the corresponding TimeRecord.
176*38e8c45fSAndroid Build Coastguard Worker     virtual void removeTimeRecord(int32_t layerId, uint64_t frameNumber) = 0;
177*38e8c45fSAndroid Build Coastguard Worker 
178*38e8c45fSAndroid Build Coastguard Worker     virtual void setPowerMode(
179*38e8c45fSAndroid Build Coastguard Worker             hardware::graphics::composer::V2_4::IComposerClient::PowerMode powerMode) = 0;
180*38e8c45fSAndroid Build Coastguard Worker     // Source of truth is RefrehRateStats.
181*38e8c45fSAndroid Build Coastguard Worker     virtual void recordRefreshRate(uint32_t fps, nsecs_t duration) = 0;
182*38e8c45fSAndroid Build Coastguard Worker     virtual void setPresentFenceGlobal(const std::shared_ptr<FenceTime>& presentFence) = 0;
183*38e8c45fSAndroid Build Coastguard Worker     virtual void pushCompositionStrategyState(const ClientCompositionRecord&) = 0;
184*38e8c45fSAndroid Build Coastguard Worker };
185*38e8c45fSAndroid Build Coastguard Worker 
186*38e8c45fSAndroid Build Coastguard Worker namespace impl {
187*38e8c45fSAndroid Build Coastguard Worker 
188*38e8c45fSAndroid Build Coastguard Worker class TimeStats : public android::TimeStats {
189*38e8c45fSAndroid Build Coastguard Worker     using PowerMode = android::hardware::graphics::composer::V2_4::IComposerClient::PowerMode;
190*38e8c45fSAndroid Build Coastguard Worker 
191*38e8c45fSAndroid Build Coastguard Worker     struct FrameTime {
192*38e8c45fSAndroid Build Coastguard Worker         uint64_t frameNumber = 0;
193*38e8c45fSAndroid Build Coastguard Worker         nsecs_t postTime = 0;
194*38e8c45fSAndroid Build Coastguard Worker         nsecs_t latchTime = 0;
195*38e8c45fSAndroid Build Coastguard Worker         nsecs_t acquireTime = 0;
196*38e8c45fSAndroid Build Coastguard Worker         nsecs_t desiredTime = 0;
197*38e8c45fSAndroid Build Coastguard Worker         nsecs_t presentTime = 0;
198*38e8c45fSAndroid Build Coastguard Worker     };
199*38e8c45fSAndroid Build Coastguard Worker 
200*38e8c45fSAndroid Build Coastguard Worker     struct TimeRecord {
201*38e8c45fSAndroid Build Coastguard Worker         bool ready = false;
202*38e8c45fSAndroid Build Coastguard Worker         FrameTime frameTime;
203*38e8c45fSAndroid Build Coastguard Worker         std::shared_ptr<FenceTime> acquireFence;
204*38e8c45fSAndroid Build Coastguard Worker         std::shared_ptr<FenceTime> presentFence;
205*38e8c45fSAndroid Build Coastguard Worker     };
206*38e8c45fSAndroid Build Coastguard Worker 
207*38e8c45fSAndroid Build Coastguard Worker     struct LayerRecord {
208*38e8c45fSAndroid Build Coastguard Worker         uid_t uid;
209*38e8c45fSAndroid Build Coastguard Worker         std::string layerName;
210*38e8c45fSAndroid Build Coastguard Worker         GameMode gameMode = GameMode::Unsupported;
211*38e8c45fSAndroid Build Coastguard Worker         // This is the index in timeRecords, at which the timestamps for that
212*38e8c45fSAndroid Build Coastguard Worker         // specific frame are still not fully received. This is not waiting for
213*38e8c45fSAndroid Build Coastguard Worker         // fences to signal, but rather waiting to receive those fences/timestamps.
214*38e8c45fSAndroid Build Coastguard Worker         int32_t waitData = -1;
215*38e8c45fSAndroid Build Coastguard Worker         uint32_t droppedFrames = 0;
216*38e8c45fSAndroid Build Coastguard Worker         uint32_t lateAcquireFrames = 0;
217*38e8c45fSAndroid Build Coastguard Worker         uint32_t badDesiredPresentFrames = 0;
218*38e8c45fSAndroid Build Coastguard Worker         TimeRecord prevTimeRecord;
219*38e8c45fSAndroid Build Coastguard Worker         std::optional<int32_t> prevPresentToPresentMs;
220*38e8c45fSAndroid Build Coastguard Worker         std::deque<TimeRecord> timeRecords;
221*38e8c45fSAndroid Build Coastguard Worker     };
222*38e8c45fSAndroid Build Coastguard Worker 
223*38e8c45fSAndroid Build Coastguard Worker     struct PowerTime {
224*38e8c45fSAndroid Build Coastguard Worker         PowerMode powerMode = PowerMode::OFF;
225*38e8c45fSAndroid Build Coastguard Worker         nsecs_t prevTime = 0;
226*38e8c45fSAndroid Build Coastguard Worker     };
227*38e8c45fSAndroid Build Coastguard Worker 
228*38e8c45fSAndroid Build Coastguard Worker     struct RenderEngineDuration {
229*38e8c45fSAndroid Build Coastguard Worker         nsecs_t startTime;
230*38e8c45fSAndroid Build Coastguard Worker         std::variant<nsecs_t, std::shared_ptr<FenceTime>> endTime;
231*38e8c45fSAndroid Build Coastguard Worker     };
232*38e8c45fSAndroid Build Coastguard Worker 
233*38e8c45fSAndroid Build Coastguard Worker     struct GlobalRecord {
234*38e8c45fSAndroid Build Coastguard Worker         nsecs_t prevPresentTime = 0;
235*38e8c45fSAndroid Build Coastguard Worker         std::deque<std::shared_ptr<FenceTime>> presentFences;
236*38e8c45fSAndroid Build Coastguard Worker         std::deque<RenderEngineDuration> renderEngineDurations;
237*38e8c45fSAndroid Build Coastguard Worker     };
238*38e8c45fSAndroid Build Coastguard Worker 
239*38e8c45fSAndroid Build Coastguard Worker public:
240*38e8c45fSAndroid Build Coastguard Worker     TimeStats();
241*38e8c45fSAndroid Build Coastguard Worker     // For testing only for injecting custom dependencies.
242*38e8c45fSAndroid Build Coastguard Worker     TimeStats(std::optional<size_t> maxPulledLayers,
243*38e8c45fSAndroid Build Coastguard Worker               std::optional<size_t> maxPulledHistogramBuckets);
244*38e8c45fSAndroid Build Coastguard Worker 
245*38e8c45fSAndroid Build Coastguard Worker     bool onPullAtom(const int atomId, std::vector<uint8_t>* pulledData) override;
246*38e8c45fSAndroid Build Coastguard Worker     void parseArgs(bool asProto, const Vector<String16>& args, std::string& result) override;
247*38e8c45fSAndroid Build Coastguard Worker     bool isEnabled() override;
248*38e8c45fSAndroid Build Coastguard Worker     std::string miniDump() override;
249*38e8c45fSAndroid Build Coastguard Worker 
250*38e8c45fSAndroid Build Coastguard Worker     void incrementTotalFrames() override;
251*38e8c45fSAndroid Build Coastguard Worker     void incrementMissedFrames() override;
252*38e8c45fSAndroid Build Coastguard Worker     void incrementRefreshRateSwitches() override;
253*38e8c45fSAndroid Build Coastguard Worker 
254*38e8c45fSAndroid Build Coastguard Worker     void recordFrameDuration(nsecs_t startTime, nsecs_t endTime) override;
255*38e8c45fSAndroid Build Coastguard Worker     void recordRenderEngineDuration(nsecs_t startTime, nsecs_t endTime) override;
256*38e8c45fSAndroid Build Coastguard Worker     void recordRenderEngineDuration(nsecs_t startTime,
257*38e8c45fSAndroid Build Coastguard Worker                                     const std::shared_ptr<FenceTime>& readyFence) override;
258*38e8c45fSAndroid Build Coastguard Worker 
259*38e8c45fSAndroid Build Coastguard Worker     void setPostTime(int32_t layerId, uint64_t frameNumber, const std::string& layerName, uid_t uid,
260*38e8c45fSAndroid Build Coastguard Worker                      nsecs_t postTime, GameMode) override;
261*38e8c45fSAndroid Build Coastguard Worker     void setLatchTime(int32_t layerId, uint64_t frameNumber, nsecs_t latchTime) override;
262*38e8c45fSAndroid Build Coastguard Worker     void incrementLatchSkipped(int32_t layerId, LatchSkipReason reason) override;
263*38e8c45fSAndroid Build Coastguard Worker     void incrementBadDesiredPresent(int32_t layerId) override;
264*38e8c45fSAndroid Build Coastguard Worker     void setDesiredTime(int32_t layerId, uint64_t frameNumber, nsecs_t desiredTime) override;
265*38e8c45fSAndroid Build Coastguard Worker     void setAcquireTime(int32_t layerId, uint64_t frameNumber, nsecs_t acquireTime) override;
266*38e8c45fSAndroid Build Coastguard Worker     void setAcquireFence(int32_t layerId, uint64_t frameNumber,
267*38e8c45fSAndroid Build Coastguard Worker                          const std::shared_ptr<FenceTime>& acquireFence) override;
268*38e8c45fSAndroid Build Coastguard Worker     void setPresentTime(int32_t layerId, uint64_t frameNumber, nsecs_t presentTime,
269*38e8c45fSAndroid Build Coastguard Worker                         Fps displayRefreshRate, std::optional<Fps> renderRate, SetFrameRateVote,
270*38e8c45fSAndroid Build Coastguard Worker                         GameMode) override;
271*38e8c45fSAndroid Build Coastguard Worker     void setPresentFence(int32_t layerId, uint64_t frameNumber,
272*38e8c45fSAndroid Build Coastguard Worker                          const std::shared_ptr<FenceTime>& presentFence, Fps displayRefreshRate,
273*38e8c45fSAndroid Build Coastguard Worker                          std::optional<Fps> renderRate, SetFrameRateVote, GameMode) override;
274*38e8c45fSAndroid Build Coastguard Worker 
275*38e8c45fSAndroid Build Coastguard Worker     void incrementJankyFrames(const JankyFramesInfo& info) override;
276*38e8c45fSAndroid Build Coastguard Worker     // Clean up the layer record
277*38e8c45fSAndroid Build Coastguard Worker     void onDestroy(int32_t layerId) override;
278*38e8c45fSAndroid Build Coastguard Worker     // If SF skips or rejects a buffer, remove the corresponding TimeRecord.
279*38e8c45fSAndroid Build Coastguard Worker     void removeTimeRecord(int32_t layerId, uint64_t frameNumber) override;
280*38e8c45fSAndroid Build Coastguard Worker 
281*38e8c45fSAndroid Build Coastguard Worker     void setPowerMode(
282*38e8c45fSAndroid Build Coastguard Worker             hardware::graphics::composer::V2_4::IComposerClient::PowerMode powerMode) override;
283*38e8c45fSAndroid Build Coastguard Worker     // Source of truth is RefrehRateStats.
284*38e8c45fSAndroid Build Coastguard Worker     void recordRefreshRate(uint32_t fps, nsecs_t duration) override;
285*38e8c45fSAndroid Build Coastguard Worker     void setPresentFenceGlobal(const std::shared_ptr<FenceTime>& presentFence) override;
286*38e8c45fSAndroid Build Coastguard Worker 
287*38e8c45fSAndroid Build Coastguard Worker     void pushCompositionStrategyState(const ClientCompositionRecord&) override;
288*38e8c45fSAndroid Build Coastguard Worker 
289*38e8c45fSAndroid Build Coastguard Worker     static const size_t MAX_NUM_TIME_RECORDS = 64;
290*38e8c45fSAndroid Build Coastguard Worker 
291*38e8c45fSAndroid Build Coastguard Worker private:
292*38e8c45fSAndroid Build Coastguard Worker     bool populateGlobalAtom(std::vector<uint8_t>* pulledData);
293*38e8c45fSAndroid Build Coastguard Worker     bool populateLayerAtom(std::vector<uint8_t>* pulledData);
294*38e8c45fSAndroid Build Coastguard Worker     bool recordReadyLocked(int32_t layerId, TimeRecord* timeRecord);
295*38e8c45fSAndroid Build Coastguard Worker     void flushAvailableRecordsToStatsLocked(int32_t layerId, Fps displayRefreshRate,
296*38e8c45fSAndroid Build Coastguard Worker                                             std::optional<Fps> renderRate, SetFrameRateVote,
297*38e8c45fSAndroid Build Coastguard Worker                                             GameMode);
298*38e8c45fSAndroid Build Coastguard Worker     void flushPowerTimeLocked();
299*38e8c45fSAndroid Build Coastguard Worker     void flushAvailableGlobalRecordsToStatsLocked();
300*38e8c45fSAndroid Build Coastguard Worker     bool canAddNewAggregatedStats(uid_t uid, const std::string& layerName, GameMode);
301*38e8c45fSAndroid Build Coastguard Worker 
302*38e8c45fSAndroid Build Coastguard Worker     void enable();
303*38e8c45fSAndroid Build Coastguard Worker     void disable();
304*38e8c45fSAndroid Build Coastguard Worker     void clearAll();
305*38e8c45fSAndroid Build Coastguard Worker     void clearGlobalLocked();
306*38e8c45fSAndroid Build Coastguard Worker     void clearLayersLocked();
307*38e8c45fSAndroid Build Coastguard Worker     void dump(bool asProto, std::optional<uint32_t> maxLayers, std::string& result);
308*38e8c45fSAndroid Build Coastguard Worker 
309*38e8c45fSAndroid Build Coastguard Worker     std::atomic<bool> mEnabled = false;
310*38e8c45fSAndroid Build Coastguard Worker     std::mutex mMutex;
311*38e8c45fSAndroid Build Coastguard Worker     TimeStatsHelper::TimeStatsGlobal mTimeStats;
312*38e8c45fSAndroid Build Coastguard Worker     // Hashmap for LayerRecord with layerId as the hash key
313*38e8c45fSAndroid Build Coastguard Worker     std::unordered_map<int32_t, LayerRecord> mTimeStatsTracker;
314*38e8c45fSAndroid Build Coastguard Worker     PowerTime mPowerTime;
315*38e8c45fSAndroid Build Coastguard Worker     GlobalRecord mGlobalRecord;
316*38e8c45fSAndroid Build Coastguard Worker 
317*38e8c45fSAndroid Build Coastguard Worker     static const size_t MAX_NUM_LAYER_RECORDS = 200;
318*38e8c45fSAndroid Build Coastguard Worker 
319*38e8c45fSAndroid Build Coastguard Worker     static const size_t REFRESH_RATE_BUCKET_WIDTH = 30;
320*38e8c45fSAndroid Build Coastguard Worker     static const size_t RENDER_RATE_BUCKET_WIDTH = REFRESH_RATE_BUCKET_WIDTH;
321*38e8c45fSAndroid Build Coastguard Worker     static const size_t MAX_NUM_LAYER_STATS = 200;
322*38e8c45fSAndroid Build Coastguard Worker     static const size_t MAX_NUM_PULLED_LAYERS = MAX_NUM_LAYER_STATS;
323*38e8c45fSAndroid Build Coastguard Worker     size_t mMaxPulledLayers = MAX_NUM_PULLED_LAYERS;
324*38e8c45fSAndroid Build Coastguard Worker     size_t mMaxPulledHistogramBuckets = 6;
325*38e8c45fSAndroid Build Coastguard Worker };
326*38e8c45fSAndroid Build Coastguard Worker 
327*38e8c45fSAndroid Build Coastguard Worker } // namespace impl
328*38e8c45fSAndroid Build Coastguard Worker 
329*38e8c45fSAndroid Build Coastguard Worker } // namespace android
330