SF: Merge EffectLayer into BufferStateLayer

This makes all the Layer instances a BufferStateLayer. The layer can
draw effects or hold a buffer. If the caller tries to do both, drawing
a buffer takes precedence.

Test: go/wm-smoke
Test: presubmit
Bug: 238781169

Change-Id: Ied68cd1ed7399f6408bd24d9e0220707d6a3a2ab
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 0cedfc8..b939752 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -300,10 +300,6 @@
              (mDrawingState.buffer != nullptr || mDrawingState.bgColorLayer != nullptr)));
 }
 
-Rect BufferStateLayer::getCrop(const Layer::State& s) const {
-    return s.crop;
-}
-
 bool BufferStateLayer::setTransform(uint32_t transform) {
     if (mDrawingState.bufferTransform == transform) return false;
     mDrawingState.bufferTransform = transform;
@@ -321,16 +317,6 @@
     return true;
 }
 
-bool BufferStateLayer::setCrop(const Rect& crop) {
-    if (mDrawingState.crop == crop) return false;
-    mDrawingState.sequence++;
-    mDrawingState.crop = crop;
-
-    mDrawingState.modified = true;
-    setTransactionFlags(eTransactionNeeded);
-    return true;
-}
-
 bool BufferStateLayer::setBufferCrop(const Rect& bufferCrop) {
     if (mDrawingState.bufferCrop == bufferCrop) return false;
 
@@ -408,9 +394,6 @@
         return false;
     }
 
-    ui::Transform t;
-    t.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
-
     mRequestedTransform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
 
     mDrawingState.sequence++;
