Loading services/surfaceflinger/SurfaceFlinger.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -3980,7 +3980,7 @@ void SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index, LayersProto layersProto = dumpProtoInfo(LayerVector::StateSet::Current); auto layerTree = LayerProtoParser::generateLayerTree(layersProto); result.append(LayerProtoParser::layersToString(layerTree).c_str()); result.append(LayerProtoParser::layersToString(std::move(layerTree)).c_str()); /* * Dump Display state Loading services/surfaceflinger/layerproto/LayerProtoParser.cpp +34 −32 Original line number Diff line number Diff line Loading @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ #include <android-base/stringprintf.h> #include <layerproto/LayerProtoParser.h> #include <ui/DebugUtils.h> Loading @@ -24,7 +23,7 @@ using android::base::StringPrintf; namespace android { namespace surfaceflinger { bool sortLayers(const LayerProtoParser::Layer* lhs, const LayerProtoParser::Layer* rhs) { bool sortLayers(LayerProtoParser::Layer* lhs, const LayerProtoParser::Layer* rhs) { uint32_t ls = lhs->layerStack; uint32_t rs = rhs->layerStack; if (ls != rs) return ls < rs; Loading @@ -38,20 +37,25 @@ bool sortLayers(const LayerProtoParser::Layer* lhs, const LayerProtoParser::Laye return lhs->id < rhs->id; } std::vector<const LayerProtoParser::Layer*> LayerProtoParser::generateLayerTree( bool sortLayerUniquePtrs(const std::unique_ptr<LayerProtoParser::Layer>& lhs, const std::unique_ptr<LayerProtoParser::Layer>& rhs) { return sortLayers(lhs.get(), rhs.get()); } std::vector<std::unique_ptr<LayerProtoParser::Layer>> LayerProtoParser::generateLayerTree( const LayersProto& layersProto) { auto layerMap = generateMap(layersProto); std::unordered_map<int32_t, LayerProtoParser::Layer*> layerMap = generateMap(layersProto); std::vector<std::unique_ptr<LayerProtoParser::Layer>> layers; std::vector<const Layer*> layers; std::for_each(layerMap.begin(), layerMap.end(), [&](const std::pair<const int32_t, Layer*>& ref) { if (ref.second->parent == nullptr) { // only save top level layers layers.push_back(ref.second); for (std::pair<int32_t, Layer*> kv : layerMap) { if (kv.second->parent == nullptr) { // Make unique_ptr for top level layers since they are not children. This ensures there // will only be one unique_ptr made for each layer. layers.push_back(std::unique_ptr<Layer>(kv.second)); } } }); std::sort(layers.begin(), layers.end(), sortLayers); std::sort(layers.begin(), layers.end(), sortLayerUniquePtrs); return layers; } Loading Loading @@ -155,63 +159,61 @@ void LayerProtoParser::updateChildrenAndRelative(const LayerProto& layerProto, for (int i = 0; i < layerProto.children_size(); i++) { if (layerMap.count(layerProto.children(i)) > 0) { auto childLayer = layerMap[layerProto.children(i)]; currLayer->children.push_back(childLayer); // Only make unique_ptrs for children since they are guaranteed to be unique, only one // parent per child. This ensures there will only be one unique_ptr made for each layer. currLayer->children.push_back(std::unique_ptr<Layer>(layerMap[layerProto.children(i)])); } } for (int i = 0; i < layerProto.relatives_size(); i++) { if (layerMap.count(layerProto.relatives(i)) > 0) { auto relativeLayer = layerMap[layerProto.relatives(i)]; currLayer->relatives.push_back(relativeLayer); currLayer->relatives.push_back(layerMap[layerProto.relatives(i)]); } } if (layerProto.has_parent()) { if (layerMap.count(layerProto.parent()) > 0) { auto parentLayer = layerMap[layerProto.parent()]; currLayer->parent = parentLayer; currLayer->parent = layerMap[layerProto.parent()]; } } if (layerProto.has_z_order_relative_of()) { if (layerMap.count(layerProto.z_order_relative_of()) > 0) { auto relativeLayer = layerMap[layerProto.z_order_relative_of()]; currLayer->zOrderRelativeOf = relativeLayer; currLayer->zOrderRelativeOf = layerMap[layerProto.z_order_relative_of()]; } } } std::string LayerProtoParser::layersToString( const std::vector<const LayerProtoParser::Layer*> layers) { std::vector<std::unique_ptr<LayerProtoParser::Layer>> layers) { std::string result; for (const LayerProtoParser::Layer* layer : layers) { for (std::unique_ptr<LayerProtoParser::Layer>& layer : layers) { if (layer->zOrderRelativeOf != nullptr) { continue; } result.append(layerToString(layer).c_str()); result.append(layerToString(layer.get()).c_str()); } return result; } std::string LayerProtoParser::layerToString(const LayerProtoParser::Layer* layer) { std::string LayerProtoParser::layerToString(LayerProtoParser::Layer* layer) { std::string result; std::vector<const Layer*> traverse(layer->relatives); for (const LayerProtoParser::Layer* child : layer->children) { std::vector<Layer*> traverse(layer->relatives); for (std::unique_ptr<LayerProtoParser::Layer>& child : layer->children) { if (child->zOrderRelativeOf != nullptr) { continue; } traverse.push_back(child); traverse.push_back(child.get()); } std::sort(traverse.begin(), traverse.end(), sortLayers); size_t i = 0; for (; i < traverse.size(); i++) { const auto& relative = traverse[i]; auto& relative = traverse[i]; if (relative->z >= 0) { break; } Loading @@ -220,7 +222,7 @@ std::string LayerProtoParser::layerToString(const LayerProtoParser::Layer* layer result.append(layer->to_string().c_str()); result.append("\n"); for (; i < traverse.size(); i++) { const auto& relative = traverse[i]; auto& relative = traverse[i]; result.append(layerToString(relative).c_str()); } Loading services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h +6 −5 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <math/vec4.h> #include <memory> #include <unordered_map> #include <vector> Loading Loading @@ -68,8 +69,8 @@ public: public: int32_t id; std::string name; std::vector<const Layer*> children; std::vector<const Layer*> relatives; std::vector<std::unique_ptr<Layer>> children; std::vector<Layer*> relatives; std::string type; LayerProtoParser::Region transparentRegion; LayerProtoParser::Region visibleRegion; Loading Loading @@ -99,8 +100,8 @@ public: std::string to_string() const; }; static std::vector<const Layer*> generateLayerTree(const LayersProto& layersProto); static std::string layersToString(const std::vector<const LayerProtoParser::Layer*> layers); static std::vector<std::unique_ptr<Layer>> generateLayerTree(const LayersProto& layersProto); static std::string layersToString(std::vector<std::unique_ptr<LayerProtoParser::Layer>> layers); private: static std::unordered_map<int32_t, Layer*> generateMap(const LayersProto& layersProto); Loading @@ -113,7 +114,7 @@ private: static void updateChildrenAndRelative(const LayerProto& layerProto, std::unordered_map<int32_t, Layer*>& layerMap); static std::string layerToString(const LayerProtoParser::Layer* layer); static std::string layerToString(LayerProtoParser::Layer* layer); }; } // namespace surfaceflinger Loading services/surfaceflinger/tests/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ cc_test { "libEGL", "libGLESv2", "libgui", "liblayers_proto", "liblog", "libprotobuf-cpp-full", "libui", Loading services/surfaceflinger/tests/Stress_test.cpp +63 −1 Original line number Diff line number Diff line Loading @@ -22,7 +22,7 @@ #include <thread> #include <functional> #include <layerproto/LayerProtoParser.h> namespace android { Loading @@ -47,4 +47,66 @@ TEST(SurfaceFlingerStress, create_and_destroy) { } } surfaceflinger::LayersProto generateLayerProto() { surfaceflinger::LayersProto layersProto; std::array<surfaceflinger::LayerProto*, 10> layers = {}; for (size_t i = 0; i < layers.size(); ++i) { layers[i] = layersProto.add_layers(); layers[i]->set_id(i); } layers[0]->add_children(1); layers[1]->set_parent(0); layers[0]->add_children(2); layers[2]->set_parent(0); layers[0]->add_children(3); layers[3]->set_parent(0); layers[2]->add_children(4); layers[4]->set_parent(2); layers[3]->add_children(5); layers[5]->set_parent(3); layers[5]->add_children(6); layers[6]->set_parent(5); layers[5]->add_children(7); layers[7]->set_parent(5); layers[6]->add_children(8); layers[8]->set_parent(6); layers[4]->set_z_order_relative_of(3); layers[3]->add_relatives(4); layers[8]->set_z_order_relative_of(9); layers[9]->add_relatives(8); layers[3]->set_z_order_relative_of(1); layers[1]->add_relatives(3); /* ---------------------------- * - 0 - - 9 - * / | \ * 1 2 3(1) * | | * 4(3) 5 * / \ * 6 7 * | * 8(9) * -------------------------- */ return layersProto; } TEST(LayerProtoStress, mem_info) { std::string cmd = "dumpsys meminfo "; cmd += std::to_string(getpid()); system(cmd.c_str()); for (int i = 0; i < 100000; i++) { surfaceflinger::LayersProto layersProto = generateLayerProto(); auto layerTree = surfaceflinger::LayerProtoParser::generateLayerTree(layersProto); // Allow some layerTrees to just fall out of scope (instead of std::move) if (i % 2) { surfaceflinger::LayerProtoParser::layersToString(std::move(layerTree)); } } system(cmd.c_str()); } } Loading
services/surfaceflinger/SurfaceFlinger.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -3980,7 +3980,7 @@ void SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index, LayersProto layersProto = dumpProtoInfo(LayerVector::StateSet::Current); auto layerTree = LayerProtoParser::generateLayerTree(layersProto); result.append(LayerProtoParser::layersToString(layerTree).c_str()); result.append(LayerProtoParser::layersToString(std::move(layerTree)).c_str()); /* * Dump Display state Loading
services/surfaceflinger/layerproto/LayerProtoParser.cpp +34 −32 Original line number Diff line number Diff line Loading @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ #include <android-base/stringprintf.h> #include <layerproto/LayerProtoParser.h> #include <ui/DebugUtils.h> Loading @@ -24,7 +23,7 @@ using android::base::StringPrintf; namespace android { namespace surfaceflinger { bool sortLayers(const LayerProtoParser::Layer* lhs, const LayerProtoParser::Layer* rhs) { bool sortLayers(LayerProtoParser::Layer* lhs, const LayerProtoParser::Layer* rhs) { uint32_t ls = lhs->layerStack; uint32_t rs = rhs->layerStack; if (ls != rs) return ls < rs; Loading @@ -38,20 +37,25 @@ bool sortLayers(const LayerProtoParser::Layer* lhs, const LayerProtoParser::Laye return lhs->id < rhs->id; } std::vector<const LayerProtoParser::Layer*> LayerProtoParser::generateLayerTree( bool sortLayerUniquePtrs(const std::unique_ptr<LayerProtoParser::Layer>& lhs, const std::unique_ptr<LayerProtoParser::Layer>& rhs) { return sortLayers(lhs.get(), rhs.get()); } std::vector<std::unique_ptr<LayerProtoParser::Layer>> LayerProtoParser::generateLayerTree( const LayersProto& layersProto) { auto layerMap = generateMap(layersProto); std::unordered_map<int32_t, LayerProtoParser::Layer*> layerMap = generateMap(layersProto); std::vector<std::unique_ptr<LayerProtoParser::Layer>> layers; std::vector<const Layer*> layers; std::for_each(layerMap.begin(), layerMap.end(), [&](const std::pair<const int32_t, Layer*>& ref) { if (ref.second->parent == nullptr) { // only save top level layers layers.push_back(ref.second); for (std::pair<int32_t, Layer*> kv : layerMap) { if (kv.second->parent == nullptr) { // Make unique_ptr for top level layers since they are not children. This ensures there // will only be one unique_ptr made for each layer. layers.push_back(std::unique_ptr<Layer>(kv.second)); } } }); std::sort(layers.begin(), layers.end(), sortLayers); std::sort(layers.begin(), layers.end(), sortLayerUniquePtrs); return layers; } Loading Loading @@ -155,63 +159,61 @@ void LayerProtoParser::updateChildrenAndRelative(const LayerProto& layerProto, for (int i = 0; i < layerProto.children_size(); i++) { if (layerMap.count(layerProto.children(i)) > 0) { auto childLayer = layerMap[layerProto.children(i)]; currLayer->children.push_back(childLayer); // Only make unique_ptrs for children since they are guaranteed to be unique, only one // parent per child. This ensures there will only be one unique_ptr made for each layer. currLayer->children.push_back(std::unique_ptr<Layer>(layerMap[layerProto.children(i)])); } } for (int i = 0; i < layerProto.relatives_size(); i++) { if (layerMap.count(layerProto.relatives(i)) > 0) { auto relativeLayer = layerMap[layerProto.relatives(i)]; currLayer->relatives.push_back(relativeLayer); currLayer->relatives.push_back(layerMap[layerProto.relatives(i)]); } } if (layerProto.has_parent()) { if (layerMap.count(layerProto.parent()) > 0) { auto parentLayer = layerMap[layerProto.parent()]; currLayer->parent = parentLayer; currLayer->parent = layerMap[layerProto.parent()]; } } if (layerProto.has_z_order_relative_of()) { if (layerMap.count(layerProto.z_order_relative_of()) > 0) { auto relativeLayer = layerMap[layerProto.z_order_relative_of()]; currLayer->zOrderRelativeOf = relativeLayer; currLayer->zOrderRelativeOf = layerMap[layerProto.z_order_relative_of()]; } } } std::string LayerProtoParser::layersToString( const std::vector<const LayerProtoParser::Layer*> layers) { std::vector<std::unique_ptr<LayerProtoParser::Layer>> layers) { std::string result; for (const LayerProtoParser::Layer* layer : layers) { for (std::unique_ptr<LayerProtoParser::Layer>& layer : layers) { if (layer->zOrderRelativeOf != nullptr) { continue; } result.append(layerToString(layer).c_str()); result.append(layerToString(layer.get()).c_str()); } return result; } std::string LayerProtoParser::layerToString(const LayerProtoParser::Layer* layer) { std::string LayerProtoParser::layerToString(LayerProtoParser::Layer* layer) { std::string result; std::vector<const Layer*> traverse(layer->relatives); for (const LayerProtoParser::Layer* child : layer->children) { std::vector<Layer*> traverse(layer->relatives); for (std::unique_ptr<LayerProtoParser::Layer>& child : layer->children) { if (child->zOrderRelativeOf != nullptr) { continue; } traverse.push_back(child); traverse.push_back(child.get()); } std::sort(traverse.begin(), traverse.end(), sortLayers); size_t i = 0; for (; i < traverse.size(); i++) { const auto& relative = traverse[i]; auto& relative = traverse[i]; if (relative->z >= 0) { break; } Loading @@ -220,7 +222,7 @@ std::string LayerProtoParser::layerToString(const LayerProtoParser::Layer* layer result.append(layer->to_string().c_str()); result.append("\n"); for (; i < traverse.size(); i++) { const auto& relative = traverse[i]; auto& relative = traverse[i]; result.append(layerToString(relative).c_str()); } Loading
services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h +6 −5 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <math/vec4.h> #include <memory> #include <unordered_map> #include <vector> Loading Loading @@ -68,8 +69,8 @@ public: public: int32_t id; std::string name; std::vector<const Layer*> children; std::vector<const Layer*> relatives; std::vector<std::unique_ptr<Layer>> children; std::vector<Layer*> relatives; std::string type; LayerProtoParser::Region transparentRegion; LayerProtoParser::Region visibleRegion; Loading Loading @@ -99,8 +100,8 @@ public: std::string to_string() const; }; static std::vector<const Layer*> generateLayerTree(const LayersProto& layersProto); static std::string layersToString(const std::vector<const LayerProtoParser::Layer*> layers); static std::vector<std::unique_ptr<Layer>> generateLayerTree(const LayersProto& layersProto); static std::string layersToString(std::vector<std::unique_ptr<LayerProtoParser::Layer>> layers); private: static std::unordered_map<int32_t, Layer*> generateMap(const LayersProto& layersProto); Loading @@ -113,7 +114,7 @@ private: static void updateChildrenAndRelative(const LayerProto& layerProto, std::unordered_map<int32_t, Layer*>& layerMap); static std::string layerToString(const LayerProtoParser::Layer* layer); static std::string layerToString(LayerProtoParser::Layer* layer); }; } // namespace surfaceflinger Loading
services/surfaceflinger/tests/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ cc_test { "libEGL", "libGLESv2", "libgui", "liblayers_proto", "liblog", "libprotobuf-cpp-full", "libui", Loading
services/surfaceflinger/tests/Stress_test.cpp +63 −1 Original line number Diff line number Diff line Loading @@ -22,7 +22,7 @@ #include <thread> #include <functional> #include <layerproto/LayerProtoParser.h> namespace android { Loading @@ -47,4 +47,66 @@ TEST(SurfaceFlingerStress, create_and_destroy) { } } surfaceflinger::LayersProto generateLayerProto() { surfaceflinger::LayersProto layersProto; std::array<surfaceflinger::LayerProto*, 10> layers = {}; for (size_t i = 0; i < layers.size(); ++i) { layers[i] = layersProto.add_layers(); layers[i]->set_id(i); } layers[0]->add_children(1); layers[1]->set_parent(0); layers[0]->add_children(2); layers[2]->set_parent(0); layers[0]->add_children(3); layers[3]->set_parent(0); layers[2]->add_children(4); layers[4]->set_parent(2); layers[3]->add_children(5); layers[5]->set_parent(3); layers[5]->add_children(6); layers[6]->set_parent(5); layers[5]->add_children(7); layers[7]->set_parent(5); layers[6]->add_children(8); layers[8]->set_parent(6); layers[4]->set_z_order_relative_of(3); layers[3]->add_relatives(4); layers[8]->set_z_order_relative_of(9); layers[9]->add_relatives(8); layers[3]->set_z_order_relative_of(1); layers[1]->add_relatives(3); /* ---------------------------- * - 0 - - 9 - * / | \ * 1 2 3(1) * | | * 4(3) 5 * / \ * 6 7 * | * 8(9) * -------------------------- */ return layersProto; } TEST(LayerProtoStress, mem_info) { std::string cmd = "dumpsys meminfo "; cmd += std::to_string(getpid()); system(cmd.c_str()); for (int i = 0; i < 100000; i++) { surfaceflinger::LayersProto layersProto = generateLayerProto(); auto layerTree = surfaceflinger::LayerProtoParser::generateLayerTree(layersProto); // Allow some layerTrees to just fall out of scope (instead of std::move) if (i % 2) { surfaceflinger::LayerProtoParser::layersToString(std::move(layerTree)); } } system(cmd.c_str()); } }