SF: Move management of HWC layers to compositionengine::OutputLayer

OutputLayer creates a HWC layer (if appropriate) on initialization, and
the HWC layer is destroyed with the OutputLayer.

Removes all explicit calls to create/destroy the HWC layers from the front-end
Layer code, and a few other places.

A call is also added to destroy all OutputLayers before switching in or
out of VrComposer mode. This change already marked the geometry as dirty
-- this just ensures all the HWC layers are recreated.

Test: atest libsurfaceflinger_unittest libcompositionengine_test
Test: atest dvr_display-test
Test: atest CtsViewTestCases
Bug: 121291683
Bug: 124537779
Change-Id: Ib7aec9e998ed5481d2753d19b061ba922e54bfe0
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index b68f053..a2e7dd2 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1651,7 +1651,18 @@
 
     sp<DisplayDevice> display = getDefaultDisplayDeviceLocked();
     LOG_ALWAYS_FATAL_IF(!display);
+
     const int currentDisplayPowerMode = display->getPowerMode();
+
+    // Clear out all the output layers from the composition engine for all
+    // displays before destroying the hardware composer interface. This ensures
+    // any HWC layers are destroyed through that interface before it becomes
+    // invalid.
+    for (const auto& [token, displayDevice] : mDisplays) {
+        displayDevice->getCompositionDisplay()->setOutputLayersOrderedByZ(
+                compositionengine::Output::OutputLayers());
+    }
+
     // This DisplayDevice will no longer be relevant once resetDisplayState() is
     // called below. Clear the reference now so we don't accidentally use it
     // later.
@@ -1866,10 +1877,8 @@
                 const auto& layer = currentLayers[i];
 
                 if (!layer->hasHwcLayer(displayDevice)) {
-                    if (!layer->createHwcLayer(&getHwComposer(), displayDevice)) {
-                        layer->forceClientComposition(displayDevice);
-                        continue;
-                    }
+                    layer->forceClientComposition(displayDevice);
+                    continue;
                 }
 
                 layer->setGeometry(displayDevice, i);
@@ -2371,42 +2380,42 @@
                         return;
                     }
 
-                    bool hwcLayerDestroyed = false;
                     const auto displayId = displayDevice->getId();
                     sp<compositionengine::LayerFE> layerFE = compositionLayer->getLayerFE();
                     LOG_ALWAYS_FATAL_IF(layerFE.get() == nullptr);
 
+                    bool needsOutputLayer = false;
+
                     if (display->belongsInOutput(layer->getLayerStack(),
                                                  layer->getPrimaryDisplayOnly())) {
                         Region drawRegion(tr.transform(
                                 layer->visibleNonTransparentRegion));
                         drawRegion.andSelf(bounds);
                         if (!drawRegion.isEmpty()) {
-                            layersSortedByZ.emplace_back(
-                                    display->getOrCreateOutputLayer(layer->getCompositionLayer(),
-                                                                    layerFE));
-
-                            deprecated_layersSortedByZ.add(layer);
-                        } else {
-                            // Clear out the HWC layer if this layer was
-                            // previously visible, but no longer is
-                            hwcLayerDestroyed = displayId && layer->destroyHwcLayer(displayDevice);
+                            needsOutputLayer = true;
                         }
-                    } else {
-                        // WM changes display->layerStack upon sleep/awake.
-                        // Here we make sure we delete the HWC layers even if
-                        // WM changed their layer stack.
-                        hwcLayerDestroyed = displayId && layer->destroyHwcLayer(displayDevice);
                     }
 
-                    // If a layer is not going to get a release fence because
-                    // it is invisible, but it is also going to release its
-                    // old buffer, add it to the list of layers needing
-                    // fences.
-                    if (hwcLayerDestroyed) {
-                        auto found = std::find(mLayersWithQueuedFrames.cbegin(),
-                                mLayersWithQueuedFrames.cend(), layer);
-                        if (found != mLayersWithQueuedFrames.cend()) {
+                    if (needsOutputLayer) {
+                        layersSortedByZ.emplace_back(
+                                display->getOrCreateOutputLayer(displayId, compositionLayer,
+                                                                layerFE));
+                        deprecated_layersSortedByZ.add(layer);
+
+                        auto& outputLayerState = layersSortedByZ.back()->editState();
+                        outputLayerState.visibleRegion =
+                                tr.transform(layer->visibleRegion.intersect(displayState.viewport));
+                    } else if (displayId) {
+                        // For layers that are being removed from a HWC display,
+                        // and that have queued frames, add them to a a list of
+                        // released layers so we can properly set a fence.
+                        bool hasExistingOutputLayer =
+                                display->getOutputLayerForLayer(compositionLayer.get()) != nullptr;
+                        bool hasQueuedFrames = std::find(mLayersWithQueuedFrames.cbegin(),
+                                                         mLayersWithQueuedFrames.cend(),
+                                                         layer) != mLayersWithQueuedFrames.cend();
+
+                        if (hasExistingOutputLayer && hasQueuedFrames) {
                             layersNeedingFences.add(layer);
                         }
                     }
@@ -3158,12 +3167,8 @@
             recordBufferingStats(l->getName().string(),
                     l->getOccupancyHistory(true));
 
-            // We need to release the HWC layers when the Layer is removed
-            // from the current state otherwise the HWC layer just continues
-            // showing at its last configured state until we eventually
-            // abandon the buffer queue.
+            // Ensure any buffers set to display on any children are released.
             if (l->isRemovedFromCurrentState()) {
-                l->destroyHwcLayersForAllDisplays();
                 latchAndReleaseBuffer(l);
             }
         }