| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright 2018 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 |  */ | 
| Ady Abraham | b0dbdaa | 2020-01-06 16:19:42 -0800 | [diff] [blame] | 16 |  | 
| Alec Mouri | 75de8f2 | 2021-01-20 14:53:44 -0800 | [diff] [blame] | 17 | #include <unordered_map> | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 18 | #undef LOG_TAG | 
 | 19 | #define LOG_TAG "TimeStats" | 
 | 20 | #define ATRACE_TAG ATRACE_TAG_GRAPHICS | 
 | 21 |  | 
 | 22 | #include "TimeStats.h" | 
 | 23 |  | 
 | 24 | #include <android-base/stringprintf.h> | 
| Alec Mouri | 3738434 | 2020-01-02 17:23:37 -0800 | [diff] [blame] | 25 | #include <android/util/ProtoOutputStream.h> | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 26 | #include <log/log.h> | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 27 | #include <utils/String8.h> | 
| Yiwei Zhang | 3a226d2 | 2018-10-16 09:23:03 -0700 | [diff] [blame] | 28 | #include <utils/Timers.h> | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 29 | #include <utils/Trace.h> | 
 | 30 |  | 
 | 31 | #include <algorithm> | 
| Alec Mouri | 9519bf1 | 2019-11-15 16:54:44 -0800 | [diff] [blame] | 32 | #include <chrono> | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 33 |  | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 34 | #include "timestatsproto/TimeStatsHelper.h" | 
 | 35 |  | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 36 | namespace android { | 
 | 37 |  | 
| Alec Mouri | fb571ea | 2019-01-24 18:42:10 -0800 | [diff] [blame] | 38 | namespace impl { | 
 | 39 |  | 
| Tej Singh | 2a457b6 | 2020-01-31 16:16:10 -0800 | [diff] [blame] | 40 | AStatsManager_PullAtomCallbackReturn TimeStats::pullAtomCallback(int32_t atom_tag, | 
 | 41 |                                                                  AStatsEventList* data, | 
 | 42 |                                                                  void* cookie) { | 
| Alec Mouri | 8e2f31b | 2020-01-16 22:04:35 +0000 | [diff] [blame] | 43 |     impl::TimeStats* timeStats = reinterpret_cast<impl::TimeStats*>(cookie); | 
| Tej Singh | 2a457b6 | 2020-01-31 16:16:10 -0800 | [diff] [blame] | 44 |     AStatsManager_PullAtomCallbackReturn result = AStatsManager_PULL_SKIP; | 
| Alec Mouri | 3738434 | 2020-01-02 17:23:37 -0800 | [diff] [blame] | 45 |     if (atom_tag == android::util::SURFACEFLINGER_STATS_GLOBAL_INFO) { | 
| Alec Mouri | 3ecd5cd | 2020-01-29 12:53:07 -0800 | [diff] [blame] | 46 |         result = timeStats->populateGlobalAtom(data); | 
| Alec Mouri | 3738434 | 2020-01-02 17:23:37 -0800 | [diff] [blame] | 47 |     } else if (atom_tag == android::util::SURFACEFLINGER_STATS_LAYER_INFO) { | 
| Alec Mouri | 3ecd5cd | 2020-01-29 12:53:07 -0800 | [diff] [blame] | 48 |         result = timeStats->populateLayerAtom(data); | 
| Alec Mouri | 8e2f31b | 2020-01-16 22:04:35 +0000 | [diff] [blame] | 49 |     } | 
 | 50 |  | 
| Alec Mouri | 3ecd5cd | 2020-01-29 12:53:07 -0800 | [diff] [blame] | 51 |     // Enable timestats now. The first full pull for a given build is expected to | 
 | 52 |     // have empty or very little stats, as stats are first enabled after the | 
 | 53 |     // first pull is completed for either the global or layer stats. | 
 | 54 |     timeStats->enable(); | 
 | 55 |     return result; | 
| Alec Mouri | 3738434 | 2020-01-02 17:23:37 -0800 | [diff] [blame] | 56 | } | 
| Alec Mouri | 8e2f31b | 2020-01-16 22:04:35 +0000 | [diff] [blame] | 57 |  | 
| Alec Mouri | 3738434 | 2020-01-02 17:23:37 -0800 | [diff] [blame] | 58 | namespace { | 
 | 59 | // Histograms align with the order of fields in SurfaceflingerStatsLayerInfo. | 
 | 60 | const std::array<std::string, 6> kHistogramNames = { | 
 | 61 |         "present2present", "post2present",    "acquire2present", | 
 | 62 |         "latch2present",   "desired2present", "post2acquire", | 
 | 63 | }; | 
| Alec Mouri | 8e2f31b | 2020-01-16 22:04:35 +0000 | [diff] [blame] | 64 |  | 
| Alec Mouri | 3738434 | 2020-01-02 17:23:37 -0800 | [diff] [blame] | 65 | std::string histogramToProtoByteString(const std::unordered_map<int32_t, int32_t>& histogram, | 
 | 66 |                                        size_t maxPulledHistogramBuckets) { | 
 | 67 |     auto buckets = std::vector<std::pair<int32_t, int32_t>>(histogram.begin(), histogram.end()); | 
 | 68 |     std::sort(buckets.begin(), buckets.end(), | 
 | 69 |               [](std::pair<int32_t, int32_t>& left, std::pair<int32_t, int32_t>& right) { | 
 | 70 |                   return left.second > right.second; | 
 | 71 |               }); | 
 | 72 |  | 
 | 73 |     util::ProtoOutputStream proto; | 
 | 74 |     int histogramSize = 0; | 
 | 75 |     for (const auto& bucket : buckets) { | 
 | 76 |         if (++histogramSize > maxPulledHistogramBuckets) { | 
 | 77 |             break; | 
 | 78 |         } | 
 | 79 |         proto.write(android::util::FIELD_TYPE_INT32 | android::util::FIELD_COUNT_REPEATED | | 
 | 80 |                             1 /* field id */, | 
 | 81 |                     (int32_t)bucket.first); | 
 | 82 |         proto.write(android::util::FIELD_TYPE_INT64 | android::util::FIELD_COUNT_REPEATED | | 
 | 83 |                             2 /* field id */, | 
 | 84 |                     (int64_t)bucket.second); | 
 | 85 |     } | 
 | 86 |  | 
 | 87 |     std::string byteString; | 
 | 88 |     proto.serializeToString(&byteString); | 
 | 89 |     return byteString; | 
 | 90 | } | 
| Alec Mouri | 75de8f2 | 2021-01-20 14:53:44 -0800 | [diff] [blame] | 91 |  | 
 | 92 | std::string frameRateVoteToProtoByteString(float refreshRate, int frameRateCompatibility, | 
 | 93 |                                            int seamlessness) { | 
 | 94 |     util::ProtoOutputStream proto; | 
 | 95 |     proto.write(android::util::FIELD_TYPE_FLOAT | 1 /* field id */, refreshRate); | 
 | 96 |     proto.write(android::util::FIELD_TYPE_ENUM | 2 /* field id */, frameRateCompatibility); | 
 | 97 |     proto.write(android::util::FIELD_TYPE_ENUM | 3 /* field id */, seamlessness); | 
 | 98 |  | 
 | 99 |     std::string byteString; | 
 | 100 |     proto.serializeToString(&byteString); | 
 | 101 |     return byteString; | 
 | 102 | } | 
| Alec Mouri | 3738434 | 2020-01-02 17:23:37 -0800 | [diff] [blame] | 103 | } // namespace | 
 | 104 |  | 
| Alec Mouri | dfad900 | 2020-02-12 17:49:09 -0800 | [diff] [blame] | 105 | AStatsManager_PullAtomCallbackReturn TimeStats::populateGlobalAtom(AStatsEventList* data) { | 
 | 106 |     std::lock_guard<std::mutex> lock(mMutex); | 
 | 107 |  | 
 | 108 |     if (mTimeStats.statsStart == 0) { | 
 | 109 |         return AStatsManager_PULL_SKIP; | 
 | 110 |     } | 
 | 111 |     flushPowerTimeLocked(); | 
 | 112 |  | 
 | 113 |     AStatsEvent* event = mStatsDelegate->addStatsEventToPullData(data); | 
 | 114 |     mStatsDelegate->statsEventSetAtomId(event, android::util::SURFACEFLINGER_STATS_GLOBAL_INFO); | 
 | 115 |     mStatsDelegate->statsEventWriteInt64(event, mTimeStats.totalFrames); | 
 | 116 |     mStatsDelegate->statsEventWriteInt64(event, mTimeStats.missedFrames); | 
 | 117 |     mStatsDelegate->statsEventWriteInt64(event, mTimeStats.clientCompositionFrames); | 
 | 118 |     mStatsDelegate->statsEventWriteInt64(event, mTimeStats.displayOnTime); | 
 | 119 |     mStatsDelegate->statsEventWriteInt64(event, mTimeStats.presentToPresent.totalTime()); | 
 | 120 |     mStatsDelegate->statsEventWriteInt32(event, mTimeStats.displayEventConnectionsCount); | 
 | 121 |     std::string frameDurationBytes = | 
 | 122 |             histogramToProtoByteString(mTimeStats.frameDuration.hist, mMaxPulledHistogramBuckets); | 
 | 123 |     mStatsDelegate->statsEventWriteByteArray(event, (const uint8_t*)frameDurationBytes.c_str(), | 
 | 124 |                                              frameDurationBytes.size()); | 
 | 125 |     std::string renderEngineTimingBytes = | 
 | 126 |             histogramToProtoByteString(mTimeStats.renderEngineTiming.hist, | 
 | 127 |                                        mMaxPulledHistogramBuckets); | 
 | 128 |     mStatsDelegate->statsEventWriteByteArray(event, (const uint8_t*)renderEngineTimingBytes.c_str(), | 
 | 129 |                                              renderEngineTimingBytes.size()); | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 130 |  | 
 | 131 |     mStatsDelegate->statsEventWriteInt32(event, mTimeStats.jankPayload.totalFrames); | 
 | 132 |     mStatsDelegate->statsEventWriteInt32(event, mTimeStats.jankPayload.totalJankyFrames); | 
 | 133 |     mStatsDelegate->statsEventWriteInt32(event, mTimeStats.jankPayload.totalSFLongCpu); | 
 | 134 |     mStatsDelegate->statsEventWriteInt32(event, mTimeStats.jankPayload.totalSFLongGpu); | 
 | 135 |     mStatsDelegate->statsEventWriteInt32(event, mTimeStats.jankPayload.totalSFUnattributed); | 
 | 136 |     mStatsDelegate->statsEventWriteInt32(event, mTimeStats.jankPayload.totalAppUnattributed); | 
| Alec Mouri | 75de8f2 | 2021-01-20 14:53:44 -0800 | [diff] [blame] | 137 |  | 
 | 138 |     // TODO: populate these with real values | 
 | 139 |     mStatsDelegate->statsEventWriteInt32(event, 0); // total_janky_frames_sf_scheduling | 
 | 140 |     mStatsDelegate->statsEventWriteInt32(event, 0); // total_jank_frames_sf_prediction_error | 
 | 141 |     mStatsDelegate->statsEventWriteInt32(event, 0); // total_jank_frames_app_buffer_stuffing | 
 | 142 |     mStatsDelegate->statsEventWriteInt32(event, 0); // display_refresh_rate_bucket | 
 | 143 |     std::string sfDeadlineMissedBytes = | 
 | 144 |             histogramToProtoByteString(std::unordered_map<int32_t, int32_t>(), | 
 | 145 |                                        mMaxPulledHistogramBuckets); | 
 | 146 |     mStatsDelegate->statsEventWriteByteArray(event, (const uint8_t*)sfDeadlineMissedBytes.c_str(), | 
 | 147 |                                              sfDeadlineMissedBytes.size()); // sf_deadline_misses | 
 | 148 |     std::string sfPredictionErrorBytes = | 
 | 149 |             histogramToProtoByteString(std::unordered_map<int32_t, int32_t>(), | 
 | 150 |                                        mMaxPulledHistogramBuckets); | 
 | 151 |     mStatsDelegate->statsEventWriteByteArray(event, (const uint8_t*)sfPredictionErrorBytes.c_str(), | 
 | 152 |                                              sfPredictionErrorBytes.size()); // sf_prediction_errors | 
 | 153 |     mStatsDelegate->statsEventWriteInt32(event, 0); // render_rate_bucket | 
| Alec Mouri | dfad900 | 2020-02-12 17:49:09 -0800 | [diff] [blame] | 154 |     mStatsDelegate->statsEventBuild(event); | 
 | 155 |     clearGlobalLocked(); | 
 | 156 |  | 
 | 157 |     return AStatsManager_PULL_SUCCESS; | 
 | 158 | } | 
 | 159 |  | 
| Tej Singh | 2a457b6 | 2020-01-31 16:16:10 -0800 | [diff] [blame] | 160 | AStatsManager_PullAtomCallbackReturn TimeStats::populateLayerAtom(AStatsEventList* data) { | 
| Alec Mouri | 3738434 | 2020-01-02 17:23:37 -0800 | [diff] [blame] | 161 |     std::lock_guard<std::mutex> lock(mMutex); | 
 | 162 |  | 
 | 163 |     std::vector<TimeStatsHelper::TimeStatsLayer const*> dumpStats; | 
 | 164 |     for (const auto& ele : mTimeStats.stats) { | 
 | 165 |         dumpStats.push_back(&ele.second); | 
 | 166 |     } | 
 | 167 |  | 
 | 168 |     std::sort(dumpStats.begin(), dumpStats.end(), | 
 | 169 |               [](TimeStatsHelper::TimeStatsLayer const* l, | 
 | 170 |                  TimeStatsHelper::TimeStatsLayer const* r) { | 
 | 171 |                   return l->totalFrames > r->totalFrames; | 
 | 172 |               }); | 
 | 173 |  | 
 | 174 |     if (mMaxPulledLayers < dumpStats.size()) { | 
 | 175 |         dumpStats.resize(mMaxPulledLayers); | 
 | 176 |     } | 
 | 177 |  | 
 | 178 |     for (const auto& layer : dumpStats) { | 
| Tej Singh | 2a457b6 | 2020-01-31 16:16:10 -0800 | [diff] [blame] | 179 |         AStatsEvent* event = mStatsDelegate->addStatsEventToPullData(data); | 
| Alec Mouri | 3738434 | 2020-01-02 17:23:37 -0800 | [diff] [blame] | 180 |         mStatsDelegate->statsEventSetAtomId(event, android::util::SURFACEFLINGER_STATS_LAYER_INFO); | 
 | 181 |         mStatsDelegate->statsEventWriteString8(event, layer->layerName.c_str()); | 
 | 182 |         mStatsDelegate->statsEventWriteInt64(event, layer->totalFrames); | 
 | 183 |         mStatsDelegate->statsEventWriteInt64(event, layer->droppedFrames); | 
 | 184 |  | 
 | 185 |         for (const auto& name : kHistogramNames) { | 
 | 186 |             const auto& histogram = layer->deltas.find(name); | 
 | 187 |             if (histogram == layer->deltas.cend()) { | 
 | 188 |                 mStatsDelegate->statsEventWriteByteArray(event, nullptr, 0); | 
 | 189 |             } else { | 
 | 190 |                 std::string bytes = histogramToProtoByteString(histogram->second.hist, | 
 | 191 |                                                                mMaxPulledHistogramBuckets); | 
 | 192 |                 mStatsDelegate->statsEventWriteByteArray(event, (const uint8_t*)bytes.c_str(), | 
 | 193 |                                                          bytes.size()); | 
 | 194 |             } | 
 | 195 |         } | 
 | 196 |  | 
| Yiwei Zhang | 7bfc75b | 2020-02-10 11:20:34 -0800 | [diff] [blame] | 197 |         mStatsDelegate->statsEventWriteInt64(event, layer->lateAcquireFrames); | 
 | 198 |         mStatsDelegate->statsEventWriteInt64(event, layer->badDesiredPresentFrames); | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 199 |         mStatsDelegate->statsEventWriteInt32(event, layer->uid); | 
 | 200 |         mStatsDelegate->statsEventWriteInt32(event, layer->jankPayload.totalFrames); | 
 | 201 |         mStatsDelegate->statsEventWriteInt32(event, layer->jankPayload.totalJankyFrames); | 
 | 202 |         mStatsDelegate->statsEventWriteInt32(event, layer->jankPayload.totalSFLongCpu); | 
 | 203 |         mStatsDelegate->statsEventWriteInt32(event, layer->jankPayload.totalSFLongGpu); | 
 | 204 |         mStatsDelegate->statsEventWriteInt32(event, layer->jankPayload.totalSFUnattributed); | 
 | 205 |         mStatsDelegate->statsEventWriteInt32(event, layer->jankPayload.totalAppUnattributed); | 
| Yiwei Zhang | 7bfc75b | 2020-02-10 11:20:34 -0800 | [diff] [blame] | 206 |  | 
| Alec Mouri | 75de8f2 | 2021-01-20 14:53:44 -0800 | [diff] [blame] | 207 |         // TODO: populate these with real values | 
 | 208 |         mStatsDelegate->statsEventWriteInt32(event, 0); // total_janky_frames_sf_scheduling | 
 | 209 |         mStatsDelegate->statsEventWriteInt32(event, 0); // total_jank_frames_sf_prediction_error | 
 | 210 |         mStatsDelegate->statsEventWriteInt32(event, 0); // total_jank_frames_app_buffer_stuffing | 
 | 211 |         mStatsDelegate->statsEventWriteInt32(event, 0); // display_refresh_rate_bucket | 
 | 212 |         mStatsDelegate->statsEventWriteInt32(event, 0); // render_rate_bucket | 
 | 213 |         std::string frameRateVoteBytes = frameRateVoteToProtoByteString(0.0, 0, 0); | 
 | 214 |         mStatsDelegate->statsEventWriteByteArray(event, (const uint8_t*)frameRateVoteBytes.c_str(), | 
 | 215 |                                                  frameRateVoteBytes.size()); // set_frame_rate_vote | 
 | 216 |         std::string appDeadlineMissedBytes = | 
 | 217 |                 histogramToProtoByteString(std::unordered_map<int32_t, int32_t>(), | 
 | 218 |                                            mMaxPulledHistogramBuckets); | 
 | 219 |         mStatsDelegate | 
 | 220 |                 ->statsEventWriteByteArray(event, (const uint8_t*)appDeadlineMissedBytes.c_str(), | 
 | 221 |                                            appDeadlineMissedBytes.size()); // app_deadline_misses | 
 | 222 |  | 
| Alec Mouri | 3738434 | 2020-01-02 17:23:37 -0800 | [diff] [blame] | 223 |         mStatsDelegate->statsEventBuild(event); | 
 | 224 |     } | 
 | 225 |     clearLayersLocked(); | 
 | 226 |  | 
| Tej Singh | 2a457b6 | 2020-01-31 16:16:10 -0800 | [diff] [blame] | 227 |     return AStatsManager_PULL_SUCCESS; | 
| Alec Mouri | 3738434 | 2020-01-02 17:23:37 -0800 | [diff] [blame] | 228 | } | 
 | 229 |  | 
 | 230 | TimeStats::TimeStats() : TimeStats(nullptr, std::nullopt, std::nullopt) {} | 
 | 231 |  | 
 | 232 | TimeStats::TimeStats(std::unique_ptr<StatsEventDelegate> statsDelegate, | 
 | 233 |                      std::optional<size_t> maxPulledLayers, | 
 | 234 |                      std::optional<size_t> maxPulledHistogramBuckets) { | 
| Alec Mouri | 8e2f31b | 2020-01-16 22:04:35 +0000 | [diff] [blame] | 235 |     if (statsDelegate != nullptr) { | 
 | 236 |         mStatsDelegate = std::move(statsDelegate); | 
 | 237 |     } | 
| Alec Mouri | 3738434 | 2020-01-02 17:23:37 -0800 | [diff] [blame] | 238 |  | 
 | 239 |     if (maxPulledLayers) { | 
 | 240 |         mMaxPulledLayers = *maxPulledLayers; | 
 | 241 |     } | 
 | 242 |  | 
 | 243 |     if (maxPulledHistogramBuckets) { | 
 | 244 |         mMaxPulledHistogramBuckets = *maxPulledHistogramBuckets; | 
 | 245 |     } | 
| Alec Mouri | 8e2f31b | 2020-01-16 22:04:35 +0000 | [diff] [blame] | 246 | } | 
 | 247 |  | 
| Alec Mouri | 3ecd5cd | 2020-01-29 12:53:07 -0800 | [diff] [blame] | 248 | TimeStats::~TimeStats() { | 
 | 249 |     std::lock_guard<std::mutex> lock(mMutex); | 
| Tej Singh | 38a4b21 | 2020-03-13 19:04:51 -0700 | [diff] [blame] | 250 |     mStatsDelegate->clearStatsPullAtomCallback(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO); | 
 | 251 |     mStatsDelegate->clearStatsPullAtomCallback(android::util::SURFACEFLINGER_STATS_LAYER_INFO); | 
| Alec Mouri | 3ecd5cd | 2020-01-29 12:53:07 -0800 | [diff] [blame] | 252 | } | 
 | 253 |  | 
| Alec Mouri | 8e2f31b | 2020-01-16 22:04:35 +0000 | [diff] [blame] | 254 | void TimeStats::onBootFinished() { | 
| Alec Mouri | 3ecd5cd | 2020-01-29 12:53:07 -0800 | [diff] [blame] | 255 |     std::lock_guard<std::mutex> lock(mMutex); | 
| Tej Singh | 38a4b21 | 2020-03-13 19:04:51 -0700 | [diff] [blame] | 256 |     mStatsDelegate->setStatsPullAtomCallback(android::util::SURFACEFLINGER_STATS_GLOBAL_INFO, | 
 | 257 |                                              nullptr, TimeStats::pullAtomCallback, this); | 
 | 258 |     mStatsDelegate->setStatsPullAtomCallback(android::util::SURFACEFLINGER_STATS_LAYER_INFO, | 
 | 259 |                                              nullptr, TimeStats::pullAtomCallback, this); | 
| Alec Mouri | b3885ad | 2019-09-06 17:08:55 -0700 | [diff] [blame] | 260 | } | 
 | 261 |  | 
| Dominik Laskowski | c286714 | 2019-01-21 11:33:38 -0800 | [diff] [blame] | 262 | void TimeStats::parseArgs(bool asProto, const Vector<String16>& args, std::string& result) { | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 263 |     ATRACE_CALL(); | 
 | 264 |  | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 265 |     std::unordered_map<std::string, int32_t> argsMap; | 
| Dominik Laskowski | c286714 | 2019-01-21 11:33:38 -0800 | [diff] [blame] | 266 |     for (size_t index = 0; index < args.size(); ++index) { | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 267 |         argsMap[std::string(String8(args[index]).c_str())] = index; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 268 |     } | 
 | 269 |  | 
 | 270 |     if (argsMap.count("-disable")) { | 
 | 271 |         disable(); | 
 | 272 |     } | 
 | 273 |  | 
 | 274 |     if (argsMap.count("-dump")) { | 
| Yiwei Zhang | 8a4015c | 2018-05-08 16:03:47 -0700 | [diff] [blame] | 275 |         std::optional<uint32_t> maxLayers = std::nullopt; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 276 |         auto iter = argsMap.find("-maxlayers"); | 
 | 277 |         if (iter != argsMap.end() && iter->second + 1 < static_cast<int32_t>(args.size())) { | 
| Yiwei Zhang | 8a4015c | 2018-05-08 16:03:47 -0700 | [diff] [blame] | 278 |             int64_t value = strtol(String8(args[iter->second + 1]).c_str(), nullptr, 10); | 
 | 279 |             value = std::clamp(value, int64_t(0), int64_t(UINT32_MAX)); | 
 | 280 |             maxLayers = static_cast<uint32_t>(value); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 281 |         } | 
 | 282 |  | 
| Yiwei Zhang | 8a4015c | 2018-05-08 16:03:47 -0700 | [diff] [blame] | 283 |         dump(asProto, maxLayers, result); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 284 |     } | 
 | 285 |  | 
 | 286 |     if (argsMap.count("-clear")) { | 
| Alec Mouri | 8e2f31b | 2020-01-16 22:04:35 +0000 | [diff] [blame] | 287 |         clearAll(); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 288 |     } | 
 | 289 |  | 
 | 290 |     if (argsMap.count("-enable")) { | 
 | 291 |         enable(); | 
 | 292 |     } | 
 | 293 | } | 
 | 294 |  | 
| Yiwei Zhang | 7eb58b7 | 2019-04-22 19:00:02 -0700 | [diff] [blame] | 295 | std::string TimeStats::miniDump() { | 
 | 296 |     ATRACE_CALL(); | 
 | 297 |  | 
 | 298 |     std::string result = "TimeStats miniDump:\n"; | 
 | 299 |     std::lock_guard<std::mutex> lock(mMutex); | 
| Yiwei Zhang | e926ab5 | 2019-08-14 15:16:00 -0700 | [diff] [blame] | 300 |     android::base::StringAppendF(&result, "Number of layers currently being tracked is %zu\n", | 
| Yiwei Zhang | 7eb58b7 | 2019-04-22 19:00:02 -0700 | [diff] [blame] | 301 |                                  mTimeStatsTracker.size()); | 
| Yiwei Zhang | e926ab5 | 2019-08-14 15:16:00 -0700 | [diff] [blame] | 302 |     android::base::StringAppendF(&result, "Number of layers in the stats pool is %zu\n", | 
 | 303 |                                  mTimeStats.stats.size()); | 
| Yiwei Zhang | 7eb58b7 | 2019-04-22 19:00:02 -0700 | [diff] [blame] | 304 |     return result; | 
 | 305 | } | 
 | 306 |  | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 307 | void TimeStats::incrementTotalFrames() { | 
 | 308 |     if (!mEnabled.load()) return; | 
 | 309 |  | 
 | 310 |     ATRACE_CALL(); | 
 | 311 |  | 
 | 312 |     std::lock_guard<std::mutex> lock(mMutex); | 
| Yiwei Zhang | dc22404 | 2018-10-18 15:34:00 -0700 | [diff] [blame] | 313 |     mTimeStats.totalFrames++; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 314 | } | 
 | 315 |  | 
| Yiwei Zhang | 621f9d4 | 2018-05-07 10:40:55 -0700 | [diff] [blame] | 316 | void TimeStats::incrementMissedFrames() { | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 317 |     if (!mEnabled.load()) return; | 
 | 318 |  | 
 | 319 |     ATRACE_CALL(); | 
 | 320 |  | 
 | 321 |     std::lock_guard<std::mutex> lock(mMutex); | 
| Yiwei Zhang | dc22404 | 2018-10-18 15:34:00 -0700 | [diff] [blame] | 322 |     mTimeStats.missedFrames++; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 323 | } | 
 | 324 |  | 
 | 325 | void TimeStats::incrementClientCompositionFrames() { | 
 | 326 |     if (!mEnabled.load()) return; | 
 | 327 |  | 
 | 328 |     ATRACE_CALL(); | 
 | 329 |  | 
 | 330 |     std::lock_guard<std::mutex> lock(mMutex); | 
| Yiwei Zhang | dc22404 | 2018-10-18 15:34:00 -0700 | [diff] [blame] | 331 |     mTimeStats.clientCompositionFrames++; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 332 | } | 
 | 333 |  | 
| Vishnu Nair | 9b079a2 | 2020-01-21 14:36:08 -0800 | [diff] [blame] | 334 | void TimeStats::incrementClientCompositionReusedFrames() { | 
 | 335 |     if (!mEnabled.load()) return; | 
 | 336 |  | 
 | 337 |     ATRACE_CALL(); | 
 | 338 |  | 
 | 339 |     std::lock_guard<std::mutex> lock(mMutex); | 
 | 340 |     mTimeStats.clientCompositionReusedFrames++; | 
 | 341 | } | 
 | 342 |  | 
| Alec Mouri | 8de697e | 2020-03-19 10:52:01 -0700 | [diff] [blame] | 343 | void TimeStats::incrementRefreshRateSwitches() { | 
 | 344 |     if (!mEnabled.load()) return; | 
 | 345 |  | 
 | 346 |     ATRACE_CALL(); | 
 | 347 |  | 
 | 348 |     std::lock_guard<std::mutex> lock(mMutex); | 
 | 349 |     mTimeStats.refreshRateSwitches++; | 
 | 350 | } | 
 | 351 |  | 
| Alec Mouri | 8f7a010 | 2020-04-15 12:11:10 -0700 | [diff] [blame] | 352 | void TimeStats::incrementCompositionStrategyChanges() { | 
 | 353 |     if (!mEnabled.load()) return; | 
 | 354 |  | 
 | 355 |     ATRACE_CALL(); | 
 | 356 |  | 
 | 357 |     std::lock_guard<std::mutex> lock(mMutex); | 
 | 358 |     mTimeStats.compositionStrategyChanges++; | 
 | 359 | } | 
 | 360 |  | 
| Alec Mouri | 717bcb6 | 2020-02-10 17:07:19 -0800 | [diff] [blame] | 361 | void TimeStats::recordDisplayEventConnectionCount(int32_t count) { | 
 | 362 |     if (!mEnabled.load()) return; | 
 | 363 |  | 
 | 364 |     ATRACE_CALL(); | 
 | 365 |  | 
 | 366 |     std::lock_guard<std::mutex> lock(mMutex); | 
 | 367 |     mTimeStats.displayEventConnectionsCount = | 
 | 368 |             std::max(mTimeStats.displayEventConnectionsCount, count); | 
 | 369 | } | 
 | 370 |  | 
| Alec Mouri | 9519bf1 | 2019-11-15 16:54:44 -0800 | [diff] [blame] | 371 | static int32_t msBetween(nsecs_t start, nsecs_t end) { | 
 | 372 |     int64_t delta = std::chrono::duration_cast<std::chrono::milliseconds>( | 
 | 373 |                             std::chrono::nanoseconds(end - start)) | 
 | 374 |                             .count(); | 
 | 375 |     delta = std::clamp(delta, int64_t(INT32_MIN), int64_t(INT32_MAX)); | 
 | 376 |     return static_cast<int32_t>(delta); | 
 | 377 | } | 
 | 378 |  | 
 | 379 | void TimeStats::recordFrameDuration(nsecs_t startTime, nsecs_t endTime) { | 
 | 380 |     if (!mEnabled.load()) return; | 
 | 381 |  | 
 | 382 |     std::lock_guard<std::mutex> lock(mMutex); | 
| Peiyong Lin | 65248e0 | 2020-04-18 21:15:07 -0700 | [diff] [blame] | 383 |     if (mPowerTime.powerMode == PowerMode::ON) { | 
| Alec Mouri | 9519bf1 | 2019-11-15 16:54:44 -0800 | [diff] [blame] | 384 |         mTimeStats.frameDuration.insert(msBetween(startTime, endTime)); | 
 | 385 |     } | 
 | 386 | } | 
 | 387 |  | 
| Alec Mouri | e4034bb | 2019-11-19 12:45:54 -0800 | [diff] [blame] | 388 | void TimeStats::recordRenderEngineDuration(nsecs_t startTime, nsecs_t endTime) { | 
 | 389 |     if (!mEnabled.load()) return; | 
 | 390 |  | 
 | 391 |     std::lock_guard<std::mutex> lock(mMutex); | 
 | 392 |     if (mGlobalRecord.renderEngineDurations.size() == MAX_NUM_TIME_RECORDS) { | 
 | 393 |         ALOGE("RenderEngineTimes are already at its maximum size[%zu]", MAX_NUM_TIME_RECORDS); | 
 | 394 |         mGlobalRecord.renderEngineDurations.pop_front(); | 
 | 395 |     } | 
 | 396 |     mGlobalRecord.renderEngineDurations.push_back({startTime, endTime}); | 
 | 397 | } | 
 | 398 |  | 
 | 399 | void TimeStats::recordRenderEngineDuration(nsecs_t startTime, | 
 | 400 |                                            const std::shared_ptr<FenceTime>& endTime) { | 
 | 401 |     if (!mEnabled.load()) return; | 
 | 402 |  | 
 | 403 |     std::lock_guard<std::mutex> lock(mMutex); | 
 | 404 |     if (mGlobalRecord.renderEngineDurations.size() == MAX_NUM_TIME_RECORDS) { | 
 | 405 |         ALOGE("RenderEngineTimes are already at its maximum size[%zu]", MAX_NUM_TIME_RECORDS); | 
 | 406 |         mGlobalRecord.renderEngineDurations.pop_front(); | 
 | 407 |     } | 
 | 408 |     mGlobalRecord.renderEngineDurations.push_back({startTime, endTime}); | 
 | 409 | } | 
 | 410 |  | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 411 | bool TimeStats::recordReadyLocked(int32_t layerId, TimeRecord* timeRecord) { | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 412 |     if (!timeRecord->ready) { | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 413 |         ALOGV("[%d]-[%" PRIu64 "]-presentFence is still not received", layerId, | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 414 |               timeRecord->frameTime.frameNumber); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 415 |         return false; | 
 | 416 |     } | 
 | 417 |  | 
 | 418 |     if (timeRecord->acquireFence != nullptr) { | 
 | 419 |         if (timeRecord->acquireFence->getSignalTime() == Fence::SIGNAL_TIME_PENDING) { | 
 | 420 |             return false; | 
 | 421 |         } | 
 | 422 |         if (timeRecord->acquireFence->getSignalTime() != Fence::SIGNAL_TIME_INVALID) { | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 423 |             timeRecord->frameTime.acquireTime = timeRecord->acquireFence->getSignalTime(); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 424 |             timeRecord->acquireFence = nullptr; | 
 | 425 |         } else { | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 426 |             ALOGV("[%d]-[%" PRIu64 "]-acquireFence signal time is invalid", layerId, | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 427 |                   timeRecord->frameTime.frameNumber); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 428 |         } | 
 | 429 |     } | 
 | 430 |  | 
 | 431 |     if (timeRecord->presentFence != nullptr) { | 
 | 432 |         if (timeRecord->presentFence->getSignalTime() == Fence::SIGNAL_TIME_PENDING) { | 
 | 433 |             return false; | 
 | 434 |         } | 
 | 435 |         if (timeRecord->presentFence->getSignalTime() != Fence::SIGNAL_TIME_INVALID) { | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 436 |             timeRecord->frameTime.presentTime = timeRecord->presentFence->getSignalTime(); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 437 |             timeRecord->presentFence = nullptr; | 
 | 438 |         } else { | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 439 |             ALOGV("[%d]-[%" PRIu64 "]-presentFence signal time invalid", layerId, | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 440 |                   timeRecord->frameTime.frameNumber); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 441 |         } | 
 | 442 |     } | 
 | 443 |  | 
 | 444 |     return true; | 
 | 445 | } | 
 | 446 |  | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 447 | void TimeStats::flushAvailableRecordsToStatsLocked(int32_t layerId) { | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 448 |     ATRACE_CALL(); | 
 | 449 |  | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 450 |     LayerRecord& layerRecord = mTimeStatsTracker[layerId]; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 451 |     TimeRecord& prevTimeRecord = layerRecord.prevTimeRecord; | 
| Yiwei Zhang | c5f2c45 | 2018-05-08 16:31:56 -0700 | [diff] [blame] | 452 |     std::deque<TimeRecord>& timeRecords = layerRecord.timeRecords; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 453 |     while (!timeRecords.empty()) { | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 454 |         if (!recordReadyLocked(layerId, &timeRecords[0])) break; | 
 | 455 |         ALOGV("[%d]-[%" PRIu64 "]-presentFenceTime[%" PRId64 "]", layerId, | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 456 |               timeRecords[0].frameTime.frameNumber, timeRecords[0].frameTime.presentTime); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 457 |  | 
 | 458 |         if (prevTimeRecord.ready) { | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 459 |             uid_t uid = layerRecord.uid; | 
| Yiwei Zhang | eafa5cc | 2019-07-26 15:06:25 -0700 | [diff] [blame] | 460 |             const std::string& layerName = layerRecord.layerName; | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 461 |             if (!mTimeStats.stats.count({uid, layerName})) { | 
 | 462 |                 mTimeStats.stats[{uid, layerName}].uid = uid; | 
 | 463 |                 mTimeStats.stats[{uid, layerName}].layerName = layerName; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 464 |             } | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 465 |             TimeStatsHelper::TimeStatsLayer& timeStatsLayer = mTimeStats.stats[{uid, layerName}]; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 466 |             timeStatsLayer.totalFrames++; | 
| Yiwei Zhang | eaeea06 | 2018-06-28 14:46:51 -0700 | [diff] [blame] | 467 |             timeStatsLayer.droppedFrames += layerRecord.droppedFrames; | 
| Alec Mouri | 91f6df3 | 2020-01-30 08:48:58 -0800 | [diff] [blame] | 468 |             timeStatsLayer.lateAcquireFrames += layerRecord.lateAcquireFrames; | 
 | 469 |             timeStatsLayer.badDesiredPresentFrames += layerRecord.badDesiredPresentFrames; | 
 | 470 |  | 
| Yiwei Zhang | eaeea06 | 2018-06-28 14:46:51 -0700 | [diff] [blame] | 471 |             layerRecord.droppedFrames = 0; | 
| Alec Mouri | 91f6df3 | 2020-01-30 08:48:58 -0800 | [diff] [blame] | 472 |             layerRecord.lateAcquireFrames = 0; | 
 | 473 |             layerRecord.badDesiredPresentFrames = 0; | 
| Yiwei Zhang | eaeea06 | 2018-06-28 14:46:51 -0700 | [diff] [blame] | 474 |  | 
 | 475 |             const int32_t postToAcquireMs = msBetween(timeRecords[0].frameTime.postTime, | 
 | 476 |                                                       timeRecords[0].frameTime.acquireTime); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 477 |             ALOGV("[%d]-[%" PRIu64 "]-post2acquire[%d]", layerId, | 
| Yiwei Zhang | eaeea06 | 2018-06-28 14:46:51 -0700 | [diff] [blame] | 478 |                   timeRecords[0].frameTime.frameNumber, postToAcquireMs); | 
 | 479 |             timeStatsLayer.deltas["post2acquire"].insert(postToAcquireMs); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 480 |  | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 481 |             const int32_t postToPresentMs = msBetween(timeRecords[0].frameTime.postTime, | 
 | 482 |                                                       timeRecords[0].frameTime.presentTime); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 483 |             ALOGV("[%d]-[%" PRIu64 "]-post2present[%d]", layerId, | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 484 |                   timeRecords[0].frameTime.frameNumber, postToPresentMs); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 485 |             timeStatsLayer.deltas["post2present"].insert(postToPresentMs); | 
 | 486 |  | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 487 |             const int32_t acquireToPresentMs = msBetween(timeRecords[0].frameTime.acquireTime, | 
 | 488 |                                                          timeRecords[0].frameTime.presentTime); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 489 |             ALOGV("[%d]-[%" PRIu64 "]-acquire2present[%d]", layerId, | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 490 |                   timeRecords[0].frameTime.frameNumber, acquireToPresentMs); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 491 |             timeStatsLayer.deltas["acquire2present"].insert(acquireToPresentMs); | 
 | 492 |  | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 493 |             const int32_t latchToPresentMs = msBetween(timeRecords[0].frameTime.latchTime, | 
 | 494 |                                                        timeRecords[0].frameTime.presentTime); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 495 |             ALOGV("[%d]-[%" PRIu64 "]-latch2present[%d]", layerId, | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 496 |                   timeRecords[0].frameTime.frameNumber, latchToPresentMs); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 497 |             timeStatsLayer.deltas["latch2present"].insert(latchToPresentMs); | 
 | 498 |  | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 499 |             const int32_t desiredToPresentMs = msBetween(timeRecords[0].frameTime.desiredTime, | 
 | 500 |                                                          timeRecords[0].frameTime.presentTime); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 501 |             ALOGV("[%d]-[%" PRIu64 "]-desired2present[%d]", layerId, | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 502 |                   timeRecords[0].frameTime.frameNumber, desiredToPresentMs); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 503 |             timeStatsLayer.deltas["desired2present"].insert(desiredToPresentMs); | 
 | 504 |  | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 505 |             const int32_t presentToPresentMs = msBetween(prevTimeRecord.frameTime.presentTime, | 
 | 506 |                                                          timeRecords[0].frameTime.presentTime); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 507 |             ALOGV("[%d]-[%" PRIu64 "]-present2present[%d]", layerId, | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 508 |                   timeRecords[0].frameTime.frameNumber, presentToPresentMs); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 509 |             timeStatsLayer.deltas["present2present"].insert(presentToPresentMs); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 510 |         } | 
 | 511 |         prevTimeRecord = timeRecords[0]; | 
| Yiwei Zhang | c5f2c45 | 2018-05-08 16:31:56 -0700 | [diff] [blame] | 512 |         timeRecords.pop_front(); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 513 |         layerRecord.waitData--; | 
 | 514 |     } | 
 | 515 | } | 
 | 516 |  | 
| Yiwei Zhang | 8bec7e8 | 2019-10-07 18:08:26 -0700 | [diff] [blame] | 517 | static constexpr const char* kPopupWindowPrefix = "PopupWindow"; | 
 | 518 | static const size_t kMinLenLayerName = std::strlen(kPopupWindowPrefix); | 
| Yiwei Zhang | bd40832 | 2018-10-15 18:31:53 -0700 | [diff] [blame] | 519 |  | 
| Yiwei Zhang | 8bec7e8 | 2019-10-07 18:08:26 -0700 | [diff] [blame] | 520 | // Avoid tracking the "PopupWindow:<random hash>#<number>" layers | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 521 | static bool layerNameIsValid(const std::string& layerName) { | 
| Yiwei Zhang | 8bec7e8 | 2019-10-07 18:08:26 -0700 | [diff] [blame] | 522 |     return layerName.length() >= kMinLenLayerName && | 
 | 523 |             layerName.compare(0, kMinLenLayerName, kPopupWindowPrefix) != 0; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 524 | } | 
 | 525 |  | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 526 | bool TimeStats::canAddNewAggregatedStats(uid_t uid, const std::string& layerName) { | 
 | 527 |     return mTimeStats.stats.count({uid, layerName}) > 0 || | 
 | 528 |             mTimeStats.stats.size() < MAX_NUM_LAYER_STATS; | 
 | 529 | } | 
 | 530 |  | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 531 | void TimeStats::setPostTime(int32_t layerId, uint64_t frameNumber, const std::string& layerName, | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 532 |                             uid_t uid, nsecs_t postTime) { | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 533 |     if (!mEnabled.load()) return; | 
 | 534 |  | 
 | 535 |     ATRACE_CALL(); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 536 |     ALOGV("[%d]-[%" PRIu64 "]-[%s]-PostTime[%" PRId64 "]", layerId, frameNumber, layerName.c_str(), | 
| Yiwei Zhang | 8e8fe52 | 2018-11-02 18:34:07 -0700 | [diff] [blame] | 537 |           postTime); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 538 |  | 
 | 539 |     std::lock_guard<std::mutex> lock(mMutex); | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 540 |     if (!canAddNewAggregatedStats(uid, layerName)) { | 
| Yiwei Zhang | e926ab5 | 2019-08-14 15:16:00 -0700 | [diff] [blame] | 541 |         return; | 
 | 542 |     } | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 543 |     if (!mTimeStatsTracker.count(layerId) && mTimeStatsTracker.size() < MAX_NUM_LAYER_RECORDS && | 
| Yiwei Zhang | 7eb58b7 | 2019-04-22 19:00:02 -0700 | [diff] [blame] | 544 |         layerNameIsValid(layerName)) { | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 545 |         mTimeStatsTracker[layerId].uid = uid; | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 546 |         mTimeStatsTracker[layerId].layerName = layerName; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 547 |     } | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 548 |     if (!mTimeStatsTracker.count(layerId)) return; | 
 | 549 |     LayerRecord& layerRecord = mTimeStatsTracker[layerId]; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 550 |     if (layerRecord.timeRecords.size() == MAX_NUM_TIME_RECORDS) { | 
| Yiwei Zhang | af8ee94 | 2018-11-22 00:15:23 -0800 | [diff] [blame] | 551 |         ALOGE("[%d]-[%s]-timeRecords is at its maximum size[%zu]. Ignore this when unittesting.", | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 552 |               layerId, layerRecord.layerName.c_str(), MAX_NUM_TIME_RECORDS); | 
 | 553 |         mTimeStatsTracker.erase(layerId); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 554 |         return; | 
 | 555 |     } | 
 | 556 |     // For most media content, the acquireFence is invalid because the buffer is | 
 | 557 |     // ready at the queueBuffer stage. In this case, acquireTime should be given | 
 | 558 |     // a default value as postTime. | 
 | 559 |     TimeRecord timeRecord = { | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 560 |             .frameTime = | 
 | 561 |                     { | 
 | 562 |                             .frameNumber = frameNumber, | 
 | 563 |                             .postTime = postTime, | 
| Yiwei Zhang | af8ee94 | 2018-11-22 00:15:23 -0800 | [diff] [blame] | 564 |                             .latchTime = postTime, | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 565 |                             .acquireTime = postTime, | 
| Yiwei Zhang | af8ee94 | 2018-11-22 00:15:23 -0800 | [diff] [blame] | 566 |                             .desiredTime = postTime, | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 567 |                     }, | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 568 |     }; | 
 | 569 |     layerRecord.timeRecords.push_back(timeRecord); | 
 | 570 |     if (layerRecord.waitData < 0 || | 
 | 571 |         layerRecord.waitData >= static_cast<int32_t>(layerRecord.timeRecords.size())) | 
 | 572 |         layerRecord.waitData = layerRecord.timeRecords.size() - 1; | 
 | 573 | } | 
 | 574 |  | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 575 | void TimeStats::setLatchTime(int32_t layerId, uint64_t frameNumber, nsecs_t latchTime) { | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 576 |     if (!mEnabled.load()) return; | 
 | 577 |  | 
 | 578 |     ATRACE_CALL(); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 579 |     ALOGV("[%d]-[%" PRIu64 "]-LatchTime[%" PRId64 "]", layerId, frameNumber, latchTime); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 580 |  | 
 | 581 |     std::lock_guard<std::mutex> lock(mMutex); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 582 |     if (!mTimeStatsTracker.count(layerId)) return; | 
 | 583 |     LayerRecord& layerRecord = mTimeStatsTracker[layerId]; | 
| Yiwei Zhang | cb7dd00 | 2019-04-16 11:03:01 -0700 | [diff] [blame] | 584 |     if (layerRecord.waitData < 0 || | 
 | 585 |         layerRecord.waitData >= static_cast<int32_t>(layerRecord.timeRecords.size())) | 
 | 586 |         return; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 587 |     TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData]; | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 588 |     if (timeRecord.frameTime.frameNumber == frameNumber) { | 
 | 589 |         timeRecord.frameTime.latchTime = latchTime; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 590 |     } | 
 | 591 | } | 
 | 592 |  | 
