SF: Introduce OutputLayerCompositionState

This moves the display-dependent state from LayerBE.h to a new
OutputLayerCompositionState.h header, adds some simple accessors to
get the new state, and minimally adjusts the existing SurfaceFlinger
code to use the new structure.

Test: atest libsurfaceflinger_unittest libcompositionengine_test
Bug: 121291683
Change-Id: I00370f05dc6b2a3db34094862c46084e7575dbda
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 51e1f00..69ec638 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -24,44 +24,40 @@
 #include <stdlib.h>
 #include <sys/types.h>
 #include <algorithm>
+#include <mutex>
 
 #include <android-base/stringprintf.h>
-
+#include <compositionengine/Display.h>
+#include <compositionengine/OutputLayer.h>
+#include <compositionengine/impl/OutputLayerCompositionState.h>
 #include <cutils/compiler.h>
 #include <cutils/native_handle.h>
 #include <cutils/properties.h>
-
+#include <gui/BufferItem.h>
+#include <gui/LayerDebugInfo.h>
+#include <gui/Surface.h>
+#include <renderengine/RenderEngine.h>
+#include <ui/DebugUtils.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/PixelFormat.h>
 #include <utils/Errors.h>
 #include <utils/Log.h>
 #include <utils/NativeHandle.h>
 #include <utils/StopWatch.h>
 #include <utils/Trace.h>
 
-#include <ui/DebugUtils.h>
-#include <ui/GraphicBuffer.h>
-#include <ui/PixelFormat.h>
-
-#include <gui/BufferItem.h>
-#include <gui/LayerDebugInfo.h>
-#include <gui/Surface.h>
-
 #include "BufferLayer.h"
 #include "ColorLayer.h"
 #include "Colorizer.h"
 #include "DisplayDevice.h"
+#include "DisplayHardware/HWComposer.h"
 #include "Layer.h"
+#include "LayerProtoHelper.h"
 #include "LayerRejecter.h"
 #include "MonitoredProducer.h"
 #include "SurfaceFlinger.h"
-
-#include "DisplayHardware/HWComposer.h"
 #include "TimeStats/TimeStats.h"
 
