From 6435b32fbf30883b84f35f96a7325c8b3413c7a7 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Tue, 8 May 2018 11:12:17 -0700 Subject: libvulkan: VkSurfaceKHR shouldn't work with must-be-YUV native windows When the provider of a Surface(the consumer) has set a default format that Vulkan can't render to, and the consumer usage bits include USAGE_CPU_*, we should let the user know the specific format asked for is not supported. Test: Test on the surface from yuv format ImageReader Bug: b/77853189 Change-Id: Id243f53b92667c621bbfb731bad37784823ba04f --- vulkan/libvulkan/swapchain.cpp | 52 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp index 6fb3351a39..c42e81132c 100644 --- a/vulkan/libvulkan/swapchain.cpp +++ b/vulkan/libvulkan/swapchain.cpp @@ -185,6 +185,7 @@ class TimingInfo { struct Surface { android::sp window; VkSwapchainKHR swapchain_handle; + uint64_t consumer_usage; }; VkSurfaceKHR HandleFromSurface(Surface* surface) { @@ -496,9 +497,18 @@ VkResult CreateAndroidSurfaceKHR( surface->window = pCreateInfo->window; surface->swapchain_handle = VK_NULL_HANDLE; + int err = native_window_get_consumer_usage(surface->window.get(), + &surface->consumer_usage); + if (err != android::NO_ERROR) { + ALOGE("native_window_get_consumer_usage() failed: %s (%d)", + strerror(-err), err); + surface->~Surface(); + allocator->pfnFree(allocator->pUserData, surface); + return VK_ERROR_INITIALIZATION_FAILED; + } // TODO(jessehall): Create and use NATIVE_WINDOW_API_VULKAN. - int err = + err = native_window_api_connect(surface->window.get(), NATIVE_WINDOW_API_EGL); if (err != 0) { // TODO(jessehall): Improve error reporting. Can we enumerate possible @@ -536,9 +546,45 @@ void DestroySurfaceKHR(VkInstance instance, VKAPI_ATTR VkResult GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice /*pdev*/, uint32_t /*queue_family*/, - VkSurfaceKHR /*surface*/, + VkSurfaceKHR surface_handle, VkBool32* supported) { - *supported = VK_TRUE; + const Surface* surface = SurfaceFromHandle(surface_handle); + if (!surface) { + return VK_ERROR_SURFACE_LOST_KHR; + } + const ANativeWindow* window = surface->window.get(); + + int query_value; + int err = window->query(window, NATIVE_WINDOW_FORMAT, &query_value); + if (err != 0 || query_value < 0) { + ALOGE("NATIVE_WINDOW_FORMAT query failed: %s (%d) value=%d", + strerror(-err), err, query_value); + return VK_ERROR_SURFACE_LOST_KHR; + } + + android_pixel_format native_format = + static_cast(query_value); + + bool format_supported = false; + switch (native_format) { + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGB_565: + format_supported = true; + break; + default: + break; + } + + // USAGE_CPU_READ_MASK 0xFUL + // USAGE_CPU_WRITE_MASK (0xFUL << 4) + // The currently used bits are as below: + // USAGE_CPU_READ_RARELY = 2UL + // USAGE_CPU_READ_OFTEN = 3UL + // USAGE_CPU_WRITE_RARELY = (2UL << 4) + // USAGE_CPU_WRITE_OFTEN = (3UL << 4) + *supported = static_cast(format_supported || + (surface->consumer_usage & 0xFFUL) == 0); + return VK_SUCCESS; } -- cgit v1.2.3-59-g8ed1b From 289fdbc732c290e45244d1658ea954e91a77d572 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Tue, 8 May 2018 15:14:29 -0700 Subject: SF TimeStats: update build file and some cleanups Remove the redundant part in the Android.bp file, and at the same time remove some unused code. Test: dumpsys SurfaceFlinger --timestats Bug: b/70388650 Change-Id: I5ddd63234780f4f482c4628de173ac6167b628f5 --- .../TimeStats/timestatsproto/Android.bp | 34 ++++------------------ .../include/timestatsproto/TimeStatsHelper.h | 3 -- .../TimeStats/timestatsproto/jarjar-rules.txt | 1 - .../TimeStats/timestatsproto/timestats.proto | 4 --- 4 files changed, 6 insertions(+), 36 deletions(-) delete mode 100644 services/surfaceflinger/TimeStats/timestatsproto/jarjar-rules.txt diff --git a/services/surfaceflinger/TimeStats/timestatsproto/Android.bp b/services/surfaceflinger/TimeStats/timestatsproto/Android.bp index 66aa719381..46c82c0eb8 100644 --- a/services/surfaceflinger/TimeStats/timestatsproto/Android.bp +++ b/services/surfaceflinger/TimeStats/timestatsproto/Android.bp @@ -1,6 +1,5 @@ cc_library_shared { name: "libtimestats_proto", - vendor_available: true, export_include_dirs: ["include"], srcs: [ @@ -9,11 +8,8 @@ cc_library_shared { ], shared_libs: [ - "android.hardware.graphics.common@1.1", - "libui", - "libprotobuf-cpp-lite", "libbase", - "liblog", + "libprotobuf-cpp-lite", ], proto: { @@ -22,34 +18,16 @@ cc_library_shared { cppflags: [ "-Werror", - "-Wno-unused-parameter", - "-Wno-format", "-Wno-c++98-compat-pedantic", - "-Wno-float-conversion", "-Wno-disabled-macro-expansion", + "-Wno-float-conversion", "-Wno-float-equal", - "-Wno-sign-conversion", - "-Wno-padded", + "-Wno-format", "-Wno-old-style-cast", + "-Wno-padded", + "-Wno-sign-conversion", "-Wno-undef", + "-Wno-unused-parameter", ], } - -java_library_static { - name: "timestatsprotosnano", - host_supported: true, - proto: { - type: "nano", - }, - srcs: ["*.proto"], - no_framework_libs: true, - target: { - android: { - jarjar_rules: "jarjar-rules.txt", - }, - host: { - static_libs: ["libprotobuf-java-nano"], - }, - }, -} diff --git a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h index c876f21404..cd35e9fc99 100644 --- a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h +++ b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h @@ -17,9 +17,6 @@ #include -#include - -#include #include #include #include diff --git a/services/surfaceflinger/TimeStats/timestatsproto/jarjar-rules.txt b/services/surfaceflinger/TimeStats/timestatsproto/jarjar-rules.txt deleted file mode 100644 index 40043a861c..0000000000 --- a/services/surfaceflinger/TimeStats/timestatsproto/jarjar-rules.txt +++ /dev/null @@ -1 +0,0 @@ -rule com.google.protobuf.nano.** com.android.framework.protobuf.nano.@1 diff --git a/services/surfaceflinger/TimeStats/timestatsproto/timestats.proto b/services/surfaceflinger/TimeStats/timestatsproto/timestats.proto index a8f6fa8ab1..f29fbd187a 100644 --- a/services/surfaceflinger/TimeStats/timestatsproto/timestats.proto +++ b/services/surfaceflinger/TimeStats/timestatsproto/timestats.proto @@ -20,10 +20,6 @@ package android.surfaceflinger; option optimize_for = LITE_RUNTIME; -// frameworks/base/core/proto/android/service/sftimestats.proto is based on -// this proto. Please only make valid protobuf changes to these messages, and -// keep the other file in sync with this one. - message SFTimeStatsGlobalProto { // The start & end timestamps in UTC as // milliseconds since January 1, 1970 -- cgit v1.2.3-59-g8ed1b From c5f2c455a99fd2a05cf3e9d3af57710b6a4334fa Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Tue, 8 May 2018 16:31:56 -0700 Subject: SF TimeStats: change the container of TimeRecord The current container of TimeRecord is std::vector which behaves not well when it tries to erase an element on the front. This change update the container to std::deque instead. Test: dumpsys SurfaceFlinger --timestats Bug: b/70388650 Change-Id: Ib3f695f46eb21dc27b0ed725b86764331f304be2 --- services/surfaceflinger/TimeStats/TimeStats.cpp | 5 ++--- services/surfaceflinger/TimeStats/TimeStats.h | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/services/surfaceflinger/TimeStats/TimeStats.cpp b/services/surfaceflinger/TimeStats/TimeStats.cpp index a6833a5b5d..b207d9993a 100644 --- a/services/surfaceflinger/TimeStats/TimeStats.cpp +++ b/services/surfaceflinger/TimeStats/TimeStats.cpp @@ -152,7 +152,7 @@ void TimeStats::flushAvailableRecordsToStatsLocked(const std::string& layerName) LayerRecord& layerRecord = timeStatsTracker[layerName]; TimeRecord& prevTimeRecord = layerRecord.prevTimeRecord; - std::vector& timeRecords = layerRecord.timeRecords; + std::deque& timeRecords = layerRecord.timeRecords; while (!timeRecords.empty()) { if (!recordReadyLocked(layerName, &timeRecords[0])) break; ALOGV("[%s]-[%" PRIu64 "]-presentFenceTime[%" PRId64 "]", layerName.c_str(), @@ -199,8 +199,7 @@ void TimeStats::flushAvailableRecordsToStatsLocked(const std::string& layerName) timeStats.stats[layerName].statsEnd = static_cast(std::time(0)); } prevTimeRecord = timeRecords[0]; - // TODO(zzyiwei): change timeRecords to use std::deque - timeRecords.erase(timeRecords.begin()); + timeRecords.pop_front(); layerRecord.waitData--; } } diff --git a/services/surfaceflinger/TimeStats/TimeStats.h b/services/surfaceflinger/TimeStats/TimeStats.h index f76a62ede0..8399c5dfca 100644 --- a/services/surfaceflinger/TimeStats/TimeStats.h +++ b/services/surfaceflinger/TimeStats/TimeStats.h @@ -25,9 +25,9 @@ #include #include +#include #include #include -#include using namespace android::surfaceflinger; @@ -57,7 +57,7 @@ class TimeStats { // fences to signal, but rather waiting to receive those fences/timestamps. int32_t waitData = -1; TimeRecord prevTimeRecord; - std::vector timeRecords; + std::deque timeRecords; }; public: -- cgit v1.2.3-59-g8ed1b From 8a4015c8d7d0316fa422ed53db7e972310f6758b Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Tue, 8 May 2018 16:03:47 -0700 Subject: SF TimeStats: move dumpStats into TimeStatsHelper Move dumpStats into TimeStatsHelper to make the TimeStatsHelper class more modularized. Test: dumpsys SurfaceFlinger --timestats Bug: b/70388650 Change-Id: Ie828d9b4c47aae54df5851e0febb8f48d34b78c8 --- services/surfaceflinger/TimeStats/TimeStats.cpp | 64 +++++++++---------- services/surfaceflinger/TimeStats/TimeStats.h | 5 +- .../TimeStats/timestatsproto/Android.bp | 2 +- .../TimeStats/timestatsproto/TimeStatsHelper.cpp | 72 ++++++++++++---------- .../include/timestatsproto/TimeStatsHelper.h | 18 +++--- 5 files changed, 80 insertions(+), 81 deletions(-) diff --git a/services/surfaceflinger/TimeStats/TimeStats.cpp b/services/surfaceflinger/TimeStats/TimeStats.cpp index a6833a5b5d..cd64da08d1 100644 --- a/services/surfaceflinger/TimeStats/TimeStats.cpp +++ b/services/surfaceflinger/TimeStats/TimeStats.cpp @@ -59,14 +59,15 @@ void TimeStats::parseArgs(bool asProto, const Vector& args, size_t& in } if (argsMap.count("-dump")) { - int64_t maxLayers = 0; + std::optional maxLayers = std::nullopt; auto iter = argsMap.find("-maxlayers"); if (iter != argsMap.end() && iter->second + 1 < static_cast(args.size())) { - maxLayers = strtol(String8(args[iter->second + 1]).c_str(), nullptr, 10); - maxLayers = std::clamp(maxLayers, int64_t(0), int64_t(UINT32_MAX)); + int64_t value = strtol(String8(args[iter->second + 1]).c_str(), nullptr, 10); + value = std::clamp(value, int64_t(0), int64_t(UINT32_MAX)); + maxLayers = static_cast(value); } - dump(asProto, static_cast(maxLayers), result); + dump(asProto, maxLayers, result); } if (argsMap.count("-clear")) { @@ -147,6 +148,21 @@ static int32_t msBetween(nsecs_t start, nsecs_t end) { return static_cast(delta); } +static std::string getPackageName(const std::string& layerName) { + // This regular expression captures the following for instance: + // StatusBar in StatusBar#0 + // com.appname in com.appname/com.appname.activity#0 + // com.appname in SurfaceView - com.appname/com.appname.activity#0 + const std::regex re("(?:SurfaceView[-\\s\\t]+)?([^/]+).*#\\d+"); + std::smatch match; + if (std::regex_match(layerName.begin(), layerName.end(), match, re)) { + // There must be a match for group 1 otherwise the whole string is not + // matched and the above will return false + return match[1]; + } + return ""; +} + void TimeStats::flushAvailableRecordsToStatsLocked(const std::string& layerName) { ATRACE_CALL(); @@ -161,6 +177,7 @@ void TimeStats::flushAvailableRecordsToStatsLocked(const std::string& layerName) if (prevTimeRecord.ready) { if (!timeStats.stats.count(layerName)) { timeStats.stats[layerName].layerName = layerName; + timeStats.stats[layerName].packageName = getPackageName(layerName); timeStats.stats[layerName].statsStart = static_cast(std::time(0)); } TimeStatsHelper::TimeStatsLayer& timeStatsLayer = timeStats.stats[layerName]; @@ -434,7 +451,6 @@ void TimeStats::clear() { std::lock_guard lock(mMutex); ALOGD("Cleared"); - timeStats.dumpStats.clear(); timeStats.stats.clear(); timeStats.statsStart = (mEnabled.load() ? static_cast(std::time(0)) : 0); timeStats.statsEnd = 0; @@ -447,7 +463,7 @@ bool TimeStats::isEnabled() { return mEnabled.load(); } -void TimeStats::dump(bool asProto, uint32_t maxLayers, String8& result) { +void TimeStats::dump(bool asProto, std::optional maxLayers, String8& result) { ATRACE_CALL(); std::lock_guard lock(mMutex); @@ -457,39 +473,15 @@ void TimeStats::dump(bool asProto, uint32_t maxLayers, String8& result) { timeStats.statsEnd = static_cast(std::time(0)); - // TODO(zzyiwei): refactor dumpStats into TimeStatsHelper - timeStats.dumpStats.clear(); - for (auto& ele : timeStats.stats) { - timeStats.dumpStats.push_back(&ele.second); - } - - std::sort(timeStats.dumpStats.begin(), timeStats.dumpStats.end(), - [](TimeStatsHelper::TimeStatsLayer* const& l, - TimeStatsHelper::TimeStatsLayer* const& r) { - return l->totalFrames > r->totalFrames; - }); - - if (maxLayers != 0 && maxLayers < timeStats.dumpStats.size()) { - timeStats.dumpStats.resize(maxLayers); - } - if (asProto) { - dumpAsProtoLocked(result); + ALOGD("Dumping TimeStats as proto"); + SFTimeStatsGlobalProto timeStatsProto = timeStats.toProto(maxLayers); + result.append(timeStatsProto.SerializeAsString().c_str(), timeStatsProto.ByteSize()); } else { - dumpAsTextLocked(result); + ALOGD("Dumping TimeStats as text"); + result.append(timeStats.toString(maxLayers).c_str()); + result.append("\n"); } } -void TimeStats::dumpAsTextLocked(String8& result) { - ALOGD("Dumping TimeStats as text"); - result.append(timeStats.toString().c_str()); - result.append("\n"); -} - -void TimeStats::dumpAsProtoLocked(String8& result) { - ALOGD("Dumping TimeStats as proto"); - SFTimeStatsGlobalProto timeStatsProto = timeStats.toProto(); - result.append(timeStatsProto.SerializeAsString().c_str(), timeStatsProto.ByteSize()); -} - } // namespace android diff --git a/services/surfaceflinger/TimeStats/TimeStats.h b/services/surfaceflinger/TimeStats/TimeStats.h index f76a62ede0..b9016a1f9d 100644 --- a/services/surfaceflinger/TimeStats/TimeStats.h +++ b/services/surfaceflinger/TimeStats/TimeStats.h @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -90,9 +91,7 @@ private: void disable(); void clear(); bool isEnabled(); - void dump(bool asProto, uint32_t maxLayer, String8& result); - void dumpAsTextLocked(String8& result); - void dumpAsProtoLocked(String8& result); + void dump(bool asProto, std::optional maxLayers, String8& result); std::atomic mEnabled = false; std::mutex mMutex; diff --git a/services/surfaceflinger/TimeStats/timestatsproto/Android.bp b/services/surfaceflinger/TimeStats/timestatsproto/Android.bp index 46c82c0eb8..bef6b7c2eb 100644 --- a/services/surfaceflinger/TimeStats/timestatsproto/Android.bp +++ b/services/surfaceflinger/TimeStats/timestatsproto/Android.bp @@ -17,6 +17,7 @@ cc_library_shared { }, cppflags: [ + "-std=c++1z", "-Werror", "-Wno-c++98-compat-pedantic", "-Wno-disabled-macro-expansion", @@ -29,5 +30,4 @@ cc_library_shared { "-Wno-undef", "-Wno-unused-parameter", ], - } diff --git a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp index 3e5007c0b8..21f3ef3d7e 100644 --- a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp +++ b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp @@ -17,7 +17,6 @@ #include #include -#include #define HISTOGRAM_SIZE 85 @@ -47,55 +46,39 @@ void TimeStatsHelper::Histogram::insert(int32_t delta) { hist[*iter]++; } -float TimeStatsHelper::Histogram::averageTime() { +float TimeStatsHelper::Histogram::averageTime() const { int64_t ret = 0; int64_t count = 0; - for (auto ele : hist) { + for (auto& ele : hist) { count += ele.second; ret += ele.first * ele.second; } return static_cast(ret) / count; } -std::string TimeStatsHelper::Histogram::toString() { +std::string TimeStatsHelper::Histogram::toString() const { std::string result; for (int32_t i = 0; i < HISTOGRAM_SIZE; ++i) { int32_t bucket = histogramConfig[i]; - int32_t count = (hist.count(bucket) == 0) ? 0 : hist[bucket]; + int32_t count = (hist.count(bucket) == 0) ? 0 : hist.at(bucket); StringAppendF(&result, "%dms=%d ", bucket, count); } result.back() = '\n'; return result; } -static std::string getPackageName(const std::string& layerName) { - // This regular expression captures the following for instance: - // StatusBar in StatusBar#0 - // com.appname in com.appname/com.appname.activity#0 - // com.appname in SurfaceView - com.appname/com.appname.activity#0 - const std::regex re("(?:SurfaceView[-\\s\\t]+)?([^/]+).*#\\d+"); - std::smatch match; - if (std::regex_match(layerName.begin(), layerName.end(), match, re)) { - // There must be a match for group 1 otherwise the whole string is not - // matched and the above will return false - return match[1]; - } - return ""; -} - -std::string TimeStatsHelper::TimeStatsLayer::toString() { +std::string TimeStatsHelper::TimeStatsLayer::toString() const { std::string result = ""; StringAppendF(&result, "layerName = %s\n", layerName.c_str()); - packageName = getPackageName(layerName); StringAppendF(&result, "packageName = %s\n", packageName.c_str()); StringAppendF(&result, "statsStart = %lld\n", static_cast(statsStart)); StringAppendF(&result, "statsEnd = %lld\n", static_cast(statsEnd)); StringAppendF(&result, "totalFrames= %d\n", totalFrames); - if (deltas.find("present2present") != deltas.end()) { - StringAppendF(&result, "averageFPS = %.3f\n", - 1000.0 / deltas["present2present"].averageTime()); + auto iter = deltas.find("present2present"); + if (iter != deltas.end()) { + StringAppendF(&result, "averageFPS = %.3f\n", 1000.0 / iter->second.averageTime()); } - for (auto ele : deltas) { + for (auto& ele : deltas) { StringAppendF(&result, "%s histogram is as below:\n", ele.first.c_str()); StringAppendF(&result, "%s", ele.second.toString().c_str()); } @@ -103,7 +86,7 @@ std::string TimeStatsHelper::TimeStatsLayer::toString() { return result; } -std::string TimeStatsHelper::TimeStatsGlobal::toString() { +std::string TimeStatsHelper::TimeStatsGlobal::toString(std::optional maxLayers) const { std::string result = "SurfaceFlinger TimeStats:\n"; StringAppendF(&result, "statsStart = %lld\n", static_cast(statsStart)); StringAppendF(&result, "statsEnd = %lld\n", static_cast(statsEnd)); @@ -111,25 +94,25 @@ std::string TimeStatsHelper::TimeStatsGlobal::toString() { StringAppendF(&result, "missedFrames= %d\n", missedFrames); StringAppendF(&result, "clientCompositionFrames= %d\n", clientCompositionFrames); StringAppendF(&result, "TimeStats for each layer is as below:\n"); - for (auto ele : dumpStats) { + const auto dumpStats = generateDumpStats(maxLayers); + for (auto& ele : dumpStats) { StringAppendF(&result, "%s", ele->toString().c_str()); } return result; } -SFTimeStatsLayerProto TimeStatsHelper::TimeStatsLayer::toProto() { +SFTimeStatsLayerProto TimeStatsHelper::TimeStatsLayer::toProto() const { SFTimeStatsLayerProto layerProto; layerProto.set_layer_name(layerName); - packageName = getPackageName(layerName); layerProto.set_package_name(packageName); layerProto.set_stats_start(statsStart); layerProto.set_stats_end(statsEnd); layerProto.set_total_frames(totalFrames); - for (auto ele : deltas) { + for (auto& ele : deltas) { SFTimeStatsDeltaProto* deltaProto = layerProto.add_deltas(); deltaProto->set_delta_name(ele.first); - for (auto histEle : ele.second.hist) { + for (auto& histEle : ele.second.hist) { SFTimeStatsHistogramBucketProto* histProto = deltaProto->add_histograms(); histProto->set_render_millis(histEle.first); histProto->set_frame_count(histEle.second); @@ -138,19 +121,40 @@ SFTimeStatsLayerProto TimeStatsHelper::TimeStatsLayer::toProto() { return layerProto; } -SFTimeStatsGlobalProto TimeStatsHelper::TimeStatsGlobal::toProto() { +SFTimeStatsGlobalProto TimeStatsHelper::TimeStatsGlobal::toProto( + std::optional 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); - for (auto ele : dumpStats) { + const auto dumpStats = generateDumpStats(maxLayers); + for (auto& ele : dumpStats) { SFTimeStatsLayerProto* layerProto = globalProto.add_stats(); layerProto->CopyFrom(ele->toProto()); } return globalProto; } +std::vector +TimeStatsHelper::TimeStatsGlobal::generateDumpStats(std::optional maxLayers) const { + std::vector dumpStats; + for (auto& ele : stats) { + dumpStats.push_back(&ele.second); + } + + std::sort(dumpStats.begin(), dumpStats.end(), + [](TimeStatsHelper::TimeStatsLayer const* l, + TimeStatsHelper::TimeStatsLayer const* r) { + return l->totalFrames > r->totalFrames; + }); + + if (maxLayers && (*maxLayers < dumpStats.size())) { + dumpStats.resize(*maxLayers); + } + return dumpStats; +} + } // namespace surfaceflinger } // namespace android diff --git a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h index cd35e9fc99..1798555be5 100644 --- a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h +++ b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h @@ -17,6 +17,7 @@ #include +#include #include #include #include @@ -33,8 +34,8 @@ public: std::unordered_map hist; void insert(int32_t delta); - float averageTime(); - std::string toString(); + float averageTime() const; + std::string toString() const; }; class TimeStatsLayer { @@ -46,8 +47,8 @@ public: int32_t totalFrames = 0; std::unordered_map deltas; - std::string toString(); - SFTimeStatsLayerProto toProto(); + std::string toString() const; + SFTimeStatsLayerProto toProto() const; }; class TimeStatsGlobal { @@ -58,10 +59,13 @@ public: int32_t missedFrames = 0; int32_t clientCompositionFrames = 0; std::unordered_map stats; - std::vector dumpStats; - std::string toString(); - SFTimeStatsGlobalProto toProto(); + std::string toString(std::optional maxLayers) const; + SFTimeStatsGlobalProto toProto(std::optional maxLayers) const; + + private: + std::vector generateDumpStats( + std::optional maxLayers) const; }; }; -- cgit v1.2.3-59-g8ed1b