| John Reck | ba6adf6 | 2015-02-19 14:36:50 -0800 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2015 The Android Open Source Project | 
 | 3 |  * | 
 | 4 |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 5 |  * you may not use this file except in compliance with the License. | 
 | 6 |  * You may obtain a copy of the License at | 
 | 7 |  * | 
 | 8 |  *      http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 |  * | 
 | 10 |  * Unless required by applicable law or agreed to in writing, software | 
 | 11 |  * distributed under the License is distributed on an "AS IS" BASIS, | 
 | 12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 13 |  * See the License for the specific language governing permissions and | 
 | 14 |  * limitations under the License. | 
 | 15 |  */ | 
| Mark Salyzyn | 96bf598 | 2016-09-28 16:15:30 -0700 | [diff] [blame] | 16 |  | 
| John Reck | ba6adf6 | 2015-02-19 14:36:50 -0800 | [diff] [blame] | 17 | #include "JankTracker.h" | 
 | 18 |  | 
| Alec Mouri | 22d753f | 2019-09-05 17:11:45 -0700 | [diff] [blame] | 19 | #include <cutils/ashmem.h> | 
| John Reck | edc524c | 2015-03-18 15:24:33 -0700 | [diff] [blame] | 20 | #include <errno.h> | 
| John Reck | ba6adf6 | 2015-02-19 14:36:50 -0800 | [diff] [blame] | 21 | #include <inttypes.h> | 
| Alec Mouri | 22d753f | 2019-09-05 17:11:45 -0700 | [diff] [blame] | 22 | #include <log/log.h> | 
| Mark Salyzyn | 96bf598 | 2016-09-28 16:15:30 -0700 | [diff] [blame] | 23 | #include <sys/mman.h> | 
| Mark Salyzyn | 52eb4e0 | 2016-09-28 16:15:30 -0700 | [diff] [blame] | 24 |  | 
 | 25 | #include <algorithm> | 
| John Reck | 5ed587f | 2016-03-24 15:57:01 -0700 | [diff] [blame] | 26 | #include <cmath> | 
| Mark Salyzyn | 52eb4e0 | 2016-09-28 16:15:30 -0700 | [diff] [blame] | 27 | #include <cstdio> | 
 | 28 | #include <limits> | 
| John Reck | 0e89ca2 | 2017-12-15 16:00:48 -0800 | [diff] [blame] | 29 | #include <sstream> | 
| Mark Salyzyn | 52eb4e0 | 2016-09-28 16:15:30 -0700 | [diff] [blame] | 30 |  | 
| Alec Mouri | 22d753f | 2019-09-05 17:11:45 -0700 | [diff] [blame] | 31 | #include "DeviceInfo.h" | 
| Mark Salyzyn | 52eb4e0 | 2016-09-28 16:15:30 -0700 | [diff] [blame] | 32 | #include "Properties.h" | 
 | 33 | #include "utils/TimeUtils.h" | 
