CE: Remove compositionengine::Layer

This was a mostly straightforward refactor that restructures the
interface between SurfaceFlinger and CompositionEngine.

1) Instead of each SurfaceFlinger Layer creating and owning a
   compositionengine::Layer, each Layer instead creates and owns a
   compositionengine::LayerFECompositionState structure. Containing this
   state structure was the only real purpose for
   compositionengine::Layer.

2) Use the compositionengine::LayerFE interface in CompositionEngine in
   place of compositionengine::Layer. This includes passing a
   std::vector for the layers when SurfaceFlinger calls into
   CompositionEngine.

3) Alters the LayerFE interface to add the ability to get the state, as
   well as changing the existing "latchCompositionState" calls taking a
   state reference as the first argument into "prepareCompositionState"
   calls that do not need it, as the target of the call owns the state.

4) Alters the SurfaceFlinger Layer implementations to match the LayerFE
   interface changes.

Test: atest libcompositionengine_test libsurfaceflinger_unittest
Test: atest CtsColorModeTestCases
Test: atest CtsDisplayTestCases
Test: atest CtsGraphicsTestCases
Test: atest CtsUiRenderingTestCases
Test: atest CtsViewTestCases
Test: atest android.media.cts.EncodeVirtualDisplayWithCompositionTest
Test: go/wm-smoke
Bug: 144117494
Change-Id: Id45df7c9cc389c8fd834ba379bc0d6360a984dac
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 e85281d..1287393 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>
@@ -215,9 +214,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);
         }
@@ -351,8 +350,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.
@@ -372,18 +371,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 2bd1e3d..486c1bc 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 cd4227c..664c199 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>
@@ -430,9 +429,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);
@@ -539,8 +537,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;
 }
@@ -552,16 +549,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 9427283..020c1b3 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -125,7 +125,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 04854d0..6a81817 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 a5da0b1..c04aff5 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;
@@ -215,18 +214,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;
@@ -256,7 +254,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 f469e62..cc31e5f 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
@@ -59,10 +59,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;
 
@@ -72,7 +71,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;
 
@@ -93,9 +92,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;
@@ -107,11 +106,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;
@@ -180,11 +177,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;
@@ -201,10 +197,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 c41302d..2608b91 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>
@@ -61,14 +60,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));
 
@@ -83,8 +81,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 55371df..47704ec 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>
@@ -265,31 +264,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;
         }
     }
@@ -352,7 +346,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);
 
@@ -371,28 +365,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;
     }
 
@@ -430,23 +425,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);
@@ -458,10 +448,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.
@@ -471,7 +461,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
@@ -495,7 +485,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;
 
@@ -509,7 +499,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
@@ -556,7 +546,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.
@@ -575,10 +565,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);
     }
 }
 
@@ -611,7 +600,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;
         }
     }
@@ -637,7 +626,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:
@@ -653,7 +642,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:
@@ -865,7 +855,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);
@@ -954,7 +944,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));
@@ -973,7 +963,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 6e8d3df..767faa5 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;
@@ -500,11 +491,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;
@@ -512,57 +510,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));
 }
 
 /*
@@ -570,29 +562,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));
 }
 
 /*
@@ -624,7 +614,7 @@
  * Output::updateLayerStateFromFE()
  */
 
-using OutputUpdateLayerStateFromFETest = OutputLatchFEStateTest;
+using OutputUpdateLayerStateFromFETest = OutputTest;
 
 TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
     CompositionRefreshArgs refreshArgs;
@@ -632,18 +622,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;
@@ -651,21 +641,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;
@@ -677,7 +664,7 @@
  * Output::updateAndWriteCompositionState()
  */
 
-using OutputUpdateAndWriteCompositionStateTest = OutputLatchFEStateTest;
+using OutputUpdateAndWriteCompositionStateTest = OutputTest;
 
 TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
     mOutput->editState().isEnabled = true;
@@ -687,27 +674,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;
 
@@ -718,16 +713,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;
 
@@ -738,16 +737,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;
 
@@ -969,7 +972,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());
@@ -982,8 +985,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() {
@@ -995,9 +998,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;
@@ -1024,9 +1027,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());
@@ -1047,43 +1050,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;
@@ -1096,11 +1095,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));
@@ -1113,275 +1108,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,
@@ -1390,16 +1392,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));
@@ -1408,25 +1410,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));
@@ -1439,28 +1441,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));
@@ -1478,53 +1481,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();
 }
 
 /*
@@ -1580,13 +1583,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;
     };
@@ -3142,12 +3143,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;
     };
 
@@ -3314,13 +3315,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;
@@ -3760,19 +3759,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 6f8df95..28cd667 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 {};
     }
 
@@ -1421,7 +1440,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);
@@ -1430,13 +1449,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);
 
@@ -2204,17 +2220,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 c75a570..e7d057b 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;
 
@@ -361,7 +360,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
@@ -506,6 +506,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; }
@@ -523,10 +524,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(
@@ -536,9 +536,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 62d47e1..727d901 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>
@@ -1857,13 +1858,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);
@@ -4422,8 +4423,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 98cc023..3f29558 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -840,8 +840,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) {