1 /*
2  * Copyright (c) 2023 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 
31 namespace OHOS {
32 namespace Rosen {
33 constexpr uint32_t STANDARD_REFRESH_RATE = 60;
34 constexpr int64_t TIMESTAMP_INITIAL = -1;
35 constexpr int32_t TRACE_ID_INITIAL = -1;
36 constexpr float TIMESTAMP_INITIAL_FLOAT = -1.f;
37 constexpr float MS_TO_US = 1000.f; // ms to us
38 
39 struct JankFrames {
40     bool isSetReportEventResponse_ = false;
41     bool isSetReportEventResponseTemp_ = false;
42     bool isSetReportEventComplete_ = false;
43     bool isSetReportEventJankFrame_ = false;
44     bool isReportEventResponse_ = false;
45     bool isReportEventComplete_ = false;
46     bool isReportEventJankFrame_ = false;
47     bool isUpdateJankFrame_ = false;
48     bool isFirstFrame_ = false;
49     bool isFirstFrameTemp_ = false;
50     bool isFrameRateRecorded_ = false;
51     bool isAnimationEnded_ = false;
52     bool isDisplayAnimator_ = false;
53     int64_t setTimeSteady_ = TIMESTAMP_INITIAL;
54     int64_t startTime_ = TIMESTAMP_INITIAL;
55     int64_t startTimeSteady_ = TIMESTAMP_INITIAL;
56     int64_t endTimeSteady_ = TIMESTAMP_INITIAL;
57     int64_t lastEndTimeSteady_ = TIMESTAMP_INITIAL;
58     int64_t traceCreateTimeSteady_ = TIMESTAMP_INITIAL;
59     int64_t traceTerminateTimeSteady_ = TIMESTAMP_INITIAL;
60     int64_t maxFrameOccurenceTimeSteady_ = TIMESTAMP_INITIAL;
61     int64_t lastMaxFrameOccurenceTimeSteady_ = TIMESTAMP_INITIAL;
62     int64_t maxHitchOccurenceTimeSteady_ = TIMESTAMP_INITIAL;
63     int64_t lastMaxHitchOccurenceTimeSteady_ = TIMESTAMP_INITIAL;
64     int32_t seqMissedFrames_ = 0;
65     int32_t totalFrames_ = 0;
66     int32_t lastTotalFrames_ = 0;
67     int32_t totalMissedFrames_ = 0;
68     int32_t lastTotalMissedFrames_ = 0;
69     int64_t maxFrameTimeSteady_ = 0;
70     int64_t lastMaxFrameTimeSteady_ = 0;
71     int32_t maxSeqMissedFrames_ = 0;
72     int32_t lastMaxSeqMissedFrames_ = 0;
73     int64_t totalFrameTimeSteady_ = 0;
74     int64_t lastTotalFrameTimeSteady_ = 0;
75     int32_t traceId_ = TRACE_ID_INITIAL;
76     int64_t totalFrameTimeSteadyForHTR_ = 0;
77     int64_t lastTotalFrameTimeSteadyForHTR_ = 0;
78     float totalHitchTimeSteady_ = 0;
79     float lastTotalHitchTimeSteady_ = 0;
80     float maxHitchTime_ = 0;
81     float lastMaxHitchTime_ = 0;
82     Rosen::DataBaseRs info_;
83 };
84 
85 struct JankFrameRecordStats {
86     const std::string countTraceName_;
87     const int64_t recordThreshold_;
88     bool isRecorded_ = false;
JankFrameRecordStatsJankFrameRecordStats89     JankFrameRecordStats(const std::string& countTraceName, int64_t recordThreshold)
90         : countTraceName_(countTraceName), recordThreshold_(recordThreshold) {}
91 };
92 
93 struct AnimationTraceStats {
94     std::pair<int64_t, std::string> animationId_ = { -1, "" };
95     std::string traceName_;
96     int64_t traceCreateTimeSteady_ = TIMESTAMP_INITIAL;
97     bool isDisplayAnimator_ = false;
98 };
99 
100 struct TraceIdRemainderStats {
101     int64_t remainder_ = 0;
102     int64_t setTimeSteady_ = TIMESTAMP_INITIAL;
103 };
104 
105 struct JankDurationParams {
106     int64_t timeStart_ = TIMESTAMP_INITIAL;
107     int64_t timeStartSteady_ = TIMESTAMP_INITIAL;
108     float timeStartSteadyFloat_ = TIMESTAMP_INITIAL_FLOAT;
109     int64_t timeEnd_ = TIMESTAMP_INITIAL;
110     int64_t timeEndSteady_ = TIMESTAMP_INITIAL;
111     float timeEndSteadyFloat_ = TIMESTAMP_INITIAL_FLOAT;
112     uint32_t refreshRate_ = 0;
113     bool discardJankFrames_ = false;
114     bool skipJankAnimatorFrame_ = false;
115 };
116 
117 class RSJankStats {
118 public:
119     static RSJankStats& GetInstance();
120     void SetOnVsyncStartTime(int64_t onVsyncStartTime, int64_t onVsyncStartTimeSteady,
121                              float onVsyncStartTimeSteadyFloat);
122     void SetStartTime(bool doDirectComposition = false);
123     void SetEndTime(bool skipJankAnimatorFrame = false, bool discardJankFrames = false,
124                     uint32_t dynamicRefreshRate = STANDARD_REFRESH_RATE,
125                     bool doDirectComposition = false, bool isReportTaskDelayed = false);
126     void HandleDirectComposition(const JankDurationParams& rsParams, bool isReportTaskDelayed);
127     void ReportJankStats();
128     void SetReportEventResponse(const DataBaseRs& info);
129     void SetReportEventComplete(const DataBaseRs& info);
130     void SetReportEventJankFrame(const DataBaseRs& info, bool isReportTaskDelayed);
131     void SetAppFirstFrame(pid_t appPid);
132     void SetImplicitAnimationEnd(bool isImplicitAnimationEnd);
133     void SetAccumulatedBufferCount(int accumulatedBufferCount);
134 
135 private:
136     RSJankStats() = default;
137     ~RSJankStats() = default;
138     DISALLOW_COPY_AND_MOVE(RSJankStats);
139 
140     void UpdateEndTime();
141     void SetRSJankStats(bool skipJankStats, uint32_t dynamicRefreshRate);
142     size_t GetJankRangeType(int64_t missedVsync) const;
143     void UpdateJankFrame(JankFrames& jankFrames, bool skipJankStats, uint32_t dynamicRefreshRate);
144     void UpdateHitchTime(JankFrames& jankFrames, float standardFrameTime);
145     void ReportEventResponse(const JankFrames& jankFrames) const;
146     void ReportEventComplete(const JankFrames& jankFrames) const;
147     void ReportEventJankFrame(const JankFrames& jankFrames, bool isReportTaskDelayed) const;
148     void ReportEventJankFrameWithoutDelay(const JankFrames& jankFrames) const;
149     void ReportEventJankFrameWithDelay(const JankFrames& jankFrames) const;
150     void GetMaxJankInfo(const JankFrames& jankFrames, bool isReportTaskDelayed,
151         int64_t& maxFrameTimeFromStart, int64_t& maxHitchTimeFromStart, int64_t& duration) const;
152     void ReportEventHitchTimeRatio(const JankFrames& jankFrames, bool isReportTaskDelayed) const;
153     void ReportEventHitchTimeRatioWithoutDelay(const JankFrames& jankFrames) const;
154     void ReportEventHitchTimeRatioWithDelay(const JankFrames& jankFrames) const;
155     void ReportEventFirstFrame();
156     void ReportEventFirstFrameByPid(pid_t appPid) const;
157     void HandleImplicitAnimationEndInAdvance(JankFrames& jankFrames, bool isReportTaskDelayed);
158     void RecordJankFrame(uint32_t dynamicRefreshRate);
159     void RecordJankFrameSingle(int64_t missedFrames, JankFrameRecordStats& recordStats);
160     void RecordAnimationDynamicFrameRate(JankFrames& jankFrames, bool isReportTaskDelayed);
161     void SetAnimationTraceBegin(std::pair<int64_t, std::string> animationId, JankFrames& jankFrames);
162     void SetAnimationTraceEnd(JankFrames& jankFrames);
163     void CheckAnimationTraceTimeout();
164     void ClearAllAnimation();
165     std::string GetSceneDescription(const DataBaseRs& info) const;
166     std::pair<int64_t, std::string> GetAnimationId(const DataBaseRs& info) const;
167     int32_t GetTraceIdInit(const DataBaseRs& info, int64_t setTimeSteady);
168     int64_t ConvertTimeToSystime(int64_t time) const;
169     int64_t GetEffectiveFrameTime(bool isConsiderRsStartTime) const;
170     float GetEffectiveFrameTimeFloat(bool isConsiderRsStartTime) const;
171     int64_t GetCurrentSystimeMs() const;
172     int64_t GetCurrentSteadyTimeMs() const;
173     float GetCurrentSteadyTimeMsFloat() const;
174 
175     static constexpr uint16_t ANIMATION_TRACE_CHECK_FREQ = 20;
176     static constexpr uint32_t JANK_RANGE_VERSION = 1;
177     static constexpr size_t JANK_STATS_SIZE = 8;
178     static constexpr int64_t TRACE_ID_SCALE_PARAM = 10;
179     static constexpr bool IS_FOLD_DISP = false;
180     static constexpr bool IS_CALCULATE_PRECISE_HITCH_TIME = true;
181     static inline const std::string ACCUMULATED_BUFFER_COUNT_TRACE_NAME = "ACCUMULATED_BUFFER_COUNT";
182     static inline const std::string JANK_FRAME_1_TO_5F_COUNT_TRACE_NAME = "JANK_FRAME_1-5F";
183     static inline const std::string JANK_FRAME_6F_COUNT_TRACE_NAME = "JANK_FRAME_6F";
184     std::vector<JankFrameRecordStats> jankExplicitAnimatorFrameRecorder_{ {"JANK_EXPLICIT_ANIMATOR_FRAME_1F", 1},
185                                                                           {"JANK_EXPLICIT_ANIMATOR_FRAME_2F", 2} };
186     std::vector<JankFrameRecordStats> jankImplicitAnimatorFrameRecorder_{ {"JANK_IMPLICIT_ANIMATOR_FRAME_1F", 1},
187                                                                           {"JANK_IMPLICIT_ANIMATOR_FRAME_2F", 2} };
188     bool isFirstSetStart_ = true;
189     bool isFirstSetEnd_ = true;
190     bool isNeedReportJankStats_ = false;
191     bool isLastFrameDoDirectComposition_ = false;
192     bool isCurrentFrameSwitchToNotDoDirectComposition_ = false;
193     float rsStartTimeSteadyFloat_ = TIMESTAMP_INITIAL_FLOAT;
194     float rtEndTimeSteadyFloat_ = TIMESTAMP_INITIAL_FLOAT;
195     float rtLastEndTimeSteadyFloat_ = TIMESTAMP_INITIAL_FLOAT;
196     int64_t rsStartTime_ = TIMESTAMP_INITIAL;
197     int64_t rsStartTimeSteady_ = TIMESTAMP_INITIAL;
198     int64_t rtStartTime_ = TIMESTAMP_INITIAL;
199     int64_t rtStartTimeSteady_ = TIMESTAMP_INITIAL;
200     int64_t rtEndTime_ = TIMESTAMP_INITIAL;
201     int64_t rtEndTimeSteady_ = TIMESTAMP_INITIAL;
202     int64_t rtLastEndTime_ = TIMESTAMP_INITIAL;
203     int64_t rtLastEndTimeSteady_ = TIMESTAMP_INITIAL;
204     int64_t lastReportTime_ = TIMESTAMP_INITIAL;
205     int64_t lastReportTimeSteady_ = TIMESTAMP_INITIAL;
206     int64_t lastJankFrame6FreqTimeSteady_ = TIMESTAMP_INITIAL;
207     int32_t explicitAnimationTotal_ = 0;
208     int32_t implicitAnimationTotal_ = 0;
209     uint16_t animationTraceCheckCnt_ = 0;
210     int accumulatedBufferCount_ = 0;
211     std::vector<uint16_t> rsJankStats_ = std::vector<uint16_t>(JANK_STATS_SIZE, 0);
212     std::queue<pid_t> firstFrameAppPids_;
213     std::map<int32_t, AnimationTraceStats> animationAsyncTraces_;
214     std::map<int64_t, TraceIdRemainderStats> traceIdRemainder_;
215     std::map<std::pair<int64_t, std::string>, JankFrames> animateJankFrames_;
216     std::mutex mutex_;
217 
218     enum JankRangeType : size_t {
219         JANK_FRAME_6_FREQ = 0,
220         JANK_FRAME_15_FREQ,
221         JANK_FRAME_20_FREQ,
222         JANK_FRAME_36_FREQ,
223         JANK_FRAME_48_FREQ,
224         JANK_FRAME_60_FREQ,
225         JANK_FRAME_120_FREQ,
226         JANK_FRAME_180_FREQ,
227         JANK_FRAME_INVALID,
228     };
229 };
230 
231 } // namespace Rosen
232 } // namespace OHOS
233 
234 #endif // ROSEN_JANK_STATS_H
235