diff options
Diffstat (limited to 'libs/hwui/service/GraphicsStatsService.cpp')
-rw-r--r-- | libs/hwui/service/GraphicsStatsService.cpp | 94 |
1 files changed, 48 insertions, 46 deletions
diff --git a/libs/hwui/service/GraphicsStatsService.cpp b/libs/hwui/service/GraphicsStatsService.cpp index 978a1f3481c3..f7a90b0a65ec 100644 --- a/libs/hwui/service/GraphicsStatsService.cpp +++ b/libs/hwui/service/GraphicsStatsService.cpp @@ -39,11 +39,9 @@ constexpr int32_t sCurrentFileVersion = 1; constexpr int32_t sHeaderSize = 4; static_assert(sizeof(sCurrentFileVersion) == sHeaderSize, "Header size is wrong"); -constexpr int sHistogramSize = - std::tuple_size<decltype(ProfileData::frameCounts)>::value + - std::tuple_size<decltype(ProfileData::slowFrameCounts)>::value; +constexpr int sHistogramSize = ProfileData::HistogramSize(); -static void mergeProfileDataIntoProto(service::GraphicsStatsProto* proto, +static bool mergeProfileDataIntoProto(service::GraphicsStatsProto* proto, const std::string& package, int versionCode, int64_t startTime, int64_t endTime, const ProfileData* data); static void dumpAsTextToFd(service::GraphicsStatsProto* proto, int outFd); @@ -162,7 +160,7 @@ bool GraphicsStatsService::parseFromFile(const std::string& path, service::Graph return success; } -void mergeProfileDataIntoProto(service::GraphicsStatsProto* proto, const std::string& package, +bool mergeProfileDataIntoProto(service::GraphicsStatsProto* proto, const std::string& package, int versionCode, int64_t startTime, int64_t endTime, const ProfileData* data) { if (proto->stats_start() == 0 || proto->stats_start() > startTime) { proto->set_stats_start(startTime); @@ -173,54 +171,49 @@ void mergeProfileDataIntoProto(service::GraphicsStatsProto* proto, const std::st proto->set_package_name(package); proto->set_version_code(versionCode); auto summary = proto->mutable_summary(); - summary->set_total_frames(summary->total_frames() + data->totalFrameCount); - summary->set_janky_frames(summary->janky_frames() + data->jankFrameCount); + summary->set_total_frames(summary->total_frames() + data->totalFrameCount()); + summary->set_janky_frames(summary->janky_frames() + data->jankFrameCount()); summary->set_missed_vsync_count( - summary->missed_vsync_count() + data->jankTypeCounts[kMissedVsync]); + summary->missed_vsync_count() + data->jankTypeCount(kMissedVsync)); summary->set_high_input_latency_count( - summary->high_input_latency_count() + data->jankTypeCounts[kHighInputLatency]); + summary->high_input_latency_count() + data->jankTypeCount(kHighInputLatency)); summary->set_slow_ui_thread_count( - summary->slow_ui_thread_count() + data->jankTypeCounts[kSlowUI]); + summary->slow_ui_thread_count() + data->jankTypeCount(kSlowUI)); summary->set_slow_bitmap_upload_count( - summary->slow_bitmap_upload_count() + data->jankTypeCounts[kSlowSync]); + summary->slow_bitmap_upload_count() + data->jankTypeCount(kSlowSync)); summary->set_slow_draw_count( - summary->slow_draw_count() + data->jankTypeCounts[kSlowRT]); + summary->slow_draw_count() + data->jankTypeCount(kSlowRT)); bool creatingHistogram = false; if (proto->histogram_size() == 0) { proto->mutable_histogram()->Reserve(sHistogramSize); creatingHistogram = true; } else if (proto->histogram_size() != sHistogramSize) { - LOG_ALWAYS_FATAL("Histogram size mismatch, proto is %d expected %d", + ALOGE("Histogram size mismatch, proto is %d expected %d", proto->histogram_size(), sHistogramSize); + return false; } - for (size_t i = 0; i < data->frameCounts.size(); i++) { - service::GraphicsStatsHistogramBucketProto* bucket; - int32_t renderTime = JankTracker::frameTimeForFrameCountIndex(i); - if (creatingHistogram) { - bucket = proto->add_histogram(); - bucket->set_render_millis(renderTime); - } else { - bucket = proto->mutable_histogram(i); - LOG_ALWAYS_FATAL_IF(bucket->render_millis() != renderTime, - "Frame time mistmatch %d vs. %d", bucket->render_millis(), renderTime); - } - bucket->set_frame_count(bucket->frame_count() + data->frameCounts[i]); - } - for (size_t i = 0; i < data->slowFrameCounts.size(); i++) { + int index = 0; + bool hitMergeError = false; + data->histogramForEach([&](ProfileData::HistogramEntry entry) { + if (hitMergeError) return; + service::GraphicsStatsHistogramBucketProto* bucket; - int32_t renderTime = JankTracker::frameTimeForSlowFrameCountIndex(i); if (creatingHistogram) { bucket = proto->add_histogram(); - bucket->set_render_millis(renderTime); + bucket->set_render_millis(entry.renderTimeMs); } else { - constexpr int offset = std::tuple_size<decltype(ProfileData::frameCounts)>::value; - bucket = proto->mutable_histogram(offset + i); - LOG_ALWAYS_FATAL_IF(bucket->render_millis() != renderTime, - "Frame time mistmatch %d vs. %d", bucket->render_millis(), renderTime); + bucket = proto->mutable_histogram(index); + if (bucket->render_millis() != static_cast<int32_t>(entry.renderTimeMs)) { + ALOGW("Frame time mistmatch %d vs. %u", bucket->render_millis(), entry.renderTimeMs); + hitMergeError = true; + return; + } } - bucket->set_frame_count(bucket->frame_count() + data->slowFrameCounts[i]); - } + bucket->set_frame_count(bucket->frame_count() + entry.frameCount); + index++; + }); + return !hitMergeError; } static int32_t findPercentile(service::GraphicsStatsProto* proto, int percentile) { @@ -237,9 +230,11 @@ static int32_t findPercentile(service::GraphicsStatsProto* proto, int percentile void dumpAsTextToFd(service::GraphicsStatsProto* proto, int fd) { // This isn't a full validation, just enough that we can deref at will - LOG_ALWAYS_FATAL_IF(proto->package_name().empty() - || !proto->has_summary(), "package_name() '%s' summary %d", - proto->package_name().c_str(), proto->has_summary()); + if (proto->package_name().empty() || !proto->has_summary()) { + ALOGW("Skipping dump, invalid package_name() '%s' or summary %d", + proto->package_name().c_str(), proto->has_summary()); + return; + } dprintf(fd, "\nPackage: %s", proto->package_name().c_str()); dprintf(fd, "\nVersion: %d", proto->version_code()); dprintf(fd, "\nStats since: %lldns", proto->stats_start()); @@ -270,14 +265,20 @@ void GraphicsStatsService::saveBuffer(const std::string& path, const std::string if (!parseFromFile(path, &statsProto)) { statsProto.Clear(); } - mergeProfileDataIntoProto(&statsProto, package, versionCode, startTime, endTime, data); + if (!mergeProfileDataIntoProto(&statsProto, package, versionCode, startTime, endTime, data)) { + return; + } // Although we might not have read any data from the file, merging the existing data // should always fully-initialize the proto - LOG_ALWAYS_FATAL_IF(!statsProto.IsInitialized(), "%s", - statsProto.InitializationErrorString().c_str()); - LOG_ALWAYS_FATAL_IF(statsProto.package_name().empty() - || !statsProto.has_summary(), "package_name() '%s' summary %d", - statsProto.package_name().c_str(), statsProto.has_summary()); + if (!statsProto.IsInitialized()) { + ALOGE("proto initialization error %s", statsProto.InitializationErrorString().c_str()); + return; + } + if (statsProto.package_name().empty() || !statsProto.has_summary()) { + ALOGE("missing package_name() '%s' summary %d", + statsProto.package_name().c_str(), statsProto.has_summary()); + return; + } int outFd = open(path.c_str(), O_CREAT | O_RDWR | O_TRUNC, 0660); if (outFd <= 0) { int err = errno; @@ -328,8 +329,9 @@ void GraphicsStatsService::addToDump(Dump* dump, const std::string& path, const if (!path.empty() && !parseFromFile(path, &statsProto)) { statsProto.Clear(); } - if (data) { - mergeProfileDataIntoProto(&statsProto, package, versionCode, startTime, endTime, data); + if (data && !mergeProfileDataIntoProto( + &statsProto, package, versionCode, startTime, endTime, data)) { + return; } if (!statsProto.IsInitialized()) { ALOGW("Failed to load profile data from path '%s' and data %p", |