diff options
| author | 2025-01-17 18:06:16 -0800 | |
|---|---|---|
| committer | 2025-01-24 16:11:47 -0800 | |
| commit | 29b3d132b75cc178dfd868714105e773aaa3135a (patch) | |
| tree | a6d76bd3987c2bbabd19d578a40aefa6d99b63d2 | |
| parent | b9bcf0ac1988d34b586c6e2ac44f6f6b4f949267 (diff) | |
[SF] increase jank threshold to 4 milliseconds
Test: Manual jank analysis on the trace
BUG: 342265411
Flag: com.android.graphics.surfaceflinger.flags.increase_missed_frame_jank_threshold
Change-Id: I6c8dfb522d3006d3c810f4b23f359f31b144c5cb
3 files changed, 28 insertions, 20 deletions
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp index 86d7388f5b..fece3122a0 100644 --- a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp +++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp @@ -611,7 +611,11 @@ void SurfaceFrame::classifyJankLocked(int32_t displayFrameJankType, const Fps& r mFrameReadyMetadata = FrameReadyMetadata::OnTimeFinish; } - if (std::abs(presentDelta) > mJankClassificationThresholds.presentThreshold) { + const nsecs_t presentThreshold = + FlagManager::getInstance().increase_missed_frame_jank_threshold() + ? mJankClassificationThresholds.presentThresholdExtended + : mJankClassificationThresholds.presentThresholdLegacy; + if (std::abs(presentDelta) > presentThreshold) { mFramePresentMetadata = presentDelta > 0 ? FramePresentMetadata::LatePresent : FramePresentMetadata::EarlyPresent; // Jank that is missing by less than the render rate period is classified as partial jank, @@ -629,9 +633,8 @@ void SurfaceFrame::classifyJankLocked(int32_t displayFrameJankType, const Fps& r } else if (mFramePresentMetadata == FramePresentMetadata::EarlyPresent) { if (mFrameReadyMetadata == FrameReadyMetadata::OnTimeFinish) { // Finish on time, Present early - if (deltaToVsync < mJankClassificationThresholds.presentThreshold || - deltaToVsync >= refreshRate.getPeriodNsecs() - - mJankClassificationThresholds.presentThreshold) { + if (deltaToVsync < presentThreshold || + deltaToVsync >= refreshRate.getPeriodNsecs() - presentThreshold) { // Delta factor of vsync mJankType = JankType::SurfaceFlingerScheduling; } else { @@ -667,9 +670,8 @@ void SurfaceFrame::classifyJankLocked(int32_t displayFrameJankType, const Fps& r if (!(mJankType & JankType::BufferStuffing)) { // In a stuffed state, if the app finishes on time and there is no display frame // jank, only buffer stuffing is the root cause of the jank. - if (deltaToVsync < mJankClassificationThresholds.presentThreshold || - deltaToVsync >= refreshRate.getPeriodNsecs() - - mJankClassificationThresholds.presentThreshold) { + if (deltaToVsync < presentThreshold || + deltaToVsync >= refreshRate.getPeriodNsecs() - presentThreshold) { // Delta factor of vsync mJankType |= JankType::SurfaceFlingerScheduling; } else { @@ -1091,7 +1093,11 @@ void FrameTimeline::DisplayFrame::classifyJank(nsecs_t& deadlineDelta, nsecs_t& ? std::abs(presentDelta) % mRefreshRate.getPeriodNsecs() : 0; - if (std::abs(presentDelta) > mJankClassificationThresholds.presentThreshold) { + nsecs_t presentThreshold = FlagManager::getInstance().increase_missed_frame_jank_threshold() + ? mJankClassificationThresholds.presentThresholdExtended + : mJankClassificationThresholds.presentThresholdLegacy; + + if (std::abs(presentDelta) > presentThreshold) { mFramePresentMetadata = presentDelta > 0 ? FramePresentMetadata::LatePresent : FramePresentMetadata::EarlyPresent; // Jank that is missing by less than the render rate period is classified as partial jank, @@ -1122,9 +1128,8 @@ void FrameTimeline::DisplayFrame::classifyJank(nsecs_t& deadlineDelta, nsecs_t& if (mFramePresentMetadata == FramePresentMetadata::EarlyPresent) { if (mFrameReadyMetadata == FrameReadyMetadata::OnTimeFinish) { // Finish on time, Present early - if (deltaToVsync < mJankClassificationThresholds.presentThreshold || - deltaToVsync >= (mRefreshRate.getPeriodNsecs() - - mJankClassificationThresholds.presentThreshold)) { + if (deltaToVsync < presentThreshold || + deltaToVsync >= (mRefreshRate.getPeriodNsecs() - presentThreshold)) { // Delta is a factor of vsync if its within the presentTheshold on either side // of the vsyncPeriod. Example: 0-2ms and 9-11ms are both within the threshold // of the vsyncPeriod if the threshold was 2ms and the vsyncPeriod was 11ms. @@ -1142,7 +1147,7 @@ void FrameTimeline::DisplayFrame::classifyJank(nsecs_t& deadlineDelta, nsecs_t& } } else if (mFramePresentMetadata == FramePresentMetadata::LatePresent) { if (std::abs(mSurfaceFlingerPredictions.presentTime - previousPresentTime) <= - mJankClassificationThresholds.presentThreshold || + presentThreshold || previousPresentTime > mSurfaceFlingerPredictions.presentTime) { // The previous frame was either presented in the current frame's expected vsync or // it was presented even later than the current frame's expected vsync. @@ -1151,9 +1156,8 @@ void FrameTimeline::DisplayFrame::classifyJank(nsecs_t& deadlineDelta, nsecs_t& if (mFrameReadyMetadata == FrameReadyMetadata::OnTimeFinish && !(mJankType & JankType::SurfaceFlingerStuffing)) { // Finish on time, Present late - if (deltaToVsync < mJankClassificationThresholds.presentThreshold || - deltaToVsync >= (mRefreshRate.getPeriodNsecs() - - mJankClassificationThresholds.presentThreshold)) { + if (deltaToVsync < presentThreshold || + deltaToVsync >= (mRefreshRate.getPeriodNsecs() - presentThreshold)) { // Delta is a factor of vsync if its within the presentTheshold on either side // of the vsyncPeriod. Example: 0-2ms and 9-11ms are both within the threshold // of the vsyncPeriod if the threshold was 2ms and the vsyncPeriod was 11ms. @@ -1165,8 +1169,7 @@ void FrameTimeline::DisplayFrame::classifyJank(nsecs_t& deadlineDelta, nsecs_t& } else if (mFrameReadyMetadata == FrameReadyMetadata::LateFinish) { if (!(mJankType & JankType::SurfaceFlingerStuffing) || mSurfaceFlingerActuals.presentTime - previousPresentTime > - mRefreshRate.getPeriodNsecs() + - mJankClassificationThresholds.presentThreshold) { + mRefreshRate.getPeriodNsecs() + presentThreshold) { // Classify CPU vs GPU if SF wasn't stuffed or if SF was stuffed but this frame // was presented more than a vsync late. if (mGpuFence != FenceTime::NO_FENCE) { diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.h b/services/surfaceflinger/FrameTimeline/FrameTimeline.h index a47bd573de..9fedb57aca 100644 --- a/services/surfaceflinger/FrameTimeline/FrameTimeline.h +++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.h @@ -107,7 +107,10 @@ struct TimelineItem { struct JankClassificationThresholds { // The various thresholds for App and SF. If the actual timestamp falls within the threshold // compared to prediction, we treat it as on time. - nsecs_t presentThreshold = std::chrono::duration_cast<std::chrono::nanoseconds>(2ms).count(); + nsecs_t presentThresholdLegacy = + std::chrono::duration_cast<std::chrono::nanoseconds>(2ms).count(); + nsecs_t presentThresholdExtended = + std::chrono::duration_cast<std::chrono::nanoseconds>(4ms).count(); nsecs_t deadlineThreshold = std::chrono::duration_cast<std::chrono::nanoseconds>(0ms).count(); nsecs_t startThreshold = std::chrono::duration_cast<std::chrono::nanoseconds>(2ms).count(); }; diff --git a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp index 08e426564a..54f225901e 100644 --- a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp +++ b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp @@ -202,10 +202,12 @@ public: uint32_t* maxDisplayFrames; size_t maxTokens; static constexpr pid_t kSurfaceFlingerPid = 666; - static constexpr nsecs_t kPresentThreshold = std::chrono::nanoseconds(2ns).count(); + static constexpr nsecs_t kPresentThresholdLegacy = std::chrono::nanoseconds(2ns).count(); + static constexpr nsecs_t kPresentThresholdExtended = std::chrono::nanoseconds(4ns).count(); static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(0ns).count(); static constexpr nsecs_t kStartThreshold = std::chrono::nanoseconds(2ns).count(); - static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold, + static constexpr JankClassificationThresholds kTestThresholds{kPresentThresholdLegacy, + kPresentThresholdExtended, kDeadlineThreshold, kStartThreshold}; }; |