| Alec Mouri | 91f6df3 | 2020-01-30 08:48:58 -0800 | [diff] [blame] | 593 | void TimeStats::incrementLatchSkipped(int32_t layerId, LatchSkipReason reason) { | 
 | 594 |     if (!mEnabled.load()) return; | 
 | 595 |  | 
 | 596 |     ATRACE_CALL(); | 
 | 597 |     ALOGV("[%d]-LatchSkipped-Reason[%d]", layerId, | 
 | 598 |           static_cast<std::underlying_type<LatchSkipReason>::type>(reason)); | 
 | 599 |  | 
 | 600 |     std::lock_guard<std::mutex> lock(mMutex); | 
 | 601 |     if (!mTimeStatsTracker.count(layerId)) return; | 
 | 602 |     LayerRecord& layerRecord = mTimeStatsTracker[layerId]; | 
 | 603 |  | 
 | 604 |     switch (reason) { | 
 | 605 |         case LatchSkipReason::LateAcquire: | 
 | 606 |             layerRecord.lateAcquireFrames++; | 
 | 607 |             break; | 
 | 608 |     } | 
 | 609 | } | 
 | 610 |  | 
 | 611 | void TimeStats::incrementBadDesiredPresent(int32_t layerId) { | 
 | 612 |     if (!mEnabled.load()) return; | 
 | 613 |  | 
 | 614 |     ATRACE_CALL(); | 
 | 615 |     ALOGV("[%d]-BadDesiredPresent", layerId); | 
 | 616 |  | 
 | 617 |     std::lock_guard<std::mutex> lock(mMutex); | 
 | 618 |     if (!mTimeStatsTracker.count(layerId)) return; | 
 | 619 |     LayerRecord& layerRecord = mTimeStatsTracker[layerId]; | 
 | 620 |     layerRecord.badDesiredPresentFrames++; | 
 | 621 | } | 
 | 622 |  | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 623 | void TimeStats::setDesiredTime(int32_t layerId, uint64_t frameNumber, nsecs_t desiredTime) { | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 624 |     if (!mEnabled.load()) return; | 
 | 625 |  | 
 | 626 |     ATRACE_CALL(); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 627 |     ALOGV("[%d]-[%" PRIu64 "]-DesiredTime[%" PRId64 "]", layerId, frameNumber, desiredTime); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 628 |  | 
 | 629 |     std::lock_guard<std::mutex> lock(mMutex); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 630 |     if (!mTimeStatsTracker.count(layerId)) return; | 
 | 631 |     LayerRecord& layerRecord = mTimeStatsTracker[layerId]; | 
| Yiwei Zhang | cb7dd00 | 2019-04-16 11:03:01 -0700 | [diff] [blame] | 632 |     if (layerRecord.waitData < 0 || | 
 | 633 |         layerRecord.waitData >= static_cast<int32_t>(layerRecord.timeRecords.size())) | 
 | 634 |         return; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 635 |     TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData]; | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 636 |     if (timeRecord.frameTime.frameNumber == frameNumber) { | 
 | 637 |         timeRecord.frameTime.desiredTime = desiredTime; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 638 |     } | 
 | 639 | } | 
 | 640 |  | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 641 | void TimeStats::setAcquireTime(int32_t layerId, uint64_t frameNumber, nsecs_t acquireTime) { | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 642 |     if (!mEnabled.load()) return; | 
 | 643 |  | 
 | 644 |     ATRACE_CALL(); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 645 |     ALOGV("[%d]-[%" PRIu64 "]-AcquireTime[%" PRId64 "]", layerId, frameNumber, acquireTime); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 646 |  | 
 | 647 |     std::lock_guard<std::mutex> lock(mMutex); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 648 |     if (!mTimeStatsTracker.count(layerId)) return; | 
 | 649 |     LayerRecord& layerRecord = mTimeStatsTracker[layerId]; | 
| Yiwei Zhang | cb7dd00 | 2019-04-16 11:03:01 -0700 | [diff] [blame] | 650 |     if (layerRecord.waitData < 0 || | 
 | 651 |         layerRecord.waitData >= static_cast<int32_t>(layerRecord.timeRecords.size())) | 
 | 652 |         return; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 653 |     TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData]; | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 654 |     if (timeRecord.frameTime.frameNumber == frameNumber) { | 
 | 655 |         timeRecord.frameTime.acquireTime = acquireTime; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 656 |     } | 
 | 657 | } | 
 | 658 |  | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 659 | void TimeStats::setAcquireFence(int32_t layerId, uint64_t frameNumber, | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 660 |                                 const std::shared_ptr<FenceTime>& acquireFence) { | 
 | 661 |     if (!mEnabled.load()) return; | 
 | 662 |  | 
 | 663 |     ATRACE_CALL(); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 664 |     ALOGV("[%d]-[%" PRIu64 "]-AcquireFenceTime[%" PRId64 "]", layerId, frameNumber, | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 665 |           acquireFence->getSignalTime()); | 
 | 666 |  | 
 | 667 |     std::lock_guard<std::mutex> lock(mMutex); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 668 |     if (!mTimeStatsTracker.count(layerId)) return; | 
 | 669 |     LayerRecord& layerRecord = mTimeStatsTracker[layerId]; | 
| Yiwei Zhang | cb7dd00 | 2019-04-16 11:03:01 -0700 | [diff] [blame] | 670 |     if (layerRecord.waitData < 0 || | 
 | 671 |         layerRecord.waitData >= static_cast<int32_t>(layerRecord.timeRecords.size())) | 
 | 672 |         return; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 673 |     TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData]; | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 674 |     if (timeRecord.frameTime.frameNumber == frameNumber) { | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 675 |         timeRecord.acquireFence = acquireFence; | 
 | 676 |     } | 
 | 677 | } | 
 | 678 |  | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 679 | void TimeStats::setPresentTime(int32_t layerId, uint64_t frameNumber, nsecs_t presentTime) { | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 680 |     if (!mEnabled.load()) return; | 
 | 681 |  | 
 | 682 |     ATRACE_CALL(); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 683 |     ALOGV("[%d]-[%" PRIu64 "]-PresentTime[%" PRId64 "]", layerId, frameNumber, presentTime); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 684 |  | 
 | 685 |     std::lock_guard<std::mutex> lock(mMutex); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 686 |     if (!mTimeStatsTracker.count(layerId)) return; | 
 | 687 |     LayerRecord& layerRecord = mTimeStatsTracker[layerId]; | 
| Yiwei Zhang | cb7dd00 | 2019-04-16 11:03:01 -0700 | [diff] [blame] | 688 |     if (layerRecord.waitData < 0 || | 
 | 689 |         layerRecord.waitData >= static_cast<int32_t>(layerRecord.timeRecords.size())) | 
 | 690 |         return; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 691 |     TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData]; | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 692 |     if (timeRecord.frameTime.frameNumber == frameNumber) { | 
 | 693 |         timeRecord.frameTime.presentTime = presentTime; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 694 |         timeRecord.ready = true; | 
 | 695 |         layerRecord.waitData++; | 
 | 696 |     } | 
 | 697 |  | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 698 |     flushAvailableRecordsToStatsLocked(layerId); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 699 | } | 
 | 700 |  | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 701 | void TimeStats::setPresentFence(int32_t layerId, uint64_t frameNumber, | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 702 |                                 const std::shared_ptr<FenceTime>& presentFence) { | 
 | 703 |     if (!mEnabled.load()) return; | 
 | 704 |  | 
 | 705 |     ATRACE_CALL(); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 706 |     ALOGV("[%d]-[%" PRIu64 "]-PresentFenceTime[%" PRId64 "]", layerId, frameNumber, | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 707 |           presentFence->getSignalTime()); | 
 | 708 |  | 
 | 709 |     std::lock_guard<std::mutex> lock(mMutex); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 710 |     if (!mTimeStatsTracker.count(layerId)) return; | 
 | 711 |     LayerRecord& layerRecord = mTimeStatsTracker[layerId]; | 
| Yiwei Zhang | cb7dd00 | 2019-04-16 11:03:01 -0700 | [diff] [blame] | 712 |     if (layerRecord.waitData < 0 || | 
 | 713 |         layerRecord.waitData >= static_cast<int32_t>(layerRecord.timeRecords.size())) | 
 | 714 |         return; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 715 |     TimeRecord& timeRecord = layerRecord.timeRecords[layerRecord.waitData]; | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 716 |     if (timeRecord.frameTime.frameNumber == frameNumber) { | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 717 |         timeRecord.presentFence = presentFence; | 
 | 718 |         timeRecord.ready = true; | 
 | 719 |         layerRecord.waitData++; | 
 | 720 |     } | 
 | 721 |  | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 722 |     flushAvailableRecordsToStatsLocked(layerId); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 723 | } | 
 | 724 |  | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 725 | template <class T> | 
 | 726 | static void updateJankPayload(T& t, int32_t reasons) { | 
 | 727 |     t.jankPayload.totalFrames++; | 
 | 728 |  | 
| Adithya Srinivasan | 9b2ca3e | 2020-11-10 10:14:17 -0800 | [diff] [blame] | 729 |     static const constexpr int32_t kValidJankyReason = JankType::SurfaceFlingerCpuDeadlineMissed | | 
 | 730 |             JankType::SurfaceFlingerGpuDeadlineMissed | JankType::AppDeadlineMissed | | 
 | 731 |             JankType::DisplayHAL; | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 732 |     if (reasons & kValidJankyReason) { | 
 | 733 |         t.jankPayload.totalJankyFrames++; | 
| Adithya Srinivasan | 9b2ca3e | 2020-11-10 10:14:17 -0800 | [diff] [blame] | 734 |         if ((reasons & JankType::SurfaceFlingerCpuDeadlineMissed) != 0) { | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 735 |             t.jankPayload.totalSFLongCpu++; | 
 | 736 |         } | 
| Jorim Jaggi | 5814ab8 | 2020-12-03 20:45:58 +0100 | [diff] [blame] | 737 |         if ((reasons & JankType::SurfaceFlingerGpuDeadlineMissed) != 0) { | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 738 |             t.jankPayload.totalSFLongGpu++; | 
 | 739 |         } | 
| Adithya Srinivasan | 9b2ca3e | 2020-11-10 10:14:17 -0800 | [diff] [blame] | 740 |         if ((reasons & JankType::DisplayHAL) != 0) { | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 741 |             t.jankPayload.totalSFUnattributed++; | 
 | 742 |         } | 
| Jorim Jaggi | 5814ab8 | 2020-12-03 20:45:58 +0100 | [diff] [blame] | 743 |         if ((reasons & JankType::AppDeadlineMissed) != 0) { | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 744 |             t.jankPayload.totalAppUnattributed++; | 
 | 745 |         } | 
 | 746 |     } | 
 | 747 | } | 
 | 748 |  | 
 | 749 | void TimeStats::incrementJankyFrames(int32_t reasons) { | 
 | 750 |     if (!mEnabled.load()) return; | 
 | 751 |  | 
 | 752 |     ATRACE_CALL(); | 
 | 753 |     std::lock_guard<std::mutex> lock(mMutex); | 
 | 754 |  | 
 | 755 |     updateJankPayload<TimeStatsHelper::TimeStatsGlobal>(mTimeStats, reasons); | 
 | 756 | } | 
 | 757 |  | 
 | 758 | void TimeStats::incrementJankyFrames(uid_t uid, const std::string& layerName, int32_t reasons) { | 
 | 759 |     if (!mEnabled.load()) return; | 
 | 760 |  | 
 | 761 |     ATRACE_CALL(); | 
 | 762 |     std::lock_guard<std::mutex> lock(mMutex); | 
 | 763 |  | 
| Alec Mouri | 542de11 | 2020-11-13 12:07:32 -0800 | [diff] [blame] | 764 |     // Only update layer stats if we're already tracking the layer in TimeStats. | 
 | 765 |     // Otherwise, continue tracking the statistic but use a default layer name instead. | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 766 |     // As an implementation detail, we do this because this method is expected to be | 
| Alec Mouri | 542de11 | 2020-11-13 12:07:32 -0800 | [diff] [blame] | 767 |     // called from FrameTimeline, whose jank classification includes transaction jank | 
 | 768 |     // that occurs without a buffer. But, in general those layer names are not suitable as | 
 | 769 |     // aggregation keys: e.g., it's normal and expected for Window Manager to include the hash code | 
 | 770 |     // for an animation leash. So while we can show that jank in dumpsys, aggregating based on the | 
 | 771 |     // layer blows up the stats size, so as a workaround drop those stats. This assumes that | 
 | 772 |     // TimeStats will flush the first present fence for a layer *before* FrameTimeline does so that | 
 | 773 |     // the first jank record is not dropped. | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 774 |  | 
| Alec Mouri | 542de11 | 2020-11-13 12:07:32 -0800 | [diff] [blame] | 775 |     bool useDefaultLayerKey = false; | 
 | 776 |     static const std::string kDefaultLayerName = "none"; | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 777 |     if (!mTimeStats.stats.count({uid, layerName})) { | 
| Alec Mouri | 542de11 | 2020-11-13 12:07:32 -0800 | [diff] [blame] | 778 |         mTimeStats.stats[{uid, kDefaultLayerName}].uid = uid; | 
 | 779 |         mTimeStats.stats[{uid, kDefaultLayerName}].layerName = kDefaultLayerName; | 
 | 780 |         useDefaultLayerKey = true; | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 781 |     } | 
 | 782 |  | 
| Alec Mouri | 542de11 | 2020-11-13 12:07:32 -0800 | [diff] [blame] | 783 |     TimeStatsHelper::TimeStatsLayer& timeStatsLayer = | 
 | 784 |             mTimeStats.stats[{uid, useDefaultLayerKey ? kDefaultLayerName : layerName}]; | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 785 |     updateJankPayload<TimeStatsHelper::TimeStatsLayer>(timeStatsLayer, reasons); | 
 | 786 | } | 
 | 787 |  | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 788 | void TimeStats::onDestroy(int32_t layerId) { | 
| Yiwei Zhang | dc22404 | 2018-10-18 15:34:00 -0700 | [diff] [blame] | 789 |     ATRACE_CALL(); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 790 |     ALOGV("[%d]-onDestroy", layerId); | 
| Mikael Pessa | 90092f4 | 2019-08-26 17:22:04 -0700 | [diff] [blame] | 791 |     std::lock_guard<std::mutex> lock(mMutex); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 792 |     mTimeStatsTracker.erase(layerId); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 793 | } | 
 | 794 |  | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 795 | void TimeStats::removeTimeRecord(int32_t layerId, uint64_t frameNumber) { | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 796 |     if (!mEnabled.load()) return; | 
 | 797 |  | 
 | 798 |     ATRACE_CALL(); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 799 |     ALOGV("[%d]-[%" PRIu64 "]-removeTimeRecord", layerId, frameNumber); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 800 |  | 
 | 801 |     std::lock_guard<std::mutex> lock(mMutex); | 
| Yiwei Zhang | 1a88c40 | 2019-11-18 10:43:58 -0800 | [diff] [blame] | 802 |     if (!mTimeStatsTracker.count(layerId)) return; | 
 | 803 |     LayerRecord& layerRecord = mTimeStatsTracker[layerId]; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 804 |     size_t removeAt = 0; | 
 | 805 |     for (const TimeRecord& record : layerRecord.timeRecords) { | 
| Yiwei Zhang | cf50ab9 | 2018-06-14 10:50:12 -0700 | [diff] [blame] | 806 |         if (record.frameTime.frameNumber == frameNumber) break; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 807 |         removeAt++; | 
 | 808 |     } | 
 | 809 |     if (removeAt == layerRecord.timeRecords.size()) return; | 
 | 810 |     layerRecord.timeRecords.erase(layerRecord.timeRecords.begin() + removeAt); | 
 | 811 |     if (layerRecord.waitData > static_cast<int32_t>(removeAt)) { | 
| Yiwei Zhang | eaeea06 | 2018-06-28 14:46:51 -0700 | [diff] [blame] | 812 |         layerRecord.waitData--; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 813 |     } | 
| Yiwei Zhang | eaeea06 | 2018-06-28 14:46:51 -0700 | [diff] [blame] | 814 |     layerRecord.droppedFrames++; | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 815 | } | 
 | 816 |  | 
