SF: Restructure OutputLayer creation to remove displayId argument

The existing code was explicitly passing the displayId when creating an
OutputLayer, so that a HWC2::Layer could be created if applicable.

This patch makes a quick adjustment to the code so that the
compositionengine::Display instance overrides the base createOutputLayer
logic to create the HWC2::Layer, as it knows the displayId itself.

This is a minor cleanup prior to moving computeVisibleLayers to the
Output class.

Test: atest libsurfaceflinger_unittest libcompositionengine_test
Test: go/wm-smoke
Bug: 121291683
Change-Id: Ic7224ba445084b833b8c344436397372b2153d42
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
index 43f44af..2e44c07 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
@@ -138,11 +138,14 @@
     // this output, or nullptr if the layer does not have one
     virtual OutputLayer* getOutputLayerForLayer(Layer*) const = 0;
 
+    // Creates an OutputLayer instance for this output
+    virtual std::unique_ptr<OutputLayer> createOutputLayer(const std::shared_ptr<Layer>&,
+                                                           const sp<LayerFE>&) const = 0;
+
     // Gets the OutputLayer corresponding to the input Layer instance from the
     // current ordered set of output layers. If there is no such layer, a new
     // one is created and returned.
-    virtual std::unique_ptr<OutputLayer> getOrCreateOutputLayer(std::optional<DisplayId>,
-                                                                std::shared_ptr<Layer>,
+    virtual std::unique_ptr<OutputLayer> getOrCreateOutputLayer(std::shared_ptr<Layer>,
                                                                 sp<LayerFE>) = 0;
 
     // Sets the new ordered set of output layers for this output
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h
index cedd728..389b605 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h
@@ -48,6 +48,9 @@
 public:
     virtual ~OutputLayer();
 
+    // Sets the HWC2::Layer associated with this layer
+    virtual void setHwcLayer(std::shared_ptr<HWC2::Layer>) = 0;
+
     // Gets the output which owns this output layer
     virtual const Output& getOutput() const = 0;
 
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
index bd1aa08..2e595d6 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
@@ -40,6 +40,8 @@
 
     // compositionengine::Output overrides
     void dump(std::string&) const override;
+    std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(
+            const std::shared_ptr<Layer>&, const sp<LayerFE>&) const override;
     void setColorTransform(const compositionengine::CompositionRefreshArgs&) override;
     void setColorProfile(const ColorProfile&) override;
     void chooseCompositionStrategy() override;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
index ece5b1c..bdb35c2 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
@@ -66,9 +66,10 @@
 
     compositionengine::OutputLayer* getOutputLayerForLayer(
             compositionengine::Layer*) const override;
+    std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(
+            const std::shared_ptr<Layer>&, const sp<LayerFE>&) const override;
     std::unique_ptr<compositionengine::OutputLayer> getOrCreateOutputLayer(
-            std::optional<DisplayId>, std::shared_ptr<compositionengine::Layer>,
-            sp<LayerFE>) override;
+            std::shared_ptr<compositionengine::Layer>, sp<LayerFE>) override;
     void setOutputLayersOrderedByZ(OutputLayers&&) override;
     const OutputLayers& getOutputLayersOrderedByZ() const override;
 
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h
index fa4d8cd..1199fea 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h
@@ -34,11 +34,11 @@
 
 class OutputLayer : public compositionengine::OutputLayer {
 public:
-    OutputLayer(const compositionengine::Output&, std::shared_ptr<compositionengine::Layer>,
-                sp<compositionengine::LayerFE>);
+    OutputLayer(const compositionengine::Output&, const std::shared_ptr<compositionengine::Layer>&,
+                const sp<compositionengine::LayerFE>&);
     ~OutputLayer() override;
 
-    void initialize(const CompositionEngine&, std::optional<DisplayId>);
+    void setHwcLayer(std::shared_ptr<HWC2::Layer>) override;
 
     const compositionengine::Output& getOutput() const override;
     compositionengine::Layer& getLayer() const override;
@@ -86,8 +86,8 @@
 };
 
 std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(
-        const CompositionEngine&, std::optional<DisplayId>, const compositionengine::Output&,
-        std::shared_ptr<compositionengine::Layer>, sp<compositionengine::LayerFE>);
+        const compositionengine::Output&, const std::shared_ptr<compositionengine::Layer>&,
+        const sp<compositionengine::LayerFE>&);
 
 } // namespace impl
 } // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
