Implement Display Layer Stats
Try to collect data for analyzing how many display controller layers we
need and what we use them for. Also part of a bug fixing for potential
memory leak of existing layer tracing work of winscope.
Test: adb shell dumpsys SurfaceFlinger --enable-layer-stats
Test: adb shell dumpsys SurfaceFlinger --disable-layer-stats
Test: adb shell dumpsys SurfaceFlinger --clear-layer-stats
Test: adb shell dumpsys SurfaceFlinger --dump-layer-stats
Bug: b/73668062
Change-Id: Ie08aa85d34db2c2c767b8e27eb5aad6f7c3fb975
Merged-In: Ie08aa85d34db2c2c767b8e27eb5aad6f7c3fb975
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index f180a3b..babac37 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1484,6 +1484,7 @@
setUpHWComposer();
doDebugFlashRegions();
doTracing("handleRefresh");
+ logLayerStats();
doComposition();
postComposition(refreshStartTime);
@@ -1553,6 +1554,25 @@
}
}
+void SurfaceFlinger::logLayerStats() {
+ ATRACE_CALL();
+ if (CC_UNLIKELY(mLayerStats.isEnabled())) {
+ int32_t hwcId = -1;
+ for (size_t dpy = 0; dpy < mDisplays.size(); ++dpy) {
+ const sp<const DisplayDevice>& displayDevice(mDisplays[dpy]);
+ if (displayDevice->isPrimary()) {
+ hwcId = displayDevice->getHwcDisplayId();
+ break;
+ }
+ }
+ if (hwcId < 0) {
+ ALOGE("LayerStats: Hmmm, no primary display?");
+ return;
+ }
+ mLayerStats.logLayerStats(dumpVisibleLayersProtoInfo(hwcId));
+ }
+}
+
void SurfaceFlinger::preComposition(nsecs_t refreshStartTime)
{
ATRACE_CALL();
@@ -3772,6 +3792,34 @@
dumpWideColorInfo(result);
dumpAll = false;
}
+
+ if ((index < numArgs) &&
+ (args[index] == String16("--enable-layer-stats"))) {
+ index++;
+ mLayerStats.enable();
+ dumpAll = false;
+ }
+
+ if ((index < numArgs) &&
+ (args[index] == String16("--disable-layer-stats"))) {
+ index++;
+ mLayerStats.disable();
+ dumpAll = false;
+ }
+
+ if ((index < numArgs) &&
+ (args[index] == String16("--clear-layer-stats"))) {
+ index++;
+ mLayerStats.clear();
+ dumpAll = false;
+ }
+
+ if ((index < numArgs) &&
+ (args[index] == String16("--dump-layer-stats"))) {
+ index++;
+ mLayerStats.dump(result);
+ dumpAll = false;
+ }
}
if (dumpAll) {
@@ -3979,6 +4027,25 @@
return layersProto;
}
+LayersProto SurfaceFlinger::dumpVisibleLayersProtoInfo(int32_t hwcId) const {
+ LayersProto layersProto;
+
+ const sp<DisplayDevice>& displayDevice(mDisplays[hwcId]);
+ SizeProto* resolution = layersProto.mutable_resolution();
+ resolution->set_w(displayDevice->getWidth());
+ resolution->set_h(displayDevice->getHeight());
+
+ mDrawingState.traverseInZOrder([&](Layer* layer) {
+ if (!layer->visibleRegion.isEmpty() &&
+ layer->getBE().mHwcLayers.count(hwcId)) {
+ LayerProto* layerProto = layersProto.add_layers();
+ layer->writeToProto(layerProto, hwcId);
+ }
+ });
+
+ return layersProto;
+}
+
void SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
String8& result) const
{