| Yiwei Zhang | 3a226d2 | 2018-10-16 09:23:03 -0700 | [diff] [blame] | 817 | void TimeStats::flushPowerTimeLocked() { | 
| Yiwei Zhang | e5c49d5 | 2018-10-29 00:15:31 -0700 | [diff] [blame] | 818 |     if (!mEnabled.load()) return; | 
 | 819 |  | 
| Yiwei Zhang | 3a226d2 | 2018-10-16 09:23:03 -0700 | [diff] [blame] | 820 |     nsecs_t curTime = systemTime(); | 
 | 821 |     // elapsedTime is in milliseconds. | 
 | 822 |     int64_t elapsedTime = (curTime - mPowerTime.prevTime) / 1000000; | 
 | 823 |  | 
 | 824 |     switch (mPowerTime.powerMode) { | 
| Peiyong Lin | 65248e0 | 2020-04-18 21:15:07 -0700 | [diff] [blame] | 825 |         case PowerMode::ON: | 
| Yiwei Zhang | 3a226d2 | 2018-10-16 09:23:03 -0700 | [diff] [blame] | 826 |             mTimeStats.displayOnTime += elapsedTime; | 
 | 827 |             break; | 
| Peiyong Lin | 65248e0 | 2020-04-18 21:15:07 -0700 | [diff] [blame] | 828 |         case PowerMode::OFF: | 
 | 829 |         case PowerMode::DOZE: | 
 | 830 |         case PowerMode::DOZE_SUSPEND: | 
 | 831 |         case PowerMode::ON_SUSPEND: | 
| Yiwei Zhang | 3a226d2 | 2018-10-16 09:23:03 -0700 | [diff] [blame] | 832 |         default: | 
 | 833 |             break; | 
 | 834 |     } | 
 | 835 |  | 
 | 836 |     mPowerTime.prevTime = curTime; | 
 | 837 | } | 
 | 838 |  | 
