surfaceflinger: simplify HWC buffer cache clean up

When a Layer is no longer connected, we destroy the associated HWC
layers on next call to SurfaceFlinger::rebuildLayerStacks or when
the Layer is destroyed.  There is no need to listen to
onBuffersReleased.  Besides, we need to perform the cleanup from the
main thread as we only talk to HWC process from the main thread.

While at it, move HWComposerBufferCache to its own files.

Bug: 35320590
Test: manual
Change-Id: Ifa32f24076b094c8fa9cda8572b03d5bfb8e0b93
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index d384bb1..92a7794 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -137,7 +137,7 @@
     status_t err = acquireBufferLocked(&item, 0);
     if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
 #ifdef USE_HWC2
-        mHwcBufferCache->getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer,
+        mHwcBufferCache.getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer,
                 &outSlot, &outBuffer);
 #else
         outBuffer = mCurrentBuffer;
@@ -178,7 +178,7 @@
 
     outFence = item.mFence;
 #ifdef USE_HWC2
-    mHwcBufferCache->getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer,
+    mHwcBufferCache.getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer,
             &outSlot, &outBuffer);
     outDataspace = item.mDataSpace;
 #else
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
index 5eea6b6..69a72d7 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
@@ -18,14 +18,13 @@
 #define ANDROID_SF_FRAMEBUFFER_SURFACE_H
 
 #include "DisplaySurface.h"
+#include "HWComposerBufferCache.h"
 
 #include <stdint.h>
 #include <sys/types.h>
 
 #include <gui/ConsumerBase.h>
 
-#include <memory>
-
 // ---------------------------------------------------------------------------
 namespace android {
 // ---------------------------------------------------------------------------
@@ -33,7 +32,6 @@
 class Rect;
 class String8;
 class HWComposer;
-class HWComposerBufferCache;
 
 // ---------------------------------------------------------------------------
 
@@ -96,8 +94,7 @@
     HWComposer& mHwc;
 
 #ifdef USE_HWC2
-    std::unique_ptr<HWComposerBufferCache> mHwcBufferCache =
-        std::make_unique<HWComposerBufferCache>();
+    HWComposerBufferCache mHwcBufferCache;
 
     // Previous buffer to release after getting an updated retire fence
     bool mHasPendingRelease;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index e1138af..6644bd9 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -925,41 +925,5 @@
     *this = DisplayData();
 }
 
-void HWComposerBufferCache::clear()
-{
-    mBuffers.clear();
-}
-
-void HWComposerBufferCache::getHwcBuffer(int slot,
-        const sp<GraphicBuffer>& buffer,
-        uint32_t* outSlot, sp<GraphicBuffer>* outBuffer)
-{
-#ifdef BYPASS_IHWC
-    *outSlot = slot;
-    *outBuffer = buffer;
-#else
-    if (slot == BufferQueue::INVALID_BUFFER_SLOT || slot < 0) {
-        // default to slot 0
-        slot = 0;
-    }
-
-    if (static_cast<size_t>(slot) >= mBuffers.size()) {
-        mBuffers.resize(slot + 1);
-    }
-
-    *outSlot = slot;
-
-    if (mBuffers[slot] == buffer) {
-        // already cached in HWC, skip sending the buffer
-        *outBuffer = nullptr;
-    } else {
-        *outBuffer = buffer;
-
-        // update cache
-        mBuffers[slot] = buffer;
-    }
-#endif
-}
-
 // ---------------------------------------------------------------------------
 }; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 20cca39..117db4a 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -26,8 +26,6 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <gui/BufferQueue.h>
-
 #include <ui/Fence.h>
 
 #include <utils/BitSet.h>
@@ -236,19 +234,6 @@
     mutable std::atomic<bool> mDumpMayLockUp;
 };
 
-class HWComposerBufferCache {
-public:
-    void clear();
-
-    void getHwcBuffer(int slot, const sp<GraphicBuffer>& buffer,
-            uint32_t* outSlot, sp<GraphicBuffer>* outBuffer);
-
-private:
-    // a vector as we expect "slot" to be in the range of [0, 63] (that is,
-    // less than BufferQueue::NUM_BUFFER_SLOTS).
-    std::vector<sp<GraphicBuffer>> mBuffers;
-};
-
 // ---------------------------------------------------------------------------
 }; // namespace android
 
