Change slot generation for BufferState

BufferState layers now do slot generation with buffer death considered
appropriately.  When a buffer dies, the slot will be pushed onto a stack
of available slots to be reused at the next opportunity.  This should
mimic BufferQueue slot behavior and prevent Composer Resources from
growing too large.

Test: build, boot, manual
Bug: 129351223

Change-Id: Icef9592593cacb0b5c6b12f6679fc2c4dabdcd19
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/HwcBufferCache.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/HwcBufferCache.h
index 97bdc8f..8eec035 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/HwcBufferCache.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/HwcBufferCache.h
@@ -48,20 +48,11 @@
     void getHwcBuffer(int slot, const sp<GraphicBuffer>& buffer, uint32_t* outSlot,
                       sp<GraphicBuffer>* outBuffer);
 
-protected:
-    bool getSlot(const sp<GraphicBuffer>& buffer, uint32_t* outSlot);
-    uint32_t getLeastRecentlyUsedSlot();
-    uint64_t getCounter();
-
 private:
     // an array where the index corresponds to a slot and the value corresponds to a (counter,
     // buffer) pair. "counter" is a unique value that indicates the last time this slot was updated
     // or used and allows us to keep track of the least-recently used buffer.
-    std::pair<uint64_t, wp<GraphicBuffer>> mBuffers[BufferQueue::NUM_BUFFER_SLOTS];
-
-    // The cache increments this counter value when a slot is updated or used.
-    // Used to track the least recently-used buffer
-    uint64_t mCounter = 1;
+    wp<GraphicBuffer> mBuffers[BufferQueue::NUM_BUFFER_SLOTS];
 };
 
 } // namespace compositionengine::impl
diff --git a/services/surfaceflinger/CompositionEngine/src/HwcBufferCache.cpp b/services/surfaceflinger/CompositionEngine/src/HwcBufferCache.cpp
index a941e09..f72862b 100644
--- a/services/surfaceflinger/CompositionEngine/src/HwcBufferCache.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/HwcBufferCache.cpp
@@ -21,60 +21,30 @@
 namespace android::compositionengine::impl {
 
 HwcBufferCache::HwcBufferCache() {
-    std::fill(std::begin(mBuffers), std::end(mBuffers),
-              std::pair<uint64_t, wp<GraphicBuffer>>(0, nullptr));
-}
-bool HwcBufferCache::getSlot(const sp<GraphicBuffer>& buffer, uint32_t* outSlot) {
-    // search for cached buffer first
-    for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
-        // Weak pointers in the cache may have had their object destroyed.
-        // Comparisons between weak pointers will accurately reflect this case,
-        // but comparisons between weak and strong may not.  Thus, we create a weak
-        // pointer from strong pointer buffer
-        wp<GraphicBuffer> weakCopy(buffer);
-        if (mBuffers[i].second == weakCopy) {
-            *outSlot = i;
-            return true;
-        }
-    }
-
-    // use the least-recently used slot
-    *outSlot = getLeastRecentlyUsedSlot();
-    return false;
-}
-
-uint32_t HwcBufferCache::getLeastRecentlyUsedSlot() {
-    auto iter = std::min_element(std::begin(mBuffers), std::end(mBuffers));
-    return std::distance(std::begin(mBuffers), iter);
+    std::fill(std::begin(mBuffers), std::end(mBuffers), wp<GraphicBuffer>(nullptr));
 }
 
 void HwcBufferCache::getHwcBuffer(int slot, const sp<GraphicBuffer>& buffer, uint32_t* outSlot,
                                   sp<GraphicBuffer>* outBuffer) {
-    // if this slot corresponds to a BufferStateLayer, generate the slot
-    if (slot == BufferQueue::INVALID_BUFFER_SLOT) {
-        getSlot(buffer, outSlot);
-    } else if (slot < 0 || slot >= BufferQueue::NUM_BUFFER_SLOTS) {
+    // default is 0
+    if (slot == BufferQueue::INVALID_BUFFER_SLOT || slot < 0 ||
+        slot >= BufferQueue::NUM_BUFFER_SLOTS) {
         *outSlot = 0;
     } else {
         *outSlot = slot;
     }
 
-    auto& [currentCounter, currentBuffer] = mBuffers[*outSlot];
+    auto& currentBuffer = mBuffers[*outSlot];
     wp<GraphicBuffer> weakCopy(buffer);
     if (currentBuffer == weakCopy) {
         // already cached in HWC, skip sending the buffer
         *outBuffer = nullptr;
-        currentCounter = getCounter();
     } else {
         *outBuffer = buffer;
 
         // update cache
         currentBuffer = buffer;
-        currentCounter = getCounter();
     }
 }
 
-uint64_t HwcBufferCache::getCounter() {
-    return mCounter++;
-}
 } // namespace android::compositionengine::impl