| Peiyong Lin | 65248e0 | 2020-04-18 21:15:07 -0700 | [diff] [blame] | 839 | void TimeStats::setPowerMode(PowerMode powerMode) { | 
| Yiwei Zhang | 3a226d2 | 2018-10-16 09:23:03 -0700 | [diff] [blame] | 840 |     if (!mEnabled.load()) { | 
 | 841 |         std::lock_guard<std::mutex> lock(mMutex); | 
 | 842 |         mPowerTime.powerMode = powerMode; | 
 | 843 |         return; | 
 | 844 |     } | 
 | 845 |  | 
 | 846 |     std::lock_guard<std::mutex> lock(mMutex); | 
 | 847 |     if (powerMode == mPowerTime.powerMode) return; | 
 | 848 |  | 
 | 849 |     flushPowerTimeLocked(); | 
 | 850 |     mPowerTime.powerMode = powerMode; | 
 | 851 | } | 
 | 852 |  | 
| Alec Mouri | fb571ea | 2019-01-24 18:42:10 -0800 | [diff] [blame] | 853 | void TimeStats::recordRefreshRate(uint32_t fps, nsecs_t duration) { | 
 | 854 |     std::lock_guard<std::mutex> lock(mMutex); | 
 | 855 |     if (mTimeStats.refreshRateStats.count(fps)) { | 
 | 856 |         mTimeStats.refreshRateStats[fps] += duration; | 
 | 857 |     } else { | 
 | 858 |         mTimeStats.refreshRateStats.insert({fps, duration}); | 
 | 859 |     } | 
 | 860 | } | 
 | 861 |  | 
