Implement Display Layer Stats V0.1
Try to collect data for analyzing how many display controller layers we
need and what we use them for. This change will collect additional data
from per frame point of view.
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/75953772
Change-Id: Ib48777df7e1fed637be7eb1aefbdf1808d1daccd
Merged-In: Ib48777df7e1fed637be7eb1aefbdf1808d1daccd
diff --git a/services/surfaceflinger/LayerStats.cpp b/services/surfaceflinger/LayerStats.cpp
index dc99b41..38ea6ed 100644
--- a/services/surfaceflinger/LayerStats.cpp
+++ b/services/surfaceflinger/LayerStats.cpp
@@ -19,6 +19,7 @@
#include "LayerStats.h"
#include "DisplayHardware/HWComposer.h"
+#include "ui/DebugUtils.h"
#include <android-base/stringprintf.h>
#include <log/log.h>
@@ -31,7 +32,7 @@
ATRACE_CALL();
std::lock_guard<std::mutex> lock(mMutex);
if (mEnabled) return;
- mLayerStatsMap.clear();
+ mLayerShapeStatsMap.clear();
mEnabled = true;
ALOGD("Logging enabled");
}
@@ -47,7 +48,7 @@
void LayerStats::clear() {
ATRACE_CALL();
std::lock_guard<std::mutex> lock(mMutex);
- mLayerStatsMap.clear();
+ mLayerShapeStatsMap.clear();
ALOGD("Cleared current layer stats");
}
@@ -57,42 +58,69 @@
void LayerStats::traverseLayerTreeStatsLocked(
std::vector<std::unique_ptr<LayerProtoParser::Layer>> layerTree,
- const LayerProtoParser::LayerGlobal* layerGlobal) {
+ const LayerProtoParser::LayerGlobal* layerGlobal, std::vector<std::string>& layerShapeVec) {
for (std::unique_ptr<LayerProtoParser::Layer>& layer : layerTree) {
if (!layer) continue;
- traverseLayerTreeStatsLocked(std::move(layer->children), layerGlobal);
- std::string key =
- base::StringPrintf("%s,%s,%s,%s,%s,%s,%s,%s,%s",
- destinationLocation(layer->hwcFrame.left,
- layerGlobal->resolution[0], true),
- destinationLocation(layer->hwcFrame.top,
- layerGlobal->resolution[1], false),
- destinationSize(layer->hwcFrame.right - layer->hwcFrame.left,
- layerGlobal->resolution[0], true),
- destinationSize(layer->hwcFrame.bottom - layer->hwcFrame.top,
- layerGlobal->resolution[1], false),
- layer->type.c_str(), scaleRatioWH(layer.get()).c_str(),
- layerTransform(layer->hwcTransform), layer->pixelFormat.c_str(),
- layer->dataspace.c_str());
- mLayerStatsMap[key]++;
+ traverseLayerTreeStatsLocked(std::move(layer->children), layerGlobal, layerShapeVec);
+ std::string key = "";
+ base::StringAppendF(&key, ",%s", layer->type.c_str());
+ base::StringAppendF(&key, ",%s", layerCompositionType(layer->hwcCompositionType));
+ base::StringAppendF(&key, ",%d", layer->isProtected);
+ base::StringAppendF(&key, ",%s", layerTransform(layer->hwcTransform));
+ base::StringAppendF(&key, ",%s", layerPixelFormat(layer->activeBuffer.format));
+ base::StringAppendF(&key, ",%s", layer->dataspace.c_str());
+ base::StringAppendF(&key, ",%s",
+ destinationLocation(layer->hwcFrame.left, layerGlobal->resolution[0],
+ true));
+ base::StringAppendF(&key, ",%s",
+ destinationLocation(layer->hwcFrame.top, layerGlobal->resolution[1],
+ false));
+ base::StringAppendF(&key, ",%s",
+ destinationSize(layer->hwcFrame.right - layer->hwcFrame.left,
+ layerGlobal->resolution[0], true));
+ base::StringAppendF(&key, ",%s",
+ destinationSize(layer->hwcFrame.bottom - layer->hwcFrame.top,
+ layerGlobal->resolution[1], false));
+ base::StringAppendF(&key, ",%s", scaleRatioWH(layer.get()).c_str());
+ base::StringAppendF(&key, ",%s", alpha(static_cast<float>(layer->color.a)));
+
+ layerShapeVec.push_back(key);
+ ALOGV("%s", key.c_str());
}
}
void LayerStats::logLayerStats(const LayersProto& layersProto) {
ATRACE_CALL();
+ ALOGV("Logging");
auto layerGlobal = LayerProtoParser::generateLayerGlobalInfo(layersProto);
auto layerTree = LayerProtoParser::generateLayerTree(layersProto);
+ std::vector<std::string> layerShapeVec;
+
std::lock_guard<std::mutex> lock(mMutex);
- traverseLayerTreeStatsLocked(std::move(layerTree), &layerGlobal);
+ traverseLayerTreeStatsLocked(std::move(layerTree), &layerGlobal, layerShapeVec);
+
+ std::string layerShapeKey =
+ base::StringPrintf("%d,%s,%s,%s", static_cast<int32_t>(layerShapeVec.size()),
+ layerGlobal.colorMode.c_str(), layerGlobal.colorTransform.c_str(),
+ layerTransform(layerGlobal.globalTransform));
+ ALOGV("%s", layerShapeKey.c_str());
+
+ std::sort(layerShapeVec.begin(), layerShapeVec.end(), std::greater<std::string>());
+ for (auto const& s : layerShapeVec) {
+ layerShapeKey += s;
+ }
+
+ mLayerShapeStatsMap[layerShapeKey]++;
}
void LayerStats::dump(String8& result) {
ATRACE_CALL();
ALOGD("Dumping");
- result.append("Count,DstPosX,DstPosY,DstWidth,DstHeight,LayerType,WScale,HScale,");
- result.append("Transform,PixelFormat,Dataspace\n");
std::lock_guard<std::mutex> lock(mMutex);
- for (auto& u : mLayerStatsMap) {
+ result.append("Frequency,LayerCount,ColorMode,ColorTransform,Orientation\n");
+ result.append("LayerType,CompositionType,IsProtected,Transform,PixelFormat,Dataspace,");
+ result.append("DstX,DstY,DstWidth,DstHeight,WScale,HScale,Alpha\n");
+ for (auto& u : mLayerShapeStatsMap) {
result.appendFormat("%u,%s\n", u.second, u.first.c_str());
}
}
@@ -129,6 +157,14 @@
return getTransformName(static_cast<hwc_transform_t>(transform));
}
+const char* LayerStats::layerCompositionType(int32_t compositionType) {
+ return getCompositionName(static_cast<hwc2_composition_t>(compositionType));
+}
+
+const char* LayerStats::layerPixelFormat(int32_t pixelFormat) {
+ return decodePixelFormat(pixelFormat).c_str();
+}
+
std::string LayerStats::scaleRatioWH(const LayerProtoParser::Layer* layer) {
if (!layer->type.compare("ColorLayer")) return "N/A,N/A";
std::string ret = "";
@@ -166,6 +202,21 @@
return ">=16";
}
+const char* LayerStats::alpha(float a) {
+ if (a == 1.0f) return "1.0";
+ if (a > 0.9f) return "0.99";
+ if (a > 0.8f) return "0.9";
+ if (a > 0.7f) return "0.8";
+ if (a > 0.6f) return "0.7";
+ if (a > 0.5f) return "0.6";
+ if (a > 0.4f) return "0.5";
+ if (a > 0.3f) return "0.4";
+ if (a > 0.2f) return "0.3";
+ if (a > 0.1f) return "0.2";
+ if (a > 0.0f) return "0.1";
+ return "0.0";
+}
+
bool LayerStats::isRotated(int32_t transform) {
return transform & HWC_TRANSFORM_ROT_90;
}
@@ -178,4 +229,4 @@
return transform & HWC_TRANSFORM_FLIP_H;
}
-} // namespace android
+} // namespace android