diff --git a/services/surfaceflinger/CompositionEngine/tests/HwcBufferCacheTest.cpp b/services/surfaceflinger/CompositionEngine/tests/HwcBufferCacheTest.cpp
index b261493..00eafb1 100644
--- a/services/surfaceflinger/CompositionEngine/tests/HwcBufferCacheTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/HwcBufferCacheTest.cpp
@@ -28,10 +28,6 @@
                       sp<GraphicBuffer>* outBuffer) {
         HwcBufferCache::getHwcBuffer(slot, buffer, outSlot, outBuffer);
     }
-    bool getSlot(const sp<GraphicBuffer>& buffer, uint32_t* outSlot) {
-        return HwcBufferCache::getSlot(buffer, outSlot);
-    }
-    uint32_t getLeastRecentlyUsedSlot() { return HwcBufferCache::getLeastRecentlyUsedSlot(); }
 };
 
 class HwcBufferCacheTest : public testing::Test {
@@ -86,41 +82,5 @@
     testSlot(-123, 0);
 }
 
-TEST_F(HwcBufferCacheTest, cacheGeneratesSlotForInvalidBufferSlot) {
-    uint32_t outSlot;
-    sp<GraphicBuffer> outBuffer;
-
-    mCache.getHwcBuffer(BufferQueue::INVALID_BUFFER_SLOT, mBuffer1, &outSlot, &outBuffer);
-    EXPECT_EQ(0, outSlot);
-    EXPECT_EQ(mBuffer1, outBuffer);
-
-    mCache.getHwcBuffer(BufferQueue::INVALID_BUFFER_SLOT, mBuffer1, &outSlot, &outBuffer);
-    EXPECT_EQ(0, outSlot);
-    EXPECT_EQ(nullptr, outBuffer.get());
-
-    mCache.getHwcBuffer(BufferQueue::INVALID_BUFFER_SLOT, mBuffer2, &outSlot, &outBuffer);
-    EXPECT_EQ(1, outSlot);
-    EXPECT_EQ(mBuffer2, outBuffer);
-
-    mCache.getHwcBuffer(BufferQueue::INVALID_BUFFER_SLOT, mBuffer2, &outSlot, &outBuffer);
-    EXPECT_EQ(1, outSlot);
-    EXPECT_EQ(nullptr, outBuffer.get());
-
-    mCache.getHwcBuffer(BufferQueue::INVALID_BUFFER_SLOT, sp<GraphicBuffer>(), &outSlot,
-                        &outBuffer);
-    EXPECT_EQ(2, outSlot);
-    EXPECT_EQ(nullptr, outBuffer.get());
-
-    // note that sending mBuffer1 with explicit slot 1 will overwrite mBuffer2
-    // and also cause mBuffer1 to be stored in two places
-    mCache.getHwcBuffer(1, mBuffer1, &outSlot, &outBuffer);
-    EXPECT_EQ(1, outSlot);
-    EXPECT_EQ(mBuffer1, outBuffer);
-
-    mCache.getHwcBuffer(BufferQueue::INVALID_BUFFER_SLOT, mBuffer2, &outSlot, &outBuffer);
-    EXPECT_EQ(3, outSlot);
-    EXPECT_EQ(mBuffer2, outBuffer);
-}
-
 } // namespace
 } // namespace android::compositionengine