SF: Intro CE::OutputLayer

Introduce compositionengine::OutputLayer, for representing the
composition state of a layer on an output (display)

This change just introduces the OutputLayer class, and modifies
SurfaceFlinger.cpp to create them properly. The new class does not yet
have any state.

Test: atest libsurfaceflinger_unittest libcompositionengine_test
Bug: 121291683
Change-Id: Ic8fe0fee61470b36539287883d4901b25208b634
diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp
index 564bd5b..1651cc4 100644
--- a/services/surfaceflinger/CompositionEngine/Android.bp
+++ b/services/surfaceflinger/CompositionEngine/Android.bp
@@ -44,6 +44,7 @@
         "src/Layer.cpp",
         "src/Output.cpp",
         "src/OutputCompositionState.cpp",
+        "src/OutputLayer.cpp",
         "src/RenderSurface.cpp",
     ],
     local_include_dirs: ["include"],
@@ -61,6 +62,7 @@
         "mock/Layer.cpp",
         "mock/LayerFE.cpp",
         "mock/Output.cpp",
+        "mock/OutputLayer.cpp",
         "mock/RenderSurface.cpp",
     ],
     static_libs: [
@@ -83,6 +85,7 @@
         "tests/LayerTest.cpp",
         "tests/MockHWComposer.cpp",
         "tests/OutputTest.cpp",
+        "tests/OutputLayerTest.cpp",
         "tests/RenderSurfaceTest.cpp",
     ],
     static_libs: [
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
index ab54b5d..84b2423 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
@@ -23,11 +23,15 @@
 #include <ui/GraphicTypes.h>
 #include <ui/Region.h>
 #include <ui/Transform.h>
+#include <utils/StrongPointer.h>
 
 namespace android::compositionengine {
 
 class DisplayColorProfile;
+class Layer;
+class LayerFE;
 class RenderSurface;
+class OutputLayer;
 
 namespace impl {
 struct OutputCompositionState;
@@ -38,6 +42,8 @@
  */
 class Output {
 public:
+    using OutputLayers = std::vector<std::unique_ptr<compositionengine::OutputLayer>>;
+
     virtual ~Output();
 
     // Returns true if the output is valid. This is meant to be checked post-
@@ -104,6 +110,22 @@
     // this output allows that.
     virtual bool belongsInOutput(uint32_t layerStackId, bool internalOnly) const = 0;
 
+    // Returns a pointer to the output layer corresponding to the given layer on
+    // this output, or nullptr if the layer does not have one
+    virtual OutputLayer* getOutputLayerForLayer(Layer*) 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::shared_ptr<Layer>,
+                                                                sp<LayerFE>) = 0;
+
+    // Sets the new ordered set of output layers for this output
+    virtual void setOutputLayersOrderedByZ(OutputLayers&&) = 0;
+
+    // Gets the ordered set of output layers for this output
+    virtual const OutputLayers& getOutputLayersOrderedByZ() const = 0;
+
 protected:
     virtual void setDisplayColorProfile(std::unique_ptr<DisplayColorProfile>) = 0;
     virtual void setRenderSurface(std::unique_ptr<RenderSurface>) = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h
new file mode 100644
index 0000000..4b8ef38
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <utils/StrongPointer.h>
+
+namespace android::compositionengine {
+
+class Output;
+class Layer;
+class LayerFE;
+
+/**
+ * An output layer contains the output-dependent composition state for a layer
+ */
+class OutputLayer {
+public:
+    virtual ~OutputLayer();
+
+    // Gets the output which owns this output layer
+    virtual const Output& getOutput() const = 0;
+
+    // Gets the display-independent layer which this output layer represents
+    virtual Layer& getLayer() const = 0;
+
+    // Gets the front-end layer interface this output layer represents
+    virtual LayerFE& getLayerFE() const = 0;
+};
+
+} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
index 1e51c5e..3fd057c 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
@@ -17,6 +17,8 @@
 #pragma once
 
 #include <memory>
+#include <utility>
+#include <vector>
 
 #include <compositionengine/Output.h>
 #include <compositionengine/impl/OutputCompositionState.h>
@@ -24,6 +26,8 @@
 namespace android::compositionengine {
 
 class CompositionEngine;
+class Layer;
+class OutputLayer;
 
 namespace impl {
 
@@ -60,6 +64,13 @@
     Region getDirtyRegion(bool repaintEverything) const override;
     bool belongsInOutput(uint32_t, bool) const override;
 
+    compositionengine::OutputLayer* getOutputLayerForLayer(
+            compositionengine::Layer*) const override;
+    std::unique_ptr<compositionengine::OutputLayer> getOrCreateOutputLayer(
+            std::shared_ptr<compositionengine::Layer>, sp<LayerFE>) override;
+    void setOutputLayersOrderedByZ(OutputLayers&&) override;
+    const OutputLayers& getOutputLayersOrderedByZ() const override;
+
     // Testing
     void setDisplayColorProfileForTest(std::unique_ptr<compositionengine::DisplayColorProfile>);
     void setRenderSurfaceForTest(std::unique_ptr<compositionengine::RenderSurface>);
@@ -79,6 +90,8 @@
 
     std::unique_ptr<compositionengine::DisplayColorProfile> mDisplayColorProfile;
     std::unique_ptr<compositionengine::RenderSurface> mRenderSurface;
+
+    OutputLayers mOutputLayersOrderedByZ;
 };
 
 } // namespace impl
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h
new file mode 100644
index 0000000..f3d0258
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <memory>
+
+#include <compositionengine/OutputLayer.h>
+
+namespace android::compositionengine::impl {
+
+class OutputLayer : public compositionengine::OutputLayer {
+public:
+    OutputLayer(const compositionengine::Output&, std::shared_ptr<compositionengine::Layer>,
+                sp<compositionengine::LayerFE>);
+    ~OutputLayer() override;
+
+    const compositionengine::Output& getOutput() const override;
+    compositionengine::Layer& getLayer() const override;
+    compositionengine::LayerFE& getLayerFE() const override;
+
+private:
+    const compositionengine::Output& mOutput;
+    std::shared_ptr<compositionengine::Layer> mLayer;
+    sp<compositionengine::LayerFE> mLayerFE;
+};
+
+std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(
+        const compositionengine::Output&, std::shared_ptr<compositionengine::Layer>,
+        sp<compositionengine::LayerFE>);
+
+} // namespace android::compositionengine::impl
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
index e767ad3..2972ad7 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
@@ -17,7 +17,10 @@
 #pragma once
 
 #include <compositionengine/DisplayColorProfile.h>
+#include <compositionengine/Layer.h>
+#include <compositionengine/LayerFE.h>
 #include <compositionengine/Output.h>
+#include <compositionengine/OutputLayer.h>
 #include <compositionengine/RenderSurface.h>
 #include <compositionengine/impl/OutputCompositionState.h>
 #include <gmock/gmock.h>
@@ -55,6 +58,15 @@
 
     MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
     MOCK_CONST_METHOD2(belongsInOutput, bool(uint32_t, bool));
+
+    MOCK_CONST_METHOD1(getOutputLayerForLayer,
+                       compositionengine::OutputLayer*(compositionengine::Layer*));
+    MOCK_METHOD2(getOrCreateOutputLayer,
+                 std::unique_ptr<compositionengine::OutputLayer>(
+                         std::shared_ptr<compositionengine::Layer>,
+                         sp<compositionengine::LayerFE>));
+    MOCK_METHOD1(setOutputLayersOrderedByZ, void(OutputLayers&&));
+    MOCK_CONST_METHOD0(getOutputLayersOrderedByZ, OutputLayers&());
 };
 
 } // namespace android::compositionengine::mock
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h
new file mode 100644
index 0000000..f5e5026
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <compositionengine/Layer.h>
+#include <compositionengine/LayerFE.h>
+#include <compositionengine/Output.h>
+#include <compositionengine/OutputLayer.h>
+#include <gmock/gmock.h>
+
+namespace android::compositionengine::mock {
+
+class OutputLayer : public compositionengine::OutputLayer {
+public:
+    OutputLayer();
+    virtual ~OutputLayer();
+
+    MOCK_CONST_METHOD0(getOutput, const compositionengine::Output&());
+    MOCK_CONST_METHOD0(getLayer, compositionengine::Layer&());
+    MOCK_CONST_METHOD0(getLayerFE, compositionengine::LayerFE&());
+};
+
+} // namespace android::compositionengine::mock
diff --git a/services/surfaceflinger/CompositionEngine/mock/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/mock/OutputLayer.cpp
new file mode 100644
index 0000000..4da9377
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/mock/OutputLayer.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <compositionengine/mock/OutputLayer.h>
+
+namespace android::compositionengine::mock {
+
+// The Google Mock documentation recommends explicit non-header instantiations
+// for better compile time performance.
+OutputLayer::OutputLayer() = default;
+OutputLayer::~OutputLayer() = default;
+
+} // namespace android::compositionengine::mock
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 2d458bf..f6c1a33 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -17,8 +17,10 @@
 #include <android-base/stringprintf.h>
 #include <compositionengine/CompositionEngine.h>
 #include <compositionengine/DisplayColorProfile.h>
+#include <compositionengine/LayerFE.h>
 #include <compositionengine/RenderSurface.h>
 #include <compositionengine/impl/Output.h>
+#include <compositionengine/impl/OutputLayer.h>
 #include <ui/DebugUtils.h>
 
 namespace android::compositionengine {
@@ -182,6 +184,34 @@
     return (layerStackId == mState.layerStackId) && (!internalOnly || mState.layerStackInternal);
 }
 
+compositionengine::OutputLayer* Output::getOutputLayerForLayer(
+        compositionengine::Layer* layer) const {
+    for (const auto& outputLayer : mOutputLayersOrderedByZ) {
+        if (outputLayer && &outputLayer->getLayer() == layer) {
+            return outputLayer.get();
+        }
+    }
+    return nullptr;
+}
+
+std::unique_ptr<compositionengine::OutputLayer> Output::getOrCreateOutputLayer(
+        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(*this, layer, layerFE);
+}
+
+void Output::setOutputLayersOrderedByZ(OutputLayers&& layers) {
+    mOutputLayersOrderedByZ = std::move(layers);
+}
+
+const Output::OutputLayers& Output::getOutputLayersOrderedByZ() const {
+    return mOutputLayersOrderedByZ;
+}
+
 void Output::dirtyEntireOutput() {
     mState.dirtyRegion.set(mState.bounds);
 }
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
new file mode 100644
index 0000000..e95f3a6
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <compositionengine/Layer.h>
+#include <compositionengine/LayerFE.h>
+#include <compositionengine/Output.h>
+#include <compositionengine/impl/OutputLayer.h>
+
+namespace android::compositionengine {
+
+OutputLayer::~OutputLayer() = default;
+
+namespace impl {
+
+std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(
+        const compositionengine::Output& display, std::shared_ptr<compositionengine::Layer> layer,
+        sp<compositionengine::LayerFE> layerFE) {
+    return std::make_unique<OutputLayer>(display, layer, layerFE);
+}
+
+OutputLayer::OutputLayer(const Output& output, std::shared_ptr<Layer> layer, sp<LayerFE> layerFE)
+      : mOutput(output), mLayer(layer), mLayerFE(layerFE) {}
+
+OutputLayer::~OutputLayer() = default;
+
+const compositionengine::Output& OutputLayer::getOutput() const {
+    return mOutput;
+}
+
+compositionengine::Layer& OutputLayer::getLayer() const {
+    return *mLayer;
+}
+
+compositionengine::LayerFE& OutputLayer::getLayerFE() const {
+    return *mLayerFE;
+}
+
+} // namespace impl
+} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
new file mode 100644
index 0000000..0a929ac
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <compositionengine/impl/OutputLayer.h>
+#include <compositionengine/mock/Layer.h>
+#include <compositionengine/mock/LayerFE.h>
+#include <compositionengine/mock/Output.h>
+#include <gtest/gtest.h>
+
+namespace android::compositionengine {
+namespace {
+
+using testing::StrictMock;
+
+class OutputLayerTest : public testing::Test {
+public:
+    ~OutputLayerTest() override = default;
+
+    compositionengine::mock::Output mOutput;
+    std::shared_ptr<compositionengine::mock::Layer> mLayer{
+            new StrictMock<compositionengine::mock::Layer>()};
+    sp<compositionengine::mock::LayerFE> mLayerFE{
+            new StrictMock<compositionengine::mock::LayerFE>()};
+    impl::OutputLayer mOutputLayer{mOutput, mLayer, mLayerFE};
+};
+
+/* ------------------------------------------------------------------------
+ * Basic construction
+ */
+
+TEST_F(OutputLayerTest, canInstantiateOutputLayer) {}
+
+} // namespace
+} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index 0df1dab..314d98b 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -19,6 +19,9 @@
 #include <compositionengine/impl/Output.h>
 #include <compositionengine/mock/CompositionEngine.h>
 #include <compositionengine/mock/DisplayColorProfile.h>
+#include <compositionengine/mock/Layer.h>
+#include <compositionengine/mock/LayerFE.h>
+#include <compositionengine/mock/OutputLayer.h>
 #include <compositionengine/mock/RenderSurface.h>
 #include <gtest/gtest.h>
 #include <ui/Rect.h>
@@ -267,5 +270,84 @@
     EXPECT_FALSE(mOutput.belongsInOutput(layerStack2, false));
 }
 
