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