diff options
Diffstat (limited to 'services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp')
-rw-r--r-- | services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp | 151 |
1 files changed, 122 insertions, 29 deletions
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp index 894ee6de06..ffb2f0921d 100644 --- a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp +++ b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp @@ -41,7 +41,7 @@ void TimeStatsHelper::Histogram::insert(int32_t delta) { if (delta < 0) return; // std::lower_bound won't work on out of range values if (delta > histogramConfig[HISTOGRAM_SIZE - 1]) { - hist[histogramConfig[HISTOGRAM_SIZE - 1]] += delta / histogramConfig[HISTOGRAM_SIZE - 1]; + hist[histogramConfig[HISTOGRAM_SIZE - 1]]++; return; } auto iter = std::lower_bound(histogramConfig.begin(), histogramConfig.end(), delta); @@ -77,14 +77,81 @@ std::string TimeStatsHelper::Histogram::toString() const { return result; } +std::string TimeStatsHelper::JankPayload::toString() const { + std::string result; + StringAppendF(&result, "totalTimelineFrames = %d\n", totalFrames); + StringAppendF(&result, "jankyFrames = %d\n", totalJankyFrames); + StringAppendF(&result, "sfLongCpuJankyFrames = %d\n", totalSFLongCpu); + StringAppendF(&result, "sfLongGpuJankyFrames = %d\n", totalSFLongGpu); + StringAppendF(&result, "sfUnattributedJankyFrames = %d\n", totalSFUnattributed); + StringAppendF(&result, "appUnattributedJankyFrames = %d\n", totalAppUnattributed); + StringAppendF(&result, "sfSchedulingJankyFrames = %d\n", totalSFScheduling); + StringAppendF(&result, "sfPredictionErrorJankyFrames = %d\n", totalSFPredictionError); + StringAppendF(&result, "appBufferStuffingJankyFrames = %d\n", totalAppBufferStuffing); + return result; +} + +std::string TimeStatsHelper::SetFrameRateVote::toString(FrameRateCompatibility compatibility) { + switch (compatibility) { + case FrameRateCompatibility::Undefined: + return "Undefined"; + case FrameRateCompatibility::Default: + return "Default"; + case FrameRateCompatibility::ExactOrMultiple: + return "ExactOrMultiple"; + } +} + +std::string TimeStatsHelper::SetFrameRateVote::toString(Seamlessness seamlessness) { + switch (seamlessness) { + case Seamlessness::Undefined: + return "Undefined"; + case Seamlessness::ShouldBeSeamless: + return "ShouldBeSeamless"; + case Seamlessness::NotRequired: + return "NotRequired"; + } +} + +std::string TimeStatsHelper::SetFrameRateVote::toString() const { + std::string result; + StringAppendF(&result, "frameRate = %.2f\n", frameRate); + StringAppendF(&result, "frameRateCompatibility = %s\n", + toString(frameRateCompatibility).c_str()); + StringAppendF(&result, "seamlessness = %s\n", toString(seamlessness).c_str()); + return result; +} + +std::string TimeStatsHelper::TimeStatsLayer::toString(int32_t gameMode) const { + switch (gameMode) { + case TimeStatsHelper::GameModeUnsupported: + return "GameModeUnsupported"; + case TimeStatsHelper::GameModeStandard: + return "GameModeStandard"; + case TimeStatsHelper::GameModePerformance: + return "GameModePerformance"; + case TimeStatsHelper::GameModeBattery: + return "GameModeBattery"; + default: + return "GameModeUnspecified"; + } +} std::string TimeStatsHelper::TimeStatsLayer::toString() const { std::string result = "\n"; + StringAppendF(&result, "displayRefreshRate = %d fps\n", displayRefreshRateBucket); + StringAppendF(&result, "renderRate = %d fps\n", renderRateBucket); + StringAppendF(&result, "uid = %d\n", uid); StringAppendF(&result, "layerName = %s\n", layerName.c_str()); StringAppendF(&result, "packageName = %s\n", packageName.c_str()); + StringAppendF(&result, "gameMode = %s\n", toString(gameMode).c_str()); StringAppendF(&result, "totalFrames = %d\n", totalFrames); StringAppendF(&result, "droppedFrames = %d\n", droppedFrames); StringAppendF(&result, "lateAcquireFrames = %d\n", lateAcquireFrames); StringAppendF(&result, "badDesiredPresentFrames = %d\n", badDesiredPresentFrames); + result.append("Jank payload for this layer:\n"); + result.append(jankPayload.toString()); + result.append("SetFrateRate vote for this layer:\n"); + result.append(setFrameRateVote.toString()); const auto iter = deltas.find("present2present"); if (iter != deltas.end()) { const float averageTime = iter->second.averageTime(); @@ -101,33 +168,49 @@ std::string TimeStatsHelper::TimeStatsLayer::toString() const { std::string TimeStatsHelper::TimeStatsGlobal::toString(std::optional<uint32_t> maxLayers) const { std::string result = "SurfaceFlinger TimeStats:\n"; - StringAppendF(&result, "statsStart = %" PRId64 "\n", statsStart); - StringAppendF(&result, "statsEnd = %" PRId64 "\n", statsEnd); - StringAppendF(&result, "totalFrames = %d\n", totalFrames); - StringAppendF(&result, "missedFrames = %d\n", missedFrames); - StringAppendF(&result, "clientCompositionFrames = %d\n", clientCompositionFrames); - StringAppendF(&result, "clientCompositionReusedFrames = %d\n", clientCompositionReusedFrames); - StringAppendF(&result, "refreshRateSwitches = %d\n", refreshRateSwitches); - StringAppendF(&result, "compositionStrategyChanges = %d\n", compositionStrategyChanges); - StringAppendF(&result, "displayOnTime = %" PRId64 " ms\n", displayOnTime); + result.append("Legacy stats are as follows:\n"); + StringAppendF(&result, "statsStart = %" PRId64 "\n", statsStartLegacy); + StringAppendF(&result, "statsEnd = %" PRId64 "\n", statsEndLegacy); + StringAppendF(&result, "totalFrames = %d\n", totalFramesLegacy); + StringAppendF(&result, "missedFrames = %d\n", missedFramesLegacy); + StringAppendF(&result, "clientCompositionFrames = %d\n", clientCompositionFramesLegacy); + StringAppendF(&result, "clientCompositionReusedFrames = %d\n", + clientCompositionReusedFramesLegacy); + StringAppendF(&result, "refreshRateSwitches = %d\n", refreshRateSwitchesLegacy); + StringAppendF(&result, "compositionStrategyChanges = %d\n", compositionStrategyChangesLegacy); + StringAppendF(&result, "displayOnTime = %" PRId64 " ms\n", displayOnTimeLegacy); StringAppendF(&result, "displayConfigStats is as below:\n"); - for (const auto& [fps, duration] : refreshRateStats) { - StringAppendF(&result, "%dfps=%ldms ", fps, ns2ms(duration)); + for (const auto& [fps, duration] : refreshRateStatsLegacy) { + StringAppendF(&result, "%dfps = %ldms\n", fps, ns2ms(duration)); } result.back() = '\n'; - StringAppendF(&result, "totalP2PTime = %" PRId64 " ms\n", presentToPresent.totalTime()); + StringAppendF(&result, "totalP2PTime = %" PRId64 " ms\n", presentToPresentLegacy.totalTime()); StringAppendF(&result, "presentToPresent histogram is as below:\n"); - result.append(presentToPresent.toString()); - const float averageFrameDuration = frameDuration.averageTime(); + result.append(presentToPresentLegacy.toString()); + const float averageFrameDuration = frameDurationLegacy.averageTime(); StringAppendF(&result, "averageFrameDuration = %.3f ms\n", std::isnan(averageFrameDuration) ? 0.0f : averageFrameDuration); StringAppendF(&result, "frameDuration histogram is as below:\n"); - result.append(frameDuration.toString()); - const float averageRenderEngineTiming = renderEngineTiming.averageTime(); + result.append(frameDurationLegacy.toString()); + const float averageRenderEngineTiming = renderEngineTimingLegacy.averageTime(); StringAppendF(&result, "averageRenderEngineTiming = %.3f ms\n", std::isnan(averageRenderEngineTiming) ? 0.0f : averageRenderEngineTiming); StringAppendF(&result, "renderEngineTiming histogram is as below:\n"); - result.append(renderEngineTiming.toString()); + result.append(renderEngineTimingLegacy.toString()); + + result.append("\nGlobal aggregated jank payload (Timeline stats):"); + for (const auto& ele : stats) { + result.append("\n"); + StringAppendF(&result, "displayRefreshRate = %d fps\n", + ele.second.key.displayRefreshRateBucket); + StringAppendF(&result, "renderRate = %d fps\n", ele.second.key.renderRateBucket); + result.append(ele.second.jankPayload.toString()); + StringAppendF(&result, "sfDeadlineMisses histogram is as below:\n"); + result.append(ele.second.displayDeadlineDeltas.toString()); + StringAppendF(&result, "sfPredictionErrors histogram is as below:\n"); + result.append(ele.second.displayPresentDeltas.toString()); + } + const auto dumpStats = generateDumpStats(maxLayers); for (const auto& ele : dumpStats) { result.append(ele->toString()); @@ -157,30 +240,30 @@ SFTimeStatsLayerProto TimeStatsHelper::TimeStatsLayer::toProto() const { SFTimeStatsGlobalProto TimeStatsHelper::TimeStatsGlobal::toProto( std::optional<uint32_t> maxLayers) const { SFTimeStatsGlobalProto globalProto; - globalProto.set_stats_start(statsStart); - globalProto.set_stats_end(statsEnd); - globalProto.set_total_frames(totalFrames); - globalProto.set_missed_frames(missedFrames); - globalProto.set_client_composition_frames(clientCompositionFrames); - globalProto.set_display_on_time(displayOnTime); - for (const auto& ele : refreshRateStats) { + globalProto.set_stats_start(statsStartLegacy); + globalProto.set_stats_end(statsEndLegacy); + globalProto.set_total_frames(totalFramesLegacy); + globalProto.set_missed_frames(missedFramesLegacy); + globalProto.set_client_composition_frames(clientCompositionFramesLegacy); + globalProto.set_display_on_time(displayOnTimeLegacy); + for (const auto& ele : refreshRateStatsLegacy) { SFTimeStatsDisplayConfigBucketProto* configBucketProto = globalProto.add_display_config_stats(); SFTimeStatsDisplayConfigProto* configProto = configBucketProto->mutable_config(); configProto->set_fps(ele.first); configBucketProto->set_duration_millis(ns2ms(ele.second)); } - for (const auto& histEle : presentToPresent.hist) { + for (const auto& histEle : presentToPresentLegacy.hist) { SFTimeStatsHistogramBucketProto* histProto = globalProto.add_present_to_present(); histProto->set_time_millis(histEle.first); histProto->set_frame_count(histEle.second); } - for (const auto& histEle : frameDuration.hist) { + for (const auto& histEle : frameDurationLegacy.hist) { SFTimeStatsHistogramBucketProto* histProto = globalProto.add_frame_duration(); histProto->set_time_millis(histEle.first); histProto->set_frame_count(histEle.second); } - for (const auto& histEle : renderEngineTiming.hist) { + for (const auto& histEle : renderEngineTimingLegacy.hist) { SFTimeStatsHistogramBucketProto* histProto = globalProto.add_render_engine_timing(); histProto->set_time_millis(histEle.first); histProto->set_frame_count(histEle.second); @@ -196,8 +279,18 @@ SFTimeStatsGlobalProto TimeStatsHelper::TimeStatsGlobal::toProto( std::vector<TimeStatsHelper::TimeStatsLayer const*> TimeStatsHelper::TimeStatsGlobal::generateDumpStats(std::optional<uint32_t> maxLayers) const { std::vector<TimeStatsLayer const*> dumpStats; + + int numLayers = 0; + for (const auto& ele : stats) { + numLayers += ele.second.stats.size(); + } + + dumpStats.reserve(numLayers); + for (const auto& ele : stats) { - dumpStats.push_back(&ele.second); + for (const auto& layerEle : ele.second.stats) { + dumpStats.push_back(&layerEle.second); + } } std::sort(dumpStats.begin(), dumpStats.end(), |