| Yiwei Zhang | ce6ebc0 | 2018-10-20 12:42:38 -0700 | [diff] [blame] | 862 | void TimeStats::flushAvailableGlobalRecordsToStatsLocked() { | 
 | 863 |     ATRACE_CALL(); | 
 | 864 |  | 
 | 865 |     while (!mGlobalRecord.presentFences.empty()) { | 
 | 866 |         const nsecs_t curPresentTime = mGlobalRecord.presentFences.front()->getSignalTime(); | 
 | 867 |         if (curPresentTime == Fence::SIGNAL_TIME_PENDING) break; | 
 | 868 |  | 
 | 869 |         if (curPresentTime == Fence::SIGNAL_TIME_INVALID) { | 
 | 870 |             ALOGE("GlobalPresentFence is invalid!"); | 
 | 871 |             mGlobalRecord.prevPresentTime = 0; | 
 | 872 |             mGlobalRecord.presentFences.pop_front(); | 
 | 873 |             continue; | 
 | 874 |         } | 
 | 875 |  | 
 | 876 |         ALOGV("GlobalPresentFenceTime[%" PRId64 "]", | 
 | 877 |               mGlobalRecord.presentFences.front()->getSignalTime()); | 
 | 878 |  | 
| Yiwei Zhang | e5c49d5 | 2018-10-29 00:15:31 -0700 | [diff] [blame] | 879 |         if (mGlobalRecord.prevPresentTime != 0) { | 
 | 880 |             const int32_t presentToPresentMs = | 
 | 881 |                     msBetween(mGlobalRecord.prevPresentTime, curPresentTime); | 
 | 882 |             ALOGV("Global present2present[%d] prev[%" PRId64 "] curr[%" PRId64 "]", | 
 | 883 |                   presentToPresentMs, mGlobalRecord.prevPresentTime, curPresentTime); | 
 | 884 |             mTimeStats.presentToPresent.insert(presentToPresentMs); | 
 | 885 |         } | 
| Yiwei Zhang | ce6ebc0 | 2018-10-20 12:42:38 -0700 | [diff] [blame] | 886 |  | 
| Yiwei Zhang | ce6ebc0 | 2018-10-20 12:42:38 -0700 | [diff] [blame] | 887 |         mGlobalRecord.prevPresentTime = curPresentTime; | 
 | 888 |         mGlobalRecord.presentFences.pop_front(); | 
 | 889 |     } | 
| Alec Mouri | e4034bb | 2019-11-19 12:45:54 -0800 | [diff] [blame] | 890 |     while (!mGlobalRecord.renderEngineDurations.empty()) { | 
 | 891 |         const auto duration = mGlobalRecord.renderEngineDurations.front(); | 
 | 892 |         const auto& endTime = duration.endTime; | 
 | 893 |  | 
 | 894 |         nsecs_t endNs = -1; | 
 | 895 |  | 
 | 896 |         if (auto val = std::get_if<nsecs_t>(&endTime)) { | 
 | 897 |             endNs = *val; | 
 | 898 |         } else { | 
 | 899 |             endNs = std::get<std::shared_ptr<FenceTime>>(endTime)->getSignalTime(); | 
 | 900 |         } | 
 | 901 |  | 
 | 902 |         if (endNs == Fence::SIGNAL_TIME_PENDING) break; | 
 | 903 |  | 
 | 904 |         if (endNs < 0) { | 
 | 905 |             ALOGE("RenderEngineTiming is invalid!"); | 
 | 906 |             mGlobalRecord.renderEngineDurations.pop_front(); | 
 | 907 |             continue; | 
 | 908 |         } | 
 | 909 |  | 
 | 910 |         const int32_t renderEngineMs = msBetween(duration.startTime, endNs); | 
 | 911 |         mTimeStats.renderEngineTiming.insert(renderEngineMs); | 
 | 912 |  | 
 | 913 |         mGlobalRecord.renderEngineDurations.pop_front(); | 
 | 914 |     } | 
| Yiwei Zhang | ce6ebc0 | 2018-10-20 12:42:38 -0700 | [diff] [blame] | 915 | } | 
 | 916 |  | 
 | 917 | void TimeStats::setPresentFenceGlobal(const std::shared_ptr<FenceTime>& presentFence) { | 
 | 918 |     if (!mEnabled.load()) return; | 
 | 919 |  | 
 | 920 |     ATRACE_CALL(); | 
 | 921 |     std::lock_guard<std::mutex> lock(mMutex); | 
| Yiwei Zhang | e5c49d5 | 2018-10-29 00:15:31 -0700 | [diff] [blame] | 922 |     if (presentFence == nullptr || !presentFence->isValid()) { | 
 | 923 |         mGlobalRecord.prevPresentTime = 0; | 
 | 924 |         return; | 
 | 925 |     } | 
 | 926 |  | 
| Peiyong Lin | 65248e0 | 2020-04-18 21:15:07 -0700 | [diff] [blame] | 927 |     if (mPowerTime.powerMode != PowerMode::ON) { | 
 | 928 |         // Try flushing the last present fence on PowerMode::ON. | 
| Yiwei Zhang | e5c49d5 | 2018-10-29 00:15:31 -0700 | [diff] [blame] | 929 |         flushAvailableGlobalRecordsToStatsLocked(); | 
 | 930 |         mGlobalRecord.presentFences.clear(); | 
| Yiwei Zhang | ce6ebc0 | 2018-10-20 12:42:38 -0700 | [diff] [blame] | 931 |         mGlobalRecord.prevPresentTime = 0; | 
 | 932 |         return; | 
 | 933 |     } | 
 | 934 |  | 
 | 935 |     if (mGlobalRecord.presentFences.size() == MAX_NUM_TIME_RECORDS) { | 
 | 936 |         // The front presentFence must be trapped in pending status in this | 
 | 937 |         // case. Try dequeuing the front one to recover. | 
 | 938 |         ALOGE("GlobalPresentFences is already at its maximum size[%zu]", MAX_NUM_TIME_RECORDS); | 
 | 939 |         mGlobalRecord.prevPresentTime = 0; | 
 | 940 |         mGlobalRecord.presentFences.pop_front(); | 
 | 941 |     } | 
 | 942 |  | 
 | 943 |     mGlobalRecord.presentFences.emplace_back(presentFence); | 
 | 944 |     flushAvailableGlobalRecordsToStatsLocked(); | 
 | 945 | } | 
 | 946 |  | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 947 | void TimeStats::enable() { | 
 | 948 |     if (mEnabled.load()) return; | 
 | 949 |  | 
 | 950 |     ATRACE_CALL(); | 
 | 951 |  | 
 | 952 |     std::lock_guard<std::mutex> lock(mMutex); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 953 |     mEnabled.store(true); | 
| Yiwei Zhang | dc22404 | 2018-10-18 15:34:00 -0700 | [diff] [blame] | 954 |     mTimeStats.statsStart = static_cast<int64_t>(std::time(0)); | 
| Yiwei Zhang | 3a226d2 | 2018-10-16 09:23:03 -0700 | [diff] [blame] | 955 |     mPowerTime.prevTime = systemTime(); | 
| Yiwei Zhang | e5c49d5 | 2018-10-29 00:15:31 -0700 | [diff] [blame] | 956 |     ALOGD("Enabled"); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 957 | } | 
 | 958 |  | 
 | 959 | void TimeStats::disable() { | 
 | 960 |     if (!mEnabled.load()) return; | 
 | 961 |  | 
 | 962 |     ATRACE_CALL(); | 
 | 963 |  | 
 | 964 |     std::lock_guard<std::mutex> lock(mMutex); | 
| Yiwei Zhang | e5c49d5 | 2018-10-29 00:15:31 -0700 | [diff] [blame] | 965 |     flushPowerTimeLocked(); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 966 |     mEnabled.store(false); | 
| Yiwei Zhang | dc22404 | 2018-10-18 15:34:00 -0700 | [diff] [blame] | 967 |     mTimeStats.statsEnd = static_cast<int64_t>(std::time(0)); | 
| Yiwei Zhang | e5c49d5 | 2018-10-29 00:15:31 -0700 | [diff] [blame] | 968 |     ALOGD("Disabled"); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 969 | } | 
 | 970 |  | 