| John Reck | 0e89ca2 | 2017-12-15 16:00:48 -0800 | [diff] [blame] | 34 | #include "utils/Trace.h" | 
| Mark Salyzyn | 52eb4e0 | 2016-09-28 16:15:30 -0700 | [diff] [blame] | 35 |  | 
| John Reck | ba6adf6 | 2015-02-19 14:36:50 -0800 | [diff] [blame] | 36 | namespace android { | 
 | 37 | namespace uirenderer { | 
 | 38 |  | 
| John Reck | ba6adf6 | 2015-02-19 14:36:50 -0800 | [diff] [blame] | 39 | struct Comparison { | 
| John Reck | 0e48647 | 2018-03-19 14:06:16 -0700 | [diff] [blame] | 40 |     JankType type; | 
 | 41 |     std::function<int64_t(nsecs_t)> computeThreadshold; | 
| John Reck | c87be99 | 2015-02-20 10:57:22 -0800 | [diff] [blame] | 42 |     FrameInfoIndex start; | 
 | 43 |     FrameInfoIndex end; | 
| John Reck | ba6adf6 | 2015-02-19 14:36:50 -0800 | [diff] [blame] | 44 | }; | 
 | 45 |  | 
| John Reck | 0e48647 | 2018-03-19 14:06:16 -0700 | [diff] [blame] | 46 | static const std::array<Comparison, 4> COMPARISONS{ | 
 | 47 |         Comparison{JankType::kMissedVsync, [](nsecs_t) { return 1; }, FrameInfoIndex::IntendedVsync, | 
 | 48 |                    FrameInfoIndex::Vsync}, | 
 | 49 |  | 
 | 50 |         Comparison{JankType::kSlowUI, | 
 | 51 |                    [](nsecs_t frameInterval) { return static_cast<int64_t>(.5 * frameInterval); }, | 
 | 52 |                    FrameInfoIndex::Vsync, FrameInfoIndex::SyncStart}, | 
 | 53 |  | 
 | 54 |         Comparison{JankType::kSlowSync, | 
 | 55 |                    [](nsecs_t frameInterval) { return static_cast<int64_t>(.2 * frameInterval); }, | 
 | 56 |                    FrameInfoIndex::SyncStart, FrameInfoIndex::IssueDrawCommandsStart}, | 
 | 57 |  | 
 | 58 |         Comparison{JankType::kSlowRT, | 
 | 59 |                    [](nsecs_t frameInterval) { return static_cast<int64_t>(.75 * frameInterval); }, | 
 | 60 |                    FrameInfoIndex::IssueDrawCommandsStart, FrameInfoIndex::FrameCompleted}, | 
| John Reck | ba6adf6 | 2015-02-19 14:36:50 -0800 | [diff] [blame] | 61 | }; | 
 | 62 |  | 
 | 63 | // If the event exceeds 10 seconds throw it away, this isn't a jank event | 
 | 64 | // it's an ANR and will be handled as such | 
 | 65 | static const int64_t IGNORE_EXCEEDING = seconds_to_nanoseconds(10); | 
 | 66 |  | 
 | 67 | /* | 
| John Reck | 6601080 | 2016-03-30 14:19:44 -0700 | [diff] [blame] | 68 |  * We don't track direct-drawing via Surface:lockHardwareCanvas() | 
| John Reck | ba6adf6 | 2015-02-19 14:36:50 -0800 | [diff] [blame] | 69 |  * for now | 
 | 70 |  * | 
 | 71 |  * TODO: kSurfaceCanvas can negatively impact other drawing by using up | 
 | 72 |  * time on the RenderThread, figure out how to attribute that as a jank-causer | 
 | 73 |  */ | 
| John Reck | 6601080 | 2016-03-30 14:19:44 -0700 | [diff] [blame] | 74 | static const int64_t EXEMPT_FRAMES_FLAGS = FrameInfoFlags::SurfaceCanvas; | 
| John Reck | ba6adf6 | 2015-02-19 14:36:50 -0800 | [diff] [blame] | 75 |  | 
| John Reck | c7cd9cf | 2016-03-28 10:38:19 -0700 | [diff] [blame] | 76 | // For testing purposes to try and eliminate test infra overhead we will | 
 | 77 | // consider any unknown delay of frame start as part of the test infrastructure | 
 | 78 | // and filter it out of the frame profile data | 
 | 79 | static FrameInfoIndex sFrameStart = FrameInfoIndex::IntendedVsync; | 
 | 80 |  | 
| Jorim Jaggi | 71db889 | 2021-02-03 23:19:29 +0100 | [diff] [blame] | 81 | JankTracker::JankTracker(ProfileDataContainer* globalData) | 
 | 82 |         : mData(globalData->getDataMutex()) | 
 | 83 |         , mDataMutex(globalData->getDataMutex()) { | 
| John Reck | 34781b2 | 2017-07-05 16:39:36 -0700 | [diff] [blame] | 84 |     mGlobalData = globalData; | 
| Alec Mouri | 4a818f1 | 2019-11-19 16:17:53 -0800 | [diff] [blame] | 85 |     nsecs_t frameIntervalNanos = DeviceInfo::getVsyncPeriod(); | 
| Alec Mouri | 22d753f | 2019-09-05 17:11:45 -0700 | [diff] [blame] | 86 |     nsecs_t sfOffset = DeviceInfo::getCompositorOffset(); | 
 | 87 |     nsecs_t offsetDelta = sfOffset - DeviceInfo::getAppOffset(); | 
| John Reck | 2d5b8d7 | 2016-07-28 15:36:11 -0700 | [diff] [blame] | 88 |     // There are two different offset cases. If the offsetDelta is positive | 
 | 89 |     // and small, then the intention is to give apps extra time by leveraging | 
 | 90 |     // pipelining between the UI & RT threads. If the offsetDelta is large or | 
 | 91 |     // negative, the intention is to subtract time from the total duration | 
 | 92 |     // in which case we can't afford to wait for dequeueBuffer blockage. | 
 | 93 |     if (offsetDelta <= 4_ms && offsetDelta >= 0) { | 
 | 94 |         // SF will begin composition at VSYNC-app + offsetDelta. If we are triple | 
 | 95 |         // buffered, this is the expected time at which dequeueBuffer will | 
 | 96 |         // return due to the staggering of VSYNC-app & VSYNC-sf. | 
| Jorim Jaggi | 10f328c | 2021-01-19 00:08:02 +0100 | [diff] [blame] | 97 |         mDequeueTimeForgivenessLegacy = offsetDelta + 4_ms; | 
| John Reck | 2d5b8d7 | 2016-07-28 15:36:11 -0700 | [diff] [blame] | 98 |     } | 
| Jorim Jaggi | 10f328c | 2021-01-19 00:08:02 +0100 | [diff] [blame] | 99 |     mFrameIntervalLegacy = frameIntervalNanos; | 
| John Reck | ba6adf6 | 2015-02-19 14:36:50 -0800 | [diff] [blame] | 100 | } | 
 | 101 |  | 
| Siarhei Vishniakou | 07d35cb | 2021-07-03 02:22:12 +0000 | [diff] [blame] | 102 | void JankTracker::calculateLegacyJank(FrameInfo& frame) REQUIRES(mDataMutex) { | 
| John Reck | ba6adf6 | 2015-02-19 14:36:50 -0800 | [diff] [blame] | 103 |     // Fast-path for jank-free frames | 
| Jorim Jaggi | 0ac066d | 2021-02-24 16:28:47 +0100 | [diff] [blame] | 104 |     int64_t totalDuration = frame.duration(sFrameStart, FrameInfoIndex::SwapBuffersCompleted); | 
| Jorim Jaggi | 10f328c | 2021-01-19 00:08:02 +0100 | [diff] [blame] | 105 |     if (mDequeueTimeForgivenessLegacy && frame[FrameInfoIndex::DequeueBufferDuration] > 500_us) { | 
 | 106 |         nsecs_t expectedDequeueDuration = mDequeueTimeForgivenessLegacy | 
 | 107 |                                           + frame[FrameInfoIndex::Vsync] | 
 | 108 |                                           - frame[FrameInfoIndex::IssueDrawCommandsStart]; | 
| John Reck | 2d5b8d7 | 2016-07-28 15:36:11 -0700 | [diff] [blame] | 109 |         if (expectedDequeueDuration > 0) { | 
 | 110 |             // Forgive only up to the expected amount, but not more than | 
 | 111 |             // the actual time spent blocked. | 
| John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 112 |             nsecs_t forgiveAmount = | 
 | 113 |                     std::min(expectedDequeueDuration, frame[FrameInfoIndex::DequeueBufferDuration]); | 
| John Reck | 00665ae | 2021-10-04 14:35:03 -0400 | [diff] [blame] | 114 |             if (forgiveAmount >= totalDuration) { | 
 | 115 |                 ALOGV("Impossible dequeue duration! dequeue duration reported %" PRId64 | 
 | 116 |                       ", total duration %" PRId64, | 
 | 117 |                       forgiveAmount, totalDuration); | 
 | 118 |                 return; | 
 | 119 |             } | 
| John Reck | 2d5b8d7 | 2016-07-28 15:36:11 -0700 | [diff] [blame] | 120 |             totalDuration -= forgiveAmount; | 
 | 121 |         } | 
 | 122 |     } | 
| John Reck | 0e48647 | 2018-03-19 14:06:16 -0700 | [diff] [blame] | 123 |  | 
| John Reck | 00665ae | 2021-10-04 14:35:03 -0400 | [diff] [blame] | 124 |     if (totalDuration <= 0) { | 
 | 125 |         ALOGV("Impossible totalDuration %" PRId64 " start=%" PRIi64 " gpuComplete=%" PRIi64, | 
 | 126 |               totalDuration, frame[FrameInfoIndex::IntendedVsync], | 
 | 127 |               frame[FrameInfoIndex::GpuCompleted]); | 
 | 128 |         return; | 
 | 129 |     } | 
| Jorim Jaggi | 10f328c | 2021-01-19 00:08:02 +0100 | [diff] [blame] | 130 |  | 
 | 131 |     // Only things like Surface.lockHardwareCanvas() are exempt from tracking | 
 | 132 |     if (CC_UNLIKELY(frame[FrameInfoIndex::Flags] & EXEMPT_FRAMES_FLAGS)) { | 
 | 133 |         return; | 
 | 134 |     } | 
 | 135 |  | 
 | 136 |     if (totalDuration > mFrameIntervalLegacy) { | 
 | 137 |         mData->reportJankLegacy(); | 
 | 138 |         (*mGlobalData)->reportJankLegacy(); | 
 | 139 |     } | 
 | 140 |  | 
 | 141 |     if (mSwapDeadlineLegacy < 0) { | 
 | 142 |         mSwapDeadlineLegacy = frame[FrameInfoIndex::IntendedVsync] + mFrameIntervalLegacy; | 
 | 143 |     } | 
 | 144 |     bool isTripleBuffered = (mSwapDeadlineLegacy - frame[FrameInfoIndex::IntendedVsync]) | 
 | 145 |             > (mFrameIntervalLegacy * 0.1); | 
 | 146 |  | 
 | 147 |     mSwapDeadlineLegacy = std::max(mSwapDeadlineLegacy + mFrameIntervalLegacy, | 
 | 148 |                              frame[FrameInfoIndex::IntendedVsync] + mFrameIntervalLegacy); | 
 | 149 |  | 
 | 150 |     // If we hit the deadline, cool! | 
 | 151 |     if (frame[FrameInfoIndex::FrameCompleted] < mSwapDeadlineLegacy | 
 | 152 |             || totalDuration < mFrameIntervalLegacy) { | 
 | 153 |         if (isTripleBuffered) { | 
 | 154 |             mData->reportJankType(JankType::kHighInputLatency); | 
 | 155 |             (*mGlobalData)->reportJankType(JankType::kHighInputLatency); | 
 | 156 |         } | 
 | 157 |         return; | 
 | 158 |     } | 
 | 159 |  | 
 | 160 |     mData->reportJankType(JankType::kMissedDeadlineLegacy); | 
 | 161 |     (*mGlobalData)->reportJankType(JankType::kMissedDeadlineLegacy); | 
 | 162 |  | 
 | 163 |     // Janked, reset the swap deadline | 
 | 164 |     nsecs_t jitterNanos = frame[FrameInfoIndex::FrameCompleted] - frame[FrameInfoIndex::Vsync]; | 
 | 165 |     nsecs_t lastFrameOffset = jitterNanos % mFrameIntervalLegacy; | 
 | 166 |     mSwapDeadlineLegacy = frame[FrameInfoIndex::FrameCompleted] | 
 | 167 |             - lastFrameOffset + mFrameIntervalLegacy; | 
 | 168 | } | 
 | 169 |  | 
| Pablo Gamito | 88660d7 | 2021-08-09 14:37:56 +0000 | [diff] [blame] | 170 | void JankTracker::finishFrame(FrameInfo& frame, std::unique_ptr<FrameMetricsReporter>& reporter, | 
 | 171 |                               int64_t frameNumber, int32_t surfaceControlId) { | 
| Jorim Jaggi | 10f328c | 2021-01-19 00:08:02 +0100 | [diff] [blame] | 172 |     std::lock_guard lock(mDataMutex); | 
 | 173 |  | 
 | 174 |     calculateLegacyJank(frame); | 
 | 175 |  | 
 | 176 |     // Fast-path for jank-free frames | 
 | 177 |     int64_t totalDuration = frame.duration(FrameInfoIndex::IntendedVsync, | 
 | 178 |             FrameInfoIndex::FrameCompleted); | 
 | 179 |  | 
| John Reck | 00665ae | 2021-10-04 14:35:03 -0400 | [diff] [blame] | 180 |     if (totalDuration <= 0) { | 
 | 181 |         ALOGV("Impossible totalDuration %" PRId64, totalDuration); | 
 | 182 |         return; | 
 | 183 |     } | 
| John Reck | 7075c79 | 2017-07-05 14:03:43 -0700 | [diff] [blame] | 184 |     mData->reportFrame(totalDuration); | 
| John Reck | 34781b2 | 2017-07-05 16:39:36 -0700 | [diff] [blame] | 185 |     (*mGlobalData)->reportFrame(totalDuration); | 
| John Reck | 7075c79 | 2017-07-05 14:03:43 -0700 | [diff] [blame] | 186 |  | 
| John Reck | 6601080 | 2016-03-30 14:19:44 -0700 | [diff] [blame] | 187 |     // Only things like Surface.lockHardwareCanvas() are exempt from tracking | 
| John Reck | 0e48647 | 2018-03-19 14:06:16 -0700 | [diff] [blame] | 188 |     if (CC_UNLIKELY(frame[FrameInfoIndex::Flags] & EXEMPT_FRAMES_FLAGS)) { | 
| John Reck | ba6adf6 | 2015-02-19 14:36:50 -0800 | [diff] [blame] | 189 |         return; | 
 | 190 |     } | 
 | 191 |  | 
| Jorim Jaggi | 10f328c | 2021-01-19 00:08:02 +0100 | [diff] [blame] | 192 |     int64_t frameInterval = frame[FrameInfoIndex::FrameInterval]; | 
| John Reck | ba6adf6 | 2015-02-19 14:36:50 -0800 | [diff] [blame] | 193 |  | 
| Jorim Jaggi | 10f328c | 2021-01-19 00:08:02 +0100 | [diff] [blame] | 194 |     // If we starter earlier than the intended frame start assuming an unstuffed scenario, it means | 
 | 195 |     // that we are in a triple buffering situation. | 
 | 196 |     bool isTripleBuffered = (mNextFrameStartUnstuffed - frame[FrameInfoIndex::IntendedVsync]) | 
 | 197 |                     > (frameInterval * 0.1); | 
| John Reck | 0e48647 | 2018-03-19 14:06:16 -0700 | [diff] [blame] | 198 |  | 
| Jorim Jaggi | 10f328c | 2021-01-19 00:08:02 +0100 | [diff] [blame] | 199 |     int64_t deadline = frame[FrameInfoIndex::FrameDeadline]; | 
 | 200 |  | 
 | 201 |     // If we are in triple buffering, we have enough buffers in queue to sustain a single frame | 
 | 202 |     // drop without jank, so adjust the frame interval to the deadline. | 
 | 203 |     if (isTripleBuffered) { | 
| Dake Gu | 3a9b4c8 | 2022-06-02 17:42:55 -0700 | [diff] [blame] | 204 |         int64_t originalDeadlineDuration = deadline - frame[FrameInfoIndex::IntendedVsync]; | 
 | 205 |         deadline = mNextFrameStartUnstuffed + originalDeadlineDuration; | 
 | 206 |         frame.set(FrameInfoIndex::FrameDeadline) = deadline; | 
| Jorim Jaggi | 10f328c | 2021-01-19 00:08:02 +0100 | [diff] [blame] | 207 |     } | 
| John Reck | 0e48647 | 2018-03-19 14:06:16 -0700 | [diff] [blame] | 208 |  | 
 | 209 |     // If we hit the deadline, cool! | 
| Jorim Jaggi | 10f328c | 2021-01-19 00:08:02 +0100 | [diff] [blame] | 210 |     if (frame[FrameInfoIndex::GpuCompleted] < deadline) { | 
| John Reck | 0e48647 | 2018-03-19 14:06:16 -0700 | [diff] [blame] | 211 |         if (isTripleBuffered) { | 
 | 212 |             mData->reportJankType(JankType::kHighInputLatency); | 
 | 213 |             (*mGlobalData)->reportJankType(JankType::kHighInputLatency); | 
| Jorim Jaggi | 10f328c | 2021-01-19 00:08:02 +0100 | [diff] [blame] | 214 |  | 
 | 215 |             // Buffer stuffing state gets carried over to next frame, unless there is a "pause" | 
| Dake Gu | f71128f | 2022-06-10 01:09:00 +0000 | [diff] [blame] | 216 |             mNextFrameStartUnstuffed += frameInterval; | 
| John Reck | 0e48647 | 2018-03-19 14:06:16 -0700 | [diff] [blame] | 217 |         } | 
| Jorim Jaggi | 10f328c | 2021-01-19 00:08:02 +0100 | [diff] [blame] | 218 |     } else { | 
 | 219 |         mData->reportJankType(JankType::kMissedDeadline); | 
 | 220 |         (*mGlobalData)->reportJankType(JankType::kMissedDeadline); | 
 | 221 |         mData->reportJank(); | 
 | 222 |         (*mGlobalData)->reportJank(); | 
 | 223 |  | 
 | 224 |         // Janked, store the adjust deadline to detect triple buffering in next frame correctly. | 
| Dake Gu | f71128f | 2022-06-10 01:09:00 +0000 | [diff] [blame] | 225 |         nsecs_t jitterNanos = frame[FrameInfoIndex::GpuCompleted] | 
 | 226 |                 - frame[FrameInfoIndex::Vsync]; | 
 | 227 |         nsecs_t lastFrameOffset = jitterNanos % frameInterval; | 
 | 228 |  | 
 | 229 |         // Note the time when the next frame would start in an unstuffed situation. If it starts | 
 | 230 |         // earlier, we are in a stuffed situation. | 
 | 231 |         mNextFrameStartUnstuffed = frame[FrameInfoIndex::GpuCompleted] | 
 | 232 |                 - lastFrameOffset + frameInterval; | 
| Jorim Jaggi | 10f328c | 2021-01-19 00:08:02 +0100 | [diff] [blame] | 233 |  | 
 | 234 |         recomputeThresholds(frameInterval); | 
 | 235 |         for (auto& comparison : COMPARISONS) { | 
 | 236 |             int64_t delta = frame.duration(comparison.start, comparison.end); | 
 | 237 |             if (delta >= mThresholds[comparison.type] && delta < IGNORE_EXCEEDING) { | 
 | 238 |                 mData->reportJankType(comparison.type); | 
 | 239 |                 (*mGlobalData)->reportJankType(comparison.type); | 
 | 240 |             } | 
 | 241 |         } | 
 | 242 |  | 
 | 243 |         // Log daveys since they are weird and we don't know what they are (b/70339576) | 
 | 244 |         if (totalDuration >= 700_ms) { | 
 | 245 |             static int sDaveyCount = 0; | 
 | 246 |             std::stringstream ss; | 
 | 247 |             ss << "Davey! duration=" << ns2ms(totalDuration) << "ms; "; | 
 | 248 |             for (size_t i = 0; i < static_cast<size_t>(FrameInfoIndex::NumIndexes); i++) { | 
 | 249 |                 ss << FrameInfoNames[i] << "=" << frame[i] << ", "; | 
 | 250 |             } | 
 | 251 |             ALOGI("%s", ss.str().c_str()); | 
 | 252 |             // Just so we have something that counts up, the value is largely irrelevant | 
 | 253 |             ATRACE_INT(ss.str().c_str(), ++sDaveyCount); | 
 | 254 |         } | 
 | 255 |     } | 
 | 256 |  | 
 | 257 |     int64_t totalGPUDrawTime = frame.gpuDrawTime(); | 
 | 258 |     if (totalGPUDrawTime >= 0) { | 
 | 259 |         mData->reportGPUFrame(totalGPUDrawTime); | 
 | 260 |         (*mGlobalData)->reportGPUFrame(totalGPUDrawTime); | 
 | 261 |     } | 
 | 262 |  | 
 | 263 |     if (CC_UNLIKELY(reporter.get() != nullptr)) { | 
| Pablo Gamito | 88660d7 | 2021-08-09 14:37:56 +0000 | [diff] [blame] | 264 |         reporter->reportFrameMetrics(frame.data(), false /* hasPresentTime */, frameNumber, | 
 | 265 |                                      surfaceControlId); | 
| Jorim Jaggi | 10f328c | 2021-01-19 00:08:02 +0100 | [diff] [blame] | 266 |     } | 
 | 267 | } | 
 | 268 |  | 
| Siarhei Vishniakou | 07d35cb | 2021-07-03 02:22:12 +0000 | [diff] [blame] | 269 | void JankTracker::recomputeThresholds(int64_t frameBudget) REQUIRES(mDataMutex) { | 
| Jorim Jaggi | 10f328c | 2021-01-19 00:08:02 +0100 | [diff] [blame] | 270 |     if (mThresholdsFrameBudget == frameBudget) { | 
| John Reck | 0e48647 | 2018-03-19 14:06:16 -0700 | [diff] [blame] | 271 |         return; | 
 | 272 |     } | 
| Jorim Jaggi | 10f328c | 2021-01-19 00:08:02 +0100 | [diff] [blame] | 273 |     mThresholdsFrameBudget = frameBudget; | 
| John Reck | 0e48647 | 2018-03-19 14:06:16 -0700 | [diff] [blame] | 274 |     for (auto& comparison : COMPARISONS) { | 
| Jorim Jaggi | 10f328c | 2021-01-19 00:08:02 +0100 | [diff] [blame] | 275 |         mThresholds[comparison.type] = comparison.computeThreadshold(frameBudget); | 
| John Reck | 0e89ca2 | 2017-12-15 16:00:48 -0800 | [diff] [blame] | 276 |     } | 
| John Reck | ba6adf6 | 2015-02-19 14:36:50 -0800 | [diff] [blame] | 277 | } | 
 | 278 |  | 
| John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 279 | void JankTracker::dumpData(int fd, const ProfileDataDescription* description, | 
 | 280 |                            const ProfileData* data) { | 
| Jorim Jaggi | 71db889 | 2021-02-03 23:19:29 +0100 | [diff] [blame] | 281 |  | 
| John Reck | df1742e | 2017-01-19 15:56:21 -0800 | [diff] [blame] | 282 |     if (description) { | 
 | 283 |         switch (description->type) { | 
 | 284 |             case JankTrackerType::Generic: | 
 | 285 |                 break; | 
 | 286 |             case JankTrackerType::Package: | 
 | 287 |                 dprintf(fd, "\nPackage: %s", description->name.c_str()); | 
 | 288 |                 break; | 
 | 289 |             case JankTrackerType::Window: | 
 | 290 |                 dprintf(fd, "\nWindow: %s", description->name.c_str()); | 
 | 291 |                 break; | 
 | 292 |         } | 
| John Reck | ba6adf6 | 2015-02-19 14:36:50 -0800 | [diff] [blame] | 293 |     } | 
| John Reck | c7cd9cf | 2016-03-28 10:38:19 -0700 | [diff] [blame] | 294 |     if (sFrameStart != FrameInfoIndex::IntendedVsync) { | 
 | 295 |         dprintf(fd, "\nNote: Data has been filtered!"); | 
 | 296 |     } | 
| John Reck | 7075c79 | 2017-07-05 14:03:43 -0700 | [diff] [blame] | 297 |     data->dump(fd); | 
| John Reck | edc524c | 2015-03-18 15:24:33 -0700 | [diff] [blame] | 298 |     dprintf(fd, "\n"); | 
| John Reck | ba6adf6 | 2015-02-19 14:36:50 -0800 | [diff] [blame] | 299 | } | 
 | 300 |  | 
| John Reck | 34781b2 | 2017-07-05 16:39:36 -0700 | [diff] [blame] | 301 | void JankTracker::dumpFrames(int fd) { | 
| John Reck | 47f5c3a | 2017-11-13 11:32:39 -0800 | [diff] [blame] | 302 |     dprintf(fd, "\n\n---PROFILEDATA---\n"); | 
| John Reck | 34781b2 | 2017-07-05 16:39:36 -0700 | [diff] [blame] | 303 |     for (size_t i = 0; i < static_cast<size_t>(FrameInfoIndex::NumIndexes); i++) { | 
| Siarhei Vishniakou | 4bcbffd | 2021-02-17 06:19:36 +0000 | [diff] [blame] | 304 |         dprintf(fd, "%s", FrameInfoNames[i]); | 
| John Reck | 47f5c3a | 2017-11-13 11:32:39 -0800 | [diff] [blame] | 305 |         dprintf(fd, ","); | 
| John Reck | 34781b2 | 2017-07-05 16:39:36 -0700 | [diff] [blame] | 306 |     } | 
 | 307 |     for (size_t i = 0; i < mFrames.size(); i++) { | 
 | 308 |         FrameInfo& frame = mFrames[i]; | 
 | 309 |         if (frame[FrameInfoIndex::SyncStart] == 0) { | 
 | 310 |             continue; | 
 | 311 |         } | 
| John Reck | 47f5c3a | 2017-11-13 11:32:39 -0800 | [diff] [blame] | 312 |         dprintf(fd, "\n"); | 
| John Reck | 34781b2 | 2017-07-05 16:39:36 -0700 | [diff] [blame] | 313 |         for (int i = 0; i < static_cast<int>(FrameInfoIndex::NumIndexes); i++) { | 
| John Reck | 47f5c3a | 2017-11-13 11:32:39 -0800 | [diff] [blame] | 314 |             dprintf(fd, "%" PRId64 ",", frame[i]); | 
| John Reck | 34781b2 | 2017-07-05 16:39:36 -0700 | [diff] [blame] | 315 |         } | 
 | 316 |     } | 
| John Reck | 47f5c3a | 2017-11-13 11:32:39 -0800 | [diff] [blame] | 317 |     dprintf(fd, "\n---PROFILEDATA---\n\n"); | 
| John Reck | 34781b2 | 2017-07-05 16:39:36 -0700 | [diff] [blame] | 318 | } | 
 | 319 |  | 
| Siarhei Vishniakou | 07d35cb | 2021-07-03 02:22:12 +0000 | [diff] [blame] | 320 | void JankTracker::reset() REQUIRES(mDataMutex) { | 
| John Reck | 34781b2 | 2017-07-05 16:39:36 -0700 | [diff] [blame] | 321 |     mFrames.clear(); | 
| John Reck | 7075c79 | 2017-07-05 14:03:43 -0700 | [diff] [blame] | 322 |     mData->reset(); | 
| John Reck | 34781b2 | 2017-07-05 16:39:36 -0700 | [diff] [blame] | 323 |     (*mGlobalData)->reset(); | 
| John Reck | 1bcacfd | 2017-11-03 10:12:19 -0700 | [diff] [blame] | 324 |     sFrameStart = Properties::filterOutTestOverhead ? FrameInfoIndex::HandleInputStart | 
 | 325 |                                                     : FrameInfoIndex::IntendedVsync; | 
| John Reck | ba6adf6 | 2015-02-19 14:36:50 -0800 | [diff] [blame] | 326 | } | 
 | 327 |  | 
| John Reck | ba6adf6 | 2015-02-19 14:36:50 -0800 | [diff] [blame] | 328 | } /* namespace uirenderer */ | 
 | 329 | } /* namespace android */ |