Avoid caching front-buffered layers

If the buffer has FRONT_BUFFER we need to tell planner
that the buffer changed even though the buffer pointer/id
didn't.

Bug: 217776226
Test: LayerStateTest::updateBufferSingleBufferedUsage
Change-Id: Ia0f603a1dfea652c7393948ee9ef54e0f998ab88
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
index 5fe9476..cb00e71 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h
@@ -28,6 +28,7 @@
 #include "DisplayHardware/Hal.h"
 #include "math/HashCombine.h"
 
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
 #include <aidl/android/hardware/graphics/composer3/Composition.h>
 
 namespace std {
@@ -395,6 +396,21 @@
                                 return std::vector<std::string>{base::StringPrintf("%p", p)};
                             }};
 
+    static auto constexpr BufferEquals = [](const wp<GraphicBuffer>& lhs,
+                                            const wp<GraphicBuffer>& rhs) -> bool {
+        // Avoid a promotion if the wp<>'s aren't equal
+        if (lhs != rhs) return false;
+
+        // Even if the buffer didn't change, check to see if we need to act as if the buffer changed
+        // anyway. Specifically, look to see if the buffer is FRONT_BUFFER & if so act as if it's
+        // always different
+        using ::aidl::android::hardware::graphics::common::BufferUsage;
+        sp<GraphicBuffer> promotedBuffer = lhs.promote();
+        return !(promotedBuffer &&
+                 ((promotedBuffer->getUsage() & static_cast<int64_t>(BufferUsage::FRONT_BUFFER)) !=
+                  0));
+    };
+
     OutputLayerState<wp<GraphicBuffer>, LayerStateField::Buffer>
             mBuffer{[](auto layer) { return layer->getLayerFE().getCompositionState()->buffer; },
                     [](const wp<GraphicBuffer>& buffer) {
@@ -403,7 +419,8 @@
                                 base::StringPrintf("%p",
                                                    promotedBuffer ? promotedBuffer.get()
                                                                   : nullptr)};
-                    }};
+                    },
+                    BufferEquals};
 
     // Even if the same buffer is passed to BLAST's setBuffer(), we still increment the frame
     // number and need to treat it as if the buffer changed. Otherwise we break existing
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp
index ae52ba2..bd4ff13 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/LayerStateTest.cpp
@@ -17,6 +17,7 @@
 #undef LOG_TAG
 #define LOG_TAG "LayerStateTest"
 
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
 #include <compositionengine/impl/OutputLayer.h>
 #include <compositionengine/impl/planner/LayerState.h>
 #include <compositionengine/mock/LayerFE.h>
@@ -29,7 +30,8 @@
 
 #include <aidl/android/hardware/graphics/composer3/Composition.h>
 
-using aidl::android::hardware::graphics::composer3::Composition;
+using ::aidl::android::hardware::graphics::common::BufferUsage;
+using ::aidl::android::hardware::graphics::composer3::Composition;
 
 namespace android::compositionengine::impl::planner {
 namespace {
@@ -383,6 +385,30 @@
     }
 }
 
+TEST_F(LayerStateTest, updateBufferSingleBufferedUsage) {
+    OutputLayerCompositionState outputLayerCompositionState;
+    LayerFECompositionState layerFECompositionState;
+    layerFECompositionState.buffer = new GraphicBuffer();
+    setupMocksForLayer(mOutputLayer, *mLayerFE, outputLayerCompositionState,
+                       layerFECompositionState);
+    mLayerState = std::make_unique<LayerState>(&mOutputLayer);
+
+    mock::OutputLayer newOutputLayer;
+    sp<mock::LayerFE> newLayerFE = sp<mock::LayerFE>::make();
+    LayerFECompositionState layerFECompositionStateTwo;
+    layerFECompositionStateTwo.buffer = new GraphicBuffer();
+    layerFECompositionStateTwo.buffer->usage = static_cast<uint64_t>(BufferUsage::FRONT_BUFFER);
+    setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
+                       layerFECompositionStateTwo);
+
+    for (uint64_t i = 0; i < 10; i++) {
+        setupMocksForLayer(newOutputLayer, *newLayerFE, outputLayerCompositionState,
+                           layerFECompositionStateTwo);
+        Flags<LayerStateField> updates = mLayerState->update(&newOutputLayer);
+        EXPECT_EQ(Flags<LayerStateField>(LayerStateField::Buffer), updates);
+    }
+}
+
 TEST_F(LayerStateTest, compareBuffer) {
     OutputLayerCompositionState outputLayerCompositionState;
     LayerFECompositionState layerFECompositionState;