| Alec Mouri | 8e2f31b | 2020-01-16 22:04:35 +0000 | [diff] [blame] | 971 | void TimeStats::clearAll() { | 
 | 972 |     std::lock_guard<std::mutex> lock(mMutex); | 
 | 973 |     clearGlobalLocked(); | 
 | 974 |     clearLayersLocked(); | 
 | 975 | } | 
 | 976 |  | 
 | 977 | void TimeStats::clearGlobalLocked() { | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 978 |     ATRACE_CALL(); | 
 | 979 |  | 
| Yiwei Zhang | dc22404 | 2018-10-18 15:34:00 -0700 | [diff] [blame] | 980 |     mTimeStats.statsStart = (mEnabled.load() ? static_cast<int64_t>(std::time(0)) : 0); | 
 | 981 |     mTimeStats.statsEnd = 0; | 
 | 982 |     mTimeStats.totalFrames = 0; | 
 | 983 |     mTimeStats.missedFrames = 0; | 
 | 984 |     mTimeStats.clientCompositionFrames = 0; | 
| Vishnu Nair | 9b079a2 | 2020-01-21 14:36:08 -0800 | [diff] [blame] | 985 |     mTimeStats.clientCompositionReusedFrames = 0; | 
| Alec Mouri | 8de697e | 2020-03-19 10:52:01 -0700 | [diff] [blame] | 986 |     mTimeStats.refreshRateSwitches = 0; | 
| Alec Mouri | 8f7a010 | 2020-04-15 12:11:10 -0700 | [diff] [blame] | 987 |     mTimeStats.compositionStrategyChanges = 0; | 
| Alec Mouri | 717bcb6 | 2020-02-10 17:07:19 -0800 | [diff] [blame] | 988 |     mTimeStats.displayEventConnectionsCount = 0; | 
| Yiwei Zhang | 3a226d2 | 2018-10-16 09:23:03 -0700 | [diff] [blame] | 989 |     mTimeStats.displayOnTime = 0; | 
| Yiwei Zhang | ce6ebc0 | 2018-10-20 12:42:38 -0700 | [diff] [blame] | 990 |     mTimeStats.presentToPresent.hist.clear(); | 
| Alec Mouri | 31ac64a | 2020-01-09 09:26:22 -0800 | [diff] [blame] | 991 |     mTimeStats.frameDuration.hist.clear(); | 
 | 992 |     mTimeStats.renderEngineTiming.hist.clear(); | 
| Alec Mouri | 9a29e67 | 2020-09-14 12:39:14 -0700 | [diff] [blame] | 993 |     mTimeStats.jankPayload = TimeStatsHelper::JankPayload(); | 
| Alec Mouri | fb571ea | 2019-01-24 18:42:10 -0800 | [diff] [blame] | 994 |     mTimeStats.refreshRateStats.clear(); | 
| Yiwei Zhang | 3a226d2 | 2018-10-16 09:23:03 -0700 | [diff] [blame] | 995 |     mPowerTime.prevTime = systemTime(); | 
| Yiwei Zhang | e5c49d5 | 2018-10-29 00:15:31 -0700 | [diff] [blame] | 996 |     mGlobalRecord.prevPresentTime = 0; | 
 | 997 |     mGlobalRecord.presentFences.clear(); | 
| Alec Mouri | 8e2f31b | 2020-01-16 22:04:35 +0000 | [diff] [blame] | 998 |     ALOGD("Cleared global stats"); | 
 | 999 | } | 
 | 1000 |  | 
 | 1001 | void TimeStats::clearLayersLocked() { | 
 | 1002 |     ATRACE_CALL(); | 
 | 1003 |  | 
 | 1004 |     mTimeStatsTracker.clear(); | 
 | 1005 |     mTimeStats.stats.clear(); | 
 | 1006 |     ALOGD("Cleared layer stats"); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 1007 | } | 
 | 1008 |  | 
 | 1009 | bool TimeStats::isEnabled() { | 
 | 1010 |     return mEnabled.load(); | 
 | 1011 | } | 
 | 1012 |  | 
