Loading libs/binder/ProcessState.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,10 @@ static void verifyNotForked(bool forked) { LOG_ALWAYS_FATAL_IF(forked, "libbinder ProcessState can not be used after fork"); } bool ProcessState::isVndservicemanagerEnabled() { return access("/vendor/bin/vndservicemanager", R_OK) == 0; } sp<ProcessState> ProcessState::init(const char *driver, bool requireDefault) { #ifdef BINDER_IPC_32BIT Loading @@ -123,6 +127,11 @@ sp<ProcessState> ProcessState::init(const char *driver, bool requireDefault) driver = "/dev/binder"; } if (0 == strcmp(driver, "/dev/vndbinder") && !isVndservicemanagerEnabled()) { ALOGE("vndservicemanager is not started on this device, you can save resources/threads " "by not initializing ProcessState with /dev/vndbinder."); } // we must install these before instantiating the gProcess object, // otherwise this would race with creating it, and there could be the // possibility of an invalid gProcess object forked by another thread Loading libs/binder/include/binder/ProcessState.h +2 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ public: static sp<ProcessState> self(); static sp<ProcessState> selfOrNull(); static bool isVndservicemanagerEnabled(); /* initWithDriver() can be used to configure libbinder to use * a different binder driver dev node. It must be called *before* * any call to ProcessState::self(). The default is /dev/vndbinder Loading services/surfaceflinger/FrontEnd/LayerHierarchy.cpp +23 −21 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #define LOG_TAG "LayerHierarchy" #include "LayerHierarchy.h" #include "LayerLog.h" #include "SwapErase.h" namespace android::surfaceflinger::frontend { Loading Loading @@ -259,6 +260,7 @@ void LayerHierarchyBuilder::onLayerAdded(RequestedLayerState* layer) { } void LayerHierarchyBuilder::onLayerDestroyed(RequestedLayerState* layer) { LLOGV(layer->id, ""); LayerHierarchy* hierarchy = getHierarchyFromId(layer->id, /*crashOnFailure=*/false); if (!hierarchy) { // Layer was never part of the hierarchy if it was created and destroyed in the same Loading Loading @@ -408,29 +410,32 @@ std::string LayerHierarchy::TraversalPath::toString() const { if (id == UNASSIGNED_LAYER_ID) { return "TraversalPath{ROOT}"; } std::string debugString = "TraversalPath{.id = " + std::to_string(id); std::stringstream ss; ss << "TraversalPath{.id = " << id; if (!mirrorRootIds.empty()) { debugString += ", .mirrorRootIds="; for (auto rootId : mirrorRootIds) { debugString += std::to_string(rootId) + ","; } if (mirrorRootId != UNASSIGNED_LAYER_ID) { ss << ", .mirrorRootId=" << mirrorRootId; } if (!relativeRootIds.empty()) { debugString += ", .relativeRootIds="; ss << ", .relativeRootIds="; for (auto rootId : relativeRootIds) { debugString += std::to_string(rootId) + ","; ss << rootId << ","; } } if (hasRelZLoop()) { debugString += ", hasRelZLoop=true invalidRelativeRootId="; debugString += std::to_string(invalidRelativeRootId) + ","; ss << "hasRelZLoop=true invalidRelativeRootId=" << invalidRelativeRootId << ","; } ss << "}"; return ss.str(); } debugString += "}"; return debugString; LayerHierarchy::TraversalPath LayerHierarchy::TraversalPath::getMirrorRoot() const { LOG_ALWAYS_FATAL_IF(!isClone(), "Cannot get mirror root of a non cloned node"); TraversalPath mirrorRootPath = *this; mirrorRootPath.id = mirrorRootId; return mirrorRootPath; } // Helper class to update a passed in TraversalPath when visiting a child. When the object goes out Loading @@ -438,16 +443,13 @@ std::string LayerHierarchy::TraversalPath::toString() const { LayerHierarchy::ScopedAddToTraversalPath::ScopedAddToTraversalPath(TraversalPath& traversalPath, uint32_t layerId, LayerHierarchy::Variant variant) : mTraversalPath(traversalPath), mParentId(traversalPath.id), mParentVariant(traversalPath.variant), mParentDetached(traversalPath.detached) { : mTraversalPath(traversalPath), mParentPath(traversalPath) { // Update the traversal id with the child layer id and variant. Parent id and variant are // stored to reset the id upon destruction. traversalPath.id = layerId; traversalPath.variant = variant; if (variant == LayerHierarchy::Variant::Mirror) { traversalPath.mirrorRootIds.emplace_back(layerId); traversalPath.mirrorRootId = layerId; } else if (variant == LayerHierarchy::Variant::Relative) { if (std::find(traversalPath.relativeRootIds.begin(), traversalPath.relativeRootIds.end(), layerId) != traversalPath.relativeRootIds.end()) { Loading @@ -462,16 +464,16 @@ LayerHierarchy::ScopedAddToTraversalPath::~ScopedAddToTraversalPath() { // Reset the traversal id to its original parent state using the state that was saved in // the constructor. if (mTraversalPath.variant == LayerHierarchy::Variant::Mirror) { mTraversalPath.mirrorRootIds.pop_back(); mTraversalPath.mirrorRootId = mParentPath.mirrorRootId; } else if (mTraversalPath.variant == LayerHierarchy::Variant::Relative) { mTraversalPath.relativeRootIds.pop_back(); } if (mTraversalPath.invalidRelativeRootId == mTraversalPath.id) { mTraversalPath.invalidRelativeRootId = UNASSIGNED_LAYER_ID; } mTraversalPath.id = mParentId; mTraversalPath.variant = mParentVariant; mTraversalPath.detached = mParentDetached; mTraversalPath.id = mParentPath.id; mTraversalPath.variant = mParentPath.variant; mTraversalPath.detached = mParentPath.detached; } } // namespace android::surfaceflinger::frontend services/surfaceflinger/FrontEnd/LayerHierarchy.h +25 −6 Original line number Diff line number Diff line Loading @@ -50,12 +50,32 @@ public: ftl_last = Mirror, }; // Represents a unique path to a node. // The layer hierarchy is represented as a graph. Each node can be visited by multiple parents. // This allows us to represent mirroring in an efficient way. See the example below: // root // ├─ A {Traversal path id = 1} // ├─ B {Traversal path id = 2} // │ ├─ C {Traversal path id = 3} // │ ├─ D {Traversal path id = 4} // │ └─ E {Traversal path id = 5} // ├─ F (Mirrors B) {Traversal path id = 6} // └─ G (Mirrors F) {Traversal path id = 7} // // C, D and E can be traversed via B or via F then B or via G then F then B. // Depending on how the node is reached, its properties such as geometry or visibility might be // different. And we can uniquely identify the node by keeping track of the nodes leading up to // it. But to be more efficient we only need to track the nodes id and the top mirror root path. // So C for example, would have the following unique traversal paths: // - {Traversal path id = 3} // - {Traversal path id = 3, mirrorRootId = 6} // - {Traversal path id = 3, mirrorRootId = 7} struct TraversalPath { uint32_t id; LayerHierarchy::Variant variant; // Mirrored layers can have a different geometry than their parents so we need to track // the mirror roots in the traversal. ftl::SmallVector<uint32_t, 5> mirrorRootIds; uint32_t mirrorRootId = UNASSIGNED_LAYER_ID; // Relative layers can be visited twice, once by their parent and then once again by // their relative parent. We keep track of the roots here to detect any loops in the // hierarchy. If a relative root already exists in the list while building the Loading @@ -73,10 +93,11 @@ public: // Returns true if the node or its parents are not Detached. bool isAttached() const { return !detached; } // Returns true if the node is a clone. bool isClone() const { return !mirrorRootIds.empty(); } bool isClone() const { return mirrorRootId != UNASSIGNED_LAYER_ID; } TraversalPath getMirrorRoot() const; bool operator==(const TraversalPath& other) const { return id == other.id && mirrorRootIds == other.mirrorRootIds; return id == other.id && mirrorRootId == other.mirrorRootId; } std::string toString() const; Loading @@ -93,9 +114,7 @@ public: private: TraversalPath& mTraversalPath; uint32_t mParentId; LayerHierarchy::Variant mParentVariant; bool mParentDetached; TraversalPath mParentPath; }; LayerHierarchy(RequestedLayerState* layer); Loading services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include "LayerLifecycleManager.h" #include "Layer.h" // temporarily needed for LayerHandle #include "LayerHandle.h" #include "LayerLog.h" #include "SwapErase.h" namespace android::surfaceflinger::frontend { Loading @@ -36,6 +37,7 @@ void LayerLifecycleManager::addLayers(std::vector<std::unique_ptr<RequestedLayer mGlobalChanges |= RequestedLayerState::Changes::Hierarchy; for (auto& newLayer : newLayers) { RequestedLayerState& layer = *newLayer.get(); LLOGV(layer.id, "%s layer %s", __func__, layer.getDebugStringShort().c_str()); auto [it, inserted] = mIdToLayer.try_emplace(layer.id, References{.owner = layer}); if (!inserted) { LOG_ALWAYS_FATAL("Duplicate layer id %d found. Existing layer: %s", layer.id, Loading Loading @@ -146,7 +148,7 @@ void LayerLifecycleManager::onHandlesDestroyed(const std::vector<uint32_t>& dest while (it != mLayers.end()) { RequestedLayerState* layer = it->get(); if (layer->changes.test(RequestedLayerState::Changes::Destroyed)) { ALOGV("%s destroyed layer %s", __func__, layer->getDebugStringShort().c_str()); LLOGV(layer->id, "destroyed layer %s", layer->getDebugStringShort().c_str()); std::iter_swap(it, mLayers.end() - 1); mDestroyedLayers.emplace_back(std::move(mLayers.back())); if (it == mLayers.end() - 1) { Loading Loading
libs/binder/ProcessState.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,10 @@ static void verifyNotForked(bool forked) { LOG_ALWAYS_FATAL_IF(forked, "libbinder ProcessState can not be used after fork"); } bool ProcessState::isVndservicemanagerEnabled() { return access("/vendor/bin/vndservicemanager", R_OK) == 0; } sp<ProcessState> ProcessState::init(const char *driver, bool requireDefault) { #ifdef BINDER_IPC_32BIT Loading @@ -123,6 +127,11 @@ sp<ProcessState> ProcessState::init(const char *driver, bool requireDefault) driver = "/dev/binder"; } if (0 == strcmp(driver, "/dev/vndbinder") && !isVndservicemanagerEnabled()) { ALOGE("vndservicemanager is not started on this device, you can save resources/threads " "by not initializing ProcessState with /dev/vndbinder."); } // we must install these before instantiating the gProcess object, // otherwise this would race with creating it, and there could be the // possibility of an invalid gProcess object forked by another thread Loading
libs/binder/include/binder/ProcessState.h +2 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ public: static sp<ProcessState> self(); static sp<ProcessState> selfOrNull(); static bool isVndservicemanagerEnabled(); /* initWithDriver() can be used to configure libbinder to use * a different binder driver dev node. It must be called *before* * any call to ProcessState::self(). The default is /dev/vndbinder Loading
services/surfaceflinger/FrontEnd/LayerHierarchy.cpp +23 −21 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #define LOG_TAG "LayerHierarchy" #include "LayerHierarchy.h" #include "LayerLog.h" #include "SwapErase.h" namespace android::surfaceflinger::frontend { Loading Loading @@ -259,6 +260,7 @@ void LayerHierarchyBuilder::onLayerAdded(RequestedLayerState* layer) { } void LayerHierarchyBuilder::onLayerDestroyed(RequestedLayerState* layer) { LLOGV(layer->id, ""); LayerHierarchy* hierarchy = getHierarchyFromId(layer->id, /*crashOnFailure=*/false); if (!hierarchy) { // Layer was never part of the hierarchy if it was created and destroyed in the same Loading Loading @@ -408,29 +410,32 @@ std::string LayerHierarchy::TraversalPath::toString() const { if (id == UNASSIGNED_LAYER_ID) { return "TraversalPath{ROOT}"; } std::string debugString = "TraversalPath{.id = " + std::to_string(id); std::stringstream ss; ss << "TraversalPath{.id = " << id; if (!mirrorRootIds.empty()) { debugString += ", .mirrorRootIds="; for (auto rootId : mirrorRootIds) { debugString += std::to_string(rootId) + ","; } if (mirrorRootId != UNASSIGNED_LAYER_ID) { ss << ", .mirrorRootId=" << mirrorRootId; } if (!relativeRootIds.empty()) { debugString += ", .relativeRootIds="; ss << ", .relativeRootIds="; for (auto rootId : relativeRootIds) { debugString += std::to_string(rootId) + ","; ss << rootId << ","; } } if (hasRelZLoop()) { debugString += ", hasRelZLoop=true invalidRelativeRootId="; debugString += std::to_string(invalidRelativeRootId) + ","; ss << "hasRelZLoop=true invalidRelativeRootId=" << invalidRelativeRootId << ","; } ss << "}"; return ss.str(); } debugString += "}"; return debugString; LayerHierarchy::TraversalPath LayerHierarchy::TraversalPath::getMirrorRoot() const { LOG_ALWAYS_FATAL_IF(!isClone(), "Cannot get mirror root of a non cloned node"); TraversalPath mirrorRootPath = *this; mirrorRootPath.id = mirrorRootId; return mirrorRootPath; } // Helper class to update a passed in TraversalPath when visiting a child. When the object goes out Loading @@ -438,16 +443,13 @@ std::string LayerHierarchy::TraversalPath::toString() const { LayerHierarchy::ScopedAddToTraversalPath::ScopedAddToTraversalPath(TraversalPath& traversalPath, uint32_t layerId, LayerHierarchy::Variant variant) : mTraversalPath(traversalPath), mParentId(traversalPath.id), mParentVariant(traversalPath.variant), mParentDetached(traversalPath.detached) { : mTraversalPath(traversalPath), mParentPath(traversalPath) { // Update the traversal id with the child layer id and variant. Parent id and variant are // stored to reset the id upon destruction. traversalPath.id = layerId; traversalPath.variant = variant; if (variant == LayerHierarchy::Variant::Mirror) { traversalPath.mirrorRootIds.emplace_back(layerId); traversalPath.mirrorRootId = layerId; } else if (variant == LayerHierarchy::Variant::Relative) { if (std::find(traversalPath.relativeRootIds.begin(), traversalPath.relativeRootIds.end(), layerId) != traversalPath.relativeRootIds.end()) { Loading @@ -462,16 +464,16 @@ LayerHierarchy::ScopedAddToTraversalPath::~ScopedAddToTraversalPath() { // Reset the traversal id to its original parent state using the state that was saved in // the constructor. if (mTraversalPath.variant == LayerHierarchy::Variant::Mirror) { mTraversalPath.mirrorRootIds.pop_back(); mTraversalPath.mirrorRootId = mParentPath.mirrorRootId; } else if (mTraversalPath.variant == LayerHierarchy::Variant::Relative) { mTraversalPath.relativeRootIds.pop_back(); } if (mTraversalPath.invalidRelativeRootId == mTraversalPath.id) { mTraversalPath.invalidRelativeRootId = UNASSIGNED_LAYER_ID; } mTraversalPath.id = mParentId; mTraversalPath.variant = mParentVariant; mTraversalPath.detached = mParentDetached; mTraversalPath.id = mParentPath.id; mTraversalPath.variant = mParentPath.variant; mTraversalPath.detached = mParentPath.detached; } } // namespace android::surfaceflinger::frontend
services/surfaceflinger/FrontEnd/LayerHierarchy.h +25 −6 Original line number Diff line number Diff line Loading @@ -50,12 +50,32 @@ public: ftl_last = Mirror, }; // Represents a unique path to a node. // The layer hierarchy is represented as a graph. Each node can be visited by multiple parents. // This allows us to represent mirroring in an efficient way. See the example below: // root // ├─ A {Traversal path id = 1} // ├─ B {Traversal path id = 2} // │ ├─ C {Traversal path id = 3} // │ ├─ D {Traversal path id = 4} // │ └─ E {Traversal path id = 5} // ├─ F (Mirrors B) {Traversal path id = 6} // └─ G (Mirrors F) {Traversal path id = 7} // // C, D and E can be traversed via B or via F then B or via G then F then B. // Depending on how the node is reached, its properties such as geometry or visibility might be // different. And we can uniquely identify the node by keeping track of the nodes leading up to // it. But to be more efficient we only need to track the nodes id and the top mirror root path. // So C for example, would have the following unique traversal paths: // - {Traversal path id = 3} // - {Traversal path id = 3, mirrorRootId = 6} // - {Traversal path id = 3, mirrorRootId = 7} struct TraversalPath { uint32_t id; LayerHierarchy::Variant variant; // Mirrored layers can have a different geometry than their parents so we need to track // the mirror roots in the traversal. ftl::SmallVector<uint32_t, 5> mirrorRootIds; uint32_t mirrorRootId = UNASSIGNED_LAYER_ID; // Relative layers can be visited twice, once by their parent and then once again by // their relative parent. We keep track of the roots here to detect any loops in the // hierarchy. If a relative root already exists in the list while building the Loading @@ -73,10 +93,11 @@ public: // Returns true if the node or its parents are not Detached. bool isAttached() const { return !detached; } // Returns true if the node is a clone. bool isClone() const { return !mirrorRootIds.empty(); } bool isClone() const { return mirrorRootId != UNASSIGNED_LAYER_ID; } TraversalPath getMirrorRoot() const; bool operator==(const TraversalPath& other) const { return id == other.id && mirrorRootIds == other.mirrorRootIds; return id == other.id && mirrorRootId == other.mirrorRootId; } std::string toString() const; Loading @@ -93,9 +114,7 @@ public: private: TraversalPath& mTraversalPath; uint32_t mParentId; LayerHierarchy::Variant mParentVariant; bool mParentDetached; TraversalPath mParentPath; }; LayerHierarchy(RequestedLayerState* layer); Loading
services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include "LayerLifecycleManager.h" #include "Layer.h" // temporarily needed for LayerHandle #include "LayerHandle.h" #include "LayerLog.h" #include "SwapErase.h" namespace android::surfaceflinger::frontend { Loading @@ -36,6 +37,7 @@ void LayerLifecycleManager::addLayers(std::vector<std::unique_ptr<RequestedLayer mGlobalChanges |= RequestedLayerState::Changes::Hierarchy; for (auto& newLayer : newLayers) { RequestedLayerState& layer = *newLayer.get(); LLOGV(layer.id, "%s layer %s", __func__, layer.getDebugStringShort().c_str()); auto [it, inserted] = mIdToLayer.try_emplace(layer.id, References{.owner = layer}); if (!inserted) { LOG_ALWAYS_FATAL("Duplicate layer id %d found. Existing layer: %s", layer.id, Loading Loading @@ -146,7 +148,7 @@ void LayerLifecycleManager::onHandlesDestroyed(const std::vector<uint32_t>& dest while (it != mLayers.end()) { RequestedLayerState* layer = it->get(); if (layer->changes.test(RequestedLayerState::Changes::Destroyed)) { ALOGV("%s destroyed layer %s", __func__, layer->getDebugStringShort().c_str()); LLOGV(layer->id, "destroyed layer %s", layer->getDebugStringShort().c_str()); std::iter_swap(it, mLayers.end() - 1); mDestroyedLayers.emplace_back(std::move(mLayers.back())); if (it == mLayers.end() - 1) { Loading