Merge "Revert "Revert "Revert "SF: Remove refresh_rate_switching flag.""""
diff --git a/libs/bufferqueueconverter/Android.bp b/libs/bufferqueueconverter/Android.bp
new file mode 100644
index 0000000..bab2674
--- /dev/null
+++ b/libs/bufferqueueconverter/Android.bp
@@ -0,0 +1,28 @@
+cc_library_headers {
+    name: "libbufferqueueconverter_headers",
+    vendor_available: true,
+    export_include_dirs: ["include"],
+}
+
+cc_library_shared {
+    name: "libbufferqueueconverter",
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
+    double_loadable: true,
+
+    srcs: [
+        "BufferQueueConverter.cpp",
+    ],
+
+    shared_libs: [
+        "libgui",
+        "libui",
+        "libutils",
+        "libbinder",
+        "libbase",
+        "liblog",
+    ],
+    export_include_dirs: ["include"],
+}
diff --git a/libs/bufferqueueconverter/BufferQueueConverter.cpp b/libs/bufferqueueconverter/BufferQueueConverter.cpp
new file mode 100644
index 0000000..b1896fa
--- /dev/null
+++ b/libs/bufferqueueconverter/BufferQueueConverter.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2020 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 <gui/Surface.h>
+#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h>
+
+#include "include/bufferqueueconverter/BufferQueueConverter.h"
+
+
+using ::android::Surface;
+using ::android::IGraphicBufferProducer;
+using ::android::hardware::graphics::bufferqueue::V2_0::utils::H2BGraphicBufferProducer;
+
+
+namespace android {
+
+struct SurfaceHolder {
+    sp<Surface> surface;
+    SurfaceHolder(const sp<Surface>& s) : surface(s) {}
+};
+
+/**
+ * Custom deleter for SurfaceHolder unique pointer
+ */
+void destroySurfaceHolder(SurfaceHolder* surfaceHolder) {
+    delete surfaceHolder;
+}
+
+
+SurfaceHolderUniquePtr getSurfaceFromHGBP(const sp<HGraphicBufferProducer>& token) {
+    if (token == nullptr) {
+        ALOGE("Passed IGraphicBufferProducer handle is invalid.");
+        return SurfaceHolderUniquePtr(nullptr, nullptr);
+    }
+
+    sp<IGraphicBufferProducer> bufferProducer = new H2BGraphicBufferProducer(token);
+    if (bufferProducer == nullptr) {
+        ALOGE("Failed to get IGraphicBufferProducer.");
+        return SurfaceHolderUniquePtr(nullptr, nullptr);
+    }
+
+    sp<Surface> newSurface(new Surface(bufferProducer, true));
+    if (newSurface == nullptr) {
+        ALOGE("Failed to create Surface from HGBP.");
+        return SurfaceHolderUniquePtr(nullptr, nullptr);
+    }
+
+    return SurfaceHolderUniquePtr(new SurfaceHolder(newSurface), destroySurfaceHolder);
+}
+
+
+ANativeWindow* getNativeWindow(SurfaceHolder* handle) {
+    if (handle == nullptr) {
+        ALOGE("SurfaceHolder is invalid.");
+        return nullptr;
+    }
+
+    return static_cast<ANativeWindow*>(handle->surface.get());
+}
+
+} // namespace android
diff --git a/libs/bufferqueueconverter/include/bufferqueueconverter/BufferQueueConverter.h b/libs/bufferqueueconverter/include/bufferqueueconverter/BufferQueueConverter.h
new file mode 100644
index 0000000..84bceba
--- /dev/null
+++ b/libs/bufferqueueconverter/include/bufferqueueconverter/BufferQueueConverter.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2020 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.
+ */
+
+#ifndef ANDROID_BUFFER_QUEUE_CONVERTER_H
+#define ANDROID_BUFFER_QUEUE_CONVERTER_H
+
+#include <gui/IGraphicBufferProducer.h>
+#include <android/native_window.h>
+
+using ::android::sp;
+using HGraphicBufferProducer =
+      ::android::hardware::graphics::bufferqueue::V2_0::IGraphicBufferProducer;
+
+namespace android {
+    /**
+     * Opaque handle for a data structure holding Surface.
+     */
+    typedef struct SurfaceHolder SurfaceHolder;
+
+    /**
+     * SurfaceHolder unique pointer type
+     */
+    using SurfaceHolderUniquePtr = std::unique_ptr<SurfaceHolder, void(*)(SurfaceHolder*)>;
+
+    /**
+     * Returns a SurfaceHolder that wraps a Surface generated from a given HGBP.
+     *
+     * @param  token         Hardware IGraphicBufferProducer to create a
+     *                       Surface.
+     * @return SurfaceHolder Unique pointer to created SurfaceHolder object.
+     */
+    SurfaceHolderUniquePtr getSurfaceFromHGBP(const sp<HGraphicBufferProducer>& token);
+
+    /**
+     * Returns ANativeWindow pointer from a given SurfaceHolder.  Returned
+     * pointer is valid only while the containing SurfaceHolder is alive.
+     *
+     * @param  surfaceHolder  SurfaceHolder to generate a native window.
+     * @return ANativeWindow* a pointer to a generated native window.
+     */
+    ANativeWindow* getNativeWindow(SurfaceHolder* surfaceHolder);
+
+} // namespace android
+
+#endif // ANDROID_BUFFER_QUEUE_CONVERTER_H
diff --git a/libs/gui/FrameTimestamps.cpp b/libs/gui/FrameTimestamps.cpp
index c04d907..6749c3c 100644
--- a/libs/gui/FrameTimestamps.cpp
+++ b/libs/gui/FrameTimestamps.cpp
@@ -355,6 +355,10 @@
     mProducerWantsEvents = false;
 }
 
+void ConsumerFrameEventHistory::setProducerWantsEvents() {
+    mProducerWantsEvents = true;
+}
+
 void ConsumerFrameEventHistory::initializeCompositorTiming(
         const CompositorTiming& compositorTiming) {
     mCompositorTiming = compositorTiming;
diff --git a/libs/gui/include/gui/FrameTimestamps.h b/libs/gui/include/gui/FrameTimestamps.h
index df02494..816dd2b 100644
--- a/libs/gui/include/gui/FrameTimestamps.h
+++ b/libs/gui/include/gui/FrameTimestamps.h
@@ -207,6 +207,7 @@
     ~ConsumerFrameEventHistory() override;
 
     void onDisconnect();
+    void setProducerWantsEvents();
 
     void initializeCompositorTiming(const CompositorTiming& compositorTiming);
 
diff --git a/services/automotive/display/CarWindowService.cpp b/services/automotive/display/CarWindowService.cpp
index fbefef0..09ae34a 100644
--- a/services/automotive/display/CarWindowService.cpp
+++ b/services/automotive/display/CarWindowService.cpp
@@ -17,8 +17,6 @@
 #include <utility>
 
 #include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h>
-#include <ui/DisplayConfig.h>
-#include <ui/DisplayState.h>
 
 #include "CarWindowService.h"
 
@@ -48,26 +46,24 @@
             return nullptr;
         }
 
-        DisplayConfig displayConfig;
-        err = SurfaceComposerClient::getActiveDisplayConfig(displayToken, &displayConfig);
+        err = SurfaceComposerClient::getActiveDisplayConfig(displayToken, &mDpyConfig);
         if (err != NO_ERROR) {
             ALOGE("Failed to get active display config");
             return nullptr;
         }
 
-        ui::DisplayState displayState;
-        err = SurfaceComposerClient::getDisplayState(displayToken, &displayState);
+        err = SurfaceComposerClient::getDisplayState(displayToken, &mDpyState);
         if (err != NO_ERROR) {
             ALOGE("Failed to get display state");
             return nullptr;
         }
 
-        const ui::Size& resolution = displayConfig.resolution;
+        const ui::Size& resolution = mDpyConfig.resolution;
         auto width = resolution.getWidth();
         auto height = resolution.getHeight();
 
-        if (displayState.orientation == ui::ROTATION_90 ||
-            displayState.orientation == ui::ROTATION_270) {
+        if (mDpyState.orientation == ui::ROTATION_90 ||
+            mDpyState.orientation == ui::ROTATION_270) {
             std::swap(width, height);
         }
 
diff --git a/services/automotive/display/include/CarWindowService.h b/services/automotive/display/include/CarWindowService.h
index 3290cc7..a32ed7c 100644
--- a/services/automotive/display/include/CarWindowService.h
+++ b/services/automotive/display/include/CarWindowService.h
@@ -20,6 +20,8 @@
 #include <gui/IGraphicBufferProducer.h>
 #include <gui/Surface.h>
 #include <gui/SurfaceComposerClient.h>
+#include <ui/DisplayConfig.h>
+#include <ui/DisplayState.h>
 
 namespace android {
 namespace frameworks {
@@ -37,11 +39,23 @@
     Return<sp<IGraphicBufferProducer>> getIGraphicBufferProducer() override;
     Return<bool> showWindow() override;
     Return<bool> hideWindow() override;
+    Return<void> getDisplayInfo(getDisplayInfo_cb _info_cb) override {
+        HwDisplayConfig cfg;
+        cfg.setToExternal((uint8_t*)&mDpyConfig, sizeof(DisplayConfig));
+
+        HwDisplayState state;
+        state.setToExternal((uint8_t*)&mDpyState, sizeof(DisplayState));
+
+       _info_cb(cfg, state);
+        return hardware::Void();
+    }
 
 private:
     sp<android::Surface> mSurface;
     sp<android::SurfaceComposerClient> mSurfaceComposerClient;
     sp<android::SurfaceControl> mSurfaceControl;
+    DisplayConfig mDpyConfig;
+    ui::DisplayState mDpyState;
 };
 }  // namespace implementation
 }  // namespace V1_0
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 35d0215..f4f45be 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -26,8 +26,6 @@
 #include "BufferLayer.h"
 
 #include <compositionengine/CompositionEngine.h>
-#include <compositionengine/Layer.h>
-#include <compositionengine/LayerCreationArgs.h>
 #include <compositionengine/LayerFECompositionState.h>
 #include <compositionengine/OutputLayer.h>
 #include <compositionengine/impl/OutputLayerCompositionState.h>
@@ -66,8 +64,7 @@
 BufferLayer::BufferLayer(const LayerCreationArgs& args)
       : Layer(args),
         mTextureName(args.textureName),
-        mCompositionLayer{mFlinger->getCompositionEngine().createLayer(
-                compositionengine::LayerCreationArgs{this})} {
+        mCompositionState{mFlinger->getCompositionEngine().createLayerFECompositionState()} {
     ALOGV("Creating Layer %s", getDebugName());
 
     mPremultipliedAlpha = !(args.flags & ISurfaceComposerClient::eNonPremultiplied);
@@ -184,7 +181,7 @@
     bool blackOutLayer = (isProtected() && !targetSettings.supportsProtectedContent) ||
             (isSecure() && !targetSettings.isSecure);
     const State& s(getDrawingState());
-    LayerFE::LayerSettings& layer = *result;
+    compositionengine::LayerFE::LayerSettings& layer = *result;
     if (!blackOutLayer) {
         layer.source.buffer.buffer = mBufferInfo.mBuffer;
         layer.source.buffer.isOpaque = isOpaque(s);
@@ -282,17 +279,29 @@
             mBufferInfo.mBuffer->getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102);
 }
 
-void BufferLayer::latchPerFrameState(
-        compositionengine::LayerFECompositionState& compositionState) const {
-    Layer::latchPerFrameState(compositionState);
+sp<compositionengine::LayerFE> BufferLayer::getCompositionEngineLayerFE() const {
+    return asLayerFE();
+}
+
+compositionengine::LayerFECompositionState* BufferLayer::editCompositionState() {
+    return mCompositionState.get();
+}
+
+const compositionengine::LayerFECompositionState* BufferLayer::getCompositionState() const {
+    return mCompositionState.get();
+}
+
+void BufferLayer::preparePerFrameCompositionState() {
+    Layer::preparePerFrameCompositionState();
 
     // Sideband layers
-    if (compositionState.sidebandStream.get()) {
-        compositionState.compositionType = Hwc2::IComposerClient::Composition::SIDEBAND;
+    auto* compositionState = editCompositionState();
+    if (compositionState->sidebandStream.get()) {
+        compositionState->compositionType = Hwc2::IComposerClient::Composition::SIDEBAND;
     } else {
         // Normal buffer layers
-        compositionState.hdrMetadata = mBufferInfo.mHdrMetadata;
-        compositionState.compositionType = mPotentialCursor
+        compositionState->hdrMetadata = mBufferInfo.mHdrMetadata;
+        compositionState->compositionType = mPotentialCursor
                 ? Hwc2::IComposerClient::Composition::CURSOR
                 : Hwc2::IComposerClient::Composition::DEVICE;
     }
@@ -641,10 +650,6 @@
     return Rect(bufWidth, bufHeight);
 }
 
-std::shared_ptr<compositionengine::Layer> BufferLayer::getCompositionLayer() const {
-    return mCompositionLayer;
-}
-
 FloatRect BufferLayer::computeSourceBounds(const FloatRect& parentBounds) const {
     const State& s(getDrawingState());
 
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index b2398a8..4085b52 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -54,7 +54,8 @@
     // Overriden from Layer
     // -----------------------------------------------------------------------
 public:
-    std::shared_ptr<compositionengine::Layer> getCompositionLayer() const override;
+    sp<compositionengine::LayerFE> getCompositionEngineLayerFE() const override;
+    compositionengine::LayerFECompositionState* editCompositionState() override;
 
     // If we have received a new buffer this frame, we will pass its surface
     // damage down to hardware composer. Otherwise, we must send a region with
@@ -175,8 +176,9 @@
     /*
      * compositionengine::LayerFE overrides
      */
+    const compositionengine::LayerFECompositionState* getCompositionState() const override;
     bool onPreComposition(nsecs_t) override;
-    void latchPerFrameState(compositionengine::LayerFECompositionState&) const override;
+    void preparePerFrameCompositionState() override;
     std::optional<compositionengine::LayerFE::LayerSettings> prepareClientComposition(
             compositionengine::LayerFE::ClientCompositionTargetSettings&) override;
 
@@ -210,7 +212,7 @@
     // and its parent layer is not bounded
     Rect getBufferSize(const State& s) const override;
 
-    std::shared_ptr<compositionengine::Layer> mCompositionLayer;
+    std::unique_ptr<compositionengine::LayerFECompositionState> mCompositionState;
 
     FloatRect computeSourceBounds(const FloatRect& parentBounds) const override;
 };
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 61386f4..3cc803e 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -23,7 +23,6 @@
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 #include "BufferQueueLayer.h"
 
-#include <compositionengine/Layer.h>
 #include <compositionengine/LayerFECompositionState.h>
 #include <gui/BufferQueueConsumer.h>
 #include <system/window.h>
@@ -223,9 +222,9 @@
     if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, false)) {
         // mSidebandStreamChanged was changed to false
         mSidebandStream = mConsumer->getSidebandStream();
-        auto& layerCompositionState = getCompositionLayer()->editFEState();
-        layerCompositionState.sidebandStream = mSidebandStream;
-        if (layerCompositionState.sidebandStream != nullptr) {
+        auto* layerCompositionState = editCompositionState();
+        layerCompositionState->sidebandStream = mSidebandStream;
+        if (layerCompositionState->sidebandStream != nullptr) {
             setTransactionFlags(eTransactionNeeded);
             mFlinger->setTransactionFlags(eTraversalNeeded);
         }
@@ -359,8 +358,8 @@
     mPreviousBufferId = getCurrentBufferId();
     mBufferInfo.mBuffer =
             mConsumer->getCurrentBuffer(&mBufferInfo.mBufferSlot, &mBufferInfo.mFence);
-    auto& layerCompositionState = getCompositionLayer()->editFEState();
-    layerCompositionState.buffer = mBufferInfo.mBuffer;
+    auto* layerCompositionState = editCompositionState();
+    layerCompositionState->buffer = mBufferInfo.mBuffer;
 
     if (mBufferInfo.mBuffer == nullptr) {
         // this can only happen if the very first buffer was rejected.
@@ -380,18 +379,19 @@
     return NO_ERROR;
 }
 
-void BufferQueueLayer::latchPerFrameState(
-        compositionengine::LayerFECompositionState& compositionState) const {
-    BufferLayer::latchPerFrameState(compositionState);
-    if (compositionState.compositionType == Hwc2::IComposerClient::Composition::SIDEBAND) {
+void BufferQueueLayer::preparePerFrameCompositionState() {
+    BufferLayer::preparePerFrameCompositionState();
+
+    auto* compositionState = editCompositionState();
+    if (compositionState->compositionType == Hwc2::IComposerClient::Composition::SIDEBAND) {
         return;
     }
 
-    compositionState.buffer = mBufferInfo.mBuffer;
-    compositionState.bufferSlot = (mBufferInfo.mBufferSlot == BufferQueue::INVALID_BUFFER_SLOT)
+    compositionState->buffer = mBufferInfo.mBuffer;
+    compositionState->bufferSlot = (mBufferInfo.mBufferSlot == BufferQueue::INVALID_BUFFER_SLOT)
             ? 0
             : mBufferInfo.mBufferSlot;
-    compositionState.acquireFence = mBufferInfo.mFence;
+    compositionState->acquireFence = mBufferInfo.mFence;
 }
 
 // -----------------------------------------------------------------------
diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h
index 598bc6b..626af4b 100644
--- a/services/surfaceflinger/BufferQueueLayer.h
+++ b/services/surfaceflinger/BufferQueueLayer.h
@@ -85,7 +85,7 @@
     status_t updateActiveBuffer() override;
     status_t updateFrameNumber(nsecs_t latchTime) override;
 
-    void latchPerFrameState(compositionengine::LayerFECompositionState&) const override;
+    void preparePerFrameCompositionState() override;
     sp<Layer> createClone() override;
 
     void onFrameAvailable(const BufferItem& item);
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index ed18901..29688da 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -27,7 +27,6 @@
 
 #include <limits>
 
-#include <compositionengine/Layer.h>
 #include <compositionengine/LayerFECompositionState.h>
 #include <gui/BufferQueue.h>
 #include <private/gui/SyncFeatures.h>
@@ -464,9 +463,8 @@
     if (mSidebandStreamChanged.exchange(false)) {
         const State& s(getDrawingState());
         // mSidebandStreamChanged was true
-        LOG_ALWAYS_FATAL_IF(!getCompositionLayer());
         mSidebandStream = s.sidebandStream;
-        getCompositionLayer()->editFEState().sidebandStream = mSidebandStream;
+        editCompositionState()->sidebandStream = mSidebandStream;
         if (mSidebandStream != nullptr) {
             setTransactionFlags(eTransactionNeeded);
             mFlinger->setTransactionFlags(eTraversalNeeded);
@@ -573,8 +571,7 @@
     mPreviousBufferId = getCurrentBufferId();
     mBufferInfo.mBuffer = s.buffer;
     mBufferInfo.mFence = s.acquireFence;
-    auto& layerCompositionState = getCompositionLayer()->editFEState();
-    layerCompositionState.buffer = mBufferInfo.mBuffer;
+    editCompositionState()->buffer = mBufferInfo.mBuffer;
 
     return NO_ERROR;
 }
@@ -590,16 +587,17 @@
     return NO_ERROR;
 }
 
-void BufferStateLayer::latchPerFrameState(
-        compositionengine::LayerFECompositionState& compositionState) const {
-    BufferLayer::latchPerFrameState(compositionState);
-    if (compositionState.compositionType == Hwc2::IComposerClient::Composition::SIDEBAND) {
+void BufferStateLayer::preparePerFrameCompositionState() {
+    BufferLayer::preparePerFrameCompositionState();
+
+    auto* compositionState = editCompositionState();
+    if (compositionState->compositionType == Hwc2::IComposerClient::Composition::SIDEBAND) {
         return;
     }
 
-    compositionState.buffer = mBufferInfo.mBuffer;
-    compositionState.bufferSlot = mBufferInfo.mBufferSlot;
-    compositionState.acquireFence = mBufferInfo.mFence;
+    compositionState->buffer = mBufferInfo.mBuffer;
+    compositionState->bufferSlot = mBufferInfo.mBufferSlot;
+    compositionState->acquireFence = mBufferInfo.mFence;
 }
 
 void BufferStateLayer::HwcSlotGenerator::bufferErased(const client_cache_t& clientCacheId) {
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 03d9684..57ff8bc 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -128,7 +128,7 @@
     status_t updateActiveBuffer() override;
     status_t updateFrameNumber(nsecs_t latchTime) override;
 
-    void latchPerFrameState(compositionengine::LayerFECompositionState&) const override;
+    void preparePerFrameCompositionState() override;
     sp<Layer> createClone() override;
 
     // Crop that applies to the buffer
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index dbdfd5b..83050c4 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -29,8 +29,6 @@
 #include <sys/types.h>
 
 #include <compositionengine/CompositionEngine.h>
-#include <compositionengine/Layer.h>
-#include <compositionengine/LayerCreationArgs.h>
 #include <compositionengine/LayerFECompositionState.h>
 #include <renderengine/RenderEngine.h>
 #include <ui/GraphicBuffer.h>
@@ -45,8 +43,7 @@
 
 ColorLayer::ColorLayer(const LayerCreationArgs& args)
       : Layer(args),
-        mCompositionLayer{mFlinger->getCompositionEngine().createLayer(
-                compositionengine::LayerCreationArgs{this})} {}
+        mCompositionState{mFlinger->getCompositionEngine().createLayerFECompositionState()} {}
 
 ColorLayer::~ColorLayer() = default;
 
@@ -91,16 +88,24 @@
     return true;
 }
 
-void ColorLayer::latchPerFrameState(
-        compositionengine::LayerFECompositionState& compositionState) const {
-    Layer::latchPerFrameState(compositionState);
+void ColorLayer::preparePerFrameCompositionState() {
+    Layer::preparePerFrameCompositionState();
 
-    compositionState.color = getColor();
-    compositionState.compositionType = Hwc2::IComposerClient::Composition::SOLID_COLOR;
+    auto* compositionState = editCompositionState();
+    compositionState->color = getColor();
+    compositionState->compositionType = Hwc2::IComposerClient::Composition::SOLID_COLOR;
 }
 
-std::shared_ptr<compositionengine::Layer> ColorLayer::getCompositionLayer() const {
-    return mCompositionLayer;
+sp<compositionengine::LayerFE> ColorLayer::getCompositionEngineLayerFE() const {
+    return asLayerFE();
+}
+
+compositionengine::LayerFECompositionState* ColorLayer::editCompositionState() {
+    return mCompositionState.get();
+}
+
+const compositionengine::LayerFECompositionState* ColorLayer::getCompositionState() const {
+    return mCompositionState.get();
 }
 
 bool ColorLayer::isOpaque(const Layer::State& s) const {
diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h
index 9246eb2..4deb162 100644
--- a/services/surfaceflinger/ColorLayer.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -28,7 +28,8 @@
     explicit ColorLayer(const LayerCreationArgs&);
     ~ColorLayer() override;
 
-    std::shared_ptr<compositionengine::Layer> getCompositionLayer() const override;
+    sp<compositionengine::LayerFE> getCompositionEngineLayerFE() const override;
+    compositionengine::LayerFECompositionState* editCompositionState() override;
 
     const char* getType() const override { return "ColorLayer"; }
     bool isVisible() const override;
@@ -45,11 +46,12 @@
     /*
      * compositionengine::LayerFE overrides
      */
-    void latchPerFrameState(compositionengine::LayerFECompositionState&) const override;
+    const compositionengine::LayerFECompositionState* getCompositionState() const override;
+    void preparePerFrameCompositionState() override;
     std::optional<compositionengine::LayerFE::LayerSettings> prepareClientComposition(
             compositionengine::LayerFE::ClientCompositionTargetSettings&) override;
 
-    std::shared_ptr<compositionengine::Layer> mCompositionLayer;
+    std::unique_ptr<compositionengine::LayerFECompositionState> mCompositionState;
 
     sp<Layer> createClone() override;
 };
diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp
index a634f2f..2792290 100644
--- a/services/surfaceflinger/CompositionEngine/Android.bp
+++ b/services/surfaceflinger/CompositionEngine/Android.bp
@@ -51,7 +51,6 @@
         "src/DisplaySurface.cpp",
         "src/DumpHelpers.cpp",
         "src/HwcBufferCache.cpp",
-        "src/Layer.cpp",
         "src/LayerFECompositionState.cpp",
         "src/Output.cpp",
         "src/OutputCompositionState.cpp",
@@ -71,7 +70,6 @@
         "mock/Display.cpp",
         "mock/DisplayColorProfile.cpp",
         "mock/DisplaySurface.cpp",
-        "mock/Layer.cpp",
         "mock/LayerFE.cpp",
         "mock/NativeWindow.cpp",
         "mock/Output.cpp",
@@ -96,7 +94,6 @@
         "tests/DisplayColorProfileTest.cpp",
         "tests/DisplayTest.cpp",
         "tests/HwcBufferCacheTest.cpp",
-        "tests/LayerTest.cpp",
         "tests/MockHWC2.cpp",
         "tests/MockHWComposer.cpp",
         "tests/MockPowerAdvisor.cpp",
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h
index e3650f3..3faa068 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h
@@ -32,11 +32,11 @@
 namespace compositionengine {
 
 class Display;
-class Layer;
 
 struct CompositionRefreshArgs;
 struct DisplayCreationArgs;
 struct LayerCreationArgs;
+struct LayerFECompositionState;
 
 /**
  * Encapsulates all the interfaces and implementation details for performing
@@ -48,7 +48,8 @@
 
     // Create a composition Display
     virtual std::shared_ptr<Display> createDisplay(const DisplayCreationArgs&) = 0;
-    virtual std::shared_ptr<Layer> createLayer(const LayerCreationArgs&) = 0;
+    virtual std::unique_ptr<compositionengine::LayerFECompositionState>
+    createLayerFECompositionState() = 0;
 
     virtual HWComposer& getHwComposer() const = 0;
     virtual void setHwComposer(std::unique_ptr<HWComposer>) = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h
index 90158c7..4a0d6ee 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionRefreshArgs.h
@@ -21,15 +21,14 @@
 #include <vector>
 
 #include <compositionengine/Display.h>
-#include <compositionengine/Layer.h>
+#include <compositionengine/LayerFE.h>
 #include <compositionengine/OutputColorSetting.h>
 #include <math/mat4.h>
 
 namespace android::compositionengine {
 
-using Layers = std::vector<std::shared_ptr<compositionengine::Layer>>;
+using Layers = std::vector<sp<compositionengine::LayerFE>>;
 using Outputs = std::vector<std::shared_ptr<compositionengine::Output>>;
-using RawLayers = std::vector<compositionengine::Layer*>;
 
 /**
  * A parameter object for refreshing a set of outputs
@@ -44,7 +43,7 @@
     Layers layers;
 
     // All the layers that have queued updates.
-    RawLayers layersWithQueuedFrames;
+    Layers layersWithQueuedFrames;
 
     // If true, forces the entire display to be considered dirty and repainted
     bool repaintEverything{false};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Layer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Layer.h
deleted file mode 100644
index 1259c52..0000000
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Layer.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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 <cstdint>
-#include <string>
-
-#include <utils/StrongPointer.h>
-
-namespace android::compositionengine {
-
-class Display;
-class LayerFE;
-
-struct LayerFECompositionState;
-
-/**
- * A layer contains the output-independent composition state for a front-end
- * Layer
- */
-class Layer {
-public:
-    virtual ~Layer();
-
-    // Gets the front-end interface for this layer.  Can return nullptr if the
-    // front-end layer no longer exists.
-    virtual sp<LayerFE> getLayerFE() const = 0;
-
-    // Gets the raw front-end composition state data for the layer
-    // TODO(lpique): Make this protected once it is only internally called.
-    virtual const LayerFECompositionState& getFEState() const = 0;
-
-    // Allows mutable access to the raw front-end composition state
-    // TODO(lpique): Make this protected once it is only internally called.
-    virtual LayerFECompositionState& editFEState() = 0;
-
-    // Debugging
-    virtual void dump(std::string& result) const = 0;
-};
-
-} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerCreationArgs.h
deleted file mode 100644
index db3312b..0000000
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerCreationArgs.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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/RefBase.h>
-
-namespace android::compositionengine {
-
-class CompositionEngine;
-class LayerFE;
-
-/**
- * A parameter object for creating Layer instances
- */
-struct LayerCreationArgs {
-    // A weak pointer to the front-end layer instance that the new layer will
-    // represent.
-    wp<LayerFE> layerFE;
-};
-
-} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
index 26442d9..912dffd 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
@@ -44,6 +44,9 @@
 // of the front-end layer
 class LayerFE : public virtual RefBase {
 public:
+    // Gets the raw front-end composition state data for the layer
+    virtual const LayerFECompositionState* getCompositionState() const = 0;
+
     // Called before composition starts. Should return true if this layer has
     // pending updates which would require an extra display refresh cycle to
     // process.
@@ -60,19 +63,18 @@
         // content (buffer or color) state for the layer.
         GeometryAndContent,
 
-        // Gets the per frame content (buffer or color) state the layer.
+        // Gets the per frame content (buffer or color) state for the layer.
         Content,
+
+        // Gets the cursor state for the layer.
+        Cursor,
     };
 
-    // Latches the output-independent composition state for the layer. The
+    // Prepares the output-independent composition state for the layer. The
     // StateSubset argument selects what portion of the state is actually needed
     // by the CompositionEngine code, since computing everything may be
     // expensive.
-    virtual void latchCompositionState(LayerFECompositionState&, StateSubset) const = 0;
-
-    // Latches the minimal bit of state for the cursor for a fast asynchronous
-    // update.
-    virtual void latchCursorCompositionState(LayerFECompositionState&) const = 0;
+    virtual void prepareCompositionState(StateSubset) = 0;
 
     struct ClientCompositionTargetSettings {
         // The clip region, or visible region that is being rendered to
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
index 1af99c5..40cd3e0 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
@@ -162,8 +162,10 @@
     // The output-independent frame for the cursor
     Rect cursorFrame;
 
+    virtual ~LayerFECompositionState();
+
     // Debugging
-    void dump(std::string& out) const;
+    virtual void dump(std::string& out) const;
 };
 
 } // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
index 4ab7082..9622e78 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
@@ -41,7 +41,6 @@
 namespace android::compositionengine {
 
 class DisplayColorProfile;
-class Layer;
 class LayerFE;
 class RenderSurface;
 class OutputLayer;
@@ -216,18 +215,17 @@
     virtual bool belongsInOutput(std::optional<uint32_t> layerStackId, bool internalOnly) const = 0;
 
     // Determines if a layer belongs to the output.
-    virtual bool belongsInOutput(const Layer*) const = 0;
+    virtual bool belongsInOutput(const sp<LayerFE>&) 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;
+    virtual OutputLayer* getOutputLayerForLayer(const sp<LayerFE>&) const = 0;
 
     // Immediately clears all layers from the output.
     virtual void clearOutputLayers() = 0;
 
     // For tests use only. Creates and appends an OutputLayer into the output.
-    virtual OutputLayer* injectOutputLayerForTest(const std::shared_ptr<Layer>&,
-                                                  const sp<LayerFE>&) = 0;
+    virtual OutputLayer* injectOutputLayerForTest(const sp<LayerFE>&) = 0;
 
     // Gets the count of output layers managed by this output
     virtual size_t getOutputLayerCount() const = 0;
@@ -257,7 +255,7 @@
 
     virtual void rebuildLayerStacks(const CompositionRefreshArgs&, LayerFESet&) = 0;
     virtual void collectVisibleLayers(const CompositionRefreshArgs&, CoverageState&) = 0;
-    virtual void ensureOutputLayerIfVisible(std::shared_ptr<Layer>, CoverageState&) = 0;
+    virtual void ensureOutputLayerIfVisible(sp<LayerFE>&, CoverageState&) = 0;
     virtual void setReleasedLayers(const CompositionRefreshArgs&) = 0;
 
     virtual void updateAndWriteCompositionState(const CompositionRefreshArgs&) = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h
index a466561..007b0e8 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h
@@ -41,7 +41,6 @@
 
 class CompositionEngine;
 class Output;
-class Layer;
 class LayerFE;
 
 namespace impl {
@@ -61,9 +60,6 @@
     // 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;
 
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h
index 450b9ca..386808d 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h
@@ -27,8 +27,8 @@
 
     std::shared_ptr<compositionengine::Display> createDisplay(
             const compositionengine::DisplayCreationArgs&) override;
-    std::shared_ptr<compositionengine::Layer> createLayer(
-            const compositionengine::LayerCreationArgs&) override;
+    std::unique_ptr<compositionengine::LayerFECompositionState> createLayerFECompositionState()
+            override;
 
     HWComposer& getHwComposer() const override;
     void setHwComposer(std::unique_ptr<HWComposer>) override;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
index 39acb37..fb597ce 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
@@ -73,8 +73,7 @@
     virtual void applyLayerRequestsToLayers(const LayerRequests&);
 
     // Internal
-    std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(
-            const std::shared_ptr<compositionengine::Layer>&, const sp<LayerFE>&) const;
+    std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(const sp<LayerFE>&) const;
 
 private:
     const bool mIsVirtual;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Layer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Layer.h
deleted file mode 100644
index 46489fb..0000000
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Layer.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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/Layer.h>
-#include <compositionengine/LayerCreationArgs.h>
-#include <utils/StrongPointer.h>
-
-namespace android::compositionengine {
-
-struct LayerCreationArgs;
-
-namespace impl {
-
-// The implementation class contains the common implementation, but does not
-// actually contain the final layer state.
-class Layer : public virtual compositionengine::Layer {
-public:
-    ~Layer() override;
-
-    // compositionengine::Layer overrides
-    void dump(std::string&) const override;
-
-protected:
-    // Implemented by the final implementation for the final state it uses.
-    virtual void dumpFEState(std::string&) const = 0;
-};
-
-// This template factory function standardizes the implementation details of the
-// final class using the types actually required by the implementation. This is
-// not possible to do in the base class as those types may not even be visible
-// to the base code.
-template <typename BaseLayer, typename LayerCreationArgs>
-std::shared_ptr<BaseLayer> createLayerTemplated(const LayerCreationArgs& args) {
-    class Layer final : public BaseLayer {
-    public:
-// Clang incorrectly complains that these are unused.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunused-local-typedef"
-        using LayerFE = std::remove_pointer_t<decltype(
-                std::declval<decltype(std::declval<LayerCreationArgs>().layerFE)>().unsafe_get())>;
-        using LayerFECompositionState = std::remove_const_t<
-                std::remove_reference_t<decltype(std::declval<BaseLayer>().getFEState())>>;
-#pragma clang diagnostic pop
-
-        explicit Layer(const LayerCreationArgs& args) : mLayerFE(args.layerFE) {}
-        ~Layer() override = default;
-
-    private:
-        // compositionengine::Layer overrides
-        sp<compositionengine::LayerFE> getLayerFE() const override { return mLayerFE.promote(); }
-        const LayerFECompositionState& getFEState() const override { return mFrontEndState; }
-        LayerFECompositionState& editFEState() override { return mFrontEndState; }
-
-        // compositionengine::impl::Layer overrides
-        void dumpFEState(std::string& out) const override { mFrontEndState.dump(out); }
-
-        const wp<LayerFE> mLayerFE;
-        LayerFECompositionState mFrontEndState;
-    };
-
-    return std::make_shared<Layer>(args);
-}
-
-std::shared_ptr<Layer> createLayer(const LayerCreationArgs&);
-
-} // namespace impl
-} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
index 8dc440c..d41337c 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
@@ -60,10 +60,9 @@
 
     Region getDirtyRegion(bool repaintEverything) const override;
     bool belongsInOutput(std::optional<uint32_t>, bool) const override;
-    bool belongsInOutput(const compositionengine::Layer*) const override;
+    bool belongsInOutput(const sp<LayerFE>&) const override;
 
-    compositionengine::OutputLayer* getOutputLayerForLayer(
-            compositionengine::Layer*) const override;
+    compositionengine::OutputLayer* getOutputLayerForLayer(const sp<LayerFE>&) const override;
 
     void setReleasedLayers(ReleasedLayers&&) override;
 
@@ -73,7 +72,7 @@
     void rebuildLayerStacks(const CompositionRefreshArgs&, LayerFESet&) override;
     void collectVisibleLayers(const CompositionRefreshArgs&,
                               compositionengine::Output::CoverageState&) override;
-    void ensureOutputLayerIfVisible(std::shared_ptr<compositionengine::Layer>,
+    void ensureOutputLayerIfVisible(sp<compositionengine::LayerFE>&,
                                     compositionengine::Output::CoverageState&) override;
     void setReleasedLayers(const compositionengine::CompositionRefreshArgs&) override;
 
@@ -94,9 +93,9 @@
     void setRenderSurfaceForTest(std::unique_ptr<compositionengine::RenderSurface>);
 
 protected:
-    std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(
-            const std::shared_ptr<compositionengine::Layer>&, const sp<LayerFE>&) const;
-    std::optional<size_t> findCurrentOutputLayerForLayer(compositionengine::Layer*) const;
+    std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(const sp<LayerFE>&) const;
+    std::optional<size_t> findCurrentOutputLayerForLayer(
+            const sp<compositionengine::LayerFE>&) const;
     void chooseCompositionStrategy() override;
     bool getSkipColorTransform() const override;
     compositionengine::Output::FrameFences presentAndGetFrameFences() override;
@@ -108,11 +107,9 @@
     void dumpBase(std::string&) const;
 
     // Implemented by the final implementation for the final state it uses.
-    virtual compositionengine::OutputLayer* ensureOutputLayer(
-            std::optional<size_t>, const std::shared_ptr<compositionengine::Layer>&,
-            const sp<LayerFE>&) = 0;
-    virtual compositionengine::OutputLayer* injectOutputLayerForTest(
-            const std::shared_ptr<compositionengine::Layer>&, const sp<LayerFE>&) = 0;
+    virtual compositionengine::OutputLayer* ensureOutputLayer(std::optional<size_t>,
+                                                              const sp<LayerFE>&) = 0;
+    virtual compositionengine::OutputLayer* injectOutputLayerForTest(const sp<LayerFE>&) = 0;
     virtual void finalizePendingOutputLayers() = 0;
     virtual const compositionengine::CompositionEngine& getCompositionEngine() const = 0;
     virtual void dumpState(std::string& out) const = 0;
@@ -181,11 +178,10 @@
         };
 
         OutputLayer* ensureOutputLayer(std::optional<size_t> prevIndex,
-                                       const std::shared_ptr<compositionengine::Layer>& layer,
                                        const sp<LayerFE>& layerFE) {
             auto outputLayer = (prevIndex && *prevIndex <= mCurrentOutputLayersOrderedByZ.size())
                     ? std::move(mCurrentOutputLayersOrderedByZ[*prevIndex])
-                    : BaseOutput::createOutputLayer(layer, layerFE);
+                    : BaseOutput::createOutputLayer(layerFE);
             auto result = outputLayer.get();
             mPendingOutputLayersOrderedByZ.emplace_back(std::move(outputLayer));
             return result;
@@ -202,10 +198,8 @@
 
         void dumpState(std::string& out) const override { mState.dump(out); }
 
-        OutputLayer* injectOutputLayerForTest(
-                const std::shared_ptr<compositionengine::Layer>& layer,
-                const sp<LayerFE>& layerFE) override {
-            auto outputLayer = BaseOutput::createOutputLayer(layer, layerFE);
+        OutputLayer* injectOutputLayerForTest(const sp<LayerFE>& layerFE) override {
+            auto outputLayer = BaseOutput::createOutputLayer(layerFE);
             auto result = outputLayer.get();
             mCurrentOutputLayersOrderedByZ.emplace_back(std::move(outputLayer));
             return result;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h
index 95c8afb..79df9b2 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayer.h
@@ -81,7 +81,6 @@
 // to the base code.
 template <typename BaseOutputLayer>
 std::unique_ptr<BaseOutputLayer> createOutputLayerTemplated(const Output& output,
-                                                            std::shared_ptr<Layer> layer,
                                                             sp<LayerFE> layerFE) {
     class OutputLayer final : public BaseOutputLayer {
     public:
@@ -93,21 +92,18 @@
                 std::remove_reference_t<decltype(std::declval<BaseOutputLayer>().getState())>>;
         using Output = std::remove_const_t<
                 std::remove_reference_t<decltype(std::declval<BaseOutputLayer>().getOutput())>>;
-        using Layer = std::remove_reference_t<decltype(std::declval<BaseOutputLayer>().getLayer())>;
         using LayerFE =
                 std::remove_reference_t<decltype(std::declval<BaseOutputLayer>().getLayerFE())>;
 
 #pragma clang diagnostic pop
 
-        OutputLayer(const Output& output, const std::shared_ptr<Layer>& layer,
-                    const sp<LayerFE>& layerFE)
-              : mOutput(output), mLayer(layer), mLayerFE(layerFE) {}
+        OutputLayer(const Output& output, const sp<LayerFE>& layerFE)
+              : mOutput(output), mLayerFE(layerFE) {}
         ~OutputLayer() override = default;
 
     private:
         // compositionengine::OutputLayer overrides
         const Output& getOutput() const override { return mOutput; }
-        Layer& getLayer() const override { return *mLayer; }
         LayerFE& getLayerFE() const override { return *mLayerFE; }
         const OutputLayerCompositionState& getState() const override { return mState; }
         OutputLayerCompositionState& editState() override { return mState; }
@@ -116,16 +112,14 @@
         void dumpState(std::string& out) const override { mState.dump(out); }
 
         const Output& mOutput;
-        const std::shared_ptr<Layer> mLayer;
         const sp<LayerFE> mLayerFE;
         OutputLayerCompositionState mState;
     };
 
-    return std::make_unique<OutputLayer>(output, layer, layerFE);
+    return std::make_unique<OutputLayer>(output, layerFE);
 }
 
 std::unique_ptr<OutputLayer> createOutputLayer(const compositionengine::Output&,
-                                               const std::shared_ptr<compositionengine::Layer>&,
                                                const sp<LayerFE>&);
 
 } // namespace impl
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h
index 104e20d..f953d0b 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h
@@ -19,7 +19,7 @@
 #include <compositionengine/CompositionEngine.h>
 #include <compositionengine/CompositionRefreshArgs.h>
 #include <compositionengine/DisplayCreationArgs.h>
-#include <compositionengine/LayerCreationArgs.h>
+#include <compositionengine/LayerFECompositionState.h>
 #include <gmock/gmock.h>
 #include <renderengine/RenderEngine.h>
 
@@ -33,7 +33,8 @@
     ~CompositionEngine() override;
 
     MOCK_METHOD1(createDisplay, std::shared_ptr<Display>(const DisplayCreationArgs&));
-    MOCK_METHOD1(createLayer, std::shared_ptr<Layer>(const LayerCreationArgs&));
+    MOCK_METHOD0(createLayerFECompositionState,
+                 std::unique_ptr<compositionengine::LayerFECompositionState>());
 
     MOCK_CONST_METHOD0(getHwComposer, HWComposer&());
     MOCK_METHOD1(setHwComposer, void(std::unique_ptr<HWComposer>));
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Layer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Layer.h
deleted file mode 100644
index 4f03cb4..0000000
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Layer.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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/LayerFECompositionState.h>
-#include <gmock/gmock.h>
-
-namespace android::compositionengine::mock {
-
-class Layer : public compositionengine::Layer {
-public:
-    Layer();
-    virtual ~Layer();
-
-    MOCK_CONST_METHOD0(getLayerFE, sp<LayerFE>());
-
-    MOCK_CONST_METHOD0(getFEState, const LayerFECompositionState&());
-    MOCK_METHOD0(editFEState, LayerFECompositionState&());
-
-    MOCK_CONST_METHOD1(dump, void(std::string&));
-};
-
-} // namespace android::compositionengine::mock
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
index 163e302..5c2ad15 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
@@ -30,11 +30,11 @@
     LayerFE();
     virtual ~LayerFE();
 
+    MOCK_CONST_METHOD0(getCompositionState, const LayerFECompositionState*());
+
     MOCK_METHOD1(onPreComposition, bool(nsecs_t));
 
-    MOCK_CONST_METHOD2(latchCompositionState,
-                       void(LayerFECompositionState&, compositionengine::LayerFE::StateSubset));
-    MOCK_CONST_METHOD1(latchCursorCompositionState, void(LayerFECompositionState&));
+    MOCK_METHOD1(prepareCompositionState, void(compositionengine::LayerFE::StateSubset));
     MOCK_METHOD1(prepareClientComposition,
                  std::optional<LayerSettings>(
                          compositionengine::LayerFE::ClientCompositionTargetSettings&));
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
index 59906b9..346c2d1 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
@@ -18,7 +18,6 @@
 
 #include <compositionengine/CompositionRefreshArgs.h>
 #include <compositionengine/DisplayColorProfile.h>
-#include <compositionengine/Layer.h>
 #include <compositionengine/LayerFE.h>
 #include <compositionengine/Output.h>
 #include <compositionengine/OutputLayer.h>
@@ -62,14 +61,13 @@
 
     MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
     MOCK_CONST_METHOD2(belongsInOutput, bool(std::optional<uint32_t>, bool));
-    MOCK_CONST_METHOD1(belongsInOutput, bool(const compositionengine::Layer*));
+    MOCK_CONST_METHOD1(belongsInOutput, bool(const sp<compositionengine::LayerFE>&));
 
     MOCK_CONST_METHOD1(getOutputLayerForLayer,
-                       compositionengine::OutputLayer*(compositionengine::Layer*));
+                       compositionengine::OutputLayer*(const sp<compositionengine::LayerFE>&));
     MOCK_METHOD0(clearOutputLayers, void());
-    MOCK_METHOD2(injectOutputLayerForTest,
-                 compositionengine::OutputLayer*(const std::shared_ptr<compositionengine::Layer>&,
-                                                 const sp<compositionengine::LayerFE>&));
+    MOCK_METHOD1(injectOutputLayerForTest,
+                 compositionengine::OutputLayer*(const sp<compositionengine::LayerFE>&));
     MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
     MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
 
@@ -84,8 +82,7 @@
                  void(const compositionengine::CompositionRefreshArgs&,
                       compositionengine::Output::CoverageState&));
     MOCK_METHOD2(ensureOutputLayerIfVisible,
-                 void(std::shared_ptr<compositionengine::Layer>,
-                      compositionengine::Output::CoverageState&));
+                 void(sp<compositionengine::LayerFE>&, compositionengine::Output::CoverageState&));
     MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
 
     MOCK_CONST_METHOD1(updateLayerStateFromFE, void(const CompositionRefreshArgs&));
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h
index 631760a..2ecbad8 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/OutputLayer.h
@@ -17,7 +17,6 @@
 #pragma once
 
 #include <compositionengine/CompositionEngine.h>
-#include <compositionengine/Layer.h>
 #include <compositionengine/LayerFE.h>
 #include <compositionengine/Output.h>
 #include <compositionengine/OutputLayer.h>
@@ -34,7 +33,6 @@
     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&());
 
     MOCK_CONST_METHOD0(getState, const impl::OutputLayerCompositionState&());
diff --git a/services/surfaceflinger/CompositionEngine/mock/Layer.cpp b/services/surfaceflinger/CompositionEngine/mock/Layer.cpp
deleted file mode 100644
index 08483cb..0000000
--- a/services/surfaceflinger/CompositionEngine/mock/Layer.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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/Layer.h>
-
-namespace android::compositionengine::mock {
-
-// The Google Mock documentation recommends explicit non-header instantiations
-// for better compile time performance.
-Layer::Layer() = default;
-Layer::~Layer() = default;
-
-} // namespace android::compositionengine::mock
diff --git a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
index aeaa18a..6203dc6 100644
--- a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
@@ -16,10 +16,10 @@
 
 #include <compositionengine/CompositionRefreshArgs.h>
 #include <compositionengine/LayerFE.h>
+#include <compositionengine/LayerFECompositionState.h>
 #include <compositionengine/OutputLayer.h>
 #include <compositionengine/impl/CompositionEngine.h>
 #include <compositionengine/impl/Display.h>
-#include <compositionengine/impl/Layer.h>
 
 #include <renderengine/RenderEngine.h>
 #include <utils/Trace.h>
@@ -51,9 +51,9 @@
     return compositionengine::impl::createDisplay(*this, args);
 }
 
-std::shared_ptr<compositionengine::Layer> CompositionEngine::createLayer(
-        const LayerCreationArgs& args) {
-    return compositionengine::impl::createLayer(args);
+std::unique_ptr<compositionengine::LayerFECompositionState>
+CompositionEngine::createLayerFECompositionState() {
+    return std::make_unique<compositionengine::LayerFECompositionState>();
 }
 
 HWComposer& CompositionEngine::getHwComposer() const {
@@ -120,8 +120,7 @@
         for (auto* layer : output->getOutputLayersOrderedByZ()) {
             if (layer->isHardwareCursor()) {
                 // Latch the cursor composition state from each front-end layer.
-                layer->getLayerFE().latchCursorCompositionState(layer->getLayer().editFEState());
-
+                layer->getLayerFE().prepareCompositionState(LayerFE::StateSubset::Cursor);
                 layer->writeCursorPositionToHWC();
             }
         }
@@ -137,8 +136,7 @@
     mRefreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
     for (auto& layer : args.layers) {
-        sp<compositionengine::LayerFE> layerFE = layer->getLayerFE();
-        if (layerFE && layerFE->onPreComposition(mRefreshStartTime)) {
+        if (layer->onPreComposition(mRefreshStartTime)) {
             needsAnotherUpdate = true;
         }
     }
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index ccd6572..1d8a23f 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -147,9 +147,8 @@
 }
 
 std::unique_ptr<compositionengine::OutputLayer> Display::createOutputLayer(
-        const std::shared_ptr<compositionengine::Layer>& layer,
         const sp<compositionengine::LayerFE>& layerFE) const {
-    auto result = impl::createOutputLayer(*this, layer, layerFE);
+    auto result = impl::createOutputLayer(*this, layerFE);
 
     if (result && mId) {
         auto& hwc = getCompositionEngine().getHwComposer();
@@ -184,16 +183,18 @@
 
     // Any non-null entries in the current list of layers are layers that are no
     // longer going to be visible
-    for (auto* layer : getOutputLayersOrderedByZ()) {
-        if (!layer) {
+    for (auto* outputLayer : getOutputLayersOrderedByZ()) {
+        if (!outputLayer) {
             continue;
         }
 
-        sp<compositionengine::LayerFE> layerFE(&layer->getLayerFE());
+        compositionengine::LayerFE* layerFE = &outputLayer->getLayerFE();
         const bool hasQueuedFrames =
-                std::find(refreshArgs.layersWithQueuedFrames.cbegin(),
-                          refreshArgs.layersWithQueuedFrames.cend(),
-                          &layer->getLayer()) != refreshArgs.layersWithQueuedFrames.cend();
+                std::any_of(refreshArgs.layersWithQueuedFrames.cbegin(),
+                            refreshArgs.layersWithQueuedFrames.cend(),
+                            [layerFE](sp<compositionengine::LayerFE> layerWithQueuedFrames) {
+                                return layerFE == layerWithQueuedFrames.get();
+                            });
 
         if (hasQueuedFrames) {
             releasedLayers.emplace_back(layerFE);
diff --git a/services/surfaceflinger/CompositionEngine/src/Layer.cpp b/services/surfaceflinger/CompositionEngine/src/Layer.cpp
deleted file mode 100644
index ecacaee..0000000
--- a/services/surfaceflinger/CompositionEngine/src/Layer.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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 <android-base/stringprintf.h>
-#include <compositionengine/LayerFE.h>
-#include <compositionengine/LayerFECompositionState.h>
-#include <compositionengine/impl/Layer.h>
-
-namespace android::compositionengine {
-
-Layer::~Layer() = default;
-
-namespace impl {
-
-std::shared_ptr<Layer> createLayer(const LayerCreationArgs& args) {
-    return compositionengine::impl::createLayerTemplated<Layer>(args);
-}
-
-Layer::~Layer() = default;
-
-void Layer::dump(std::string& out) const {
-    auto layerFE = getLayerFE();
-    android::base::StringAppendF(&out, "* compositionengine::Layer %p (%s)\n", this,
-                                 layerFE ? layerFE->getDebugName() : "<unknown>");
-    out.append("    frontend:\n");
-    dumpFEState(out);
-}
-
-} // namespace impl
-} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp b/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp
index 016084f..3e0f803 100644
--- a/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp
@@ -32,6 +32,8 @@
 
 } // namespace
 
+LayerFECompositionState::~LayerFECompositionState() = default;
+
 void LayerFECompositionState::dump(std::string& out) const {
     out.append("      ");
     dumpVal(out, "isSecure", isSecure);
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index ce4b84a..a389bf3 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -20,7 +20,6 @@
 #include <compositionengine/CompositionEngine.h>
 #include <compositionengine/CompositionRefreshArgs.h>
 #include <compositionengine/DisplayColorProfile.h>
-#include <compositionengine/Layer.h>
 #include <compositionengine/LayerFE.h>
 #include <compositionengine/LayerFECompositionState.h>
 #include <compositionengine/RenderSurface.h>
@@ -267,31 +266,26 @@
             (!internalOnly || outputState.layerStackInternal);
 }
 
-bool Output::belongsInOutput(const compositionengine::Layer* layer) const {
-    if (!layer) {
-        return false;
-    }
-
-    const auto& layerFEState = layer->getFEState();
-    return belongsInOutput(layerFEState.layerStackId, layerFEState.internalOnly);
+bool Output::belongsInOutput(const sp<compositionengine::LayerFE>& layerFE) const {
+    const auto* layerFEState = layerFE->getCompositionState();
+    return layerFEState && belongsInOutput(layerFEState->layerStackId, layerFEState->internalOnly);
 }
 
 std::unique_ptr<compositionengine::OutputLayer> Output::createOutputLayer(
-        const std::shared_ptr<compositionengine::Layer>& layer, const sp<LayerFE>& layerFE) const {
-    return impl::createOutputLayer(*this, layer, layerFE);
+        const sp<LayerFE>& layerFE) const {
+    return impl::createOutputLayer(*this, layerFE);
 }
 
-compositionengine::OutputLayer* Output::getOutputLayerForLayer(
-        compositionengine::Layer* layer) const {
-    auto index = findCurrentOutputLayerForLayer(layer);
+compositionengine::OutputLayer* Output::getOutputLayerForLayer(const sp<LayerFE>& layerFE) const {
+    auto index = findCurrentOutputLayerForLayer(layerFE);
     return index ? getOutputLayerOrderedByZByIndex(*index) : nullptr;
 }
 
 std::optional<size_t> Output::findCurrentOutputLayerForLayer(
-        compositionengine::Layer* layer) const {
+        const sp<compositionengine::LayerFE>& layer) const {
     for (size_t i = 0; i < getOutputLayerCount(); i++) {
         auto outputLayer = getOutputLayerOrderedByZByIndex(i);
-        if (outputLayer && &outputLayer->getLayer() == layer) {
+        if (outputLayer && &outputLayer->getLayerFE() == layer.get()) {
             return i;
         }
     }
@@ -354,7 +348,7 @@
     // Evaluate the layers from front to back to determine what is visible. This
     // also incrementally calculates the coverage information for each layer as
     // well as the entire output.
-    for (auto& layer : reversed(refreshArgs.layers)) {
+    for (auto layer : reversed(refreshArgs.layers)) {
         // Incrementally process the coverage for each layer
         ensureOutputLayerIfVisible(layer, coverage);
 
@@ -373,28 +367,29 @@
     }
 }
 
-void Output::ensureOutputLayerIfVisible(std::shared_ptr<compositionengine::Layer> layer,
+void Output::ensureOutputLayerIfVisible(sp<compositionengine::LayerFE>& layerFE,
                                         compositionengine::Output::CoverageState& coverage) {
-    // Note: Converts a wp<LayerFE> to a sp<LayerFE>
-    auto layerFE = layer->getLayerFE();
-    if (layerFE == nullptr) {
-        return;
-    }
-
     // Ensure we have a snapshot of the basic geometry layer state. Limit the
     // snapshots to once per frame for each candidate layer, as layers may
     // appear on multiple outputs.
     if (!coverage.latchedLayers.count(layerFE)) {
         coverage.latchedLayers.insert(layerFE);
-        layerFE->latchCompositionState(layer->editFEState(),
-                                       compositionengine::LayerFE::StateSubset::BasicGeometry);
+        layerFE->prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry);
     }
 
-    // Obtain a read-only reference to the front-end layer state
-    const auto& layerFEState = layer->getFEState();
-
     // Only consider the layers on the given layer stack
-    if (!belongsInOutput(layer.get())) {
+    if (!belongsInOutput(layerFE)) {
+        return;
+    }
+
+    // Obtain a read-only pointer to the front-end layer state
+    const auto* layerFEState = layerFE->getCompositionState();
+    if (CC_UNLIKELY(!layerFEState)) {
+        return;
+    }
+
+    // handle hidden surfaces by setting the visible region to empty
+    if (CC_UNLIKELY(!layerFEState->isVisible)) {
         return;
     }
 
@@ -432,23 +427,18 @@
      */
     Region shadowRegion;
 
-    // handle hidden surfaces by setting the visible region to empty
-    if (CC_UNLIKELY(!layerFEState.isVisible)) {
-        return;
-    }
-
-    const ui::Transform& tr = layerFEState.geomLayerTransform;
+    const ui::Transform& tr = layerFEState->geomLayerTransform;
 
     // Get the visible region
     // TODO(b/121291683): Is it worth creating helper methods on LayerFEState
     // for computations like this?
-    const Rect visibleRect(tr.transform(layerFEState.geomLayerBounds));
+    const Rect visibleRect(tr.transform(layerFEState->geomLayerBounds));
     visibleRegion.set(visibleRect);
 
-    if (layerFEState.shadowRadius > 0.0f) {
+    if (layerFEState->shadowRadius > 0.0f) {
         // if the layer casts a shadow, offset the layers visible region and
         // calculate the shadow region.
-        const auto inset = static_cast<int32_t>(ceilf(layerFEState.shadowRadius) * -1.0f);
+        const auto inset = static_cast<int32_t>(ceilf(layerFEState->shadowRadius) * -1.0f);
         Rect visibleRectWithShadows(visibleRect);
         visibleRectWithShadows.inset(inset, inset, inset, inset);
         visibleRegion.set(visibleRectWithShadows);
@@ -460,10 +450,10 @@
     }
 
     // Remove the transparent area from the visible region
-    if (!layerFEState.isOpaque) {
+    if (!layerFEState->isOpaque) {
         if (tr.preserveRects()) {
             // transform the transparent region
-            transparentRegion = tr.transform(layerFEState.transparentRegionHint);
+            transparentRegion = tr.transform(layerFEState->transparentRegionHint);
         } else {
             // transformation too complex, can't do the
             // transparent region optimization.
@@ -473,7 +463,7 @@
 
     // compute the opaque region
     const auto layerOrientation = tr.getOrientation();
-    if (layerFEState.isOpaque && ((layerOrientation & ui::Transform::ROT_INVALID) == 0)) {
+    if (layerFEState->isOpaque && ((layerOrientation & ui::Transform::ROT_INVALID) == 0)) {
         // If we one of the simple category of transforms (0/90/180/270 rotation
         // + any flip), then the opaque region is the layer's footprint.
         // Otherwise we don't try and compute the opaque region since there may
@@ -497,7 +487,7 @@
 
     // Get coverage information for the layer as previously displayed,
     // also taking over ownership from mOutputLayersorderedByZ.
-    auto prevOutputLayerIndex = findCurrentOutputLayerForLayer(layer.get());
+    auto prevOutputLayerIndex = findCurrentOutputLayerForLayer(layerFE);
     auto prevOutputLayer =
             prevOutputLayerIndex ? getOutputLayerOrderedByZByIndex(*prevOutputLayerIndex) : nullptr;
 
@@ -511,7 +501,7 @@
 
     // compute this layer's dirty region
     Region dirty;
-    if (layerFEState.contentDirty) {
+    if (layerFEState->contentDirty) {
         // we need to invalidate the whole region
         dirty = visibleRegion;
         // as well, as the old visible region
@@ -558,7 +548,7 @@
 
     // The layer is visible. Either reuse the existing outputLayer if we have
     // one, or create a new one if we do not.
-    auto result = ensureOutputLayer(prevOutputLayerIndex, layer, layerFE);
+    auto result = ensureOutputLayer(prevOutputLayerIndex, layerFE);
 
     // Store the layer coverage information into the layer state as some of it
     // is useful later.
@@ -577,10 +567,9 @@
 
 void Output::updateLayerStateFromFE(const CompositionRefreshArgs& args) const {
     for (auto* layer : getOutputLayersOrderedByZ()) {
-        layer->getLayerFE().latchCompositionState(layer->getLayer().editFEState(),
-                                                  args.updatingGeometryThisFrame
-                                                          ? LayerFE::StateSubset::GeometryAndContent
-                                                          : LayerFE::StateSubset::Content);
+        layer->getLayerFE().prepareCompositionState(
+                args.updatingGeometryThisFrame ? LayerFE::StateSubset::GeometryAndContent
+                                               : LayerFE::StateSubset::Content);
     }
 }
 
@@ -613,7 +602,7 @@
 compositionengine::OutputLayer* Output::findLayerRequestingBackgroundComposition() const {
     compositionengine::OutputLayer* layerRequestingBgComposition = nullptr;
     for (auto* layer : getOutputLayersOrderedByZ()) {
-        if (layer->getLayer().getFEState().backgroundBlurRadius > 0) {
+        if (layer->getLayerFE().getCompositionState()->backgroundBlurRadius > 0) {
             layerRequestingBgComposition = layer;
         }
     }
@@ -639,7 +628,7 @@
     *outHdrDataSpace = ui::Dataspace::UNKNOWN;
 
     for (const auto* layer : getOutputLayersOrderedByZ()) {
-        switch (layer->getLayer().getFEState().dataspace) {
+        switch (layer->getLayerFE().getCompositionState()->dataspace) {
             case ui::Dataspace::V0_SCRGB:
             case ui::Dataspace::V0_SCRGB_LINEAR:
             case ui::Dataspace::BT2020:
@@ -655,7 +644,8 @@
             case ui::Dataspace::BT2020_ITU_PQ:
                 bestDataSpace = ui::Dataspace::DISPLAY_P3;
                 *outHdrDataSpace = ui::Dataspace::BT2020_PQ;
-                *outIsHdrClientComposition = layer->getLayer().getFEState().forceClientComposition;
+                *outIsHdrClientComposition =
+                        layer->getLayerFE().getCompositionState()->forceClientComposition;
                 break;
             case ui::Dataspace::BT2020_HLG:
             case ui::Dataspace::BT2020_ITU_HLG:
@@ -867,7 +857,7 @@
     if (outputState.isSecure && supportsProtectedContent) {
         auto layers = getOutputLayersOrderedByZ();
         bool needsProtected = std::any_of(layers.begin(), layers.end(), [](auto* layer) {
-            return layer->getLayer().getFEState().hasProtectedContent;
+            return layer->getLayerFE().getCompositionState()->hasProtectedContent;
         });
         if (needsProtected != renderEngine.isProtected()) {
             renderEngine.useProtectedContext(needsProtected);
@@ -955,7 +945,7 @@
 
     for (auto* layer : getOutputLayersOrderedByZ()) {
         const auto& layerState = layer->getState();
-        const auto& layerFEState = layer->getLayer().getFEState();
+        const auto* layerFEState = layer->getLayerFE().getCompositionState();
         auto& layerFE = layer->getLayerFE();
 
         const Region clip(viewportRegion.intersect(layerState.visibleRegion));
@@ -974,7 +964,7 @@
         // underneath. We also skip the first layer as the buffer target is
         // guaranteed to start out cleared.
         bool clearClientComposition =
-                layerState.clearClientTarget && layerFEState.isOpaque && !firstLayer;
+                layerState.clearClientTarget && layerFEState->isOpaque && !firstLayer;
 
         ALOGV("  Composition type: client %d clear %d", clientComposition, clearClientComposition);
 
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index d92b7ef..b538d75 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -16,7 +16,6 @@
 
 #include <android-base/stringprintf.h>
 #include <compositionengine/DisplayColorProfile.h>
-#include <compositionengine/Layer.h>
 #include <compositionengine/LayerFE.h>
 #include <compositionengine/LayerFECompositionState.h>
 #include <compositionengine/Output.h>
@@ -51,11 +50,9 @@
 
 } // namespace
 
-std::unique_ptr<OutputLayer> createOutputLayer(
-        const compositionengine::Output& output,
-        const std::shared_ptr<compositionengine::Layer>& layer,
-        const sp<compositionengine::LayerFE>& layerFE) {
-    return createOutputLayerTemplated<OutputLayer>(output, layer, layerFE);
+std::unique_ptr<OutputLayer> createOutputLayer(const compositionengine::Output& output,
+                                               const sp<compositionengine::LayerFE>& layerFE) {
+    return createOutputLayerTemplated<OutputLayer>(output, layerFE);
 }
 
 OutputLayer::~OutputLayer() = default;
@@ -70,7 +67,7 @@
 }
 
 Rect OutputLayer::calculateInitialCrop() const {
-    const auto& layerState = getLayer().getFEState();
+    const auto& layerState = *getLayerFE().getCompositionState();
 
     // apply the projection's clipping to the window crop in
     // layerstack space, and convert-back to layer space.
@@ -103,7 +100,7 @@
 }
 
 FloatRect OutputLayer::calculateOutputSourceCrop() const {
-    const auto& layerState = getLayer().getFEState();
+    const auto& layerState = *getLayerFE().getCompositionState();
     const auto& outputState = getOutput().getState();
 
     if (!layerState.geomUsesSourceCrop) {
@@ -180,7 +177,7 @@
 }
 
 Rect OutputLayer::calculateOutputDisplayFrame() const {
-    const auto& layerState = getLayer().getFEState();
+    const auto& layerState = *getLayerFE().getCompositionState();
     const auto& outputState = getOutput().getState();
 
     // apply the layer's transform, followed by the display's global transform
@@ -227,7 +224,7 @@
 }
 
 uint32_t OutputLayer::calculateOutputRelativeBufferTransform() const {
-    const auto& layerState = getLayer().getFEState();
+    const auto& layerState = *getLayerFE().getCompositionState();
     const auto& outputState = getOutput().getState();
 
     /*
@@ -267,7 +264,11 @@
 } // namespace impl
 
 void OutputLayer::updateCompositionState(bool includeGeometry, bool forceClientComposition) {
-    const auto& layerFEState = getLayer().getFEState();
+    const auto* layerFEState = getLayerFE().getCompositionState();
+    if (!layerFEState) {
+        return;
+    }
+
     const auto& outputState = getOutput().getState();
     const auto& profile = *getOutput().getDisplayColorProfile();
     auto& state = editState();
@@ -285,7 +286,7 @@
         state.bufferTransform =
                 static_cast<Hwc2::Transform>(calculateOutputRelativeBufferTransform());
 
-        if ((layerFEState.isSecure && !outputState.isSecure) ||
+        if ((layerFEState->isSecure && !outputState.isSecure) ||
             (state.bufferTransform & ui::Transform::ROT_INVALID)) {
             state.forceClientComposition = true;
         }
@@ -294,14 +295,14 @@
     // Determine the output dependent dataspace for this layer. If it is
     // colorspace agnostic, it just uses the dataspace chosen for the output to
     // avoid the need for color conversion.
-    state.dataspace = layerFEState.isColorspaceAgnostic &&
+    state.dataspace = layerFEState->isColorspaceAgnostic &&
                     outputState.targetDataspace != ui::Dataspace::UNKNOWN
             ? outputState.targetDataspace
-            : layerFEState.dataspace;
+            : layerFEState->dataspace;
 
     // These are evaluated every frame as they can potentially change at any
     // time.
-    if (layerFEState.forceClientComposition || !profile.isDataspaceSupported(state.dataspace) ||
+    if (layerFEState->forceClientComposition || !profile.isDataspaceSupported(state.dataspace) ||
         forceClientComposition) {
         state.forceClientComposition = true;
     }
@@ -321,21 +322,25 @@
         return;
     }
 
-    const auto& outputIndependentState = getLayer().getFEState();
-    auto requestedCompositionType = outputIndependentState.compositionType;
+    const auto* outputIndependentState = getLayerFE().getCompositionState();
+    if (!outputIndependentState) {
+        return;
+    }
+
+    auto requestedCompositionType = outputIndependentState->compositionType;
 
     if (includeGeometry) {
         writeOutputDependentGeometryStateToHWC(hwcLayer.get(), requestedCompositionType);
-        writeOutputIndependentGeometryStateToHWC(hwcLayer.get(), outputIndependentState);
+        writeOutputIndependentGeometryStateToHWC(hwcLayer.get(), *outputIndependentState);
     }
 
     writeOutputDependentPerFrameStateToHWC(hwcLayer.get());
-    writeOutputIndependentPerFrameStateToHWC(hwcLayer.get(), outputIndependentState);
+    writeOutputIndependentPerFrameStateToHWC(hwcLayer.get(), *outputIndependentState);
 
     writeCompositionTypeToHWC(hwcLayer.get(), requestedCompositionType);
 
     // Always set the layer color after setting the composition type.
-    writeSolidColorStateToHWC(hwcLayer.get(), outputIndependentState);
+    writeSolidColorStateToHWC(hwcLayer.get(), *outputIndependentState);
 }
 
 void OutputLayer::writeOutputDependentGeometryStateToHWC(
@@ -546,10 +551,14 @@
         return;
     }
 
-    const auto& layerFEState = getLayer().getFEState();
+    const auto* layerFEState = getLayerFE().getCompositionState();
+    if (!layerFEState) {
+        return;
+    }
+
     const auto& outputState = getOutput().getState();
 
-    Rect frame = layerFEState.cursorFrame;
+    Rect frame = layerFEState->cursorFrame;
     frame.intersect(outputState.viewport, &frame);
     Rect position = outputState.transform.transform(frame);
 
@@ -646,8 +655,7 @@
 void OutputLayer::dump(std::string& out) const {
     using android::base::StringAppendF;
 
-    StringAppendF(&out, "  - Output Layer %p (Composition layer %p) (%s)\n", this, &getLayer(),
-                  getLayerFE().getDebugName());
+    StringAppendF(&out, "  - Output Layer %p(%s)\n", this, getLayerFE().getDebugName());
     dumpState(out);
 }
 
diff --git a/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp
index c1faa90..d889d74 100644
--- a/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp
@@ -17,7 +17,6 @@
 #include <compositionengine/CompositionRefreshArgs.h>
 #include <compositionengine/LayerFECompositionState.h>
 #include <compositionengine/impl/CompositionEngine.h>
-#include <compositionengine/mock/Layer.h>
 #include <compositionengine/mock/LayerFE.h>
 #include <compositionengine/mock/Output.h>
 #include <compositionengine/mock/OutputLayer.h>
@@ -50,11 +49,6 @@
     std::shared_ptr<mock::Output> mOutput1{std::make_shared<StrictMock<mock::Output>>()};
     std::shared_ptr<mock::Output> mOutput2{std::make_shared<StrictMock<mock::Output>>()};
     std::shared_ptr<mock::Output> mOutput3{std::make_shared<StrictMock<mock::Output>>()};
-
-    std::shared_ptr<mock::Layer> mLayer1{std::make_shared<StrictMock<mock::Layer>>()};
-    std::shared_ptr<mock::Layer> mLayer2{std::make_shared<StrictMock<mock::Layer>>()};
-    std::shared_ptr<mock::Layer> mLayer3{std::make_shared<StrictMock<mock::Layer>>()};
-    std::shared_ptr<mock::Layer> mLayer4{std::make_shared<StrictMock<mock::Layer>>()};
 };
 
 TEST_F(CompositionEngineTest, canInstantiateCompositionEngine) {
@@ -134,48 +128,32 @@
 
 struct CompositionEngineUpdateCursorAsyncTest : public CompositionEngineTest {
 public:
+    struct Layer {
+        Layer() { EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE)); }
+
+        StrictMock<mock::OutputLayer> outputLayer;
+        StrictMock<mock::LayerFE> layerFE;
+        LayerFECompositionState layerFEState;
+    };
+
     CompositionEngineUpdateCursorAsyncTest() {
         EXPECT_CALL(*mOutput1, getOutputLayerCount()).WillRepeatedly(Return(0u));
         EXPECT_CALL(*mOutput1, getOutputLayerOrderedByZByIndex(_)).Times(0);
 
         EXPECT_CALL(*mOutput2, getOutputLayerCount()).WillRepeatedly(Return(1u));
         EXPECT_CALL(*mOutput2, getOutputLayerOrderedByZByIndex(0))
-                .WillRepeatedly(Return(&mOutput2OutputLayer1));
+                .WillRepeatedly(Return(&mOutput2Layer1.outputLayer));
 
         EXPECT_CALL(*mOutput3, getOutputLayerCount()).WillRepeatedly(Return(2u));
         EXPECT_CALL(*mOutput3, getOutputLayerOrderedByZByIndex(0))
-                .WillRepeatedly(Return(&mOutput3OutputLayer1));
+                .WillRepeatedly(Return(&mOutput3Layer1.outputLayer));
         EXPECT_CALL(*mOutput3, getOutputLayerOrderedByZByIndex(1))
-                .WillRepeatedly(Return(&mOutput3OutputLayer2));
-
-        EXPECT_CALL(mOutput2OutputLayer1, getLayerFE()).WillRepeatedly(ReturnRef(mOutput2Layer1FE));
-        EXPECT_CALL(mOutput3OutputLayer1, getLayerFE()).WillRepeatedly(ReturnRef(mOutput3Layer1FE));
-        EXPECT_CALL(mOutput3OutputLayer2, getLayerFE()).WillRepeatedly(ReturnRef(mOutput3Layer2FE));
-
-        EXPECT_CALL(mOutput2OutputLayer1, getLayer()).WillRepeatedly(ReturnRef(mOutput2Layer1));
-        EXPECT_CALL(mOutput3OutputLayer1, getLayer()).WillRepeatedly(ReturnRef(mOutput3Layer1));
-        EXPECT_CALL(mOutput3OutputLayer2, getLayer()).WillRepeatedly(ReturnRef(mOutput3Layer2));
-
-        EXPECT_CALL(mOutput2Layer1, editFEState()).WillRepeatedly(ReturnRef(mOutput2Layer1FEState));
-        EXPECT_CALL(mOutput3Layer1, editFEState()).WillRepeatedly(ReturnRef(mOutput3Layer1FEState));
-        EXPECT_CALL(mOutput3Layer2, editFEState()).WillRepeatedly(ReturnRef(mOutput3Layer2FEState));
+                .WillRepeatedly(Return(&mOutput3Layer2.outputLayer));
     }
 
-    StrictMock<mock::OutputLayer> mOutput2OutputLayer1;
-    StrictMock<mock::OutputLayer> mOutput3OutputLayer1;
-    StrictMock<mock::OutputLayer> mOutput3OutputLayer2;
-
-    StrictMock<mock::LayerFE> mOutput2Layer1FE;
-    StrictMock<mock::LayerFE> mOutput3Layer1FE;
-    StrictMock<mock::LayerFE> mOutput3Layer2FE;
-
-    StrictMock<mock::Layer> mOutput2Layer1;
-    StrictMock<mock::Layer> mOutput3Layer1;
-    StrictMock<mock::Layer> mOutput3Layer2;
-
-    LayerFECompositionState mOutput2Layer1FEState;
-    LayerFECompositionState mOutput3Layer1FEState;
-    LayerFECompositionState mOutput3Layer2FEState;
+    Layer mOutput2Layer1;
+    Layer mOutput3Layer1;
+    Layer mOutput3Layer2;
 };
 
 TEST_F(CompositionEngineUpdateCursorAsyncTest, handlesNoOutputs) {
@@ -183,9 +161,9 @@
 }
 
 TEST_F(CompositionEngineUpdateCursorAsyncTest, handlesNoLayersBeingCursorLayers) {
-    EXPECT_CALL(mOutput2OutputLayer1, isHardwareCursor()).WillRepeatedly(Return(false));
-    EXPECT_CALL(mOutput3OutputLayer1, isHardwareCursor()).WillRepeatedly(Return(false));
-    EXPECT_CALL(mOutput3OutputLayer2, isHardwareCursor()).WillRepeatedly(Return(false));
+    EXPECT_CALL(mOutput3Layer1.outputLayer, isHardwareCursor()).WillRepeatedly(Return(false));
+    EXPECT_CALL(mOutput3Layer2.outputLayer, isHardwareCursor()).WillRepeatedly(Return(false));
+    EXPECT_CALL(mOutput2Layer1.outputLayer, isHardwareCursor()).WillRepeatedly(Return(false));
 
     mRefreshArgs.outputs = {mOutput1, mOutput2, mOutput3};
 
@@ -195,23 +173,23 @@
 TEST_F(CompositionEngineUpdateCursorAsyncTest, handlesMultipleLayersBeingCursorLayers) {
     {
         InSequence seq;
-        EXPECT_CALL(mOutput2OutputLayer1, isHardwareCursor()).WillRepeatedly(Return(true));
-        EXPECT_CALL(mOutput2Layer1FE, latchCursorCompositionState(Ref(mOutput2Layer1FEState)));
-        EXPECT_CALL(mOutput2OutputLayer1, writeCursorPositionToHWC());
+        EXPECT_CALL(mOutput2Layer1.outputLayer, isHardwareCursor()).WillRepeatedly(Return(true));
+        EXPECT_CALL(mOutput2Layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::Cursor));
+        EXPECT_CALL(mOutput2Layer1.outputLayer, writeCursorPositionToHWC());
     }
 
     {
         InSequence seq;
-        EXPECT_CALL(mOutput3OutputLayer1, isHardwareCursor()).WillRepeatedly(Return(true));
-        EXPECT_CALL(mOutput3Layer1FE, latchCursorCompositionState(Ref(mOutput3Layer1FEState)));
-        EXPECT_CALL(mOutput3OutputLayer1, writeCursorPositionToHWC());
+        EXPECT_CALL(mOutput3Layer1.outputLayer, isHardwareCursor()).WillRepeatedly(Return(true));
+        EXPECT_CALL(mOutput3Layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::Cursor));
+        EXPECT_CALL(mOutput3Layer1.outputLayer, writeCursorPositionToHWC());
     }
 
     {
         InSequence seq;
-        EXPECT_CALL(mOutput3OutputLayer2, isHardwareCursor()).WillRepeatedly(Return(true));
-        EXPECT_CALL(mOutput3Layer2FE, latchCursorCompositionState(Ref(mOutput3Layer2FEState)));
-        EXPECT_CALL(mOutput3OutputLayer2, writeCursorPositionToHWC());
+        EXPECT_CALL(mOutput3Layer2.outputLayer, isHardwareCursor()).WillRepeatedly(Return(true));
+        EXPECT_CALL(mOutput3Layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::Cursor));
+        EXPECT_CALL(mOutput3Layer2.outputLayer, writeCursorPositionToHWC());
     }
 
     mRefreshArgs.outputs = {mOutput1, mOutput2, mOutput3};
@@ -224,14 +202,6 @@
  */
 
 struct CompositionTestPreComposition : public CompositionEngineTest {
-    CompositionTestPreComposition() {
-        EXPECT_CALL(*mLayer1, getLayerFE()).WillRepeatedly(Return(mLayer1FE));
-        EXPECT_CALL(*mLayer2, getLayerFE()).WillRepeatedly(Return(mLayer2FE));
-        EXPECT_CALL(*mLayer3, getLayerFE()).WillRepeatedly(Return(mLayer3FE));
-        // getLayerFE() can return nullptr. Ensure that this is handled.
-        EXPECT_CALL(*mLayer4, getLayerFE()).WillRepeatedly(Return(nullptr));
-    }
-
     sp<StrictMock<mock::LayerFE>> mLayer1FE{new StrictMock<mock::LayerFE>()};
     sp<StrictMock<mock::LayerFE>> mLayer2FE{new StrictMock<mock::LayerFE>()};
     sp<StrictMock<mock::LayerFE>> mLayer3FE{new StrictMock<mock::LayerFE>()};
@@ -256,7 +226,7 @@
     EXPECT_CALL(*mLayer3FE, onPreComposition(_)).WillOnce(DoAll(SaveArg<0>(&ts3), Return(false)));
 
     mRefreshArgs.outputs = {mOutput1};
-    mRefreshArgs.layers = {mLayer1, mLayer2, mLayer3, mLayer4};
+    mRefreshArgs.layers = {mLayer1FE, mLayer2FE, mLayer3FE};
 
     mEngine.preComposition(mRefreshArgs);
 
@@ -274,7 +244,7 @@
     mEngine.setNeedsAnotherUpdateForTest(true);
 
     mRefreshArgs.outputs = {mOutput1};
-    mRefreshArgs.layers = {mLayer1, mLayer2, mLayer3, mLayer4};
+    mRefreshArgs.layers = {mLayer1FE, mLayer2FE, mLayer3FE};
 
     mEngine.preComposition(mRefreshArgs);
 
@@ -289,7 +259,7 @@
     EXPECT_CALL(*mLayer3FE, onPreComposition(_)).WillOnce(Return(false));
 
     mRefreshArgs.outputs = {mOutput1};
-    mRefreshArgs.layers = {mLayer1, mLayer2, mLayer3, mLayer4};
+    mRefreshArgs.layers = {mLayer1FE, mLayer2FE, mLayer3FE};
 
     mEngine.preComposition(mRefreshArgs);
 
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index ae93969..16f7a4e 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -25,7 +25,6 @@
 #include <compositionengine/mock/CompositionEngine.h>
 #include <compositionengine/mock/DisplayColorProfile.h>
 #include <compositionengine/mock/DisplaySurface.h>
-#include <compositionengine/mock/Layer.h>
 #include <compositionengine/mock/LayerFE.h>
 #include <compositionengine/mock/NativeWindow.h>
 #include <compositionengine/mock/OutputLayer.h>
@@ -53,6 +52,27 @@
 constexpr int32_t DEFAULT_DISPLAY_WIDTH = 1920;
 constexpr int32_t DEFAULT_DISPLAY_HEIGHT = 1080;
 
+struct Layer {
+    Layer() {
+        EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
+        EXPECT_CALL(*outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
+    }
+
+    sp<mock::LayerFE> layerFE = new StrictMock<mock::LayerFE>();
+    StrictMock<mock::OutputLayer>* outputLayer = new StrictMock<mock::OutputLayer>();
+    StrictMock<HWC2::mock::Layer> hwc2Layer;
+};
+
+struct LayerNoHWC2Layer {
+    LayerNoHWC2Layer() {
+        EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
+        EXPECT_CALL(*outputLayer, getHwcLayer()).WillRepeatedly(Return(nullptr));
+    }
+
+    sp<mock::LayerFE> layerFE = new StrictMock<mock::LayerFE>();
+    StrictMock<mock::OutputLayer>* outputLayer = new StrictMock<mock::OutputLayer>();
+};
+
 struct DisplayTest : public testing::Test {
     class Display : public impl::Display {
     public:
@@ -71,28 +91,24 @@
 
     DisplayTest() {
         EXPECT_CALL(mCompositionEngine, getHwComposer()).WillRepeatedly(ReturnRef(mHwComposer));
-        EXPECT_CALL(*mLayer1, getHwcLayer()).WillRepeatedly(Return(&mHWC2Layer1));
-        EXPECT_CALL(*mLayer2, getHwcLayer()).WillRepeatedly(Return(&mHWC2Layer2));
-        EXPECT_CALL(*mLayer3, getHwcLayer()).WillRepeatedly(Return(nullptr));
 
         mDisplay->injectOutputLayerForTest(
-                std::unique_ptr<compositionengine::OutputLayer>(mLayer1));
+                std::unique_ptr<compositionengine::OutputLayer>(mLayer1.outputLayer));
         mDisplay->injectOutputLayerForTest(
-                std::unique_ptr<compositionengine::OutputLayer>(mLayer2));
+                std::unique_ptr<compositionengine::OutputLayer>(mLayer2.outputLayer));
         mDisplay->injectOutputLayerForTest(
-                std::unique_ptr<compositionengine::OutputLayer>(mLayer3));
+                std::unique_ptr<compositionengine::OutputLayer>(mLayer3.outputLayer));
     }
 
     StrictMock<android::mock::HWComposer> mHwComposer;
     StrictMock<Hwc2::mock::PowerAdvisor> mPowerAdvisor;
     StrictMock<mock::CompositionEngine> mCompositionEngine;
     sp<mock::NativeWindow> mNativeWindow = new StrictMock<mock::NativeWindow>();
-    StrictMock<HWC2::mock::Layer> mHWC2Layer1;
-    StrictMock<HWC2::mock::Layer> mHWC2Layer2;
-    StrictMock<HWC2::mock::Layer> mHWC2LayerUnknown;
-    mock::OutputLayer* mLayer1 = new StrictMock<mock::OutputLayer>();
-    mock::OutputLayer* mLayer2 = new StrictMock<mock::OutputLayer>();
-    mock::OutputLayer* mLayer3 = new StrictMock<mock::OutputLayer>();
+    Layer mLayer1;
+    Layer mLayer2;
+    LayerNoHWC2Layer mLayer3;
+    StrictMock<HWC2::mock::Layer> hwc2LayerUnknown;
+
     std::shared_ptr<Display> mDisplay = createDisplay(mCompositionEngine,
                                                       DisplayCreationArgsBuilder()
                                                               .setDisplayId(DEFAULT_DISPLAY_ID)
@@ -283,12 +299,11 @@
 
 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);
+    auto outputLayer = mDisplay->createOutputLayer(layerFE);
 
     EXPECT_EQ(&hwcLayer, outputLayer->getHwcLayer());
 
@@ -305,7 +320,6 @@
             impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())};
 
     sp<mock::LayerFE> layerXLayerFE = new StrictMock<mock::LayerFE>();
-    mock::Layer layerXLayer;
 
     {
         Output::ReleasedLayers releasedLayers;
@@ -314,7 +328,7 @@
     }
 
     CompositionRefreshArgs refreshArgs;
-    refreshArgs.layersWithQueuedFrames.push_back(&layerXLayer);
+    refreshArgs.layersWithQueuedFrames.push_back(layerXLayerFE);
 
     nonHwcDisplay->setReleasedLayers(refreshArgs);
 
@@ -339,34 +353,19 @@
 }
 
 TEST_F(DisplayTest, setReleasedLayers) {
-    sp<mock::LayerFE> layer1LayerFE = new StrictMock<mock::LayerFE>();
-    sp<mock::LayerFE> layer2LayerFE = new StrictMock<mock::LayerFE>();
-    sp<mock::LayerFE> layer3LayerFE = new StrictMock<mock::LayerFE>();
-    sp<mock::LayerFE> layerXLayerFE = new StrictMock<mock::LayerFE>();
-    mock::Layer layer1Layer;
-    mock::Layer layer2Layer;
-    mock::Layer layer3Layer;
-    mock::Layer layerXLayer;
-
-    EXPECT_CALL(*mLayer1, getLayer()).WillRepeatedly(ReturnRef(layer1Layer));
-    EXPECT_CALL(*mLayer1, getLayerFE()).WillRepeatedly(ReturnRef(*layer1LayerFE.get()));
-    EXPECT_CALL(*mLayer2, getLayer()).WillRepeatedly(ReturnRef(layer2Layer));
-    EXPECT_CALL(*mLayer2, getLayerFE()).WillRepeatedly(ReturnRef(*layer2LayerFE.get()));
-    EXPECT_CALL(*mLayer3, getLayer()).WillRepeatedly(ReturnRef(layer3Layer));
-    EXPECT_CALL(*mLayer3, getLayerFE()).WillRepeatedly(ReturnRef(*layer3LayerFE.get()));
+    sp<mock::LayerFE> unknownLayer = new StrictMock<mock::LayerFE>();
 
     CompositionRefreshArgs refreshArgs;
-    refreshArgs.layersWithQueuedFrames.push_back(&layer1Layer);
-    refreshArgs.layersWithQueuedFrames.push_back(&layer2Layer);
-    refreshArgs.layersWithQueuedFrames.push_back(&layerXLayer);
-    refreshArgs.layersWithQueuedFrames.push_back(nullptr);
+    refreshArgs.layersWithQueuedFrames.push_back(mLayer1.layerFE);
+    refreshArgs.layersWithQueuedFrames.push_back(mLayer2.layerFE);
+    refreshArgs.layersWithQueuedFrames.push_back(unknownLayer);
 
     mDisplay->setReleasedLayers(refreshArgs);
 
     const auto& releasedLayers = mDisplay->getReleasedLayersForTest();
     ASSERT_EQ(2, releasedLayers.size());
-    ASSERT_EQ(layer1LayerFE.get(), releasedLayers[0].promote().get());
-    ASSERT_EQ(layer2LayerFE.get(), releasedLayers[1].promote().get());
+    ASSERT_EQ(mLayer1.layerFE.get(), releasedLayers[0].promote().get());
+    ASSERT_EQ(mLayer2.layerFE.get(), releasedLayers[1].promote().get());
 }
 
 /*
@@ -400,16 +399,12 @@
         MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
         MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex,
                            compositionengine::OutputLayer*(size_t));
-        MOCK_METHOD3(ensureOutputLayer,
-                     compositionengine::OutputLayer*(
-                             std::optional<size_t>,
-                             const std::shared_ptr<compositionengine::Layer>&, const sp<LayerFE>&));
+        MOCK_METHOD2(ensureOutputLayer,
+                     compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
         MOCK_METHOD0(finalizePendingOutputLayers, void());
         MOCK_METHOD0(clearOutputLayers, void());
         MOCK_CONST_METHOD1(dumpState, void(std::string&));
-        MOCK_METHOD2(injectOutputLayerForTest,
-                     compositionengine::OutputLayer*(
-                             const std::shared_ptr<compositionengine::Layer>&, const sp<LayerFE>&));
+        MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
         MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
 
         const compositionengine::CompositionEngine& mCompositionEngine;
@@ -523,16 +518,16 @@
  */
 
 TEST_F(DisplayTest, anyLayersRequireClientCompositionReturnsFalse) {
-    EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(false));
-    EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(false));
-    EXPECT_CALL(*mLayer3, requiresClientComposition()).WillOnce(Return(false));
+    EXPECT_CALL(*mLayer1.outputLayer, requiresClientComposition()).WillOnce(Return(false));
+    EXPECT_CALL(*mLayer2.outputLayer, requiresClientComposition()).WillOnce(Return(false));
+    EXPECT_CALL(*mLayer3.outputLayer, requiresClientComposition()).WillOnce(Return(false));
 
     EXPECT_FALSE(mDisplay->anyLayersRequireClientComposition());
 }
 
 TEST_F(DisplayTest, anyLayersRequireClientCompositionReturnsTrue) {
-    EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(false));
-    EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(true));
+    EXPECT_CALL(*mLayer1.outputLayer, requiresClientComposition()).WillOnce(Return(false));
+    EXPECT_CALL(*mLayer2.outputLayer, requiresClientComposition()).WillOnce(Return(true));
 
     EXPECT_TRUE(mDisplay->anyLayersRequireClientComposition());
 }
@@ -542,16 +537,16 @@
  */
 
 TEST_F(DisplayTest, allLayersRequireClientCompositionReturnsTrue) {
-    EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(true));
-    EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(true));
-    EXPECT_CALL(*mLayer3, requiresClientComposition()).WillOnce(Return(true));
+    EXPECT_CALL(*mLayer1.outputLayer, requiresClientComposition()).WillOnce(Return(true));
+    EXPECT_CALL(*mLayer2.outputLayer, requiresClientComposition()).WillOnce(Return(true));
+    EXPECT_CALL(*mLayer3.outputLayer, requiresClientComposition()).WillOnce(Return(true));
 
     EXPECT_TRUE(mDisplay->allLayersRequireClientComposition());
 }
 
 TEST_F(DisplayTest, allLayersRequireClientCompositionReturnsFalse) {
-    EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(true));
-    EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(false));
+    EXPECT_CALL(*mLayer1.outputLayer, requiresClientComposition()).WillOnce(Return(true));
+    EXPECT_CALL(*mLayer2.outputLayer, requiresClientComposition()).WillOnce(Return(false));
 
     EXPECT_FALSE(mDisplay->allLayersRequireClientComposition());
 }
@@ -565,17 +560,17 @@
 }
 
 TEST_F(DisplayTest, applyChangedTypesToLayersAppliesChanges) {
-    EXPECT_CALL(*mLayer1,
+    EXPECT_CALL(*mLayer1.outputLayer,
                 applyDeviceCompositionTypeChange(Hwc2::IComposerClient::Composition::CLIENT))
             .Times(1);
-    EXPECT_CALL(*mLayer2,
+    EXPECT_CALL(*mLayer2.outputLayer,
                 applyDeviceCompositionTypeChange(Hwc2::IComposerClient::Composition::DEVICE))
             .Times(1);
 
     mDisplay->applyChangedTypesToLayers(impl::Display::ChangedTypes{
-            {&mHWC2Layer1, HWC2::Composition::Client},
-            {&mHWC2Layer2, HWC2::Composition::Device},
-            {&mHWC2LayerUnknown, HWC2::Composition::SolidColor},
+            {&mLayer1.hwc2Layer, HWC2::Composition::Client},
+            {&mLayer2.hwc2Layer, HWC2::Composition::Device},
+            {&hwc2LayerUnknown, HWC2::Composition::SolidColor},
     });
 }
 
@@ -616,25 +611,25 @@
  */
 
 TEST_F(DisplayTest, applyLayerRequestsToLayersPreparesAllLayers) {
-    EXPECT_CALL(*mLayer1, prepareForDeviceLayerRequests()).Times(1);
-    EXPECT_CALL(*mLayer2, prepareForDeviceLayerRequests()).Times(1);
-    EXPECT_CALL(*mLayer3, prepareForDeviceLayerRequests()).Times(1);
+    EXPECT_CALL(*mLayer1.outputLayer, prepareForDeviceLayerRequests()).Times(1);
+    EXPECT_CALL(*mLayer2.outputLayer, prepareForDeviceLayerRequests()).Times(1);
+    EXPECT_CALL(*mLayer3.outputLayer, prepareForDeviceLayerRequests()).Times(1);
 
     mDisplay->applyLayerRequestsToLayers(impl::Display::LayerRequests());
 }
 
 TEST_F(DisplayTest, applyLayerRequestsToLayers2) {
-    EXPECT_CALL(*mLayer1, prepareForDeviceLayerRequests()).Times(1);
-    EXPECT_CALL(*mLayer2, prepareForDeviceLayerRequests()).Times(1);
-    EXPECT_CALL(*mLayer3, prepareForDeviceLayerRequests()).Times(1);
+    EXPECT_CALL(*mLayer1.outputLayer, prepareForDeviceLayerRequests()).Times(1);
+    EXPECT_CALL(*mLayer2.outputLayer, prepareForDeviceLayerRequests()).Times(1);
+    EXPECT_CALL(*mLayer3.outputLayer, prepareForDeviceLayerRequests()).Times(1);
 
-    EXPECT_CALL(*mLayer1,
+    EXPECT_CALL(*mLayer1.outputLayer,
                 applyDeviceLayerRequest(Hwc2::IComposerClient::LayerRequest::CLEAR_CLIENT_TARGET))
             .Times(1);
 
     mDisplay->applyLayerRequestsToLayers(impl::Display::LayerRequests{
-            {&mHWC2Layer1, HWC2::LayerRequest::ClearClientTarget},
-            {&mHWC2LayerUnknown, HWC2::LayerRequest::ClearClientTarget},
+            {&mLayer1.hwc2Layer, HWC2::LayerRequest::ClearClientTarget},
+            {&hwc2LayerUnknown, HWC2::LayerRequest::ClearClientTarget},
     });
 }
 
@@ -660,9 +655,9 @@
 
     EXPECT_CALL(mHwComposer, presentAndGetReleaseFences(DEFAULT_DISPLAY_ID)).Times(1);
     EXPECT_CALL(mHwComposer, getPresentFence(DEFAULT_DISPLAY_ID)).WillOnce(Return(presentFence));
-    EXPECT_CALL(mHwComposer, getLayerReleaseFence(DEFAULT_DISPLAY_ID, &mHWC2Layer1))
+    EXPECT_CALL(mHwComposer, getLayerReleaseFence(DEFAULT_DISPLAY_ID, &mLayer1.hwc2Layer))
             .WillOnce(Return(layer1Fence));
-    EXPECT_CALL(mHwComposer, getLayerReleaseFence(DEFAULT_DISPLAY_ID, &mHWC2Layer2))
+    EXPECT_CALL(mHwComposer, getLayerReleaseFence(DEFAULT_DISPLAY_ID, &mLayer2.hwc2Layer))
             .WillOnce(Return(layer2Fence));
     EXPECT_CALL(mHwComposer, clearReleaseFences(DEFAULT_DISPLAY_ID)).Times(1);
 
@@ -671,10 +666,10 @@
     EXPECT_EQ(presentFence, result.presentFence);
 
     EXPECT_EQ(2u, result.layerFences.size());
-    ASSERT_EQ(1, result.layerFences.count(&mHWC2Layer1));
-    EXPECT_EQ(layer1Fence, result.layerFences[&mHWC2Layer1]);
-    ASSERT_EQ(1, result.layerFences.count(&mHWC2Layer2));
-    EXPECT_EQ(layer2Fence, result.layerFences[&mHWC2Layer2]);
+    ASSERT_EQ(1, result.layerFences.count(&mLayer1.hwc2Layer));
+    EXPECT_EQ(layer1Fence, result.layerFences[&mLayer1.hwc2Layer]);
+    ASSERT_EQ(1, result.layerFences.count(&mLayer2.hwc2Layer));
+    EXPECT_EQ(layer2Fence, result.layerFences[&mLayer2.hwc2Layer]);
 }
 
 /*
diff --git a/services/surfaceflinger/CompositionEngine/tests/LayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/LayerTest.cpp
deleted file mode 100644
index 787f973..0000000
--- a/services/surfaceflinger/CompositionEngine/tests/LayerTest.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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 <gtest/gtest.h>
-
-#include <compositionengine/LayerCreationArgs.h>
-#include <compositionengine/LayerFECompositionState.h>
-#include <compositionengine/impl/Layer.h>
-#include <compositionengine/mock/CompositionEngine.h>
-#include <compositionengine/mock/LayerFE.h>
-
-namespace android::compositionengine {
-namespace {
-
-using testing::StrictMock;
-
-struct LayerTest : public testing::Test {
-    struct Layer final : public impl::Layer {
-        explicit Layer(const LayerCreationArgs& args) : mLayerFE(args.layerFE) {}
-        ~Layer() override = default;
-
-        // compositionengine::Layer overrides
-        sp<LayerFE> getLayerFE() const { return mLayerFE.promote(); }
-        const LayerFECompositionState& getFEState() const override { return mFrontEndState; }
-        LayerFECompositionState& editFEState() override { return mFrontEndState; }
-
-        // compositionengine::impl::Layer overrides
-        void dumpFEState(std::string& out) const override { mFrontEndState.dump(out); }
-
-        const wp<LayerFE> mLayerFE;
-        LayerFECompositionState mFrontEndState;
-    };
-
-    ~LayerTest() override = default;
-
-    StrictMock<mock::CompositionEngine> mCompositionEngine;
-    sp<LayerFE> mLayerFE = new StrictMock<mock::LayerFE>();
-    Layer mLayer{LayerCreationArgs{mLayerFE}};
-};
-
-/* ------------------------------------------------------------------------
- * Basic construction
- */
-
-TEST_F(LayerTest, canInstantiateLayer) {}
-
-} // namespace
-} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
index 0e579fa..963062f 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
@@ -18,7 +18,6 @@
 #include <compositionengine/impl/OutputLayerCompositionState.h>
 #include <compositionengine/mock/CompositionEngine.h>
 #include <compositionengine/mock/DisplayColorProfile.h>
-#include <compositionengine/mock/Layer.h>
 #include <compositionengine/mock/LayerFE.h>
 #include <compositionengine/mock/Output.h>
 #include <gtest/gtest.h>
@@ -56,15 +55,12 @@
 
 struct OutputLayerTest : public testing::Test {
     struct OutputLayer final : public impl::OutputLayer {
-        OutputLayer(const compositionengine::Output& output,
-                    std::shared_ptr<compositionengine::Layer> layer,
-                    sp<compositionengine::LayerFE> layerFE)
-              : mOutput(output), mLayer(layer), mLayerFE(layerFE) {}
+        OutputLayer(const compositionengine::Output& output, sp<compositionengine::LayerFE> layerFE)
+              : mOutput(output), mLayerFE(layerFE) {}
         ~OutputLayer() override = default;
 
         // compositionengine::OutputLayer overrides
         const compositionengine::Output& getOutput() const override { return mOutput; }
-        compositionengine::Layer& getLayer() const override { return *mLayer; }
         compositionengine::LayerFE& getLayerFE() const override { return *mLayerFE; }
         const impl::OutputLayerCompositionState& getState() const override { return mState; }
         impl::OutputLayerCompositionState& editState() override { return mState; }
@@ -73,7 +69,6 @@
         void dumpState(std::string& out) const override { mState.dump(out); }
 
         const compositionengine::Output& mOutput;
-        std::shared_ptr<compositionengine::Layer> mLayer;
         sp<compositionengine::LayerFE> mLayerFE;
         impl::OutputLayerCompositionState mState;
     };
@@ -82,16 +77,14 @@
         EXPECT_CALL(*mLayerFE, getDebugName()).WillRepeatedly(Return("Test LayerFE"));
         EXPECT_CALL(mOutput, getName()).WillRepeatedly(ReturnRef(kOutputName));
 
-        EXPECT_CALL(*mLayer, getFEState()).WillRepeatedly(ReturnRef(mLayerFEState));
+        EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
         EXPECT_CALL(mOutput, getState()).WillRepeatedly(ReturnRef(mOutputState));
     }
 
     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>()};
-    OutputLayer mOutputLayer{mOutput, mLayer, mLayerFE};
+    OutputLayer mOutputLayer{mOutput, mLayerFE};
 
     LayerFECompositionState mLayerFEState;
     impl::OutputCompositionState mOutputState;
@@ -436,9 +429,8 @@
 
 struct OutputLayerPartialMockForUpdateCompositionState : public impl::OutputLayer {
     OutputLayerPartialMockForUpdateCompositionState(const compositionengine::Output& output,
-                                                    std::shared_ptr<compositionengine::Layer> layer,
                                                     sp<compositionengine::LayerFE> layerFE)
-          : mOutput(output), mLayer(layer), mLayerFE(layerFE) {}
+          : mOutput(output), mLayerFE(layerFE) {}
     // Mock everything called by updateCompositionState to simplify testing it.
     MOCK_CONST_METHOD0(calculateOutputSourceCrop, FloatRect());
     MOCK_CONST_METHOD0(calculateOutputDisplayFrame, Rect());
@@ -446,7 +438,6 @@
 
     // compositionengine::OutputLayer overrides
     const compositionengine::Output& getOutput() const override { return mOutput; }
-    compositionengine::Layer& getLayer() const override { return *mLayer; }
     compositionengine::LayerFE& getLayerFE() const override { return *mLayerFE; }
     const impl::OutputLayerCompositionState& getState() const override { return mState; }
     impl::OutputLayerCompositionState& editState() override { return mState; }
@@ -455,7 +446,6 @@
     MOCK_CONST_METHOD1(dumpState, void(std::string&));
 
     const compositionengine::Output& mOutput;
-    std::shared_ptr<compositionengine::Layer> mLayer;
     sp<compositionengine::LayerFE> mLayerFE;
     impl::OutputLayerCompositionState mState;
 };
@@ -463,7 +453,6 @@
 struct OutputLayerUpdateCompositionStateTest : public OutputLayerTest {
 public:
     OutputLayerUpdateCompositionStateTest() {
-        EXPECT_CALL(*mLayer, getFEState()).WillRepeatedly(ReturnRef(mLayerFEState));
         EXPECT_CALL(mOutput, getState()).WillRepeatedly(ReturnRef(mOutputState));
         EXPECT_CALL(mOutput, getDisplayColorProfile())
                 .WillRepeatedly(Return(&mDisplayColorProfile));
@@ -491,10 +480,16 @@
     uint32_t mBufferTransform{21};
 
     using OutputLayer = OutputLayerPartialMockForUpdateCompositionState;
-    StrictMock<OutputLayer> mOutputLayer{mOutput, mLayer, mLayerFE};
+    StrictMock<OutputLayer> mOutputLayer{mOutput, mLayerFE};
     StrictMock<mock::DisplayColorProfile> mDisplayColorProfile;
 };
 
+TEST_F(OutputLayerUpdateCompositionStateTest, doesNothingIfNoFECompositionState) {
+    EXPECT_CALL(*mLayerFE, getCompositionState()).WillOnce(Return(nullptr));
+
+    mOutputLayer.updateCompositionState(true, false);
+}
+
 TEST_F(OutputLayerUpdateCompositionStateTest, setsStateNormally) {
     mLayerFEState.isSecure = true;
     mOutputState.isSecure = true;
@@ -745,6 +740,12 @@
 const sp<GraphicBuffer> OutputLayerWriteStateToHWCTest::kBuffer;
 const sp<Fence> OutputLayerWriteStateToHWCTest::kFence;
 
+TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoFECompositionState) {
+    EXPECT_CALL(*mLayerFE, getCompositionState()).WillOnce(Return(nullptr));
+
+    mOutputLayer.writeStateToHWC(true);
+}
+
 TEST_F(OutputLayerWriteStateToHWCTest, doesNothingIfNoHWCState) {
     mOutputLayer.editState().hwc.reset();
 
@@ -888,6 +889,12 @@
 const Rect OutputLayerWriteCursorPositionToHWCTest::kDefaultDisplayViewport{0, 0, 1920, 1080};
 const Rect OutputLayerWriteCursorPositionToHWCTest::kDefaultCursorFrame{1, 2, 3, 4};
 
+TEST_F(OutputLayerWriteCursorPositionToHWCTest, doesNothingIfNoFECompositionState) {
+    EXPECT_CALL(*mLayerFE, getCompositionState()).WillOnce(Return(nullptr));
+
+    mOutputLayer.writeCursorPositionToHWC();
+}
+
 TEST_F(OutputLayerWriteCursorPositionToHWCTest, writeCursorPositionToHWCHandlesNoHwcState) {
     mOutputLayer.editState().hwc.reset();
 
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index 463d095..2b45046 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -23,7 +23,6 @@
 #include <compositionengine/impl/OutputLayerCompositionState.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>
@@ -78,22 +77,48 @@
     // not implemented by the base implementation class.
     MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
     MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
-    MOCK_METHOD3(ensureOutputLayer,
-                 compositionengine::OutputLayer*(std::optional<size_t>,
-                                                 const std::shared_ptr<compositionengine::Layer>&,
-                                                 const sp<LayerFE>&));
+    MOCK_METHOD2(ensureOutputLayer,
+                 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
     MOCK_METHOD0(finalizePendingOutputLayers, void());
     MOCK_METHOD0(clearOutputLayers, void());
     MOCK_CONST_METHOD1(dumpState, void(std::string&));
     MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
-    MOCK_METHOD2(injectOutputLayerForTest,
-                 compositionengine::OutputLayer*(const std::shared_ptr<compositionengine::Layer>&,
-                                                 const sp<LayerFE>&));
+    MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
     MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
 
     impl::OutputCompositionState mState;
 };
 
+struct InjectedLayer {
+    InjectedLayer() {
+        EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
+        EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
+        EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
+
+        EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
+    }
+
+    mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
+    sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
+    LayerFECompositionState layerFEState;
+    impl::OutputLayerCompositionState outputLayerState;
+};
+
+struct NonInjectedLayer {
+    NonInjectedLayer() {
+        EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
+        EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
+        EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
+
+        EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
+    }
+
+    mock::OutputLayer outputLayer;
+    sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
+    LayerFECompositionState layerFEState;
+    impl::OutputLayerCompositionState outputLayerState;
+};
+
 struct OutputTest : public testing::Test {
     class Output : public impl::Output {
     public:
@@ -114,6 +139,14 @@
         mOutput->editState().bounds = kDefaultDisplaySize;
     }
 
+    void injectOutputLayer(InjectedLayer& layer) {
+        mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
+    }
+
+    void injectNullOutputLayer() {
+        mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
+    }
+
     static const Rect kDefaultDisplaySize;
 
     StrictMock<mock::CompositionEngine> mCompositionEngine;
@@ -122,48 +155,6 @@
     std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
 };
 
-// Extension of the base test useful for checking interactions with the LayerFE
-// functions to latch composition state.
-struct OutputLatchFEStateTest : public OutputTest {
-    OutputLatchFEStateTest() {
-        EXPECT_CALL(*mOutputLayer1, getLayer()).WillRepeatedly(ReturnRef(mLayer1));
-        EXPECT_CALL(*mOutputLayer2, getLayer()).WillRepeatedly(ReturnRef(mLayer2));
-        EXPECT_CALL(*mOutputLayer3, getLayer()).WillRepeatedly(ReturnRef(mLayer3));
-
-        EXPECT_CALL(*mOutputLayer1, getLayerFE()).WillRepeatedly(ReturnRef(mLayer1FE));
-        EXPECT_CALL(*mOutputLayer2, getLayerFE()).WillRepeatedly(ReturnRef(mLayer2FE));
-        EXPECT_CALL(*mOutputLayer3, getLayerFE()).WillRepeatedly(ReturnRef(mLayer3FE));
-
-        EXPECT_CALL(mLayer1, editFEState()).WillRepeatedly(ReturnRef(mLayer1FEState));
-        EXPECT_CALL(mLayer2, editFEState()).WillRepeatedly(ReturnRef(mLayer2FEState));
-        EXPECT_CALL(mLayer3, editFEState()).WillRepeatedly(ReturnRef(mLayer3FEState));
-
-        EXPECT_CALL(mLayer1, getFEState()).WillRepeatedly(ReturnRef(mLayer1FEState));
-        EXPECT_CALL(mLayer2, getFEState()).WillRepeatedly(ReturnRef(mLayer2FEState));
-        EXPECT_CALL(mLayer3, getFEState()).WillRepeatedly(ReturnRef(mLayer3FEState));
-    }
-
-    void injectLayer(std::unique_ptr<mock::OutputLayer> layer) {
-        mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.release()));
-    }
-
-    std::unique_ptr<mock::OutputLayer> mOutputLayer1{new StrictMock<mock::OutputLayer>};
-    std::unique_ptr<mock::OutputLayer> mOutputLayer2{new StrictMock<mock::OutputLayer>};
-    std::unique_ptr<mock::OutputLayer> mOutputLayer3{new StrictMock<mock::OutputLayer>};
-
-    StrictMock<mock::Layer> mLayer1;
-    StrictMock<mock::Layer> mLayer2;
-    StrictMock<mock::Layer> mLayer3;
-
-    StrictMock<mock::LayerFE> mLayer1FE;
-    StrictMock<mock::LayerFE> mLayer2FE;
-    StrictMock<mock::LayerFE> mLayer3FE;
-
-    LayerFECompositionState mLayer1FEState;
-    LayerFECompositionState mLayer2FEState;
-    LayerFECompositionState mLayer3FEState;
-};
-
 const Rect OutputTest::kDefaultDisplaySize{100, 200};
 
 using ColorProfile = compositionengine::Output::ColorProfile;
@@ -503,11 +494,18 @@
     EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
 }
 
-TEST_F(OutputTest, belongsInOutputFiltersLayersAsExpected) {
-    StrictMock<mock::Layer> layer;
-    LayerFECompositionState layerFEState;
+TEST_F(OutputTest, belongsInOutputHandlesLayerWithNoCompositionState) {
+    NonInjectedLayer layer;
+    sp<LayerFE> layerFE(layer.layerFE);
 
-    EXPECT_CALL(layer, getFEState()).WillRepeatedly(ReturnRef(layerFEState));
+    // If the layer has no composition state, it does not belong to any output.
+    EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
+    EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
+}
+
+TEST_F(OutputTest, belongsInOutputFiltersLayersAsExpected) {
+    NonInjectedLayer layer;
+    sp<LayerFE> layerFE(layer.layerFE);
 
     const uint32_t layerStack1 = 123u;
     const uint32_t layerStack2 = 456u;
@@ -515,57 +513,51 @@
     // If the output accepts layerStack1 and internal-only layers....
     mOutput->setLayerStackFilter(layerStack1, true);
 
-    // A null layer pointer does not belong to the output
-    EXPECT_FALSE(mOutput->belongsInOutput(nullptr));
-
     // A layer with no layerStack does not belong to it, internal-only or not.
-    layerFEState.layerStackId = std::nullopt;
-    layerFEState.internalOnly = false;
-    EXPECT_FALSE(mOutput->belongsInOutput(&layer));
+    layer.layerFEState.layerStackId = std::nullopt;
+    layer.layerFEState.internalOnly = false;
+    EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
 
-    layerFEState.layerStackId = std::nullopt;
-    layerFEState.internalOnly = true;
-    EXPECT_FALSE(mOutput->belongsInOutput(&layer));
+    layer.layerFEState.layerStackId = std::nullopt;
+    layer.layerFEState.internalOnly = true;
+    EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
 
     // Any layer with layerStack1 belongs to it, internal-only or not.
-    layerFEState.layerStackId = layerStack1;
-    layerFEState.internalOnly = false;
-    EXPECT_TRUE(mOutput->belongsInOutput(&layer));
+    layer.layerFEState.layerStackId = layerStack1;
+    layer.layerFEState.internalOnly = false;
+    EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
 
-    layerFEState.layerStackId = layerStack1;
-    layerFEState.internalOnly = true;
-    EXPECT_TRUE(mOutput->belongsInOutput(&layer));
+    layer.layerFEState.layerStackId = layerStack1;
+    layer.layerFEState.internalOnly = true;
+    EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
 
-    layerFEState.layerStackId = layerStack2;
-    layerFEState.internalOnly = true;
-    EXPECT_FALSE(mOutput->belongsInOutput(&layer));
+    layer.layerFEState.layerStackId = layerStack2;
+    layer.layerFEState.internalOnly = true;
+    EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
 
-    layerFEState.layerStackId = layerStack2;
-    layerFEState.internalOnly = false;
-    EXPECT_FALSE(mOutput->belongsInOutput(&layer));
+    layer.layerFEState.layerStackId = layerStack2;
+    layer.layerFEState.internalOnly = false;
+    EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
 
     // If the output accepts layerStack1 but not internal-only layers...
     mOutput->setLayerStackFilter(layerStack1, false);
 
-    // A null layer pointer does not belong to the output
-    EXPECT_FALSE(mOutput->belongsInOutput(nullptr));
-
     // Only non-internal layers with layerStack1 belong to it.
-    layerFEState.layerStackId = layerStack1;
-    layerFEState.internalOnly = false;
-    EXPECT_TRUE(mOutput->belongsInOutput(&layer));
+    layer.layerFEState.layerStackId = layerStack1;
+    layer.layerFEState.internalOnly = false;
+    EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
 
-    layerFEState.layerStackId = layerStack1;
-    layerFEState.internalOnly = true;
-    EXPECT_FALSE(mOutput->belongsInOutput(&layer));
+    layer.layerFEState.layerStackId = layerStack1;
+    layer.layerFEState.internalOnly = true;
+    EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
 
-    layerFEState.layerStackId = layerStack2;
-    layerFEState.internalOnly = true;
-    EXPECT_FALSE(mOutput->belongsInOutput(&layer));
+    layer.layerFEState.layerStackId = layerStack2;
+    layer.layerFEState.internalOnly = true;
+    EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
 
-    layerFEState.layerStackId = layerStack2;
-    layerFEState.internalOnly = false;
-    EXPECT_FALSE(mOutput->belongsInOutput(&layer));
+    layer.layerFEState.layerStackId = layerStack2;
+    layer.layerFEState.internalOnly = false;
+    EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
 }
 
 /*
@@ -573,29 +565,27 @@
  */
 
 TEST_F(OutputTest, getOutputLayerForLayerWorks) {
-    mock::OutputLayer* outputLayer1 = new StrictMock<mock::OutputLayer>();
-    mock::OutputLayer* outputLayer2 = new StrictMock<mock::OutputLayer>();
+    InjectedLayer layer1;
+    InjectedLayer layer2;
+    NonInjectedLayer layer3;
 
-    mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(outputLayer1));
-    mOutput->injectOutputLayerForTest(nullptr);
-    mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(outputLayer2));
-
-    StrictMock<mock::Layer> layer;
-    StrictMock<mock::Layer> otherLayer;
+    injectOutputLayer(layer1);
+    injectNullOutputLayer();
+    injectOutputLayer(layer2);
 
     // 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));
+    EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
+    EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
 
     // 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));
+    EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
+    EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
+    EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
 
     // 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));
+    EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
+    EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
+    EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
 }
 
 /*
@@ -627,7 +617,7 @@
  * Output::updateLayerStateFromFE()
  */
 
-using OutputUpdateLayerStateFromFETest = OutputLatchFEStateTest;
+using OutputUpdateLayerStateFromFETest = OutputTest;
 
 TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
     CompositionRefreshArgs refreshArgs;
@@ -635,18 +625,18 @@
     mOutput->updateLayerStateFromFE(refreshArgs);
 }
 
-TEST_F(OutputUpdateLayerStateFromFETest, latchesContentStateForAllContainedLayers) {
-    EXPECT_CALL(mLayer1FE,
-                latchCompositionState(Ref(mLayer1FEState), LayerFE::StateSubset::Content));
-    EXPECT_CALL(mLayer2FE,
-                latchCompositionState(Ref(mLayer2FEState), LayerFE::StateSubset::Content));
-    EXPECT_CALL(mLayer3FE,
-                latchCompositionState(Ref(mLayer3FEState), LayerFE::StateSubset::Content));
+TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
+    InjectedLayer layer1;
+    InjectedLayer layer2;
+    InjectedLayer layer3;
 
-    // Note: Must be performed after any expectations on these mocks
-    injectLayer(std::move(mOutputLayer1));
-    injectLayer(std::move(mOutputLayer2));
-    injectLayer(std::move(mOutputLayer3));
+    EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
+    EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
+    EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
+
+    injectOutputLayer(layer1);
+    injectOutputLayer(layer2);
+    injectOutputLayer(layer3);
 
     CompositionRefreshArgs refreshArgs;
     refreshArgs.updatingGeometryThisFrame = false;
@@ -654,21 +644,18 @@
     mOutput->updateLayerStateFromFE(refreshArgs);
 }
 
-TEST_F(OutputUpdateLayerStateFromFETest, latchesGeometryAndContentStateForAllContainedLayers) {
-    EXPECT_CALL(mLayer1FE,
-                latchCompositionState(Ref(mLayer1FEState),
-                                      LayerFE::StateSubset::GeometryAndContent));
-    EXPECT_CALL(mLayer2FE,
-                latchCompositionState(Ref(mLayer2FEState),
-                                      LayerFE::StateSubset::GeometryAndContent));
-    EXPECT_CALL(mLayer3FE,
-                latchCompositionState(Ref(mLayer3FEState),
-                                      LayerFE::StateSubset::GeometryAndContent));
+TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
+    InjectedLayer layer1;
+    InjectedLayer layer2;
+    InjectedLayer layer3;
 
-    // Note: Must be performed after any expectations on these mocks
-    injectLayer(std::move(mOutputLayer1));
-    injectLayer(std::move(mOutputLayer2));
-    injectLayer(std::move(mOutputLayer3));
+    EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
+    EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
+    EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
+
+    injectOutputLayer(layer1);
+    injectOutputLayer(layer2);
+    injectOutputLayer(layer3);
 
     CompositionRefreshArgs refreshArgs;
     refreshArgs.updatingGeometryThisFrame = true;
@@ -680,7 +667,7 @@
  * Output::updateAndWriteCompositionState()
  */
 
-using OutputUpdateAndWriteCompositionStateTest = OutputLatchFEStateTest;
+using OutputUpdateAndWriteCompositionStateTest = OutputTest;
 
 TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
     mOutput->editState().isEnabled = true;
@@ -690,27 +677,35 @@
 }
 
 TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
+    InjectedLayer layer1;
+    InjectedLayer layer2;
+    InjectedLayer layer3;
+
     mOutput->editState().isEnabled = false;
 
-    injectLayer(std::move(mOutputLayer1));
-    injectLayer(std::move(mOutputLayer2));
-    injectLayer(std::move(mOutputLayer3));
+    injectOutputLayer(layer1);
+    injectOutputLayer(layer2);
+    injectOutputLayer(layer3);
 
     CompositionRefreshArgs args;
     mOutput->updateAndWriteCompositionState(args);
 }
 
 TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
-    EXPECT_CALL(*mOutputLayer1, updateCompositionState(false, false));
-    EXPECT_CALL(*mOutputLayer1, writeStateToHWC(false));
-    EXPECT_CALL(*mOutputLayer2, updateCompositionState(false, false));
-    EXPECT_CALL(*mOutputLayer2, writeStateToHWC(false));
-    EXPECT_CALL(*mOutputLayer3, updateCompositionState(false, false));
-    EXPECT_CALL(*mOutputLayer3, writeStateToHWC(false));
+    InjectedLayer layer1;
+    InjectedLayer layer2;
+    InjectedLayer layer3;
 
-    injectLayer(std::move(mOutputLayer1));
-    injectLayer(std::move(mOutputLayer2));
-    injectLayer(std::move(mOutputLayer3));
+    EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false));
+    EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
+    EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false));
+    EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
+    EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false));
+    EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
+
+    injectOutputLayer(layer1);
+    injectOutputLayer(layer2);
+    injectOutputLayer(layer3);
 
     mOutput->editState().isEnabled = true;
 
@@ -721,16 +716,20 @@
 }
 
 TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
-    EXPECT_CALL(*mOutputLayer1, updateCompositionState(true, false));
-    EXPECT_CALL(*mOutputLayer1, writeStateToHWC(true));
-    EXPECT_CALL(*mOutputLayer2, updateCompositionState(true, false));
-    EXPECT_CALL(*mOutputLayer2, writeStateToHWC(true));
-    EXPECT_CALL(*mOutputLayer3, updateCompositionState(true, false));
-    EXPECT_CALL(*mOutputLayer3, writeStateToHWC(true));
+    InjectedLayer layer1;
+    InjectedLayer layer2;
+    InjectedLayer layer3;
 
-    injectLayer(std::move(mOutputLayer1));
-    injectLayer(std::move(mOutputLayer2));
-    injectLayer(std::move(mOutputLayer3));
+    EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false));
+    EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(true));
+    EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false));
+    EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(true));
+    EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false));
+    EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(true));
+
+    injectOutputLayer(layer1);
+    injectOutputLayer(layer2);
+    injectOutputLayer(layer3);
 
     mOutput->editState().isEnabled = true;
 
@@ -741,16 +740,20 @@
 }
 
 TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
-    EXPECT_CALL(*mOutputLayer1, updateCompositionState(false, true));
-    EXPECT_CALL(*mOutputLayer1, writeStateToHWC(false));
-    EXPECT_CALL(*mOutputLayer2, updateCompositionState(false, true));
-    EXPECT_CALL(*mOutputLayer2, writeStateToHWC(false));
-    EXPECT_CALL(*mOutputLayer3, updateCompositionState(false, true));
-    EXPECT_CALL(*mOutputLayer3, writeStateToHWC(false));
+    InjectedLayer layer1;
+    InjectedLayer layer2;
+    InjectedLayer layer3;
 
-    injectLayer(std::move(mOutputLayer1));
-    injectLayer(std::move(mOutputLayer2));
-    injectLayer(std::move(mOutputLayer3));
+    EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true));
+    EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
+    EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true));
+    EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
+    EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true));
+    EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
+
+    injectOutputLayer(layer1);
+    injectOutputLayer(layer2);
+    injectOutputLayer(layer3);
 
     mOutput->editState().isEnabled = true;
 
@@ -972,7 +975,7 @@
         // Sets up the helper functions called by the function under test to use
         // mock implementations.
         MOCK_METHOD2(ensureOutputLayerIfVisible,
-                     void(std::shared_ptr<compositionengine::Layer>,
+                     void(sp<compositionengine::LayerFE>&,
                           compositionengine::Output::CoverageState&));
         MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
         MOCK_METHOD0(finalizePendingOutputLayers, void());
@@ -985,8 +988,8 @@
         }
 
         StrictMock<mock::OutputLayer> outputLayer;
-        std::shared_ptr<StrictMock<mock::Layer>> layer{new StrictMock<mock::Layer>()};
         impl::OutputLayerCompositionState outputLayerState;
+        sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
     };
 
     OutputCollectVisibleLayersTest() {
@@ -998,9 +1001,9 @@
         EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
                 .WillRepeatedly(Return(&mLayer3.outputLayer));
 
-        mRefreshArgs.layers.push_back(mLayer1.layer);
-        mRefreshArgs.layers.push_back(mLayer2.layer);
-        mRefreshArgs.layers.push_back(mLayer3.layer);
+        mRefreshArgs.layers.push_back(mLayer1.layerFE);
+        mRefreshArgs.layers.push_back(mLayer2.layerFE);
+        mRefreshArgs.layers.push_back(mLayer3.layerFE);
     }
 
     StrictMock<OutputPartialMock> mOutput;
@@ -1027,9 +1030,9 @@
     InSequence seq;
 
     // Layer coverage is evaluated from front to back!
-    EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layer), Ref(mCoverageState)));
-    EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layer), Ref(mCoverageState)));
-    EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layer), Ref(mCoverageState)));
+    EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
+    EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
+    EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
 
     EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
     EXPECT_CALL(mOutput, finalizePendingOutputLayers());
@@ -1050,43 +1053,39 @@
     struct OutputPartialMock : public OutputPartialMockBase {
         // Sets up the helper functions called by the function under test to use
         // mock implementations.
-        MOCK_CONST_METHOD1(belongsInOutput, bool(const compositionengine::Layer*));
+        MOCK_CONST_METHOD1(belongsInOutput, bool(const sp<compositionengine::LayerFE>&));
         MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
-        MOCK_METHOD3(ensureOutputLayer,
-                     compositionengine::OutputLayer*(
-                             std::optional<size_t>,
-                             const std::shared_ptr<compositionengine::Layer>&, const sp<LayerFE>&));
+        MOCK_METHOD2(ensureOutputLayer,
+                     compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
     };
 
     OutputEnsureOutputLayerIfVisibleTest() {
-        EXPECT_CALL(*mLayer, getLayerFE()).WillRepeatedly(Return(mLayerFE));
-        EXPECT_CALL(*mLayer, getFEState()).WillRepeatedly(ReturnRef(mLayerFEState));
-        EXPECT_CALL(*mLayer, editFEState()).WillRepeatedly(ReturnRef(mLayerFEState));
-
-        EXPECT_CALL(mOutput, belongsInOutput(mLayer.get())).WillRepeatedly(Return(true));
+        EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE)))
+                .WillRepeatedly(Return(true));
         EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
         EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
-                .WillRepeatedly(Return(&mOutputLayer));
-
-        EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
-        EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
-        EXPECT_CALL(mOutputLayer, getLayer()).WillRepeatedly(ReturnRef(*mLayer.get()));
+                .WillRepeatedly(Return(&mLayer.outputLayer));
 
         mOutput.mState.bounds = Rect(0, 0, 200, 300);
         mOutput.mState.viewport = Rect(0, 0, 200, 300);
         mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
 
-        mLayerFEState.isVisible = true;
-        mLayerFEState.isOpaque = true;
-        mLayerFEState.contentDirty = true;
-        mLayerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
-        mLayerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
-        mLayerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
+        mLayer.layerFEState.isVisible = true;
+        mLayer.layerFEState.isOpaque = true;
+        mLayer.layerFEState.contentDirty = true;
+        mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
+        mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
+        mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
 
-        mOutputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
-        mOutputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
+        mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
+        mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
 
-        mGeomSnapshots.insert(mLayerFE);
+        mGeomSnapshots.insert(mLayer.layerFE);
+    }
+
+    void ensureOutputLayerIfVisible() {
+        sp<LayerFE> layerFE(mLayer.layerFE);
+        mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
     }
 
     static const Region kEmptyRegion;
@@ -1099,11 +1098,7 @@
     LayerFESet mGeomSnapshots;
     Output::CoverageState mCoverageState{mGeomSnapshots};
 
-    std::shared_ptr<mock::Layer> mLayer{new StrictMock<mock::Layer>()};
-    sp<StrictMock<mock::LayerFE>> mLayerFE{new StrictMock<mock::LayerFE>()};
-    LayerFECompositionState mLayerFEState;
-    mock::OutputLayer mOutputLayer;
-    impl::OutputLayerCompositionState mOutputLayerState;
+    NonInjectedLayer mLayer;
 };
 
 const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
@@ -1116,275 +1111,282 @@
 const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
         Region(Rect(0, 0, 200, 100));
 
-TEST_F(OutputEnsureOutputLayerIfVisibleTest, doesNothingIfNoLayerFE) {
-    EXPECT_CALL(*mLayer, getLayerFE).WillOnce(Return(sp<LayerFE>()));
-
-    mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
-}
-
 TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerBelongs) {
-    EXPECT_CALL(mOutput, belongsInOutput(mLayer.get())).WillOnce(Return(false));
-    EXPECT_CALL(*mLayerFE.get(),
-                latchCompositionState(Ref(mLayerFEState),
-                                      compositionengine::LayerFE::StateSubset::BasicGeometry));
+    EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
+    EXPECT_CALL(*mLayer.layerFE,
+                prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
 
     mGeomSnapshots.clear();
 
-    mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
+    ensureOutputLayerIfVisible();
 }
 
 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
        skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerBelongs) {
-    EXPECT_CALL(mOutput, belongsInOutput(mLayer.get())).WillOnce(Return(false));
+    EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
 
-    mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
+    ensureOutputLayerIfVisible();
+}
+
+TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
+    EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
+
+    ensureOutputLayerIfVisible();
 }
 
 TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
-    mLayerFEState.isVisible = false;
+    mLayer.layerFEState.isVisible = false;
 
-    mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
+    ensureOutputLayerIfVisible();
 }
 
 TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
-    mLayerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
+    mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
 
-    mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
+    ensureOutputLayerIfVisible();
 }
 
 TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
     mOutput.mState.bounds = Rect(0, 0, 0, 0);
 
-    mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
+    ensureOutputLayerIfVisible();
 }
 
 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
        handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
-    mLayerFEState.isOpaque = true;
-    mLayerFEState.contentDirty = true;
-    mLayerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
+    mLayer.layerFEState.isOpaque = true;
+    mLayer.layerFEState.contentDirty = true;
+    mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
 
     EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
-    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer), Eq(mLayerFE)))
-            .WillOnce(Return(&mOutputLayer));
+    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
+            .WillOnce(Return(&mLayer.outputLayer));
 
-    mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
+    ensureOutputLayerIfVisible();
 
     EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
     EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
     EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
 
-    EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
-    EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion, RegionEq(kFullBoundsNoRotation));
-    EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
-    EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
+                RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
+    EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
 }
 
 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
        handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
-    mLayerFEState.isOpaque = true;
-    mLayerFEState.contentDirty = true;
-    mLayerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
+    mLayer.layerFEState.isOpaque = true;
+    mLayer.layerFEState.contentDirty = true;
+    mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
 
-    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer), Eq(mLayerFE)))
-            .WillOnce(Return(&mOutputLayer));
+    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
+            .WillOnce(Return(&mLayer.outputLayer));
 
-    mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
+    ensureOutputLayerIfVisible();
 
     EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
     EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
     EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
 
-    EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
-    EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion, RegionEq(kFullBoundsNoRotation));
-    EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
-    EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
+                RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
+    EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
 }
 
 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
        handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
-    mLayerFEState.isOpaque = false;
-    mLayerFEState.contentDirty = true;
-    mLayerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
+    mLayer.layerFEState.isOpaque = false;
+    mLayer.layerFEState.contentDirty = true;
+    mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
 
     EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
-    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer), Eq(mLayerFE)))
-            .WillOnce(Return(&mOutputLayer));
+    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
+            .WillOnce(Return(&mLayer.outputLayer));
 
-    mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
+    ensureOutputLayerIfVisible();
 
     EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
     EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
     EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
 
-    EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
-    EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion,
+    EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
                 RegionEq(kRightHalfBoundsNoRotation));
-    EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
-    EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
+    EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
 }
 
 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
        handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
-    mLayerFEState.isOpaque = false;
-    mLayerFEState.contentDirty = true;
-    mLayerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
+    mLayer.layerFEState.isOpaque = false;
+    mLayer.layerFEState.contentDirty = true;
+    mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
 
-    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer), Eq(mLayerFE)))
-            .WillOnce(Return(&mOutputLayer));
+    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
+            .WillOnce(Return(&mLayer.outputLayer));
 
-    mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
+    ensureOutputLayerIfVisible();
 
     EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
     EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
     EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
 
-    EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
-    EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion,
+    EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
                 RegionEq(kRightHalfBoundsNoRotation));
-    EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
-    EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
+    EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
 }
 
 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
        handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
-    mLayerFEState.isOpaque = true;
-    mLayerFEState.contentDirty = false;
-    mLayerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
+    mLayer.layerFEState.isOpaque = true;
+    mLayer.layerFEState.contentDirty = false;
+    mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
 
     EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
-    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer), Eq(mLayerFE)))
-            .WillOnce(Return(&mOutputLayer));
+    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
+            .WillOnce(Return(&mLayer.outputLayer));
 
-    mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
+    ensureOutputLayerIfVisible();
 
     EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
     EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
     EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
 
-    EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
-    EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion, RegionEq(kFullBoundsNoRotation));
-    EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
-    EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
+                RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
+    EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
 }
 
 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
        handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
-    mLayerFEState.isOpaque = true;
-    mLayerFEState.contentDirty = false;
-    mLayerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
+    mLayer.layerFEState.isOpaque = true;
+    mLayer.layerFEState.contentDirty = false;
+    mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
 
-    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer), Eq(mLayerFE)))
-            .WillOnce(Return(&mOutputLayer));
+    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
+            .WillOnce(Return(&mLayer.outputLayer));
 
-    mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
+    ensureOutputLayerIfVisible();
 
     EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
     EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
     EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
 
-    EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
-    EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion, RegionEq(kFullBoundsNoRotation));
-    EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
-    EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
+                RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
+    EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
 }
 
 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
        handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
-    mLayerFEState.isOpaque = true;
-    mLayerFEState.contentDirty = true;
-    mLayerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
-    mLayerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
-    mOutputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
-    mOutputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
+    mLayer.layerFEState.isOpaque = true;
+    mLayer.layerFEState.contentDirty = true;
+    mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
+    mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
+    mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
+    mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
 
     EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
-    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer), Eq(mLayerFE)))
-            .WillOnce(Return(&mOutputLayer));
+    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
+            .WillOnce(Return(&mLayer.outputLayer));
 
-    mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
+    ensureOutputLayerIfVisible();
 
     EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
     EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
     EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
 
-    EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
-    EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion, RegionEq(kFullBoundsNoRotation));
-    EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
-    EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
+                RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
+    EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
 }
 
 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
        handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
-    mLayerFEState.isOpaque = true;
-    mLayerFEState.contentDirty = true;
-    mLayerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
-    mLayerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
-    mOutputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
-    mOutputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
+    mLayer.layerFEState.isOpaque = true;
+    mLayer.layerFEState.contentDirty = true;
+    mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
+    mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
+    mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
+    mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
 
-    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer), Eq(mLayerFE)))
-            .WillOnce(Return(&mOutputLayer));
+    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
+            .WillOnce(Return(&mLayer.outputLayer));
 
-    mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
+    ensureOutputLayerIfVisible();
 
     EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
     EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
     EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
 
-    EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
-    EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion, RegionEq(kFullBoundsNoRotation));
-    EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
-    EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
+                RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
+    EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
 }
 
 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
        handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
-    mLayerFEState.isOpaque = true;
-    mLayerFEState.contentDirty = true;
-    mLayerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
+    mLayer.layerFEState.isOpaque = true;
+    mLayer.layerFEState.contentDirty = true;
+    mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
 
     mOutput.mState.viewport = Rect(0, 0, 300, 200);
     mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
 
     EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
-    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer), Eq(mLayerFE)))
-            .WillOnce(Return(&mOutputLayer));
+    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
+            .WillOnce(Return(&mLayer.outputLayer));
 
-    mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
+    ensureOutputLayerIfVisible();
 
     EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
     EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
     EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
 
-    EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
-    EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion, RegionEq(kFullBoundsNoRotation));
-    EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
-    EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
+    EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
+                RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
+    EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
 }
 
 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
        handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
-    mLayerFEState.isOpaque = true;
-    mLayerFEState.contentDirty = true;
-    mLayerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
+    mLayer.layerFEState.isOpaque = true;
+    mLayer.layerFEState.contentDirty = true;
+    mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
 
     mOutput.mState.viewport = Rect(0, 0, 300, 200);
     mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
 
-    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer), Eq(mLayerFE)))
-            .WillOnce(Return(&mOutputLayer));
+    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
+            .WillOnce(Return(&mLayer.outputLayer));
 
-    mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
+    ensureOutputLayerIfVisible();
 
     EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
     EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
     EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
 
-    EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
-    EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion, RegionEq(kFullBoundsNoRotation));
-    EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
-    EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
+    EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
+                RegionEq(kFullBoundsNoRotation));
+    EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
+    EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
 }
 
 TEST_F(OutputEnsureOutputLayerIfVisibleTest,
@@ -1393,16 +1395,16 @@
     arbitraryTransform.set(1, 1, -1, 1);
     arbitraryTransform.set(0, 100);
 
-    mLayerFEState.isOpaque = true;
-    mLayerFEState.contentDirty = true;
-    mLayerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
-    mLayerFEState.geomLayerTransform = arbitraryTransform;
+    mLayer.layerFEState.isOpaque = true;
+    mLayer.layerFEState.contentDirty = true;
+    mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
+    mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
 
     EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
-    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer), Eq(mLayerFE)))
-            .WillOnce(Return(&mOutputLayer));
+    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
+            .WillOnce(Return(&mLayer.outputLayer));
 
-    mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
+    ensureOutputLayerIfVisible();
 
     const Region kRegion = Region(Rect(0, 0, 300, 300));
     const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
@@ -1411,25 +1413,25 @@
     EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
     EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
 
-    EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kRegion));
-    EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
-    EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
-    EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
+    EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
+    EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
+    EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
+    EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
 }
 
 TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
-    mLayerFEState.isOpaque = false;
-    mLayerFEState.contentDirty = true;
-    mLayerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
+    mLayer.layerFEState.isOpaque = false;
+    mLayer.layerFEState.contentDirty = true;
+    mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
 
     mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
     mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
     mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
 
-    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer), Eq(mLayerFE)))
-            .WillOnce(Return(&mOutputLayer));
+    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
+            .WillOnce(Return(&mLayer.outputLayer));
 
-    mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
+    ensureOutputLayerIfVisible();
 
     const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
     const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
@@ -1442,28 +1444,29 @@
     EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
     EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
 
-    EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
-    EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion,
+    EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
+    EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
                 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
-    EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
-    EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kExpectedLayerVisibleRegion));
+    EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
+    EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
+                RegionEq(kExpectedLayerVisibleRegion));
 }
 
 TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
     ui::Transform translate;
     translate.set(50, 50);
-    mLayerFEState.geomLayerTransform = translate;
-    mLayerFEState.shadowRadius = 10.0f;
+    mLayer.layerFEState.geomLayerTransform = translate;
+    mLayer.layerFEState.shadowRadius = 10.0f;
 
     mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
     // half of the layer including the casting shadow is covered and opaque
     mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
     mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
 
-    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer), Eq(mLayerFE)))
-            .WillOnce(Return(&mOutputLayer));
+    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
+            .WillOnce(Return(&mLayer.outputLayer));
 
-    mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
+    ensureOutputLayerIfVisible();
 
     const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
     const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
@@ -1481,53 +1484,53 @@
     EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
     EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
 
-    EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
-    EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion,
+    EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
+    EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
                 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
-    EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
-    EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion,
+    EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
+    EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
                 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
-    EXPECT_THAT(mOutputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
+    EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
     EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
 }
 
 TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
     ui::Transform translate;
     translate.set(50, 50);
-    mLayerFEState.geomLayerTransform = translate;
-    mLayerFEState.shadowRadius = 10.0f;
+    mLayer.layerFEState.geomLayerTransform = translate;
+    mLayer.layerFEState.shadowRadius = 10.0f;
 
     mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
     // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
     mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
     mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
 
-    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer), Eq(mLayerFE)))
-            .WillOnce(Return(&mOutputLayer));
+    EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
+            .WillOnce(Return(&mLayer.outputLayer));
 
-    mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
+    ensureOutputLayerIfVisible();
 
     const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
     const Region kExpectedLayerShadowRegion =
             Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
 
-    EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
-    EXPECT_THAT(mOutputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
+    EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
+    EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
     EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
 }
 
 TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
     ui::Transform translate;
     translate.set(50, 50);
-    mLayerFEState.geomLayerTransform = translate;
-    mLayerFEState.shadowRadius = 10.0f;
+    mLayer.layerFEState.geomLayerTransform = translate;
+    mLayer.layerFEState.shadowRadius = 10.0f;
 
     mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
     // Casting layer and its shadows are covered by an opaque region
     mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
     mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
 
-    mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
+    ensureOutputLayerIfVisible();
 }
 
 /*
@@ -1583,13 +1586,11 @@
 
     struct Layer {
         Layer() {
-            EXPECT_CALL(mOutputLayer, getLayer()).WillRepeatedly(ReturnRef(mLayer));
             EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
-            EXPECT_CALL(mLayer, getFEState()).WillRepeatedly(ReturnRef(mLayerFEState));
+            EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
         }
 
         StrictMock<mock::OutputLayer> mOutputLayer;
-        StrictMock<mock::Layer> mLayer;
         StrictMock<mock::LayerFE> mLayerFE;
         LayerFECompositionState mLayerFEState;
     };
@@ -3151,12 +3152,12 @@
 struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
     struct Layer {
         Layer() {
-            EXPECT_CALL(mOutputLayer, getLayer()).WillRepeatedly(ReturnRef(mLayer));
-            EXPECT_CALL(mLayer, getFEState()).WillRepeatedly(ReturnRef(mLayerFEState));
+            EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
+            EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
         }
 
         StrictMock<mock::OutputLayer> mOutputLayer;
-        StrictMock<mock::Layer> mLayer;
+        StrictMock<mock::LayerFE> mLayerFE;
         LayerFECompositionState mLayerFEState;
     };
 
@@ -3323,13 +3324,11 @@
         Layer() {
             EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
             EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
-            EXPECT_CALL(mOutputLayer, getLayer()).WillRepeatedly(ReturnRef(mLayer));
             EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
-            EXPECT_CALL(mLayer, getFEState()).WillRepeatedly(ReturnRef(mLayerFEState));
+            EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
         }
 
         StrictMock<mock::OutputLayer> mOutputLayer;
-        StrictMock<mock::Layer> mLayer;
         StrictMock<mock::LayerFE> mLayerFE;
         LayerFECompositionState mLayerFEState;
         impl::OutputLayerCompositionState mOutputLayerState;
@@ -3773,19 +3772,23 @@
 }
 
 TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
+    InjectedLayer layer1;
+    InjectedLayer layer2;
+    InjectedLayer layer3;
+
     // Layer requesting blur, or below, should request client composition.
-    EXPECT_CALL(*mOutputLayer1, updateCompositionState(false, true));
-    EXPECT_CALL(*mOutputLayer1, writeStateToHWC(false));
-    EXPECT_CALL(*mOutputLayer2, updateCompositionState(false, true));
-    EXPECT_CALL(*mOutputLayer2, writeStateToHWC(false));
-    EXPECT_CALL(*mOutputLayer3, updateCompositionState(false, false));
-    EXPECT_CALL(*mOutputLayer3, writeStateToHWC(false));
+    EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true));
+    EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
+    EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true));
+    EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
+    EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false));
+    EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
 
-    mLayer2FEState.backgroundBlurRadius = 10;
+    layer2.layerFEState.backgroundBlurRadius = 10;
 
-    injectLayer(std::move(mOutputLayer1));
-    injectLayer(std::move(mOutputLayer2));
-    injectLayer(std::move(mOutputLayer3));
+    injectOutputLayer(layer1);
+    injectOutputLayer(layer2);
+    injectOutputLayer(layer3);
 
     mOutput->editState().isEnabled = true;
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index cf1e8b0..effbed6 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -28,7 +28,6 @@
 #include <android-base/stringprintf.h>
 #include <binder/IPCThreadState.h>
 #include <compositionengine/Display.h>
-#include <compositionengine/Layer.h>
 #include <compositionengine/LayerFECompositionState.h>
 #include <compositionengine/OutputLayer.h>
 #include <compositionengine/impl/OutputLayerCompositionState.h>
@@ -415,7 +414,7 @@
     win.bottom -= roundedCornersCrop.top;
 }
 
-void Layer::latchBasicGeometry(compositionengine::LayerFECompositionState& compositionState) const {
+void Layer::prepareBasicGeometryCompositionState() {
     const auto& drawingState{getDrawingState()};
     const uint32_t layerStack = getLayerStack();
     const auto alpha = static_cast<float>(getAlpha());
@@ -428,31 +427,28 @@
                                         : Hwc2::IComposerClient::BlendMode::COVERAGE;
     }
 
-    // TODO(b/121291683): Instead of filling in a passed-in compositionState
-    // structure, switch to Layer owning the structure and have
-    // CompositionEngine be able to get a reference to it.
-
-    compositionState.layerStackId =
+    auto* compositionState = editCompositionState();
+    compositionState->layerStackId =
             (layerStack != ~0u) ? std::make_optional(layerStack) : std::nullopt;
-    compositionState.internalOnly = getPrimaryDisplayOnly();
-    compositionState.isVisible = isVisible();
-    compositionState.isOpaque = opaque && !usesRoundedCorners && alpha == 1.f;
-    compositionState.shadowRadius = mEffectiveShadowRadius;
+    compositionState->internalOnly = getPrimaryDisplayOnly();
+    compositionState->isVisible = isVisible();
+    compositionState->isOpaque = opaque && !usesRoundedCorners && alpha == 1.f;
+    compositionState->shadowRadius = mEffectiveShadowRadius;
 
-    compositionState.contentDirty = contentDirty;
+    compositionState->contentDirty = contentDirty;
     contentDirty = false;
 
-    compositionState.geomLayerBounds = mBounds;
-    compositionState.geomLayerTransform = getTransform();
-    compositionState.geomInverseLayerTransform = compositionState.geomLayerTransform.inverse();
-    compositionState.transparentRegionHint = getActiveTransparentRegion(drawingState);
+    compositionState->geomLayerBounds = mBounds;
+    compositionState->geomLayerTransform = getTransform();
+    compositionState->geomInverseLayerTransform = compositionState->geomLayerTransform.inverse();
+    compositionState->transparentRegionHint = getActiveTransparentRegion(drawingState);
 
-    compositionState.blendMode = static_cast<Hwc2::IComposerClient::BlendMode>(blendMode);
-    compositionState.alpha = alpha;
-    compositionState.backgroundBlurRadius = drawingState.backgroundBlurRadius;
+    compositionState->blendMode = static_cast<Hwc2::IComposerClient::BlendMode>(blendMode);
+    compositionState->alpha = alpha;
+    compositionState->backgroundBlurRadius = drawingState.backgroundBlurRadius;
 }
 
-void Layer::latchGeometry(compositionengine::LayerFECompositionState& compositionState) const {
+void Layer::prepareGeometryCompositionState() {
     const auto& drawingState{getDrawingState()};
 
     int type = drawingState.metadata.getInt32(METADATA_WINDOW_TYPE, 0);
@@ -468,45 +464,48 @@
         }
     }
 
-    compositionState.geomBufferSize = getBufferSize(drawingState);
-    compositionState.geomContentCrop = getBufferCrop();
-    compositionState.geomCrop = getCrop(drawingState);
-    compositionState.geomBufferTransform = getBufferTransform();
-    compositionState.geomBufferUsesDisplayInverseTransform = getTransformToDisplayInverse();
-    compositionState.geomUsesSourceCrop = usesSourceCrop();
-    compositionState.isSecure = isSecure();
+    auto* compositionState = editCompositionState();
 
-    compositionState.type = type;
-    compositionState.appId = appId;
+    compositionState->geomBufferSize = getBufferSize(drawingState);
+    compositionState->geomContentCrop = getBufferCrop();
+    compositionState->geomCrop = getCrop(drawingState);
+    compositionState->geomBufferTransform = getBufferTransform();
+    compositionState->geomBufferUsesDisplayInverseTransform = getTransformToDisplayInverse();
+    compositionState->geomUsesSourceCrop = usesSourceCrop();
+    compositionState->isSecure = isSecure();
+
+    compositionState->type = type;
+    compositionState->appId = appId;
 }
 
-void Layer::latchPerFrameState(compositionengine::LayerFECompositionState& compositionState) const {
+void Layer::preparePerFrameCompositionState() {
     const auto& drawingState{getDrawingState()};
-    compositionState.forceClientComposition = false;
+    auto* compositionState = editCompositionState();
 
-    compositionState.isColorspaceAgnostic = isColorSpaceAgnostic();
-    compositionState.dataspace = getDataSpace();
-    compositionState.colorTransform = getColorTransform();
-    compositionState.colorTransformIsIdentity = !hasColorTransform();
-    compositionState.surfaceDamage = surfaceDamageRegion;
-    compositionState.hasProtectedContent = isProtected();
+    compositionState->forceClientComposition = false;
+
+    compositionState->isColorspaceAgnostic = isColorSpaceAgnostic();
+    compositionState->dataspace = getDataSpace();
+    compositionState->colorTransform = getColorTransform();
+    compositionState->colorTransformIsIdentity = !hasColorTransform();
+    compositionState->surfaceDamage = surfaceDamageRegion;
+    compositionState->hasProtectedContent = isProtected();
 
     const bool usesRoundedCorners = getRoundedCornerState().radius != 0.f;
     const bool drawsShadows = mEffectiveShadowRadius != 0.f;
 
-    compositionState.isOpaque =
+    compositionState->isOpaque =
             isOpaque(drawingState) && !usesRoundedCorners && getAlpha() == 1.0_hf;
 
     // Force client composition for special cases known only to the front-end.
     if (isHdrY410() || usesRoundedCorners || drawsShadows) {
-        compositionState.forceClientComposition = true;
+        compositionState->forceClientComposition = true;
     }
 }
 
-void Layer::latchCursorCompositionState(
-        compositionengine::LayerFECompositionState& compositionState) const {
-    // This gives us only the "orientation" component of the transform
+void Layer::prepareCursorCompositionState() {
     const State& drawingState{getDrawingState()};
+    auto* compositionState = editCompositionState();
 
     // Apply the layer's transform, followed by the display's global transform
     // Here we're guaranteed that the layer's transform preserves rects
@@ -515,30 +514,50 @@
     Rect bounds = reduce(win, getActiveTransparentRegion(drawingState));
     Rect frame(getTransform().transform(bounds));
 
-    compositionState.cursorFrame = frame;
+    compositionState->cursorFrame = frame;
+}
+
+sp<compositionengine::LayerFE> Layer::asLayerFE() const {
+    return const_cast<compositionengine::LayerFE*>(
+            static_cast<const compositionengine::LayerFE*>(this));
+}
+
+sp<compositionengine::LayerFE> Layer::getCompositionEngineLayerFE() const {
+    return nullptr;
+}
+
+compositionengine::LayerFECompositionState* Layer::editCompositionState() {
+    return nullptr;
+}
+
+const compositionengine::LayerFECompositionState* Layer::getCompositionState() const {
+    return nullptr;
 }
 
 bool Layer::onPreComposition(nsecs_t) {
     return false;
 }
 
-void Layer::latchCompositionState(compositionengine::LayerFECompositionState& compositionState,
-                                  compositionengine::LayerFE::StateSubset subset) const {
+void Layer::prepareCompositionState(compositionengine::LayerFE::StateSubset subset) {
     using StateSubset = compositionengine::LayerFE::StateSubset;
 
     switch (subset) {
         case StateSubset::BasicGeometry:
-            latchBasicGeometry(compositionState);
+            prepareBasicGeometryCompositionState();
             break;
 
         case StateSubset::GeometryAndContent:
-            latchBasicGeometry(compositionState);
-            latchGeometry(compositionState);
-            latchPerFrameState(compositionState);
+            prepareBasicGeometryCompositionState();
+            prepareGeometryCompositionState();
+            preparePerFrameCompositionState();
             break;
 
         case StateSubset::Content:
-            latchPerFrameState(compositionState);
+            preparePerFrameCompositionState();
+            break;
+
+        case StateSubset::Cursor:
+            prepareCursorCompositionState();
             break;
     }
 }
@@ -553,7 +572,7 @@
 
 std::optional<compositionengine::LayerFE::LayerSettings> Layer::prepareClientComposition(
         compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) {
-    if (!getCompositionLayer()) {
+    if (!getCompositionState()) {
         return {};
     }
 
@@ -1418,7 +1437,7 @@
     StringAppendF(&result, " %s\n", name.c_str());
 
     const State& layerState(getDrawingState());
-    const auto& compositionState = outputLayer->getState();
+    const auto& outputLayerState = outputLayer->getState();
 
     if (layerState.zOrderRelativeOf != nullptr || mDrawingParent != nullptr) {
         StringAppendF(&result, "  rel %6d | ", layerState.z);
@@ -1427,13 +1446,10 @@
     }
     StringAppendF(&result, "  %10d | ", mWindowType);
     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, "%10s | ", toString(outputLayerState.bufferTransform).c_str());
+    const Rect& frame = outputLayerState.displayFrame;
     StringAppendF(&result, "%4d %4d %4d %4d | ", frame.left, frame.top, frame.right, frame.bottom);
-    const FloatRect& crop = compositionState.sourceCrop;
+    const FloatRect& crop = outputLayerState.sourceCrop;
     StringAppendF(&result, "%6.1f %6.1f %6.1f %6.1f\n", crop.left, crop.top, crop.right,
                   crop.bottom);
 
@@ -2210,17 +2226,13 @@
     return mDrawingState.inputInfo.token != nullptr;
 }
 
-std::shared_ptr<compositionengine::Layer> Layer::getCompositionLayer() const {
-    return nullptr;
-}
-
 bool Layer::canReceiveInput() const {
     return !isHiddenByPolicy();
 }
 
 compositionengine::OutputLayer* Layer::findOutputLayerForDisplay(
         const sp<const DisplayDevice>& display) const {
-    return display->getCompositionDisplay()->getOutputLayerForLayer(getCompositionLayer().get());
+    return display->getCompositionDisplay()->getOutputLayerForLayer(getCompositionEngineLayerFE());
 }
 
 Region Layer::debugGetVisibleRegionOnDefaultDisplay() const {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index f7907c3..810e0af 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -66,7 +66,6 @@
 class LayerDebugInfo;
 
 namespace compositionengine {
-class Layer;
 class OutputLayer;
 struct LayerFECompositionState;
 }
@@ -94,7 +93,7 @@
     uint32_t textureName;
 };
 
-class Layer : public compositionengine::LayerFE {
+class Layer : public virtual RefBase, compositionengine::LayerFE {
     static std::atomic<int32_t> sSequence;
     static constexpr int32_t PRIORITY_UNSET = -1;
 
@@ -390,7 +389,8 @@
     // visually.
     bool isLegacyDataSpace() const;
 
-    virtual std::shared_ptr<compositionengine::Layer> getCompositionLayer() const;
+    virtual sp<compositionengine::LayerFE> getCompositionEngineLayerFE() const;
+    virtual compositionengine::LayerFECompositionState* editCompositionState();
 
     // If we have received a new buffer this frame, we will pass its surface
     // damage down to hardware composer. Otherwise, we must send a region with
@@ -535,6 +535,7 @@
     virtual void updateCloneBufferInfo(){};
 
 protected:
+    sp<compositionengine::LayerFE> asLayerFE() const;
     sp<Layer> getClonedFrom() { return mClonedFrom != nullptr ? mClonedFrom.promote() : nullptr; }
     bool isClone() { return mClonedFrom != nullptr; }
     bool isClonedFromAlive() { return getClonedFrom() != nullptr; }
@@ -552,10 +553,9 @@
     /*
      * compositionengine::LayerFE overrides
      */
+    const compositionengine::LayerFECompositionState* getCompositionState() const override;
     bool onPreComposition(nsecs_t) override;
-    void latchCompositionState(compositionengine::LayerFECompositionState&,
-                               compositionengine::LayerFE::StateSubset subset) const override;
-    void latchCursorCompositionState(compositionengine::LayerFECompositionState&) const override;
+    void prepareCompositionState(compositionengine::LayerFE::StateSubset subset) override;
     std::optional<LayerSettings> prepareClientComposition(
             compositionengine::LayerFE::ClientCompositionTargetSettings&) override;
     std::optional<LayerSettings> prepareShadowClientComposition(
@@ -565,9 +565,10 @@
     const char* getDebugName() const override;
 
 protected:
-    void latchBasicGeometry(compositionengine::LayerFECompositionState& outState) const;
-    void latchGeometry(compositionengine::LayerFECompositionState& outState) const;
-    virtual void latchPerFrameState(compositionengine::LayerFECompositionState& outState) const;
+    void prepareBasicGeometryCompositionState();
+    void prepareGeometryCompositionState();
+    virtual void preparePerFrameCompositionState();
+    void prepareCursorCompositionState();
 
 public:
     virtual void setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) {}
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 8492242..33d85cb 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -45,6 +45,7 @@
 #include <compositionengine/CompositionRefreshArgs.h>
 #include <compositionengine/Display.h>
 #include <compositionengine/DisplayColorProfile.h>
+#include <compositionengine/LayerFECompositionState.h>
 #include <compositionengine/OutputLayer.h>
 #include <compositionengine/RenderSurface.h>
 #include <compositionengine/impl/OutputCompositionState.h>
@@ -1877,13 +1878,13 @@
         refreshArgs.outputs.push_back(display->getCompositionDisplay());
     }
     mDrawingState.traverseInZOrder([&refreshArgs](Layer* layer) {
-        auto compositionLayer = layer->getCompositionLayer();
-        if (compositionLayer) refreshArgs.layers.push_back(compositionLayer);
+        if (auto layerFE = layer->getCompositionEngineLayerFE())
+            refreshArgs.layers.push_back(layerFE);
     });
     refreshArgs.layersWithQueuedFrames.reserve(mLayersWithQueuedFrames.size());
     for (sp<Layer> layer : mLayersWithQueuedFrames) {
-        auto compositionLayer = layer->getCompositionLayer();
-        if (compositionLayer) refreshArgs.layersWithQueuedFrames.push_back(compositionLayer.get());
+        if (auto layerFE = layer->getCompositionEngineLayerFE())
+            refreshArgs.layersWithQueuedFrames.push_back(layerFE);
     }
 
     refreshArgs.repaintEverything = mRepaintEverything.exchange(false);
@@ -4445,8 +4446,13 @@
     {
         StringAppendF(&result, "Composition layers\n");
         mDrawingState.traverseInZOrder([&](Layer* layer) {
-            auto compositionLayer = layer->getCompositionLayer();
-            if (compositionLayer) compositionLayer->dump(result);
+            auto* compositionState = layer->getCompositionState();
+            if (!compositionState) return;
+
+            android::base::StringAppendF(&result, "* Layer %p (%s)\n", layer,
+                                         layer->getDebugName() ? layer->getDebugName()
+                                                               : "<unknown>");
+            compositionState->dump(result);
         });
     }
 
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index c6d8a2e..888e009 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -842,8 +842,8 @@
         EXPECT_CALL(*test->mComposer, createLayer(HWC_DISPLAY, _))
                 .WillOnce(DoAll(SetArgPointee<1>(HWC_LAYER), Return(Error::NONE)));
 
-        auto outputLayer = test->mDisplay->getCompositionDisplay()
-                                   ->injectOutputLayerForTest(layer->getCompositionLayer(), layer);
+        auto outputLayer = test->mDisplay->getCompositionDisplay()->injectOutputLayerForTest(
+                layer->getCompositionEngineLayerFE());
         outputLayer->editState().visibleRegion = Region(Rect(0, 0, 100, 100));
         outputLayer->editState().outputSpaceVisibleRegion = Region(Rect(0, 0, 100, 100));
 
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 2491533..64838ca 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -17,7 +17,6 @@
 #pragma once
 
 #include <compositionengine/Display.h>
-#include <compositionengine/Layer.h>
 #include <compositionengine/LayerFECompositionState.h>
 #include <compositionengine/OutputLayer.h>
 #include <compositionengine/impl/CompositionEngine.h>
@@ -252,7 +251,7 @@
     void setLayerSidebandStream(sp<Layer> layer, sp<NativeHandle> sidebandStream) {
         layer->mDrawingState.sidebandStream = sidebandStream;
         layer->mSidebandStream = sidebandStream;
-        layer->getCompositionLayer()->editFEState().sidebandStream = sidebandStream;
+        layer->editCompositionState()->sidebandStream = sidebandStream;
     }
 
     void setLayerCompositionType(sp<Layer> layer, HWC2::Composition type) {