index 2f24c15..93274e7 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
@@ -63,9 +63,13 @@
 
     MOCK_CONST_METHOD1(getOutputLayerForLayer,
                        compositionengine::OutputLayer*(compositionengine::Layer*));
-    MOCK_METHOD3(getOrCreateOutputLayer,
+    MOCK_CONST_METHOD2(createOutputLayer,
+                       std::unique_ptr<compositionengine::OutputLayer>(
+                               const std::shared_ptr<compositionengine::Layer>&,
+                               const sp<compositionengine::LayerFE>&));
+    MOCK_METHOD2(getOrCreateOutputLayer,
                  std::unique_ptr<compositionengine::OutputLayer>(
-                         std::optional<DisplayId>, std::shared_ptr<compositionengine::Layer>,
+                         std::shared_ptr<compositionengine::Layer>,
                          sp<compositionengine::LayerFE>));
 
     MOCK_METHOD1(setOutputLayersOrderedByZ, void(OutputLayers&&));
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h
index 6b2224a..4f2afac 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h
@@ -31,6 +31,8 @@
     OutputLayer();
     virtual ~OutputLayer();
 
+    MOCK_METHOD1(setHwcLayer, void(std::shared_ptr<HWC2::Layer>));
+
     MOCK_CONST_METHOD0(getOutput, const compositionengine::Output&());
     MOCK_CONST_METHOD0(getLayer, compositionengine::Layer&());
     MOCK_CONST_METHOD0(getLayerFE, compositionengine::LayerFE&());
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index 000a294..49727df 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -19,6 +19,7 @@
 #include <compositionengine/CompositionRefreshArgs.h>
 #include <compositionengine/DisplayCreationArgs.h>
 #include <compositionengine/DisplaySurface.h>
+#include <compositionengine/LayerFE.h>
 #include <compositionengine/impl/Display.h>
 #include <compositionengine/impl/DisplayColorProfile.h>
 #include <compositionengine/impl/DumpHelpers.h>
@@ -133,6 +134,30 @@
                                                                   std::move(args)));
 }
 
+std::unique_ptr<compositionengine::OutputLayer> Display::createOutputLayer(
+        const std::shared_ptr<compositionengine::Layer>& layer,
+        const sp<compositionengine::LayerFE>& layerFE) const {
+    auto result = Output::createOutputLayer(layer, layerFE);
+
+    if (result && mId) {
+        auto& hwc = getCompositionEngine().getHwComposer();
+        auto displayId = *mId;
+        // Note: For the moment we ensure it is safe to take a reference to the
+        // HWComposer implementation by destroying all the OutputLayers (and
+        // hence the HWC2::Layers they own) before setting a new HWComposer. See
+        // for example SurfaceFlinger::updateVrFlinger().
+        // TODO(b/121291683): Make this safer.
+        auto hwcLayer = std::shared_ptr<HWC2::Layer>(hwc.createLayer(displayId),
+                                                     [&hwc, displayId](HWC2::Layer* layer) {
+                                                         hwc.destroyLayer(displayId, layer);
+                                                     });
+        ALOGE_IF(!hwcLayer, "Failed to create a HWC layer for a HWC supported display %s",
+                 getName().c_str());
+        result->setHwcLayer(std::move(hwcLayer));
+    }
+    return result;
+}
+
 void Display::chooseCompositionStrategy() {
     ATRACE_CALL();
     ALOGV(__FUNCTION__);
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 4dfdeba..cb04e95 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -230,14 +230,20 @@
 }
 
 std::unique_ptr<compositionengine::OutputLayer> Output::getOrCreateOutputLayer(
-        std::optional<DisplayId> displayId, std::shared_ptr<compositionengine::Layer> layer,
-        sp<compositionengine::LayerFE> layerFE) {
+        std::shared_ptr<compositionengine::Layer> layer, sp<compositionengine::LayerFE> layerFE) {
     for (auto& outputLayer : mOutputLayersOrderedByZ) {
         if (outputLayer && &outputLayer->getLayer() == layer.get()) {
             return std::move(outputLayer);
         }
     }
-    return createOutputLayer(mCompositionEngine, displayId, *this, layer, layerFE);
+
+    return createOutputLayer(layer, layerFE);
+}
+
+std::unique_ptr<compositionengine::OutputLayer> Output::createOutputLayer(
+        const std::shared_ptr<compositionengine::Layer>& layer,
+        const sp<compositionengine::LayerFE>& layerFE) const {
+    return impl::createOutputLayer(*this, layer, layerFE);
 }
 
 void Output::setOutputLayersOrderedByZ(OutputLayers&& layers) {
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index 3a0ebf8..4eb256f 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -15,7 +15,6 @@
  */
 
 #include <android-base/stringprintf.h>
-#include <compositionengine/CompositionEngine.h>
 #include <compositionengine/DisplayColorProfile.h>
 #include <compositionengine/Layer.h>
 #include <compositionengine/LayerFE.h>
@@ -46,31 +45,24 @@
 } // namespace
 
 std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(
-        const CompositionEngine& compositionEngine, std::optional<DisplayId> displayId,
-        const compositionengine::Output& output, std::shared_ptr<compositionengine::Layer> layer,
-        sp<compositionengine::LayerFE> layerFE) {
-    auto result = std::make_unique<OutputLayer>(output, layer, layerFE);
-    result->initialize(compositionEngine, displayId);
-    return result;
+        const compositionengine::Output& output,
+        const std::shared_ptr<compositionengine::Layer>& layer,
+        const sp<compositionengine::LayerFE>& layerFE) {
+    return std::make_unique<OutputLayer>(output, layer, layerFE);
 }
 