+/* ------------------------------------------------------------------------
+ * Output::getOutputLayerForLayer()
+ */
+
+TEST_F(OutputTest, getOutputLayerForLayerWorks) {
+    mock::OutputLayer* outputLayer1 = new StrictMock<mock::OutputLayer>();
+    mock::OutputLayer* outputLayer2 = new StrictMock<mock::OutputLayer>();
+
+    Output::OutputLayers outputLayers;
+    outputLayers.emplace_back(std::unique_ptr<OutputLayer>(outputLayer1));
+    outputLayers.emplace_back(nullptr);
+    outputLayers.emplace_back(std::unique_ptr<OutputLayer>(outputLayer2));
+    mOutput.setOutputLayersOrderedByZ(std::move(outputLayers));
+
+    StrictMock<mock::Layer> layer;
+    StrictMock<mock::Layer> otherLayer;
+
+    // If the input layer matches the first OutputLayer, it will be returned.
+    EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(layer));
+    EXPECT_EQ(outputLayer1, mOutput.getOutputLayerForLayer(&layer));
+
+    // If the input layer matches the second OutputLayer, it will be returned.
+    EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(otherLayer));
+    EXPECT_CALL(*outputLayer2, getLayer()).WillOnce(ReturnRef(layer));
+    EXPECT_EQ(outputLayer2, mOutput.getOutputLayerForLayer(&layer));
+
+    // If the input layer does not match an output layer, null will be returned.
+    EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(otherLayer));
+    EXPECT_CALL(*outputLayer2, getLayer()).WillOnce(ReturnRef(otherLayer));
+    EXPECT_EQ(nullptr, mOutput.getOutputLayerForLayer(&layer));
+}
+
+/* ------------------------------------------------------------------------
+ * Output::getOrCreateOutputLayer()
+ */
+
+TEST_F(OutputTest, getOrCreateOutputLayerWorks) {
+    mock::OutputLayer* existingOutputLayer = new StrictMock<mock::OutputLayer>();
+
+    Output::OutputLayers outputLayers;
+    outputLayers.emplace_back(nullptr);
+    outputLayers.emplace_back(std::unique_ptr<OutputLayer>(existingOutputLayer));
+    mOutput.setOutputLayersOrderedByZ(std::move(outputLayers));
+
+    std::shared_ptr<mock::Layer> layer{new StrictMock<mock::Layer>()};
+    sp<LayerFE> layerFE{new StrictMock<mock::LayerFE>()};
+
+    StrictMock<mock::Layer> otherLayer;
+
+    {
+        // 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(layer, layerFE);
+        EXPECT_NE(existingOutputLayer, result.get());
+        EXPECT_TRUE(result.get() != nullptr);
+        EXPECT_EQ(layer.get(), &result->getLayer());
+        EXPECT_EQ(layerFE.get(), &result->getLayerFE());
+
+        // The entries in the ordered array should be unchanged.
+        auto& outputLayers = mOutput.getOutputLayersOrderedByZ();
+        EXPECT_EQ(nullptr, outputLayers[0].get());
+        EXPECT_EQ(existingOutputLayer, outputLayers[1].get());
+    }
+
+    {
+        // 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(layer, layerFE);
+        EXPECT_EQ(existingOutputLayer, result.get());
+
+        // The corresponding entry in the ordered array should be cleared.
+        auto& outputLayers = mOutput.getOutputLayersOrderedByZ();
+        EXPECT_EQ(nullptr, outputLayers[0].get());
+        EXPECT_EQ(nullptr, outputLayers[1].get());
+    }
+}
+
 } // namespace
 } // namespace android::compositionengine
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 2cf2cd8..35ceedc 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -40,6 +40,8 @@
 #include <compositionengine/CompositionEngine.h>
 #include <compositionengine/Display.h>
 #include <compositionengine/DisplayColorProfile.h>
