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