@@ -536,6 +519,7 @@
 }
 
 bool BufferStateLayer::setDataspace(ui::Dataspace dataspace) {
+    mDrawingState.dataspaceRequested = true;
     if (mDrawingState.dataspace == dataspace) return false;
     mDrawingState.dataspace = dataspace;
     mDrawingState.modified = true;
@@ -858,6 +842,9 @@
  * how to go from screen space back to window space.
  */
 ui::Transform BufferStateLayer::getInputTransform() const {
+    if (!hasBufferOrSidebandStream()) {
+        return getTransform();
+    }
     sp<Layer> parent = mDrawingParent.promote();
     if (parent == nullptr) {
         return ui::Transform();
@@ -872,6 +859,10 @@
  * that's already included.
  */
 Rect BufferStateLayer::getInputBounds() const {
+    if (!hasBufferOrSidebandStream()) {
+        return getCroppedBufferSize(getDrawingState());
+    }
+
     Rect bufferBounds = getCroppedBufferSize(getDrawingState());
     if (mDrawingState.transform.getType() == ui::Transform::IDENTITY || !bufferBounds.isValid()) {
         return bufferBounds;
@@ -1080,13 +1071,22 @@
 bool BufferStateLayer::isOpaque(const Layer::State& s) const {
     // if we don't have a buffer or sidebandStream yet, we're translucent regardless of the
     // layer's opaque flag.
-    if ((mSidebandStream == nullptr) && (mBufferInfo.mBuffer == nullptr)) {
+    if (!hasSomethingToDraw()) {
         return false;
     }
 
-    // if the layer has the opaque flag, then we're always opaque,
-    // otherwise we use the current buffer's format.
-    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || getOpacityForFormat(getPixelFormat());
+    // if the layer has the opaque flag, then we're always opaque
+    if ((s.flags & layer_state_t::eLayerOpaque) == layer_state_t::eLayerOpaque) {
+        return true;
+    }
+
+    // If the buffer has no alpha channel, then we are opaque
+    if (hasBufferOrSidebandStream() && isOpaqueFormat(getPixelFormat())) {
+        return true;
+    }
+
+    // Lastly consider the layer opaque if drawing a color with alpha == 1.0
+    return fillsColor() && getAlpha() == 1.0_hf;
 }
 
 bool BufferStateLayer::canReceiveInput() const {
@@ -1094,8 +1094,15 @@
 }
 
 bool BufferStateLayer::isVisible() const {
-    return !isHiddenByPolicy() && getAlpha() > 0.0f &&
-            (mBufferInfo.mBuffer != nullptr || mSidebandStream != nullptr);
+    if (!hasSomethingToDraw()) {
+        return false;
+    }
+
+    if (isHiddenByPolicy()) {
+        return false;
+    }
+
+    return getAlpha() > 0.0f || hasBlur();
 }
 
 std::optional<compositionengine::LayerFE::LayerSettings> BufferStateLayer::prepareClientComposition(
@@ -1130,6 +1137,11 @@
         return result;
     }
 
+    if (hasEffect()) {
+        prepareEffectsClientComposition(*result, targetSettings);
+        return result;
+    }
+
     if (CC_UNLIKELY(mBufferInfo.mBuffer == 0) && mSidebandStream != nullptr) {
         // For surfaceview of tv sideband, there is no activeBuffer
         // in bufferqueue, we need return LayerSettings.
@@ -1241,6 +1253,18 @@
     return layer;
 }
 
+void BufferStateLayer::prepareEffectsClientComposition(
+        compositionengine::LayerFE::LayerSettings& layerSettings,
+        compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const {
+    // If fill bounds are occluded or the fill color is invalid skip the fill settings.
+    if (targetSettings.realContentIsVisible && fillsColor()) {
+        // Set color for color fill settings.
+        layerSettings.source.solidColor = getColor().rgb;
+    } else if (hasBlur() || drawShadows()) {
+        layerSettings.skipContentDraw = true;
+    }
+}
+
 bool BufferStateLayer::isHdrY410() const {
     // pixel format is HDR Y410 masquerading as RGBA_1010102
     return (mBufferInfo.mDataspace == ui::Dataspace::BT2020_ITU_PQ &&
@@ -1249,7 +1273,12 @@
 }
 
 sp<compositionengine::LayerFE> BufferStateLayer::getCompositionEngineLayerFE() const {
-    return asLayerFE();
+    // There's no need to get a CE Layer if the layer isn't going to draw anything.
+    if (hasSomethingToDraw()) {
+        return asLayerFE();
+    } else {
+        return nullptr;
+    }
 }
 
 compositionengine::LayerFECompositionState* BufferStateLayer::editCompositionState() {
@@ -1262,7 +1291,14 @@
 
 void BufferStateLayer::preparePerFrameCompositionState() {
     Layer::preparePerFrameCompositionState();
+    if (hasBufferOrSidebandStream()) {
+        preparePerFrameBufferCompositionState();
+    } else {
+        preparePerFrameEffectsCompositionState();
+    }
+}
 
+void BufferStateLayer::preparePerFrameBufferCompositionState() {
     // Sideband layers
     auto* compositionState = editCompositionState();
     if (compositionState->sidebandStream.get() && !compositionState->sidebandStreamHasFrame) {
@@ -1289,6 +1325,13 @@
     compositionState->sidebandStreamHasFrame = false;
 }
 
+void BufferStateLayer::preparePerFrameEffectsCompositionState() {
+    auto* compositionState = editCompositionState();
+    compositionState->color = getColor();
+    compositionState->compositionType =
+            aidl::android::hardware::graphics::composer3::Composition::SOLID_COLOR;
+}
+
 void BufferStateLayer::onPostComposition(const DisplayDevice* display,
                                          const std::shared_ptr<FenceTime>& glDoneFence,
                                          const std::shared_ptr<FenceTime>& presentFence,
@@ -1441,7 +1484,7 @@
 // hardware.h, instead of using hard-coded values here.
 #define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
 
-bool BufferStateLayer::getOpacityForFormat(PixelFormat format) {
+bool BufferStateLayer::isOpaqueFormat(PixelFormat format) {
     if (HARDWARE_IS_DEVICE_FORMAT(format)) {
         return true;
     }
@@ -1458,6 +1501,9 @@
 }
 
 bool BufferStateLayer::needsFiltering(const DisplayDevice* display) const {
+    if (!hasBufferOrSidebandStream()) {
+        return false;
+    }
     const auto outputLayer = findOutputLayerForDisplay(display);
     if (outputLayer == nullptr) {
         return false;
@@ -1474,6 +1520,9 @@
 
 bool BufferStateLayer::needsFilteringForScreenshots(
         const DisplayDevice* display, const ui::Transform& inverseParentTransform) const {
+    if (!hasBufferOrSidebandStream()) {
+        return false;
+    }
     const auto outputLayer = findOutputLayerForDisplay(display);
     if (outputLayer == nullptr) {
         return false;
@@ -1535,7 +1584,11 @@
 }
 
 ui::Dataspace BufferStateLayer::getDataSpace() const {
-    return mBufferInfo.mDataspace;
+    return mDrawingState.dataspaceRequested ? getRequestedDataSpace() : ui::Dataspace::UNKNOWN;
+}
+
+ui::Dataspace BufferStateLayer::getRequestedDataSpace() const {
+    return hasBufferOrSidebandStream() ? mBufferInfo.mDataspace : mDrawingState.dataspace;
 }
 
 ui::Dataspace BufferStateLayer::translateDataspace(ui::Dataspace dataspace) {
@@ -1636,4 +1689,28 @@
     return mBufferInfo.mBuffer;
 }
 
+bool BufferStateLayer::setColor(const half3& color) {
+    if (mDrawingState.color.r == color.r && mDrawingState.color.g == color.g &&
+        mDrawingState.color.b == color.b) {
+        return false;
+    }
+
+    mDrawingState.sequence++;
+    mDrawingState.color.r = color.r;
+    mDrawingState.color.g = color.g;
+    mDrawingState.color.b = color.b;
+    mDrawingState.modified = true;
+    setTransactionFlags(eTransactionNeeded);
+    return true;
+}
+
+bool BufferStateLayer::fillsColor() const {
+    return !hasBufferOrSidebandStream() && mDrawingState.color.r >= 0.0_hf &&
+            mDrawingState.color.g >= 0.0_hf && mDrawingState.color.b >= 0.0_hf;
+}
+
+bool BufferStateLayer::hasBlur() const {
+    return getBackgroundBlurRadius() > 0 || getDrawingState().blurRegions.size() > 0;
+}
+
 } // namespace android
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index a0a52bf..6ef2b19 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -75,7 +75,7 @@
     // GRALLOC_USAGE_PROTECTED sense.
     bool isProtected() const override;
 
-    bool usesSourceCrop() const override { return true; }
+    bool usesSourceCrop() const override { return hasBufferOrSidebandStream(); }
 
     bool isHdrY410() const override;
 
@@ -103,7 +103,7 @@
     uint32_t getBufferTransform() const override;
 
     ui::Dataspace getDataSpace() const override;
-
+    ui::Dataspace getRequestedDataSpace() const;
     sp<GraphicBuffer> getBuffer() const override;
     const std::shared_ptr<renderengine::ExternalTexture>& getExternalTexture() const override;
 
@@ -116,11 +116,12 @@
 
     void releasePendingBuffer(nsecs_t dequeueReadyTime) override;
 
-    Rect getCrop(const Layer::State& s) const;
+    Region getActiveTransparentRegion(const Layer::State& s) const override {
+        return s.transparentRegionHint;
+    }
 
     bool setTransform(uint32_t transform) override;
     bool setTransformToDisplayInverse(bool transformToDisplayInverse) override;
-    bool setCrop(const Rect& crop) override;
     bool setBuffer(std::shared_ptr<renderengine::ExternalTexture>& /* buffer */,
                    const BufferData& bufferData, nsecs_t postTime, nsecs_t desiredPresentTime,
                    bool isAutoTimestamp, std::optional<nsecs_t> dequeueTime,
@@ -154,6 +155,7 @@
 
     std::optional<compositionengine::LayerFE::LayerSettings> prepareClientComposition(
             compositionengine::LayerFE::ClientCompositionTargetSettings&) const override;
+    bool setColor(const half3& color) override;
 
 protected:
     void gatherBufferInfo();
@@ -189,8 +191,10 @@
      */
     const compositionengine::LayerFECompositionState* getCompositionState() const override;
     void preparePerFrameCompositionState() override;
+    void preparePerFrameBufferCompositionState();
+    void preparePerFrameEffectsCompositionState();
 
-    static bool getOpacityForFormat(PixelFormat format);
+    static bool isOpaqueFormat(PixelFormat format);
 
     // from graphics API
     const uint32_t mTextureName;
@@ -218,7 +222,9 @@
     // We generate InputWindowHandles for all non-cursor buffered layers regardless of whether they
     // have an InputChannel. This is to enable the InputDispatcher to do PID based occlusion
     // detection.
-    bool needsInputInfo() const override { return !mPotentialCursor; }
+    bool needsInputInfo() const override {
+        return (hasInputInfo() || hasBufferOrSidebandStream()) && !mPotentialCursor;
+    }
 
     // Returns true if this layer requires filtering
     bool needsFiltering(const DisplayDevice*) const override;
@@ -265,6 +271,18 @@
 
     std::optional<compositionengine::LayerFE::LayerSettings> prepareClientCompositionInternal(
             compositionengine::LayerFE::ClientCompositionTargetSettings&) const;
+    // Returns true if there is a valid color to fill.
+    bool fillsColor() const;
+    // Returns true if this layer has a blur value.
+    bool hasBlur() const;
+    bool hasEffect() const { return fillsColor() || drawShadows() || hasBlur(); }
+    bool hasBufferOrSidebandStream() const {
+        return ((mSidebandStream != nullptr) || (mBufferInfo.mBuffer != nullptr));
+    }
+    bool hasSomethingToDraw() const { return hasEffect() || hasBufferOrSidebandStream(); }
+    void prepareEffectsClientComposition(
+            compositionengine::LayerFE::LayerSettings&,
+            compositionengine::LayerFE::ClientCompositionTargetSettings&) const;
 
     ReleaseCallbackId mPreviousReleaseCallbackId = ReleaseCallbackId::INVALID_ID;
     uint64_t mPreviousReleasedFrameNumber = 0;
diff --git a/services/surfaceflinger/EffectLayer.cpp b/services/surfaceflinger/EffectLayer.cpp
index d161c51..7180fa6 100644
--- a/services/surfaceflinger/EffectLayer.cpp
+++ b/services/surfaceflinger/EffectLayer.cpp
@@ -41,122 +41,7 @@
 namespace android {
 // ---------------------------------------------------------------------------
 
-EffectLayer::EffectLayer(const LayerCreationArgs& args)
-      : Layer(args),
-        mCompositionState{mFlinger->getCompositionEngine().createLayerFECompositionState()} {}
-
+EffectLayer::EffectLayer(const LayerCreationArgs& args) : BufferStateLayer(args) {}
 EffectLayer::~EffectLayer() = default;
 
-std::optional<compositionengine::LayerFE::LayerSettings> EffectLayer::prepareClientComposition(
-        compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const {
-    std::optional<compositionengine::LayerFE::LayerSettings> layerSettings =
-            Layer::prepareClientComposition(targetSettings);
-    // Nothing to render.
-    if (!layerSettings) {
-        return {};
-    }
-
-    // set the shadow for the layer if needed
-    prepareShadowClientComposition(*layerSettings, targetSettings.viewport);
-
-    // If fill bounds are occluded or the fill color is invalid skip the fill settings.
-    if (targetSettings.realContentIsVisible && fillsColor()) {
-        // Set color for color fill settings.
-        layerSettings->source.solidColor = getColor().rgb;
-        return layerSettings;
-    } else if (hasBlur() || drawShadows()) {
-        layerSettings->skipContentDraw = true;
-        return layerSettings;
-    }
-
-    return {};
-}
-
-bool EffectLayer::isVisible() const {
-    return hasSomethingToDraw() && !isHiddenByPolicy() && (getAlpha() > 0.0_hf || hasBlur());
-}
-
-bool EffectLayer::setColor(const half3& color) {
-    if (mDrawingState.color.r == color.r && mDrawingState.color.g == color.g &&
-        mDrawingState.color.b == color.b) {
-        return false;
-    }
-
-    mDrawingState.sequence++;
-    mDrawingState.color.r = color.r;
-    mDrawingState.color.g = color.g;
-    mDrawingState.color.b = color.b;
-    mDrawingState.modified = true;
-    setTransactionFlags(eTransactionNeeded);
-    return true;
-}
-
-bool EffectLayer::setDataspace(ui::Dataspace dataspace) {
-    if (mDrawingState.dataspace == dataspace) {
-        return false;
-    }
-
-    mDrawingState.sequence++;
-    mDrawingState.dataspace = dataspace;
-    mDrawingState.modified = true;
-    setTransactionFlags(eTransactionNeeded);
-    return true;
-}
-
-void EffectLayer::preparePerFrameCompositionState() {
-    Layer::preparePerFrameCompositionState();
-
-    auto* compositionState = editCompositionState();
-    compositionState->color = getColor();
-    compositionState->compositionType =
-            aidl::android::hardware::graphics::composer3::Composition::SOLID_COLOR;
-}
-
-sp<compositionengine::LayerFE> EffectLayer::getCompositionEngineLayerFE() const {
-    // There's no need to get a CE Layer if the EffectLayer isn't going to draw anything. In that
-    // case, it acts more like a ContainerLayer so returning a null CE Layer makes more sense
-    if (hasSomethingToDraw()) {
-        return asLayerFE();
-    } else {
-        return nullptr;
-    }
-}
-
-compositionengine::LayerFECompositionState* EffectLayer::editCompositionState() {
-    return mCompositionState.get();
-}
-
-const compositionengine::LayerFECompositionState* EffectLayer::getCompositionState() const {
-    return mCompositionState.get();
-}
-
-bool EffectLayer::isOpaque(const Layer::State& s) const {
-    // Consider the layer to be opaque if its opaque flag is set or its effective
-    // alpha (considering the alpha of its parents as well) is 1.0;
-    return (s.flags & layer_state_t::eLayerOpaque) != 0 || (fillsColor() && getAlpha() == 1.0_hf);
-}
-
-ui::Dataspace EffectLayer::getDataSpace() const {
-    return mDrawingState.dataspace;
-}
-
-sp<Layer> EffectLayer::createClone() {
-    sp<EffectLayer> layer = mFlinger->getFactory().createEffectLayer(
-            LayerCreationArgs(mFlinger.get(), nullptr, mName + " (Mirror)", 0, LayerMetadata()));
-    layer->setInitialValuesForClone(sp<Layer>::fromExisting(this));
-    return layer;
-}
-
-bool EffectLayer::fillsColor() const {
-    return mDrawingState.color.r >= 0.0_hf && mDrawingState.color.g >= 0.0_hf &&
-            mDrawingState.color.b >= 0.0_hf;
-}
-
-bool EffectLayer::hasBlur() const {
-    return getBackgroundBlurRadius() > 0 || getDrawingState().blurRegions.size() > 0;
-}
-
 } // namespace android
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic pop // ignored "-Wconversion"
diff --git a/services/surfaceflinger/EffectLayer.h b/services/surfaceflinger/EffectLayer.h
index 747b0bf..311d493 100644
--- a/services/surfaceflinger/EffectLayer.h
+++ b/services/surfaceflinger/EffectLayer.h
@@ -19,7 +19,7 @@
 
 #include <cstdint>
 
-#include "Layer.h"
+#include "BufferStateLayer.h"
 
 namespace android {
 
@@ -27,45 +27,10 @@
 //   * fill the bounds of the layer with a color
 //   * render a shadow cast by the bounds of the layer
 // If no effects are enabled, the layer is considered to be invisible.
-class EffectLayer : public Layer {
+class EffectLayer : public BufferStateLayer {
 public:
     explicit EffectLayer(const LayerCreationArgs&);
     ~EffectLayer() override;
-
-    sp<compositionengine::LayerFE> getCompositionEngineLayerFE() const override;
-    compositionengine::LayerFECompositionState* editCompositionState() override;
-
-    const char* getType() const override { return "EffectLayer"; }
-    bool isVisible() const override;
-
-    bool setColor(const half3& color) override;
-
-    bool setDataspace(ui::Dataspace dataspace) override;
-
-    ui::Dataspace getDataSpace() const override;
-
-    bool isOpaque(const Layer::State& s) const override;
-
-protected:
-    /*
-     * compositionengine::LayerFE overrides
-     */
-    const compositionengine::LayerFECompositionState* getCompositionState() const override;
-    void preparePerFrameCompositionState() override;
-    std::optional<compositionengine::LayerFE::LayerSettings> prepareClientComposition(
-            compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings)
-            const override;
-
-    std::unique_ptr<compositionengine::LayerFECompositionState> mCompositionState;
-
-    sp<Layer> createClone() override;
-
-private:
-    // Returns true if there is a valid color to fill.
-    bool fillsColor() const;
-    // Returns true if this layer has a blur value.
-    bool hasBlur() const;
-    bool hasSomethingToDraw() const { return fillsColor() || drawShadows() || hasBlur(); }
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 8a401eb..930ae72 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -124,6 +124,7 @@
     mDrawingState.acquireFence = sp<Fence>::make(-1);
     mDrawingState.acquireFenceTime = std::make_shared<FenceTime>(mDrawingState.acquireFence);
     mDrawingState.dataspace = ui::Dataspace::UNKNOWN;
+    mDrawingState.dataspaceRequested = false;
     mDrawingState.hdrMetadata.validTypes = 0;
     mDrawingState.surfaceDamageRegion = Region::INVALID_REGION;
     mDrawingState.cornerRadius = 0.0f;
@@ -204,13 +205,6 @@
 // callbacks
 // ---------------------------------------------------------------------------
 
-/*
- * onLayerDisplayed is only meaningful for BufferLayer, but, is called through
- * Layer.  So, the implementation is done in BufferLayer.  When called on a
- * EffectLayer object, it's essentially a NOP.
- */
-void Layer::onLayerDisplayed(ftl::SharedFuture<FenceResult>) {}
-
 void Layer::removeRelativeZ(const std::vector<Layer*>& layersInTree) {
     if (mDrawingState.zOrderRelativeOf == nullptr) {
         return;
@@ -521,22 +515,6 @@
     return sp<compositionengine::LayerFE>::fromExisting(layerFE);
 }
 
-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::prepareCompositionState(compositionengine::LayerFE::StateSubset subset) {
     using StateSubset = compositionengine::LayerFE::StateSubset;
 
@@ -736,16 +714,6 @@
     mTransactionFlags |= mask;
 }
 
-bool Layer::setPosition(float x, float y) {
-    if (mDrawingState.transform.tx() == x && mDrawingState.transform.ty() == y) return false;
-    mDrawingState.sequence++;
-    mDrawingState.transform.set(x, y);
-
-    mDrawingState.modified = true;
-    setTransactionFlags(eTransactionNeeded);
-    return true;
-}
-
 bool Layer::setChildLayer(const sp<Layer>& childLayer, int32_t z) {
     ssize_t idx = mCurrentChildren.indexOf(childLayer);
     if (idx < 0) {
@@ -939,24 +907,6 @@
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
-bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
-    if (matrix.dsdx == mDrawingState.transform.dsdx() &&
-        matrix.dtdy == mDrawingState.transform.dtdy() &&
-        matrix.dtdx == mDrawingState.transform.dtdx() &&
-        matrix.dsdy == mDrawingState.transform.dsdy()) {
-        return false;
-    }
-
-    ui::Transform t;
-    t.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
-
-    mDrawingState.sequence++;
-    mDrawingState.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
-    mDrawingState.modified = true;
-
-    setTransactionFlags(eTransactionNeeded);
-    return true;
-}
 
 bool Layer::setTransparentRegionHint(const Region& transparent) {
     mDrawingState.sequence++;
@@ -2188,14 +2138,6 @@
     return mRemovedFromDrawingState;
 }
 
-ui::Transform Layer::getInputTransform() const {
-    return getTransform();
-}
-
-Rect Layer::getInputBounds() const {
-    return getCroppedBufferSize(getDrawingState());
-}
-
 // Applies the given transform to the region, while protecting against overflows caused by any
 // offsets. If applying the offset in the transform to any of the Rects in the region would result
 // in an overflow, they are not added to the output Region.
@@ -2459,10 +2401,6 @@
             mDrawingState.inputInfo.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
 }
 
-bool Layer::canReceiveInput() const {
-    return !isHiddenByPolicy();
-}
-
 compositionengine::OutputLayer* Layer::findOutputLayerForDisplay(
         const DisplayDevice* display) const {
     if (!display) return nullptr;
@@ -2684,18 +2622,6 @@
     mDrawingState.callbackHandles = {};
 }
 
-bool Layer::setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& handles) {
-    if (handles.empty()) {
-        return false;
-    }
-
-    for (const auto& handle : handles) {
-        mFlinger->getTransactionCallbackInvoker().registerUnpresentedCallbackHandle(handle);
-    }
-
-    return true;
-}
-
 // ---------------------------------------------------------------------------
 
 std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index b05a4a0..946b7d0 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -172,6 +172,7 @@
 
         // dataspace is only used by BufferStateLayer and EffectLayer
         ui::Dataspace dataspace;
+        bool dataspaceRequested;
 
         // The fields below this point are only used by BufferStateLayer
         uint64_t frameNumber;
@@ -317,7 +318,7 @@
     // Set a 2x2 transformation matrix on the layer. This transform
     // will be applied after parent transforms, but before any final
     // producer specified transform.
-    virtual bool setMatrix(const layer_state_t::matrix22_t& matrix);
+    virtual bool setMatrix(const layer_state_t::matrix22_t& matrix) = 0;
 
     // This second set of geometry attributes are controlled by
     // setGeometryAppliesWithResize, and their default mode is to be
@@ -327,9 +328,9 @@
 
     // setPosition operates in parent buffer space (pre parent-transform) or display
     // space for top-level layers.
-    virtual bool setPosition(float x, float y);
+    virtual bool setPosition(float x, float y) = 0;
     // Buffer space
-    virtual bool setCrop(const Rect& crop);
+    bool setCrop(const Rect& crop);
 
     // TODO(b/38182121): Could we eliminate the various latching modes by
     // using the layer hierarchy?
@@ -338,7 +339,7 @@
     virtual bool setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ);
 
     virtual bool setAlpha(float alpha);
-    virtual bool setColor(const half3& /*color*/) { return false; };
+    virtual bool setColor(const half3& /*color*/) = 0;
 
     // Set rounded corner radius for this layer and its children.
     //
@@ -365,29 +366,27 @@
     virtual bool isDimmingEnabled() const { return getDrawingState().dimmingEnabled; };
 
     // Used only to set BufferStateLayer state
-    virtual bool setTransform(uint32_t /*transform*/) { return false; };
-    virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/) { return false; };
+    virtual bool setTransform(uint32_t /*transform*/) = 0;
+    virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/) = 0;
     virtual bool setBuffer(std::shared_ptr<renderengine::ExternalTexture>& /* buffer */,
                            const BufferData& /* bufferData */, nsecs_t /* postTime */,
                            nsecs_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/,
                            std::optional<nsecs_t> /* dequeueTime */,
-                           const FrameTimelineInfo& /*info*/) {
-        return false;
-    };
-    virtual bool setDataspace(ui::Dataspace /*dataspace*/) { return false; };
-    virtual bool setHdrMetadata(const HdrMetadata& /*hdrMetadata*/) { return false; };
-    virtual bool setSurfaceDamageRegion(const Region& /*surfaceDamage*/) { return false; };
-    virtual bool setApi(int32_t /*api*/) { return false; };
-    virtual bool setSidebandStream(const sp<NativeHandle>& /*sidebandStream*/) { return false; };
+                           const FrameTimelineInfo& /*info*/) = 0;
+    virtual bool setDataspace(ui::Dataspace /*dataspace*/) = 0;
+    virtual bool setHdrMetadata(const HdrMetadata& /*hdrMetadata*/) = 0;
+    virtual bool setSurfaceDamageRegion(const Region& /*surfaceDamage*/) = 0;
+    virtual bool setApi(int32_t /*api*/) = 0;
+    virtual bool setSidebandStream(const sp<NativeHandle>& /*sidebandStream*/) = 0;
     virtual bool setTransactionCompletedListeners(
-            const std::vector<sp<CallbackHandle>>& /*handles*/);
+            const std::vector<sp<CallbackHandle>>& /*handles*/) = 0;
     virtual bool setBackgroundColor(const half3& color, float alpha, ui::Dataspace dataspace);
     virtual bool setColorSpaceAgnostic(const bool agnostic);
     virtual bool setDimmingEnabled(const bool dimmingEnabled);
     virtual bool setDefaultFrameRateCompatibility(FrameRateCompatibility compatibility);
     virtual bool setFrameRateSelectionPriority(int32_t priority);
     virtual bool setFixedTransformHint(ui::Transform::RotationFlags fixedTransformHint);
-    virtual void setAutoRefresh(bool /* autoRefresh */) {}
+    virtual void setAutoRefresh(bool /* autoRefresh */) = 0;
     bool setDropInputMode(gui::DropInputMode);
 
     //  If the variable is not set on the layer, it traverses up the tree to inherit the frame
@@ -396,10 +395,10 @@
     //
     virtual FrameRateCompatibility getDefaultFrameRateCompatibility() const;
     //
-    virtual ui::Dataspace getDataSpace() const { return ui::Dataspace::UNKNOWN; }
+    virtual ui::Dataspace getDataSpace() const = 0;
 
-    virtual sp<compositionengine::LayerFE> getCompositionEngineLayerFE() const;
-    virtual compositionengine::LayerFECompositionState* editCompositionState();
+    virtual sp<compositionengine::LayerFE> getCompositionEngineLayerFE() const = 0;
+    virtual compositionengine::LayerFECompositionState* editCompositionState() = 0;
 
     // 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
@@ -415,18 +414,18 @@
      * pixel format includes an alpha channel) and the "opaque" flag set
      * on the layer.  It does not examine the current plane alpha value.
      */
-    virtual bool isOpaque(const Layer::State&) const { return false; }
+    virtual bool isOpaque(const Layer::State&) const = 0;
 
     /*
      * Returns whether this layer can receive input.
      */
-    virtual bool canReceiveInput() const;
+    virtual bool canReceiveInput() const = 0;
 
     /*
      * isProtected - true if the layer may contain protected contents in the
      * GRALLOC_USAGE_PROTECTED sense.
      */
-    virtual bool isProtected() const { return false; }
+    virtual bool isProtected() const = 0;
 
     /*
      * isFixedSize - true if content has a fixed size
@@ -436,7 +435,7 @@
     /*
      * usesSourceCrop - true if content should use a source crop
      */
-    virtual bool usesSourceCrop() const { return false; }
+    virtual bool usesSourceCrop() const = 0;
 
     // Most layers aren't created from the main thread, and therefore need to
     // grab the SF state lock to access HWC, but ContainerLayer does, so we need
@@ -444,11 +443,9 @@
     virtual bool isCreatedFromMainThread() const { return false; }
 
     ui::Transform getActiveTransform(const Layer::State& s) const { return s.transform; }
-    Region getActiveTransparentRegion(const Layer::State& s) const {
-        return s.transparentRegionHint;
-    }
-    virtual Rect getCrop(const Layer::State& s) const { return s.crop; }
-    virtual bool needsFiltering(const DisplayDevice*) const { return false; }
+    virtual Region getActiveTransparentRegion(const Layer::State& s) const = 0;
+    Rect getCrop(const Layer::State& s) const { return s.crop; }
+    virtual bool needsFiltering(const DisplayDevice*) const = 0;
 
     // True if this layer requires filtering
     // This method is distinct from needsFiltering() in how the filter
@@ -459,13 +456,11 @@
     // different.
     // If the parent transform needs to be undone when capturing the layer, then
     // the inverse parent transform is also required.
-    virtual bool needsFilteringForScreenshots(const DisplayDevice*, const ui::Transform&) const {
-        return false;
-    }
+    virtual bool needsFilteringForScreenshots(const DisplayDevice*, const ui::Transform&) const = 0;
 
     virtual void updateCloneBufferInfo(){};
 
-    virtual bool isHdrY410() const { return false; }
+    virtual bool isHdrY410() const = 0;
 
     /*
      * called after composition.
@@ -474,10 +469,10 @@
     virtual void onPostComposition(const DisplayDevice*,
                                    const std::shared_ptr<FenceTime>& /*glDoneFence*/,
                                    const std::shared_ptr<FenceTime>& /*presentFence*/,
-                                   const CompositorTiming&) {}
+                                   const CompositorTiming&) = 0;
 
     // If a buffer was replaced this frame, release the former buffer
-    virtual void releasePendingBuffer(nsecs_t /*dequeueReadyTime*/) { }
+    virtual void releasePendingBuffer(nsecs_t /*dequeueReadyTime*/) = 0;
 
     /*
      * latchBuffer - called each time the screen is redrawn and returns whether
@@ -485,34 +480,30 @@
      * operation, so this should be set only if needed). Typically this is used
      * to figure out if the content or size of a surface has changed.
      */
-    virtual bool latchBuffer(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/) {
-        return false;
-    }
+    virtual bool latchBuffer(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/) = 0;
 
-    virtual void latchAndReleaseBuffer() {}
+    virtual void latchAndReleaseBuffer() = 0;
 
     /*
      * returns the rectangle that crops the content of the layer and scales it
      * to the layer's size.
      */
-    virtual Rect getBufferCrop() const { return Rect(); }
+    virtual Rect getBufferCrop() const = 0;
 
     /*
      * Returns the transform applied to the buffer.
      */
-    virtual uint32_t getBufferTransform() const { return 0; }
+    virtual uint32_t getBufferTransform() const = 0;
 
-    virtual sp<GraphicBuffer> getBuffer() const { return nullptr; }
-    virtual const std::shared_ptr<renderengine::ExternalTexture>& getExternalTexture() const {
-        return mDrawingState.buffer;
-    };
+    virtual sp<GraphicBuffer> getBuffer() const = 0;
+    virtual const std::shared_ptr<renderengine::ExternalTexture>& getExternalTexture() const = 0;
 
-    virtual ui::Transform::RotationFlags getTransformHint() const { return ui::Transform::ROT_0; }
+    virtual ui::Transform::RotationFlags getTransformHint() const = 0;
 
     /*
      * Returns if a frame is ready
      */
-    virtual bool hasReadyFrame() const { return false; }
+    virtual bool hasReadyFrame() const = 0;
 
     virtual int32_t getQueuedFrameCount() const { return 0; }
 
@@ -520,19 +511,17 @@
      * Returns active buffer size in the correct orientation. Buffer size is determined by undoing
      * any buffer transformations. If the layer has no buffer then return INVALID_RECT.
      */
-    virtual Rect getBufferSize(const Layer::State&) const { return Rect::INVALID_RECT; }
+    virtual Rect getBufferSize(const Layer::State&) const = 0;
 
     /**
      * Returns the source bounds. If the bounds are not defined, it is inferred from the
      * buffer size. Failing that, the bounds are determined from the passed in parent bounds.
      * For the root layer, this is the display viewport size.
      */
-    virtual FloatRect computeSourceBounds(const FloatRect& parentBounds) const {
-        return parentBounds;
-    }
+    virtual FloatRect computeSourceBounds(const FloatRect& parentBounds) const = 0;
     virtual FrameRate getFrameRateForLayerTree() const;
 
-    virtual bool getTransformToDisplayInverse() const { return false; }
+    virtual bool getTransformToDisplayInverse() const = 0;
 
     // Returns how rounded corners should be drawn for this layer.
     // A layer can override its parent's rounded corner settings if the parent's rounded
@@ -548,19 +537,19 @@
      * overrides this so we can generate input-info for Buffered layers that don't
      * have them (for input occlusion detection checks).
      */
-    virtual bool needsInputInfo() const { return hasInputInfo(); }
+    virtual bool needsInputInfo() const = 0;
 
     // Implements RefBase.
     void onFirstRef() override;
 
     // implements compositionengine::LayerFE
-    const compositionengine::LayerFECompositionState* getCompositionState() const override;
-    bool onPreComposition(nsecs_t) override;
+    virtual const compositionengine::LayerFECompositionState* getCompositionState() const = 0;
+    virtual bool onPreComposition(nsecs_t) = 0;
     void prepareCompositionState(compositionengine::LayerFE::StateSubset subset) override;
 
     std::optional<compositionengine::LayerFE::LayerSettings> prepareClientComposition(
             compositionengine::LayerFE::ClientCompositionTargetSettings&) const override;
-    void onLayerDisplayed(ftl::SharedFuture<FenceResult>) override;
+    virtual void onLayerDisplayed(ftl::SharedFuture<FenceResult>) = 0;
 
     void setWasClientComposed(const sp<Fence>& fence) override {
         mLastClientCompositionFence = fence;
@@ -838,13 +827,13 @@
     float getBorderWidth();
     const half4& getBorderColor();
 
-    virtual bool setBufferCrop(const Rect& /* bufferCrop */) { return false; }
-    virtual bool setDestinationFrame(const Rect& /* destinationFrame */) { return false; }
-    virtual std::atomic<int32_t>* getPendingBufferCounter() { return nullptr; }
-    virtual std::string getPendingBufferCounterName() { return ""; }
-    virtual bool updateGeometry() { return false; }
+    virtual bool setBufferCrop(const Rect& /* bufferCrop */) = 0;
+    virtual bool setDestinationFrame(const Rect& /* destinationFrame */) = 0;
+    virtual std::atomic<int32_t>* getPendingBufferCounter() = 0;
+    virtual std::string getPendingBufferCounterName() = 0;
+    virtual bool updateGeometry() = 0;
 
-    virtual bool simpleBufferUpdate(const layer_state_t&) const { return false; }
+    virtual bool simpleBufferUpdate(const layer_state_t&) const = 0;
 
 protected:
     friend class impl::SurfaceInterceptor;
@@ -899,7 +888,7 @@
     compositionengine::OutputLayer* findOutputLayerForDisplay(const DisplayDevice*) const;
     bool usingRelativeZ(LayerVector::StateSet) const;
 
-    virtual ui::Transform getInputTransform() const;
+    virtual ui::Transform getInputTransform() const = 0;
     /**
      * Get the bounds in layer space within which this layer can receive input.
      *
@@ -913,7 +902,7 @@
      * "replaceTouchableRegionWithCrop" is specified. In this case, the layer will receive input
      * in this layer's space, regardless of the specified crop layer.
      */
-    virtual Rect getInputBounds() const;
+    virtual Rect getInputBounds() const = 0;
 
     // constant
     sp<SurfaceFlinger> mFlinger;
@@ -984,7 +973,7 @@
     sp<Fence> mLastClientCompositionFence;
     bool mClearClientCompositionFenceOnLayerDisplayed = false;
 private:
-    virtual void setTransformHint(ui::Transform::RotationFlags) {}
+    virtual void setTransformHint(ui::Transform::RotationFlags) = 0;
 
     // Returns true if the layer can draw shadows on its border.
     virtual bool canDrawShadows() const { return true; }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 3acf203..57ca859 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4575,7 +4575,11 @@
 
     switch (args.flags & ISurfaceComposerClient::eFXSurfaceMask) {
         case ISurfaceComposerClient::eFXSurfaceBufferQueue:
-        case ISurfaceComposerClient::eFXSurfaceBufferState: {
+        case ISurfaceComposerClient::eFXSurfaceContainer:
+        case ISurfaceComposerClient::eFXSurfaceBufferState:
+            args.flags |= ISurfaceComposerClient::eNoColorFill;
+            FMT_FALLTHROUGH;
+        case ISurfaceComposerClient::eFXSurfaceEffect: {
             result = createBufferStateLayer(args, outHandle, &layer);
             std::atomic<int32_t>* pendingBufferCounter = layer->getPendingBufferCounter();
             if (pendingBufferCounter) {
@@ -4584,12 +4588,6 @@
                                         pendingBufferCounter);
             }
         } break;
-        case ISurfaceComposerClient::eFXSurfaceContainer:
-            args.flags |= ISurfaceComposerClient::eNoColorFill;
-            FMT_FALLTHROUGH;
-        case ISurfaceComposerClient::eFXSurfaceEffect:
-            result = createEffectLayer(args, outHandle, &layer);
-            break;
         default:
             result = BAD_VALUE;
             break;
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h
index 1a49ead..2c62b28 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.h
@@ -24,8 +24,8 @@
 
 #include <scheduler/TimeKeeper.h>
 
+#include "BufferStateLayer.h"
 #include "Clock.h"
-#include "Layer.h"
 #include "Scheduler/EventThread.h"
 #include "Scheduler/RefreshRateConfigs.h"
 #include "Scheduler/Scheduler.h"
@@ -66,10 +66,10 @@
     std::chrono::steady_clock::time_point mNow;
 };
 
-class FuzzImplLayer : public Layer {
+class FuzzImplLayer : public BufferStateLayer {
 public:
     FuzzImplLayer(SurfaceFlinger* flinger, std::string name)
-          : Layer(LayerCreationArgs(flinger, nullptr, std::move(name), 0, {})) {}
+          : BufferStateLayer(LayerCreationArgs(flinger, nullptr, std::move(name), 0, {})) {}
     explicit FuzzImplLayer(SurfaceFlinger* flinger) : FuzzImplLayer(flinger, "FuzzLayer") {}
 
     const char* getType() const override { return ""; }
diff --git a/services/surfaceflinger/tests/unittests/mock/MockLayer.h b/services/surfaceflinger/tests/unittests/mock/MockLayer.h
index d086d79..48d05cb 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockLayer.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockLayer.h
@@ -18,14 +18,14 @@
 
 #include <gmock/gmock.h>
 
-#include "Layer.h"
+#include "BufferStateLayer.h"
 
 namespace android::mock {
 
-class MockLayer : public Layer {
+class MockLayer : public BufferStateLayer {
 public:
     MockLayer(SurfaceFlinger* flinger, std::string name)
-          : Layer(LayerCreationArgs(flinger, nullptr, std::move(name), 0, {})) {
+          : BufferStateLayer(LayerCreationArgs(flinger, nullptr, std::move(name), 0, {})) {
         EXPECT_CALL(*this, getDefaultFrameRateCompatibility())
                 .WillOnce(testing::Return(scheduler::LayerInfo::FrameRateCompatibility::Default));
     }