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/LayerStats.h b/services/surfaceflinger/LayerStats.h
new file mode 100644
index 0000000..de2b47c
--- /dev/null
+++ b/services/surfaceflinger/LayerStats.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <layerproto/LayerProtoHeader.h>
+#include <layerproto/LayerProtoParser.h>
+#include <mutex>
+#include <unordered_map>
+
+using namespace android::surfaceflinger;
+
+namespace android {
+class String8;
+
+class LayerStats {
+public:
+ void enable();
+ void disable();
+ void clear();
+ bool isEnabled();
+ void logLayerStats(const LayersProto& layersProto);
+ void dump(String8& result);
+
+private:
+ // Traverse layer tree to get all visible layers' stats
+ void traverseLayerTreeStatsLocked(
+ std::vector<std::unique_ptr<LayerProtoParser::Layer>> layerTree,
+ const LayerProtoParser::LayerGlobal* layerGlobal);
+ // Convert layer's top-left position into 8x8 percentage of the display
+ static const char* destinationLocation(int32_t location, int32_t range, bool isHorizontal);
+ // Convert layer's size into 8x8 percentage of the display
+ static const char* destinationSize(int32_t size, int32_t range, bool isWidth);
+ // Return the name of the transform
+ static const char* layerTransform(int32_t transform);
+ // Calculate scale ratios of layer's width/height with rotation information
+ static std::string scaleRatioWH(const LayerProtoParser::Layer* layer);
+ // Calculate scale ratio from source to destination and convert to string
+ static const char* scaleRatio(int32_t destinationScale, int32_t sourceScale);
+ // Return whether the original buffer is rotated in final composition
+ static bool isRotated(int32_t transform);
+ // Return whether the original buffer is V-flipped in final composition
+ static bool isVFlipped(int32_t transform);
+ // Return whether the original buffer is H-flipped in final composition
+ static bool isHFlipped(int32_t transform);
+
+ bool mEnabled = false;
+ // Protect mLayersStatsMap
+ std::mutex mMutex;
+ // Hashmap for tracking the layer stats
+ // KEY is a concatenation of a particular set of layer properties
+ // VALUE is the number of times this particular get scanned out
+ std::unordered_map<std::string, uint32_t> mLayerStatsMap;
+};
+
+} // namespace android