summaryrefslogtreecommitdiff
path: root/libs/hwui/service/GraphicsStatsService.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/service/GraphicsStatsService.cpp')
-rw-r--r--libs/hwui/service/GraphicsStatsService.cpp94
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",