diff --git a/services/surfaceflinger/DisplayHardware/HWComposerBufferCache.cpp b/services/surfaceflinger/DisplayHardware/HWComposerBufferCache.cpp
new file mode 100644
index 0000000..6b91224
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/HWComposerBufferCache.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 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 "HWComposerBufferCache.h"
+
+#include <gui/BufferQueue.h>
+
+namespace android {
+
+HWComposerBufferCache::HWComposerBufferCache()
+{
+    mBuffers.reserve(BufferQueue::NUM_BUFFER_SLOTS);
+}
+
+void HWComposerBufferCache::getHwcBuffer(int slot,
+        const sp<GraphicBuffer>& buffer,
+        uint32_t* outSlot, sp<GraphicBuffer>* outBuffer)
+{
+#ifdef BYPASS_IHWC
+    *outSlot = slot;
+    *outBuffer = buffer;
+#else
+    if (slot == BufferQueue::INVALID_BUFFER_SLOT || slot < 0) {
+        // default to slot 0
+        slot = 0;
+    }
+
+    if (static_cast<size_t>(slot) >= mBuffers.size()) {
+        mBuffers.resize(slot + 1);
+    }
+
+    *outSlot = slot;
+
+    if (mBuffers[slot] == buffer) {
+        // already cached in HWC, skip sending the buffer
+        *outBuffer = nullptr;
+    } else {
+        *outBuffer = buffer;
+
+        // update cache
+        mBuffers[slot] = buffer;
+    }
+#endif
+}
+
+} // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWComposerBufferCache.h b/services/surfaceflinger/DisplayHardware/HWComposerBufferCache.h
new file mode 100644
index 0000000..a008ca9
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/HWComposerBufferCache.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef ANDROID_SF_HWCOMPOSERBUFFERCACHE_H
+#define ANDROID_SF_HWCOMPOSERBUFFERCACHE_H
+
+#include <stdint.h>
+
+#include <utils/StrongPointer.h>
+
+#include <vector>
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+class GraphicBuffer;
+
+// With HIDLized hwcomposer HAL, the HAL can maintain a buffer cache for each
+// HWC display and layer.  When updating a display target or a layer buffer,
+// we have the option to send the buffer handle over or to request the HAL to
+// retrieve it from its cache.  The latter is cheaper since it eliminates the
+// overhead to transfer the handle over the trasport layer, and the overhead
+// for the HAL to clone and retain the handle.
+//
+// To be able to find out whether a buffer is already in the HAL's cache, we
+// use HWComposerBufferCache to mirror the cache in SF.
+class HWComposerBufferCache {
+public:
+    HWComposerBufferCache();
+
+    // Given a buffer queue slot and buffer, return the HWC cache slot and
+    // buffer to be sent to HWC.
+    //
+    // outBuffer is set to buffer when buffer is not in the HWC cache;
+    // otherwise, outBuffer is set to nullptr.
+    void getHwcBuffer(int slot, const sp<GraphicBuffer>& buffer,
+            uint32_t* outSlot, sp<GraphicBuffer>* outBuffer);
+
+private:
+    // a vector as we expect "slot" to be in the range of [0, 63] (that is,
+    // less than BufferQueue::NUM_BUFFER_SLOTS).
+    std::vector<sp<GraphicBuffer>> mBuffers;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_SF_HWCOMPOSERBUFFERCACHE_H
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index c5a4f99..6f253ab 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -224,7 +224,7 @@
 #ifdef USE_HWC2
         uint32_t hwcSlot = 0;
         sp<GraphicBuffer> hwcBuffer;
-        mHwcBufferCache->getHwcBuffer(mFbProducerSlot, fbBuffer,
+        mHwcBufferCache.getHwcBuffer(mFbProducerSlot, fbBuffer,
                 &hwcSlot, &hwcBuffer);
 
         // TODO: Correctly propagate the dataspace from GL composition
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index fb5fcc8..ee2772a 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -18,18 +18,16 @@
 #define ANDROID_SF_VIRTUAL_DISPLAY_SURFACE_H
 
 #include "DisplaySurface.h"
+#include "HWComposerBufferCache.h"
 
 #include <gui/ConsumerBase.h>
 #include <gui/IGraphicBufferProducer.h>
 
-#include <memory>
-
 // ---------------------------------------------------------------------------
 namespace android {
 // ---------------------------------------------------------------------------
 
 class HWComposer;
-class HWComposerBufferCache;
 class IProducerListener;
 
 /* This DisplaySurface implementation supports virtual displays, where GLES
@@ -255,8 +253,7 @@
     bool mMustRecompose;
 
 #ifdef USE_HWC2
-    std::unique_ptr<HWComposerBufferCache> mHwcBufferCache =
-        std::make_unique<HWComposerBufferCache>();
+    HWComposerBufferCache mHwcBufferCache;
 #endif
 };