From 3be61905f09f265de9732eed00985e324540e5b8 Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Wed, 26 Apr 2023 19:47:29 -0700 Subject: [sf] Properly update clones of clones Relanding with the change to only update onscreen mirror roots and cleaning up some debug logs. When updating a cloned layer hierarchy that contains another cloned layer hierarchy, we are dependent on the order in which we update each hierarchy. The inner cloned hierarchy must be updated first otherwise the outer clone will not capture the entire tree and some layers might be omitted from composition. To fix this we track all layer mirror roots. When updating each root, we check to see if they mirror another root. If they do mirror another root and that root has not been updated, we update the root again at the end. Test: repro steps in bug Fixes: 279622227 Change-Id: I125f7c788716d59909b77a88ef4098b7cac08919 --- services/surfaceflinger/Layer.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'services/surfaceflinger/Layer.cpp') diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 3371ae2d8c..f5bfb31c8c 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -254,7 +254,8 @@ Layer::~Layer() { mFlinger->mTunnelModeEnabledReporter->decrementTunnelModeCount(); } if (mHadClonedChild) { - mFlinger->mNumClones--; + auto& roots = mFlinger->mLayerMirrorRoots; + roots.erase(std::remove(roots.begin(), roots.end(), this), roots.end()); } if (hasTrustedPresentationListener()) { mFlinger->mNumTrustedPresentationListeners--; @@ -1649,8 +1650,8 @@ void Layer::getFrameStats(FrameStats* outStats) const { void Layer::dumpOffscreenDebugInfo(std::string& result) const { std::string hasBuffer = hasBufferOrSidebandStream() ? " (contains buffer)" : ""; - StringAppendF(&result, "Layer %s%s pid:%d uid:%d\n", getName().c_str(), hasBuffer.c_str(), - mOwnerPid, mOwnerUid); + StringAppendF(&result, "Layer %s%s pid:%d uid:%d%s\n", getName().c_str(), hasBuffer.c_str(), + mOwnerPid, mOwnerUid, isHandleAlive() ? " handleAlive" : ""); } void Layer::onDisconnect() { @@ -2594,7 +2595,7 @@ void Layer::updateCloneBufferInfo() { mDrawingState.inputInfo = tmpInputInfo; } -void Layer::updateMirrorInfo() { +bool Layer::updateMirrorInfo(const std::deque& cloneRootsPendingUpdates) { if (mClonedChild == nullptr || !mClonedChild->isClonedFromAlive()) { // If mClonedChild is null, there is nothing to mirror. If isClonedFromAlive returns false, // it means that there is a clone, but the layer it was cloned from has been destroyed. In @@ -2602,7 +2603,7 @@ void Layer::updateMirrorInfo() { // destroyed. The root, this layer, will still be around since the client can continue // to hold a reference, but no cloned layers will be displayed. mClonedChild = nullptr; - return; + return true; } std::map, sp> clonedLayersMap; @@ -2617,6 +2618,13 @@ void Layer::updateMirrorInfo() { mClonedChild->updateClonedDrawingState(clonedLayersMap); mClonedChild->updateClonedChildren(sp::fromExisting(this), clonedLayersMap); mClonedChild->updateClonedRelatives(clonedLayersMap); + + for (Layer* root : cloneRootsPendingUpdates) { + if (clonedLayersMap.find(sp::fromExisting(root)) != clonedLayersMap.end()) { + return false; + } + } + return true; } void Layer::updateClonedDrawingState(std::map, sp>& clonedLayersMap) { @@ -2764,7 +2772,7 @@ bool Layer::isInternalDisplayOverlay() const { void Layer::setClonedChild(const sp& clonedChild) { mClonedChild = clonedChild; mHadClonedChild = true; - mFlinger->mNumClones++; + mFlinger->mLayerMirrorRoots.push_back(this); } bool Layer::setDropInputMode(gui::DropInputMode mode) { -- cgit v1.2.3-59-g8ed1b