+#include <compositionengine/Layer.h>
+#include <compositionengine/OutputLayer.h>
 #include <compositionengine/RenderSurface.h>
 #include <compositionengine/impl/OutputCompositionState.h>
 #include <dvr/vr_flinger.h>
@@ -2250,7 +2252,8 @@
             const auto& displayState = display->getState();
             Region opaqueRegion;
             Region dirtyRegion;
-            Vector<sp<Layer>> layersSortedByZ;
+            compositionengine::Output::OutputLayers layersSortedByZ;
+            Vector<sp<Layer>> deprecated_layersSortedByZ;
             Vector<sp<Layer>> layersNeedingFences;
             const ui::Transform& tr = displayState.transform;
             const Rect bounds = displayState.bounds;
@@ -2258,15 +2261,27 @@
                 computeVisibleRegions(displayDevice, dirtyRegion, opaqueRegion);
 
                 mDrawingState.traverseInZOrder([&](Layer* layer) {
+                    auto compositionLayer = layer->getCompositionLayer();
+                    if (compositionLayer == nullptr) {
+                        return;
+                    }
+
                     bool hwcLayerDestroyed = false;
                     const auto displayId = displayDevice->getId();
+                    sp<compositionengine::LayerFE> layerFE = compositionLayer->getLayerFE();
+                    LOG_ALWAYS_FATAL_IF(layerFE.get() == nullptr);
+
                     if (display->belongsInOutput(layer->getLayerStack(),
                                                  layer->getPrimaryDisplayOnly())) {
                         Region drawRegion(tr.transform(
                                 layer->visibleNonTransparentRegion));
                         drawRegion.andSelf(bounds);
                         if (!drawRegion.isEmpty()) {
-                            layersSortedByZ.add(layer);
+                            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
@@ -2292,7 +2307,10 @@
                     }
                 });
             }
-            displayDevice->setVisibleLayersSortedByZ(layersSortedByZ);
+
+            display->setOutputLayersOrderedByZ(std::move(layersSortedByZ));
+
+            displayDevice->setVisibleLayersSortedByZ(deprecated_layersSortedByZ);
             displayDevice->setLayersNeedingFences(layersNeedingFences);
 
             Region undefinedRegion{bounds};