SF: Clear mCompositionInfo before recomputing visible layers

Both SurfaceFlingerBE::mCompositionInfo and LayerBE::HWCInfo can hold a
shared_ptr to the same HWC2::Layer.

However the lifetime of the HWC2::Layer is only really expected to last
as long as the Layer is referenced by the visible layer list for a
display. This list might be the last thing keeping a sp<Layer> alive,
and when it is removed from the list, cleanup occurs.

The Layer dtor invokes Layer::destroyAllLayers(), which asserts that
cleanup completes succesfully. Effectively it requires that the
HWC2::Layer instance it holds is destroyed, as when it does so the
HWC2::Layer dtor invokes a callback to remove the entry from
LayerBE::HWCInfo for the display.

This fails to happen if the reference count for the shared_ptr does not
drop to zero. Clearing out mCompositionInfo before the visible layers
are recomputed fixes this.

Bug: 119629556
Test: atest CtsViewTestCases
Change-Id: I9b0ea0389fc1ba22a2a230f165689b5ee2f474ce
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 35ba391..41c7a93 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1683,8 +1683,6 @@
     mDrawingState.colorMatrixChanged = false;
 
     for (const auto& [token, display] : mDisplays) {
-        getBE().mCompositionInfo[token].clear();
-
         for (auto& layer : display->getVisibleLayersSortedByZ()) {
             const auto displayId = display->getId();
             layer->getBE().compositionInfo.compositionType = layer->getCompositionType(displayId);
@@ -1968,6 +1966,17 @@
     ATRACE_CALL();
     ALOGV("rebuildLayerStacks");
 
+    // We need to clear these out now as these may be holding on to a
+    // HWC2::Layer reference at the same time as the LayerBE::HWCInfo structure
+    // also holds a reference. When the set of visible layers is recomputed,
+    // some layers may be destroyed if the only thing keeping them alive was
+    // that list of visible layers associated with each display. The layer
+    // destruction code asserts that the HWC2::Layer is properly destroyed, but
+    // that doesn't happen if SurfaceFlingerBE::mCompositionInfo keeps it alive.
+    for (const auto& [token, display] : mDisplays) {
+        getBE().mCompositionInfo[token].clear();
+    }
+
     // rebuild the visible layer list per screen
     if (CC_UNLIKELY(mVisibleRegionsDirty)) {
         ATRACE_NAME("rebuildLayerStacks VR Dirty");