-OutputLayer::OutputLayer(const Output& output, std::shared_ptr<Layer> layer, sp<LayerFE> layerFE)
+OutputLayer::OutputLayer(const Output& output, const std::shared_ptr<Layer>& layer,
+                         const sp<LayerFE>& layerFE)
       : mOutput(output), mLayer(layer), mLayerFE(layerFE) {}
 
 OutputLayer::~OutputLayer() = default;
 
-void OutputLayer::initialize(const CompositionEngine& compositionEngine,
-                             std::optional<DisplayId> displayId) {
-    if (!displayId) {
-        return;
+void OutputLayer::setHwcLayer(std::shared_ptr<HWC2::Layer> hwcLayer) {
+    if (hwcLayer) {
+        mState.hwc.emplace(hwcLayer);
+    } else {
+        mState.hwc.reset();
     }
-
-    auto& hwc = compositionEngine.getHwComposer();
-
-    mState.hwc.emplace(std::shared_ptr<HWC2::Layer>(hwc.createLayer(*displayId),
-                                                    [&hwc, displayId](HWC2::Layer* layer) {
-                                                        hwc.destroyLayer(*displayId, layer);
-                                                    }));
 }
 
 const compositionengine::Output& OutputLayer::getOutput() const {
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index 008e631..6821ec1 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -23,6 +23,8 @@
 #include <compositionengine/impl/Display.h>
 #include <compositionengine/mock/CompositionEngine.h>
 #include <compositionengine/mock/DisplayColorProfile.h>
+#include <compositionengine/mock/Layer.h>
+#include <compositionengine/mock/LayerFE.h>
 #include <compositionengine/mock/NativeWindow.h>
 #include <compositionengine/mock/OutputLayer.h>
 #include <compositionengine/mock/RenderSurface.h>
@@ -256,6 +258,25 @@
 }
 
 /*
+ * Display::createOutputLayer()
+ */
+
+TEST_F(DisplayTest, createOutputLayerSetsHwcLayer) {
+    sp<mock::LayerFE> layerFE = new StrictMock<mock::LayerFE>();
+    auto layer = std::make_shared<StrictMock<mock::Layer>>();
+    StrictMock<HWC2::mock::Layer> hwcLayer;
+
+    EXPECT_CALL(mHwComposer, createLayer(DEFAULT_DISPLAY_ID)).WillOnce(Return(&hwcLayer));
+
+    auto outputLayer = mDisplay.createOutputLayer(layer, layerFE);
+
+    EXPECT_EQ(&hwcLayer, outputLayer->getHwcLayer());
+
+    EXPECT_CALL(mHwComposer, destroyLayer(DEFAULT_DISPLAY_ID, &hwcLayer));
+    outputLayer.reset();
+}
+
+/*
  * Display::chooseCompositionStrategy()
  */
 
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
index 65691ff..b73c47b 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
@@ -36,8 +36,6 @@
 using testing::ReturnRef;
 using testing::StrictMock;
 
-constexpr DisplayId DEFAULT_DISPLAY_ID = DisplayId{42};
-
 constexpr auto TR_IDENT = 0u;
 constexpr auto TR_FLP_H = HAL_TRANSFORM_FLIP_H;
 constexpr auto TR_FLP_V = HAL_TRANSFORM_FLIP_V;
@@ -83,35 +81,27 @@
 TEST_F(OutputLayerTest, canInstantiateOutputLayer) {}
 
 /*
- * OutputLayer::initialize()
+ * OutputLayer::setHwcLayer()
  */
 
-TEST_F(OutputLayerTest, initializingOutputLayerWithoutHwcDoesNothingInteresting) {
+TEST_F(OutputLayerTest, settingNullHwcLayerSetsEmptyHwcState) {
     StrictMock<compositionengine::mock::CompositionEngine> compositionEngine;
 
-    mOutputLayer.initialize(compositionEngine, std::nullopt);
+    mOutputLayer.setHwcLayer(nullptr);
 
     EXPECT_FALSE(mOutputLayer.getState().hwc);
 }
 
-TEST_F(OutputLayerTest, initializingOutputLayerWithHwcDisplayCreatesHwcLayer) {
-    StrictMock<compositionengine::mock::CompositionEngine> compositionEngine;
-    StrictMock<android::mock::HWComposer> hwc;
-    StrictMock<HWC2::mock::Layer> hwcLayer;
+TEST_F(OutputLayerTest, settingHwcLayerSetsHwcState) {
+    auto hwcLayer = std::make_shared<StrictMock<HWC2::mock::Layer>>();
 
-    EXPECT_CALL(compositionEngine, getHwComposer()).WillOnce(ReturnRef(hwc));
-    EXPECT_CALL(hwc, createLayer(DEFAULT_DISPLAY_ID)).WillOnce(Return(&hwcLayer));
-
-    mOutputLayer.initialize(compositionEngine, DEFAULT_DISPLAY_ID);
+    mOutputLayer.setHwcLayer(hwcLayer);
 
     const auto& outputLayerState = mOutputLayer.getState();
     ASSERT_TRUE(outputLayerState.hwc);
 
     const auto& hwcState = *outputLayerState.hwc;
-    EXPECT_EQ(&hwcLayer, hwcState.hwcLayer.get());
-
-    EXPECT_CALL(hwc, destroyLayer(DEFAULT_DISPLAY_ID, &hwcLayer));
-    mOutputLayer.editState().hwc.reset();
+    EXPECT_EQ(hwcLayer, hwcState.hwcLayer);
 }
 
 /*
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index 70d9871..10ec1ee 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -429,7 +429,7 @@
         // If there is no OutputLayer corresponding to the input layer, a
         // new OutputLayer is constructed and returned.
         EXPECT_CALL(*existingOutputLayer, getLayer()).WillOnce(ReturnRef(otherLayer));
-        auto result = mOutput.getOrCreateOutputLayer(std::nullopt, layer, layerFE);
+        auto result = mOutput.getOrCreateOutputLayer(layer, layerFE);
         EXPECT_NE(existingOutputLayer, result.get());
         EXPECT_TRUE(result.get() != nullptr);
         EXPECT_EQ(layer.get(), &result->getLayer());
@@ -445,7 +445,7 @@
         // If there is an existing OutputLayer for the requested layer, an owned
         // pointer is returned
         EXPECT_CALL(*existingOutputLayer, getLayer()).WillOnce(ReturnRef(*layer));
-        auto result = mOutput.getOrCreateOutputLayer(std::nullopt, layer, layerFE);
+        auto result = mOutput.getOrCreateOutputLayer(layer, layerFE);
         EXPECT_EQ(existingOutputLayer, result.get());
 
         // The corresponding entry in the ordered array should be cleared.