• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef ROSEN_JANK_STATS_H
17 #define ROSEN_JANK_STATS_H
18 
19 #include <cstdint>
20 #include <map>
21 #include <mutex>
22 #include <queue>
23 #include <string>
24 #include <tuple>
25 #include <utility>
26 #include <vector>
27 
28 #include "nocopyable.h"
29 #include "transaction/rs_render_service_client.h"
30 #include "platform/common/rs_system_properties.h"
31 
32 namespace OHOS {
33 namespace Rosen {
34 constexpr uint32_t STANDARD_REFRESH_RATE = 60;
35 constexpr uint32_t MAX_REFRESH_RATE_TO_OPTIMIZE_JANK_LOAD = 90;
36 constexpr int64_t TIMESTAMP_INITIAL = -1;
37 constexpr int32_t TRACE_ID_INITIAL = -1;
38 constexpr float TIMESTAMP_INITIAL_FLOAT = -1.f;
39 constexpr float MS_TO_US = 1000.f; // ms to us
40 constexpr std::string_view SWITCH_SCENE_NAME = "ABILITY_OR_PAGE_SWITCH";
41 
42 struct JankFrames {
43     bool isSetReportEventResponse_ = false;
44     bool isSetReportEventResponseTemp_ = false;
45     bool isSetReportEventComplete_ = false;
46     bool isSetReportEventJankFrame_ = false;
47     bool isReportEventResponse_ = false;
48     bool isReportEventComplete_ = false;
49     bool isReportEventJankFrame_ = false;
50     bool isUpdateJankFrame_ = false;
51     bool isFirstFrame_ = false;
52     bool isFirstFrameTemp_ = false;
53     bool isFrameRateRecorded_ = false;
54     bool isAnimationEnded_ = false;
55     bool isDisplayAnimator_ = false;
56     bool isAnimationInterrupted_ = false;
57     int64_t setTimeSteady_ = TIMESTAMP_INITIAL;
58     int64_t startTime_ = TIMESTAMP_INITIAL;
59     int64_t traceCreateTime_ = TIMESTAMP_INITIAL;
60     int64_t traceCreateTimeSteady_ = TIMESTAMP_INITIAL;
61     int64_t traceTerminateTime_ = TIMESTAMP_INITIAL;
62     int64_t traceTerminateTimeSteady_ = TIMESTAMP_INITIAL;
63     int64_t maxFrameOccurenceTimeSteady_ = TIMESTAMP_INITIAL;
64     int64_t lastMaxFrameOccurenceTimeSteady_ = TIMESTAMP_INITIAL;
65     int64_t maxHitchOccurenceTimeSteady_ = TIMESTAMP_INITIAL;
66     int64_t lastMaxHitchOccurenceTimeSteady_ = TIMESTAMP_INITIAL;
67     int32_t seqMissedFrames_ = 0;
68     int32_t totalFrames_ = 0;
69     int32_t lastTotalFrames_ = 0;
70     int32_t totalMissedFrames_ = 0;
71     int32_t lastTotalMissedFrames_ = 0;
72     int64_t maxFrameTimeSteady_ = 0;
73     int64_t lastMaxFrameTimeSteady_ = 0;
74     int64_t maxTechFrameTimeSteady_ = 0;
75     int64_t lastMaxTechFrameTimeSteady_ = 0;
76     int64_t maxRealFrameTimeSteady_ = 0;
77     int64_t lastMaxRealFrameTimeSteady_ = 0;
78     int32_t maxSeqMissedFrames_ = 0;
79     int32_t lastMaxSeqMissedFrames_ = 0;
80     int64_t totalFrameTimeSteady_ = 0;
81     int64_t lastTotalFrameTimeSteady_ = 0;
82     int32_t traceId_ = TRACE_ID_INITIAL;
83     int64_t totalFrameTimeSteadyForHTR_ = 0;
84     int64_t lastTotalFrameTimeSteadyForHTR_ = 0;
85     uint32_t lastMaxFrameRefreshRate_ = 0;
86     uint32_t maxFrameRefreshRate_ = 0;
87     float totalHitchTimeSteady_ = 0;
88     float lastTotalHitchTimeSteady_ = 0;
89     float maxHitchTime_ = 0;
90     float lastMaxHitchTime_ = 0;
91     Rosen::DataBaseRs info_;
92 };
93 
94 struct JankFrameRecordStats {
95     const std::string countTraceName_;
96     const int64_t recordThreshold_;
97     bool isRecorded_ = false;
JankFrameRecordStatsJankFrameRecordStats98     JankFrameRecordStats(const std::string& countTraceName, int64_t recordThreshold)
99         : countTraceName_(countTraceName), recordThreshold_(recordThreshold) {}
100 };
101 
102 struct AnimationTraceStats {
103     std::pair<int64_t, std::string> animationId_ = { -1, "" };
104     std::string traceName_;
105     int64_t traceCreateTimeSteady_ = TIMESTAMP_INITIAL;
106     bool isDisplayAnimator_ = false;
107 };
108 
109 struct TraceIdRemainderStats {
110     int64_t remainder_ = 0;
111     int64_t setTimeSteady_ = TIMESTAMP_INITIAL;
112 };
113 
114 struct JankDurationParams {
115     int64_t timeStart_ = TIMESTAMP_INITIAL;
116     int64_t timeStartSteady_ = TIMESTAMP_INITIAL;
117     float timeStartSteadyFloat_ = TIMESTAMP_INITIAL_FLOAT;
118     int64_t timeEnd_ = TIMESTAMP_INITIAL;
119     int64_t timeEndSteady_ = TIMESTAMP_INITIAL;
120     float timeEndSteadyFloat_ = TIMESTAMP_INITIAL_FLOAT;
121     uint32_t refreshRate_ = 0;
122     bool discardJankFrames_ = false;
123     bool skipJankAnimatorFrame_ = false;
124     bool implicitAnimationEnd_ = false;
125 };
126 
127 struct AvcodecVideoParam {
128     std::string surfaceName;
129     uint32_t fps;
130     uint64_t reportTime;
131     uint64_t startTime;
132     uint64_t decodeCount;
133     uint32_t previousSequence = 0;
134     uint64_t previousFrameTime = 0;
135     uint32_t continuousFrameLoss = 0;
136 };
137 
138 class RSJankStats {
139 public:
140     static RSJankStats& GetInstance();
141     void SetOnVsyncStartTime(int64_t onVsyncStartTime, int64_t onVsyncStartTimeSteady,
142                              float onVsyncStartTimeSteadyFloat);
143     void SetStartTime(bool doDirectComposition = false);
144     void SetEndTime(bool skipJankAnimatorFrame = false, bool discardJankFrames = false,
145                     uint32_t dynamicRefreshRate = STANDARD_REFRESH_RATE,
146                     bool doDirectComposition = false, bool isReportTaskDelayed = false);
147     void HandleDirectComposition(const JankDurationParams& rsParams, bool isReportTaskDelayed,
148         std::function<void(const std::function<void()>&)> postTaskHandler = nullptr);
149     void ReportJankStats();
150     void SetReportEventResponse(const DataBaseRs& info);
151     void SetReportEventComplete(const DataBaseRs& info);
152     void SetReportEventJankFrame(const DataBaseRs& info, bool isReportTaskDelayed);
153     void SetReportRsSceneJankStart(const AppInfo& info);
154     void SetReportRsSceneJankEnd(const AppInfo& info);
155     void SetAppFirstFrame(pid_t appPid);
156     void SetImplicitAnimationEnd(bool isImplicitAnimationEnd);
157     void SetAccumulatedBufferCount(int accumulatedBufferCount);
158     bool IsAnimationEmpty();
159     void AvcodecVideoDump(std::string& dumpString, std::string& type, const std::string& avcodecVideo);
160     void AvcodecVideoStart(
161         const uint64_t queueId, const std::string& surfaceName, const uint32_t fps, const uint64_t reportTime);
162     void AvcodecVideoStop(const uint64_t queueId, const std::string& surfaceName = "", const uint32_t fps = 0);
163     void AvcodecVideoCollectBegin();
164     void AvcodecVideoCollectFinish();
165     void AvcodecVideoCollect(const uint64_t queueId, const uint32_t sequence);
166     bool GetEarlyZEnableFlag();
167     bool GetFlushEarlyZ();
168 
169 private:
170     RSJankStats() = default;
171     ~RSJankStats() = default;
172     DISALLOW_COPY_AND_MOVE(RSJankStats);
173 
174     void SetStartTimeInner(bool doDirectComposition = false);
175     void SetEndTimeInner(bool skipJankAnimatorFrame = false, bool discardJankFrames = false,
176                          uint32_t dynamicRefreshRate = STANDARD_REFRESH_RATE,
177                          bool doDirectComposition = false, bool isReportTaskDelayed = false);
178     void SetImplicitAnimationEndInner(bool isImplicitAnimationEnd);
179     bool NeedPostTaskToUniRenderThread() const;
180     void UpdateEndTime();
181     void SetRSJankStats(bool skipJankStats, uint32_t dynamicRefreshRate);
182     size_t GetJankRangeType(int64_t missedVsync) const;
183     void UpdateJankFrame(JankFrames& jankFrames, bool skipJankStats, uint32_t dynamicRefreshRate);
184     void UpdateHitchTime(JankFrames& jankFrames, float standardFrameTime);
185     void ReportEventResponse(const JankFrames& jankFrames) const;
186     void ReportEventComplete(const JankFrames& jankFrames) const;
187     void ReportEventJankFrame(const JankFrames& jankFrames, bool isReportTaskDelayed) const;
188     void ReportEventJankFrameWithoutDelay(const JankFrames& jankFrames) const;
189     void ReportEventJankFrameWithDelay(const JankFrames& jankFrames) const;
190     void GetMaxJankInfo(const JankFrames& jankFrames, bool isReportTaskDelayed,
191         int64_t& maxFrameTimeFromStart, int64_t& maxHitchTimeFromStart, int64_t& duration) const;
192     void ReportEventHitchTimeRatio(const JankFrames& jankFrames, bool isReportTaskDelayed) const;
193     void ReportEventHitchTimeRatioWithoutDelay(const JankFrames& jankFrames) const;
194     void ReportEventHitchTimeRatioWithDelay(const JankFrames& jankFrames) const;
195     void ReportEventFirstFrame();
196     void ReportEventFirstFrameByPid(pid_t appPid) const;
197     void ReportSceneJankStats(const AppInfo& appInfo);
198     void ReportSceneJankFrame(uint32_t dynamicRefreshRate);
199     void HandleImplicitAnimationEndInAdvance(JankFrames& jankFrames, bool isReportTaskDelayed);
200     void RecordJankFrame(uint32_t dynamicRefreshRate);
201     void RecordJankFrameSingle(int64_t missedFrames, JankFrameRecordStats& recordStats);
202     void RecordAnimationDynamicFrameRate(JankFrames& jankFrames, bool isReportTaskDelayed);
203     void SetAnimationTraceBegin(std::pair<int64_t, std::string> animationId, JankFrames& jankFrames);
204     void SetAnimationTraceEnd(JankFrames& jankFrames);
205     void CheckAnimationTraceTimeout();
206     void ClearAllAnimation();
207     std::string GetSceneDescription(const DataBaseRs& info) const;
208     std::pair<int64_t, std::string> GetAnimationId(const DataBaseRs& info) const;
209     int32_t GetTraceIdInit(const DataBaseRs& info, int64_t setTimeSteady);
210     int64_t ConvertTimeToSystime(int64_t time) const;
211     int64_t GetEffectiveFrameTime(bool isConsiderRsStartTime) const;
212     float GetEffectiveFrameTimeFloat(bool isConsiderRsStartTime) const;
213     int64_t GetCurrentSystimeMs() const;
214     int64_t GetCurrentSteadyTimeMs() const;
215     float GetCurrentSteadyTimeMsFloat() const;
216 
217     static constexpr uint16_t ANIMATION_TRACE_CHECK_FREQ = 20;
218     static constexpr uint32_t JANK_RANGE_VERSION = 1;
219     static constexpr uint32_t JANK_SCENE_RANGE_VERSION = 2;
220     static constexpr size_t JANK_STATS_SIZE = 8;
221     static constexpr int64_t TRACE_ID_SCALE_PARAM = 10;
222     static constexpr int64_t MIN_FRAME_SHOW_TIME = 16;
223     static constexpr int32_t DEFAULT_INT_VALUE = 0;
224     static inline const std::string DEFAULT_STRING_VALUE = "";
225     const int64_t SCENE_JANK_FRAME_THRESHOLD = RSSystemProperties::GetSceneJankFrameThreshold();
226     static constexpr int32_t FILTER_TYPE = 0;
227     static constexpr bool IS_FOLD_DISP = false;
228     static constexpr bool IS_CALCULATE_PRECISE_HITCH_TIME = true;
229     static inline const std::string ACCUMULATED_BUFFER_COUNT_TRACE_NAME = "ACCUMULATED_BUFFER_COUNT";
230     static inline const std::string JANK_FRAME_1_TO_5F_COUNT_TRACE_NAME = "JANK_FRAME_1-5F";
231     static inline const std::string JANK_FRAME_6F_COUNT_TRACE_NAME = "JANK_FRAME_6F";
232     std::vector<JankFrameRecordStats> jankExplicitAnimatorFrameRecorder_{ {"JANK_EXPLICIT_ANIMATOR_FRAME_1F", 1},
233                                                                           {"JANK_EXPLICIT_ANIMATOR_FRAME_2F", 2} };
234     std::vector<JankFrameRecordStats> jankImplicitAnimatorFrameRecorder_{ {"JANK_IMPLICIT_ANIMATOR_FRAME_1F", 1},
235                                                                           {"JANK_IMPLICIT_ANIMATOR_FRAME_2F", 2} };
236     bool isFirstSetStart_ = true;
237     bool isFirstSetEnd_ = true;
238     bool isNeedReportJankStats_ = false;
239     bool isNeedReportSceneJankStats_ = false;
240     bool isLastReportSceneDone_ = true;
241     bool isLastFrameDoDirectComposition_ = false;
242     bool isCurrentFrameSwitchToNotDoDirectComposition_ = false;
243     float rsStartTimeSteadyFloat_ = TIMESTAMP_INITIAL_FLOAT;
244     float rtEndTimeSteadyFloat_ = TIMESTAMP_INITIAL_FLOAT;
245     float rtLastEndTimeSteadyFloat_ = TIMESTAMP_INITIAL_FLOAT;
246     int64_t rsStartTime_ = TIMESTAMP_INITIAL;
247     int64_t rsStartTimeSteady_ = TIMESTAMP_INITIAL;
248     int64_t rtStartTime_ = TIMESTAMP_INITIAL;
249     int64_t rtStartTimeSteady_ = TIMESTAMP_INITIAL;
250     int64_t rtEndTime_ = TIMESTAMP_INITIAL;
251     int64_t rtEndTimeSteady_ = TIMESTAMP_INITIAL;
252     int64_t rtLastEndTime_ = TIMESTAMP_INITIAL;
253     int64_t rtLastEndTimeSteady_ = TIMESTAMP_INITIAL;
254     int64_t lastReportTime_ = TIMESTAMP_INITIAL;
255     int64_t lastReportTimeSteady_ = TIMESTAMP_INITIAL;
256     int64_t lastJankFrame6FreqTimeSteady_ = TIMESTAMP_INITIAL;
257     int64_t lastSceneReportTime_ = TIMESTAMP_INITIAL;
258     int64_t lastSceneReportTimeSteady_ = TIMESTAMP_INITIAL;
259     int64_t lastSceneJankFrame6FreqTimeSteady_ = TIMESTAMP_INITIAL;
260     int32_t explicitAnimationTotal_ = 0;
261     int32_t implicitAnimationTotal_ = 0;
262     uint16_t animationTraceCheckCnt_ = 0;
263     int accumulatedBufferCount_ = 0;
264     std::vector<uint16_t> rsJankStats_ = std::vector<uint16_t>(JANK_STATS_SIZE, 0);
265     std::vector<uint16_t> rsSceneJankStats_ = std::vector<uint16_t>(JANK_STATS_SIZE, 0);
266     std::queue<pid_t> firstFrameAppPids_;
267     std::map<int32_t, AnimationTraceStats> animationAsyncTraces_;
268     std::map<int64_t, TraceIdRemainderStats> traceIdRemainder_;
269     std::map<std::pair<int64_t, std::string>, JankFrames> animateJankFrames_;
270     std::mutex mutex_;
271     Rosen::AppInfo appInfo_;
272     bool avcodecVideoCollectOpen_ = false;
273     std::unordered_map<uint64_t, AvcodecVideoParam> avcodecVideoMap_;
274 
275     enum JankRangeType : size_t {
276         JANK_FRAME_6_FREQ = 0,
277         JANK_FRAME_15_FREQ,
278         JANK_FRAME_20_FREQ,
279         JANK_FRAME_36_FREQ,
280         JANK_FRAME_48_FREQ,
281         JANK_FRAME_60_FREQ,
282         JANK_FRAME_120_FREQ,
283         JANK_FRAME_180_FREQ,
284         JANK_FRAME_INVALID,
285     };
286     bool ddgrEarlyZEnable_ = false;
287     bool isFlushEarlyZ_ = false;
288     int32_t lastReportEarlyZTraceId_ = -1;
289 };
290 
291 } // namespace Rosen
292 } // namespace OHOS
293 
294 #endif // ROSEN_JANK_STATS_H
295