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 services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp +19 −10 Original line number Diff line number Diff line Loading @@ -259,8 +259,8 @@ void updateSurfaceDamage(const RequestedLayerState& requested, bool hasReadyFram } } void updateVisibility(LayerSnapshot& snapshot) { snapshot.isVisible = snapshot.getIsVisible(); void updateVisibility(LayerSnapshot& snapshot, bool visible) { snapshot.isVisible = visible; // TODO(b/238781169) we are ignoring this compat for now, since we will have // to remove any optimization based on visibility. Loading @@ -273,9 +273,9 @@ void updateVisibility(LayerSnapshot& snapshot) { // We are just using these layers for occlusion detection in // InputDispatcher, and obviously if they aren't visible they can't occlude // anything. const bool visible = const bool visibleForInput = (snapshot.inputInfo.token != nullptr) ? snapshot.canReceiveInput() : snapshot.isVisible; snapshot.inputInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_VISIBLE, !visible); snapshot.inputInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_VISIBLE, !visibleForInput); } bool needsInputInfo(const LayerSnapshot& snapshot, const RequestedLayerState& requested) { Loading Loading @@ -521,7 +521,7 @@ void LayerSnapshotBuilder::sortSnapshotsByZ(const Args& args) { } if (snapshot->getIsVisible() || snapshot->hasInputInfo()) { updateVisibility(*snapshot); updateVisibility(*snapshot, snapshot->getIsVisible()); size_t oldZ = snapshot->globalZ; size_t newZ = globalZ++; snapshot->globalZ = newZ; Loading @@ -539,7 +539,8 @@ void LayerSnapshotBuilder::sortSnapshotsByZ(const Args& args) { mNumInterestingSnapshots = (int)globalZ; while (globalZ < mSnapshots.size()) { mSnapshots[globalZ]->globalZ = globalZ; updateVisibility(*mSnapshots[globalZ]); /* mark unreachable snapshots as explicitly invisible */ updateVisibility(*mSnapshots[globalZ], false); globalZ++; } } Loading Loading @@ -634,11 +635,15 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a const bool forceUpdate = newSnapshot || args.forceUpdate || snapshot.changes.any(RequestedLayerState::Changes::Visibility | RequestedLayerState::Changes::Created); snapshot.outputFilter.layerStack = requested.parentId != UNASSIGNED_LAYER_ID ? parentSnapshot.outputFilter.layerStack : requested.layerStack; uint32_t displayRotationFlags = getDisplayRotationFlags(args.displays, snapshot.outputFilter.layerStack); // always update the buffer regardless of visibility if (forceUpdate || requested.what & layer_state_t::BUFFER_CHANGES) { if (forceUpdate || requested.what & layer_state_t::BUFFER_CHANGES || args.displayChanges) { snapshot.acquireFence = (requested.externalTexture && requested.bufferData->flags.test(BufferData::BufferDataChange::fenceChanged)) Loading Loading @@ -727,9 +732,13 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a if (forceUpdate || snapshot.changes.any(RequestedLayerState::Changes::Content)) { snapshot.color.rgb = requested.getColor().rgb; snapshot.isColorspaceAgnostic = requested.colorSpaceAgnostic; snapshot.backgroundBlurRadius = args.supportsBlur ? static_cast<int>(requested.backgroundBlurRadius) : 0; snapshot.backgroundBlurRadius = args.supportsBlur ? static_cast<int>(parentSnapshot.color.a * (float)requested.backgroundBlurRadius) : 0; snapshot.blurRegions = requested.blurRegions; for (auto& region : snapshot.blurRegions) { region.alpha = region.alpha * snapshot.color.a; } snapshot.hdrMetadata = requested.hdrMetadata; } Loading Loading @@ -965,7 +974,7 @@ void LayerSnapshotBuilder::updateInput(LayerSnapshot& snapshot, // touches from going outside the cloned area. if (path.isClone()) { snapshot.inputInfo.inputConfig |= gui::WindowInfo::InputConfig::CLONE; auto clonedRootSnapshot = getSnapshot(path.mirrorRootIds.back()); auto clonedRootSnapshot = getSnapshot(path.getMirrorRoot()); if (clonedRootSnapshot) { const Rect rect = displayInfo.transform.transform(Rect{clonedRootSnapshot->transformedBounds}); Loading services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h +2 −2 Original line number Diff line number Diff line Loading @@ -115,8 +115,8 @@ private: struct TraversalPathHash { std::size_t operator()(const LayerHierarchy::TraversalPath& key) const { uint32_t hashCode = key.id * 31; for (auto mirrorRoot : key.mirrorRootIds) { hashCode += mirrorRoot * 31; if (key.mirrorRootId != UNASSIGNED_LAYER_ID) { hashCode += key.mirrorRootId * 31; } return std::hash<size_t>{}(hashCode); } Loading 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
services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp +19 −10 Original line number Diff line number Diff line Loading @@ -259,8 +259,8 @@ void updateSurfaceDamage(const RequestedLayerState& requested, bool hasReadyFram } } void updateVisibility(LayerSnapshot& snapshot) { snapshot.isVisible = snapshot.getIsVisible(); void updateVisibility(LayerSnapshot& snapshot, bool visible) { snapshot.isVisible = visible; // TODO(b/238781169) we are ignoring this compat for now, since we will have // to remove any optimization based on visibility. Loading @@ -273,9 +273,9 @@ void updateVisibility(LayerSnapshot& snapshot) { // We are just using these layers for occlusion detection in // InputDispatcher, and obviously if they aren't visible they can't occlude // anything. const bool visible = const bool visibleForInput = (snapshot.inputInfo.token != nullptr) ? snapshot.canReceiveInput() : snapshot.isVisible; snapshot.inputInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_VISIBLE, !visible); snapshot.inputInfo.setInputConfig(gui::WindowInfo::InputConfig::NOT_VISIBLE, !visibleForInput); } bool needsInputInfo(const LayerSnapshot& snapshot, const RequestedLayerState& requested) { Loading Loading @@ -521,7 +521,7 @@ void LayerSnapshotBuilder::sortSnapshotsByZ(const Args& args) { } if (snapshot->getIsVisible() || snapshot->hasInputInfo()) { updateVisibility(*snapshot); updateVisibility(*snapshot, snapshot->getIsVisible()); size_t oldZ = snapshot->globalZ; size_t newZ = globalZ++; snapshot->globalZ = newZ; Loading @@ -539,7 +539,8 @@ void LayerSnapshotBuilder::sortSnapshotsByZ(const Args& args) { mNumInterestingSnapshots = (int)globalZ; while (globalZ < mSnapshots.size()) { mSnapshots[globalZ]->globalZ = globalZ; updateVisibility(*mSnapshots[globalZ]); /* mark unreachable snapshots as explicitly invisible */ updateVisibility(*mSnapshots[globalZ], false); globalZ++; } } Loading Loading @@ -634,11 +635,15 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a const bool forceUpdate = newSnapshot || args.forceUpdate || snapshot.changes.any(RequestedLayerState::Changes::Visibility | RequestedLayerState::Changes::Created); snapshot.outputFilter.layerStack = requested.parentId != UNASSIGNED_LAYER_ID ? parentSnapshot.outputFilter.layerStack : requested.layerStack; uint32_t displayRotationFlags = getDisplayRotationFlags(args.displays, snapshot.outputFilter.layerStack); // always update the buffer regardless of visibility if (forceUpdate || requested.what & layer_state_t::BUFFER_CHANGES) { if (forceUpdate || requested.what & layer_state_t::BUFFER_CHANGES || args.displayChanges) { snapshot.acquireFence = (requested.externalTexture && requested.bufferData->flags.test(BufferData::BufferDataChange::fenceChanged)) Loading Loading @@ -727,9 +732,13 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a if (forceUpdate || snapshot.changes.any(RequestedLayerState::Changes::Content)) { snapshot.color.rgb = requested.getColor().rgb; snapshot.isColorspaceAgnostic = requested.colorSpaceAgnostic; snapshot.backgroundBlurRadius = args.supportsBlur ? static_cast<int>(requested.backgroundBlurRadius) : 0; snapshot.backgroundBlurRadius = args.supportsBlur ? static_cast<int>(parentSnapshot.color.a * (float)requested.backgroundBlurRadius) : 0; snapshot.blurRegions = requested.blurRegions; for (auto& region : snapshot.blurRegions) { region.alpha = region.alpha * snapshot.color.a; } snapshot.hdrMetadata = requested.hdrMetadata; } Loading Loading @@ -965,7 +974,7 @@ void LayerSnapshotBuilder::updateInput(LayerSnapshot& snapshot, // touches from going outside the cloned area. if (path.isClone()) { snapshot.inputInfo.inputConfig |= gui::WindowInfo::InputConfig::CLONE; auto clonedRootSnapshot = getSnapshot(path.mirrorRootIds.back()); auto clonedRootSnapshot = getSnapshot(path.getMirrorRoot()); if (clonedRootSnapshot) { const Rect rect = displayInfo.transform.transform(Rect{clonedRootSnapshot->transformedBounds}); Loading
services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h +2 −2 Original line number Diff line number Diff line Loading @@ -115,8 +115,8 @@ private: struct TraversalPathHash { std::size_t operator()(const LayerHierarchy::TraversalPath& key) const { uint32_t hashCode = key.id * 31; for (auto mirrorRoot : key.mirrorRootIds) { hashCode += mirrorRoot * 31; if (key.mirrorRootId != UNASSIGNED_LAYER_ID) { hashCode += key.mirrorRootId * 31; } return std::hash<size_t>{}(hashCode); } Loading