-#include <renderengine/RenderEngine.h>
-
-#include <mutex>
-#include "LayerProtoHelper.h"
-
 #define DEBUG_RESIZE 0
 
 namespace android {
@@ -211,9 +207,16 @@
 // h/w composer set-up
 // ---------------------------------------------------------------------------
 
-bool Layer::createHwcLayer(HWComposer* hwc, DisplayId displayId) {
-    LOG_ALWAYS_FATAL_IF(hasHwcLayer(displayId), "Already have a layer for display %s",
-                        to_string(displayId).c_str());
+bool Layer::createHwcLayer(HWComposer* hwc, const sp<DisplayDevice>& displayDevice) {
+    LOG_ALWAYS_FATAL_IF(!displayDevice->getId());
+    auto displayId = *displayDevice->getId();
+    auto outputLayer = findOutputLayerForDisplay(displayDevice);
+    LOG_ALWAYS_FATAL_IF(!outputLayer);
+
+    LOG_ALWAYS_FATAL_IF(outputLayer->getState().hwc.has_value(),
+                        "Already have a layer for display %s",
+                        displayDevice->getDisplayName().c_str());
+
     auto layer = std::shared_ptr<HWC2::Layer>(
             hwc->createLayer(displayId),
             [hwc, displayId](HWC2::Layer* layer) {
@@ -221,42 +224,56 @@
     if (!layer) {
         return false;
     }
-    LayerBE::HWCInfo& hwcInfo = getBE().mHwcLayers[displayId];
-    hwcInfo.hwc = hwc;
-    hwcInfo.layer = layer;
-    layer->setLayerDestroyedListener(
-            [this, displayId](HWC2::Layer* /*layer*/) { getBE().mHwcLayers.erase(displayId); });
+    auto& state = outputLayer->editState();
+    state.hwc.emplace(layer);
     return true;
 }
 
-bool Layer::destroyHwcLayer(DisplayId displayId) {
-    if (!hasHwcLayer(displayId)) {
+bool Layer::destroyHwcLayer(const sp<DisplayDevice>& displayDevice) {
+    auto outputLayer = findOutputLayerForDisplay(displayDevice);
+    if (outputLayer == nullptr) {
         return false;
     }
-    auto& hwcInfo = getBE().mHwcLayers[displayId];
-    LOG_ALWAYS_FATAL_IF(hwcInfo.layer == nullptr, "Attempt to destroy null layer");
-    LOG_ALWAYS_FATAL_IF(hwcInfo.hwc == nullptr, "Missing HWComposer");
-    hwcInfo.layer = nullptr;
-
-    return true;
+    auto& state = outputLayer->editState();
+    bool result = state.hwc.has_value();
+    state.hwc.reset();
+    return result;
 }
 
-void Layer::destroyHwcLayersForAllDisplays() {
-    size_t numLayers = getBE().mHwcLayers.size();
-    for (size_t i = 0; i < numLayers; ++i) {
-        LOG_ALWAYS_FATAL_IF(getBE().mHwcLayers.empty(), "destroyAllHwcLayers failed");
-        destroyHwcLayer(getBE().mHwcLayers.begin()->first);
+bool Layer::destroyHwcLayersForAllDisplays() {
+    bool destroyedAnyLayers = false;
+
+    for (const auto& [token, displayDevice] : mFlinger->mDisplays) {
+        if (destroyHwcLayer(displayDevice)) {
+            destroyedAnyLayers = true;
+        }
     }
+
+    return destroyedAnyLayers;
 }
 
-void Layer::destroyAllHwcLayersPlusChildren() {
-    destroyHwcLayersForAllDisplays();
-    LOG_ALWAYS_FATAL_IF(!getBE().mHwcLayers.empty(),
-                        "All hardware composer layers should have been destroyed");
+bool Layer::destroyAllHwcLayersPlusChildren() {
+    bool result = destroyHwcLayersForAllDisplays();
 
     for (const sp<Layer>& child : mDrawingChildren) {
-        child->destroyAllHwcLayersPlusChildren();
+        result |= child->destroyAllHwcLayersPlusChildren();
     }
+
+    return result;
+}
+
+bool Layer::hasHwcLayer(const sp<const DisplayDevice>& displayDevice) {
+    auto outputLayer = findOutputLayerForDisplay(displayDevice);
+    LOG_FATAL_IF(!outputLayer);
+    return outputLayer->getState().hwc && (*outputLayer->getState().hwc).hwcLayer != nullptr;
+}
+
+HWC2::Layer* Layer::getHwcLayer(const sp<const DisplayDevice>& displayDevice) {
+    auto outputLayer = findOutputLayerForDisplay(displayDevice);
+    if (!outputLayer || !outputLayer->getState().hwc) {
+        return nullptr;
+    }
+    return (*outputLayer->getState().hwc).hwcLayer.get();
 }
 
 Rect Layer::getContentCrop() const {
@@ -494,19 +511,25 @@
 }
 
 void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) {
-    const auto displayId = display->getId();
-    LOG_ALWAYS_FATAL_IF(!displayId);
-    RETURN_IF_NO_HWC_LAYER(*displayId);
-    auto& hwcInfo = getBE().mHwcLayers[*displayId];
+    const auto outputLayer = findOutputLayerForDisplay(display);
+    LOG_FATAL_IF(!outputLayer);
+    LOG_FATAL_IF(!outputLayer->getState().hwc);
+    auto& hwcLayer = (*outputLayer->getState().hwc).hwcLayer;
 
-    // enable this layer
-    hwcInfo.forceClientComposition = false;
-
-    if (isSecure() && !display->isSecure()) {
-        hwcInfo.forceClientComposition = true;
+    if (!hasHwcLayer(display)) {
+        ALOGE("[%s] failed to setGeometry: no HWC layer found (%s)", mName.string(),
+              display->getDebugName().c_str());
+        return;
     }
 
-    auto& hwcLayer = hwcInfo.layer;
+    auto& compositionState = outputLayer->editState();
+
+    // enable this layer
+    compositionState.forceClientComposition = false;
+
+    if (isSecure() && !display->isSecure()) {
+        compositionState.forceClientComposition = true;
+    }
 
     // this gives us only the "orientation" component of the transform
     const State& s(getDrawingState());
@@ -567,9 +590,8 @@
               transformedFrame.left, transformedFrame.top, transformedFrame.right,
               transformedFrame.bottom, to_string(error).c_str(), static_cast<int32_t>(error));
     } else {
-        hwcInfo.displayFrame = transformedFrame;
+        compositionState.displayFrame = transformedFrame;
     }
-    getBE().compositionInfo.hwc.displayFrame = transformedFrame;
 
     FloatRect sourceCrop = computeCrop(display);
     error = hwcLayer->setSourceCrop(sourceCrop);
@@ -579,9 +601,8 @@
               mName.string(), sourceCrop.left, sourceCrop.top, sourceCrop.right, sourceCrop.bottom,
               to_string(error).c_str(), static_cast<int32_t>(error));
     } else {
-        hwcInfo.sourceCrop = sourceCrop;
+        compositionState.sourceCrop = sourceCrop;
     }
-    getBE().compositionInfo.hwc.sourceCrop = sourceCrop;
 
     float alpha = static_cast<float>(getAlpha());
     error = hwcLayer->setPlaneAlpha(alpha);
@@ -594,7 +615,7 @@
     error = hwcLayer->setZOrder(z);
     ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)", mName.string(), z,
              to_string(error).c_str(), static_cast<int32_t>(error));
-    getBE().compositionInfo.hwc.z = z;
+    compositionState.z = z;
 
     int type = s.metadata.getInt32(METADATA_WINDOW_TYPE, 0);
     int appId = s.metadata.getInt32(METADATA_OWNER_UID, 0);
@@ -651,35 +672,39 @@
     const uint32_t orientation = transform.getOrientation();
     if (orientation & ui::Transform::ROT_INVALID) {
         // we can only handle simple transformation
-        hwcInfo.forceClientComposition = true;
-        getBE().mHwcLayers[*displayId].compositionType = HWC2::Composition::Client;
+        compositionState.forceClientComposition = true;
+        (*compositionState.hwc).hwcCompositionType = Hwc2::IComposerClient::Composition::CLIENT;
     } else {
         auto transform = static_cast<HWC2::Transform>(orientation);
-        hwcInfo.transform = transform;
         auto error = hwcLayer->setTransform(transform);
         ALOGE_IF(error != HWC2::Error::None,
                  "[%s] Failed to set transform %s: "
                  "%s (%d)",
                  mName.string(), to_string(transform).c_str(), to_string(error).c_str(),
                  static_cast<int32_t>(error));
-        getBE().compositionInfo.hwc.transform = transform;
+        compositionState.bufferTransform = static_cast<Hwc2::Transform>(transform);
     }
 }
 
-void Layer::forceClientComposition(DisplayId displayId) {
-    RETURN_IF_NO_HWC_LAYER(displayId);
-    getBE().mHwcLayers[displayId].forceClientComposition = true;
+void Layer::forceClientComposition(const sp<DisplayDevice>& display) {
+    const auto outputLayer = findOutputLayerForDisplay(display);
+    LOG_FATAL_IF(!outputLayer);
+    outputLayer->editState().forceClientComposition = true;
 }
 
-bool Layer::getForceClientComposition(DisplayId displayId) {
-    RETURN_IF_NO_HWC_LAYER(displayId, false);
-    return getBE().mHwcLayers[displayId].forceClientComposition;
+bool Layer::getForceClientComposition(const sp<DisplayDevice>& display) {
+    const auto outputLayer = findOutputLayerForDisplay(display);
+    LOG_FATAL_IF(!outputLayer);
+    return outputLayer->getState().forceClientComposition;
 }
 
 void Layer::updateCursorPosition(const sp<const DisplayDevice>& display) {
-    const auto displayId = display->getId();
-    LOG_ALWAYS_FATAL_IF(!displayId);
-    if (!hasHwcLayer(*displayId) || getCompositionType(displayId) != HWC2::Composition::Cursor) {
+    const auto outputLayer = findOutputLayerForDisplay(display);
+    LOG_FATAL_IF(!outputLayer);
+
+    if (!outputLayer->getState().hwc ||
+        (*outputLayer->getState().hwc).hwcCompositionType !=
+                Hwc2::IComposerClient::Composition::CURSOR) {
         return;
     }
 
@@ -697,8 +722,7 @@
     auto position = displayTransform.transform(frame);
 
     auto error =
-            getBE().mHwcLayers[*displayId].layer->setCursorPosition(position.left, position.top);
-
+            (*outputLayer->getState().hwc).hwcLayer->setCursorPosition(position.left, position.top);
     ALOGE_IF(error != HWC2::Error::None,
              "[%s] Failed to set cursor position "
              "to (%d, %d): %s (%d)",
@@ -769,56 +793,41 @@
     clearWithOpenGL(renderArea, 0, 0, 0, 0);
 }
 
-void Layer::setCompositionType(DisplayId displayId, HWC2::Composition type, bool callIntoHwc) {
-    if (getBE().mHwcLayers.count(displayId) == 0) {
-        ALOGE("setCompositionType called without a valid HWC layer");
-        return;
-    }
-    auto& hwcInfo = getBE().mHwcLayers[displayId];
-    auto& hwcLayer = hwcInfo.layer;
-    ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", (hwcLayer)->getId(), to_string(type).c_str(),
-          static_cast<int>(callIntoHwc));
-    if (hwcInfo.compositionType != type) {
+void Layer::setCompositionType(const sp<const DisplayDevice>& display,
+                               Hwc2::IComposerClient::Composition type) {
+    const auto outputLayer = findOutputLayerForDisplay(display);
+    LOG_FATAL_IF(!outputLayer);
+    LOG_FATAL_IF(!outputLayer->getState().hwc);
+    auto& compositionState = outputLayer->editState();
+
+    ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", ((*compositionState.hwc).hwcLayer)->getId(),
+          toString(type).c_str(), 1);
+    if ((*compositionState.hwc).hwcCompositionType != type) {
         ALOGV("    actually setting");
-        hwcInfo.compositionType = type;
-        if (callIntoHwc) {
-            auto error = (hwcLayer)->setCompositionType(type);
-            ALOGE_IF(error != HWC2::Error::None,
-                     "[%s] Failed to set "
-                     "composition type %s: %s (%d)",
-                     mName.string(), to_string(type).c_str(), to_string(error).c_str(),
-                     static_cast<int32_t>(error));
-        }
+        (*compositionState.hwc).hwcCompositionType = type;
+
+        auto error = (*compositionState.hwc)
+                             .hwcLayer->setCompositionType(static_cast<HWC2::Composition>(type));
+        ALOGE_IF(error != HWC2::Error::None,
+                 "[%s] Failed to set "
+                 "composition type %s: %s (%d)",
+                 mName.string(), toString(type).c_str(), to_string(error).c_str(),
+                 static_cast<int32_t>(error));
     }
 }
 
-HWC2::Composition Layer::getCompositionType(const std::optional<DisplayId>& displayId) const {
-    if (!displayId) {
-        // If we're querying the composition type for a display that does not
-        // have a HWC counterpart, then it will always be Client
-        return HWC2::Composition::Client;
-    }
-    if (getBE().mHwcLayers.count(*displayId) == 0) {
-        ALOGE("getCompositionType called with an invalid HWC layer");
-        return HWC2::Composition::Invalid;
-    }
-    return getBE().mHwcLayers.at(*displayId).compositionType;
+Hwc2::IComposerClient::Composition Layer::getCompositionType(
+        const sp<const DisplayDevice>& display) const {
+    const auto outputLayer = findOutputLayerForDisplay(display);
+    LOG_FATAL_IF(!outputLayer);
+    return outputLayer->getState().hwc ? (*outputLayer->getState().hwc).hwcCompositionType
+                                       : Hwc2::IComposerClient::Composition::CLIENT;
 }
 
-void Layer::setClearClientTarget(DisplayId displayId, bool clear) {
-    if (getBE().mHwcLayers.count(displayId) == 0) {
-        ALOGE("setClearClientTarget called without a valid HWC layer");
-        return;
-    }
-    getBE().mHwcLayers[displayId].clearClientTarget = clear;
-}
-
-bool Layer::getClearClientTarget(DisplayId displayId) const {
-    if (getBE().mHwcLayers.count(displayId) == 0) {
-        ALOGE("getClearClientTarget called without a valid HWC layer");
-        return false;
-    }
-    return getBE().mHwcLayers.at(displayId).clearClientTarget;
+bool Layer::getClearClientTarget(const sp<const DisplayDevice>& display) const {
+    const auto outputLayer = findOutputLayerForDisplay(display);
+    LOG_FATAL_IF(!outputLayer);
+    return outputLayer->getState().clearClientTarget;
 }
 
 bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
@@ -1535,8 +1544,9 @@
     result.append("-----------------------------\n");
 }
 
-void Layer::miniDump(std::string& result, DisplayId displayId) const {
-    if (!hasHwcLayer(displayId)) {
+void Layer::miniDump(std::string& result, const sp<DisplayDevice>& displayDevice) const {
+    auto outputLayer = findOutputLayerForDisplay(displayDevice);
+    if (!outputLayer) {
         return;
     }
 
@@ -1554,17 +1564,21 @@
     StringAppendF(&result, " %s\n", name.c_str());
 
     const State& layerState(getDrawingState());
-    const LayerBE::HWCInfo& hwcInfo = getBE().mHwcLayers.at(displayId);
+    const auto& compositionState = outputLayer->getState();
+
     if (layerState.zOrderRelativeOf != nullptr || mDrawingParent != nullptr) {
         StringAppendF(&result, "  rel %6d | ", layerState.z);
     } else {
         StringAppendF(&result, "  %10d | ", layerState.z);
     }
-    StringAppendF(&result, "%10s | ", to_string(getCompositionType(displayId)).c_str());
-    StringAppendF(&result, "%10s | ", to_string(hwcInfo.transform).c_str());
-    const Rect& frame = hwcInfo.displayFrame;
+    StringAppendF(&result, "%10s | ", toString(getCompositionType(displayDevice)).c_str());
+    StringAppendF(&result, "%10s | ",
+                  toString(getCompositionLayer() ? compositionState.bufferTransform
+                                                 : static_cast<Hwc2::Transform>(0))
+                          .c_str());
+    const Rect& frame = compositionState.displayFrame;
     StringAppendF(&result, "%4d %4d %4d %4d | ", frame.left, frame.top, frame.right, frame.bottom);
-    const FloatRect& crop = hwcInfo.sourceCrop;
+    const FloatRect& crop = compositionState.sourceCrop;
     StringAppendF(&result, "%6.1f %6.1f %6.1f %6.1f\n", crop.left, crop.top, crop.right,
                   crop.bottom);
 
@@ -2164,25 +2178,29 @@
     LayerProtoHelper::writeToProto(mBounds, layerInfo->mutable_bounds());
 }
 
-void Layer::writeToProto(LayerProto* layerInfo, DisplayId displayId) {
-    if (!hasHwcLayer(displayId)) {
+void Layer::writeToProto(LayerProto* layerInfo, const sp<DisplayDevice>& displayDevice) {
+    auto outputLayer = findOutputLayerForDisplay(displayDevice);
+    if (!outputLayer) {
         return;
     }
 
     writeToProto(layerInfo, LayerVector::StateSet::Drawing);
 
-    const auto& hwcInfo = getBE().mHwcLayers.at(displayId);
+    const auto& compositionState = outputLayer->getState();
 
-    const Rect& frame = hwcInfo.displayFrame;
+    const Rect& frame = compositionState.displayFrame;
     LayerProtoHelper::writeToProto(frame, layerInfo->mutable_hwc_frame());
 
-    const FloatRect& crop = hwcInfo.sourceCrop;
+    const FloatRect& crop = compositionState.sourceCrop;
     LayerProtoHelper::writeToProto(crop, layerInfo->mutable_hwc_crop());
 
-    const int32_t transform = static_cast<int32_t>(hwcInfo.transform);
+    const int32_t transform =
+            getCompositionLayer() ? static_cast<int32_t>(compositionState.bufferTransform) : 0;
     layerInfo->set_hwc_transform(transform);
 
-    const int32_t compositionType = static_cast<int32_t>(hwcInfo.compositionType);
+    const int32_t compositionType =
+            static_cast<int32_t>(compositionState.hwc ? (*compositionState.hwc).hwcCompositionType
+                                                      : Hwc2::IComposerClient::Composition::CLIENT);
     layerInfo->set_hwc_composition_type(compositionType);
 
     if (std::strcmp(getTypeId(), "BufferLayer") == 0 &&
@@ -2249,6 +2267,11 @@
     return isVisible();
 }
 
+compositionengine::OutputLayer* Layer::findOutputLayerForDisplay(
+        const sp<const DisplayDevice>& display) const {
+    return display->getCompositionDisplay()->getOutputLayerForLayer(getCompositionLayer().get());
+}
+
 // ---------------------------------------------------------------------------
 
 }; // namespace android