| Yiwei Zhang | 5434a78 | 2018-12-05 18:06:32 -0800 | [diff] [blame] | 1013 | void TimeStats::dump(bool asProto, std::optional<uint32_t> maxLayers, std::string& result) { | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 1014 |     ATRACE_CALL(); | 
 | 1015 |  | 
 | 1016 |     std::lock_guard<std::mutex> lock(mMutex); | 
| Yiwei Zhang | dc22404 | 2018-10-18 15:34:00 -0700 | [diff] [blame] | 1017 |     if (mTimeStats.statsStart == 0) { | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 1018 |         return; | 
 | 1019 |     } | 
 | 1020 |  | 
| Yiwei Zhang | dc22404 | 2018-10-18 15:34:00 -0700 | [diff] [blame] | 1021 |     mTimeStats.statsEnd = static_cast<int64_t>(std::time(0)); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 1022 |  | 
| Yiwei Zhang | 3a226d2 | 2018-10-16 09:23:03 -0700 | [diff] [blame] | 1023 |     flushPowerTimeLocked(); | 
 | 1024 |  | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 1025 |     if (asProto) { | 
| Yiwei Zhang | 8a4015c | 2018-05-08 16:03:47 -0700 | [diff] [blame] | 1026 |         ALOGD("Dumping TimeStats as proto"); | 
| Yiwei Zhang | dc22404 | 2018-10-18 15:34:00 -0700 | [diff] [blame] | 1027 |         SFTimeStatsGlobalProto timeStatsProto = mTimeStats.toProto(maxLayers); | 
| Dominik Laskowski | 4647011 | 2019-08-02 13:13:11 -0700 | [diff] [blame] | 1028 |         result.append(timeStatsProto.SerializeAsString()); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 1029 |     } else { | 
| Yiwei Zhang | 8a4015c | 2018-05-08 16:03:47 -0700 | [diff] [blame] | 1030 |         ALOGD("Dumping TimeStats as text"); | 
| Yiwei Zhang | 5434a78 | 2018-12-05 18:06:32 -0800 | [diff] [blame] | 1031 |         result.append(mTimeStats.toString(maxLayers)); | 
| Yiwei Zhang | 8a4015c | 2018-05-08 16:03:47 -0700 | [diff] [blame] | 1032 |         result.append("\n"); | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 1033 |     } | 
 | 1034 | } | 
 | 1035 |  | 
| Alec Mouri | fb571ea | 2019-01-24 18:42:10 -0800 | [diff] [blame] | 1036 | } // namespace impl | 
 | 1037 |  | 
| Yiwei Zhang | 0102ad2 | 2018-05-02 17:37:17 -0700 | [diff] [blame] | 1038 | } // namespace android |