Reduce heap allocations in BLASTBufferQueue.
* Replace std::unordered_map members with ftl::SmallMap with empirically
determined sizes.
* Eliminate creating an unnecessary std::vector
Test: unit, manual
Bug: 285377983
Flag: EXEMPT refactoring
Change-Id: I20402bf58d6619573cb1ff85be5092447f841b8a
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 0848fac..c770db9 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -415,14 +415,12 @@
stat.frameEventStats.dequeueReadyTime);
}
auto currFrameNumber = stat.frameEventStats.frameNumber;
- std::vector<ReleaseCallbackId> staleReleases;
- for (const auto& [key, value]: mSubmitted) {
- if (currFrameNumber > key.framenumber) {
- staleReleases.push_back(key);
+ // Release stale buffers.
+ for (const auto& [key, _] : mSubmitted) {
+ if (currFrameNumber <= key.framenumber) {
+ continue; // not stale.
}
- }
- for (const auto& staleRelease : staleReleases) {
- releaseBufferCallbackLocked(staleRelease,
+ releaseBufferCallbackLocked(key,
stat.previousReleaseFence
? stat.previousReleaseFence
: Fence::NO_FENCE,
@@ -618,7 +616,7 @@
mNumAcquired++;
mLastAcquiredFrameNumber = bufferItem.mFrameNumber;
ReleaseCallbackId releaseCallbackId(buffer->getId(), mLastAcquiredFrameNumber);
- mSubmitted[releaseCallbackId] = bufferItem;
+ mSubmitted.emplace_or_replace(releaseCallbackId, bufferItem);
bool needsDisconnect = false;
mBufferItemConsumer->getConnectionEvents(bufferItem.mFrameNumber, &needsDisconnect);
@@ -851,7 +849,7 @@
void BLASTBufferQueue::onFrameDequeued(const uint64_t bufferId) {
std::lock_guard _lock{mTimestampMutex};
- mDequeueTimestamps[bufferId] = systemTime();
+ mDequeueTimestamps.emplace_or_replace(bufferId, systemTime());
};
void BLASTBufferQueue::onFrameCancelled(const uint64_t bufferId) {
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index b97a496..cdc2150 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -20,6 +20,7 @@
#include <optional>
#include <queue>
+#include <ftl/small_map.h>
#include <gui/BufferItem.h>
#include <gui/BufferItemConsumer.h>
#include <gui/IGraphicBufferConsumer.h>
@@ -36,6 +37,10 @@
namespace android {
+// Sizes determined empirically to avoid allocations during common activity.
+constexpr size_t kSubmittedBuffersMapSizeHint = 8;
+constexpr size_t kDequeueTimestampsMapSizeHint = 32;
+
class BLASTBufferQueue;
class BufferItemConsumer;
@@ -206,7 +211,7 @@
// Keep a reference to the submitted buffers so we can release when surfaceflinger drops the
// buffer or the buffer has been presented and a new buffer is ready to be presented.
- std::unordered_map<ReleaseCallbackId, BufferItem, ReleaseBufferCallbackIdHash> mSubmitted
+ ftl::SmallMap<ReleaseCallbackId, BufferItem, kSubmittedBuffersMapSizeHint> mSubmitted
GUARDED_BY(mMutex);
// Keep a queue of the released buffers instead of immediately releasing
@@ -291,8 +296,8 @@
std::mutex mTimestampMutex;
// Tracks buffer dequeue times by the client. This info is sent to SurfaceFlinger which uses
// it for debugging purposes.
- std::unordered_map<uint64_t /* bufferId */, nsecs_t> mDequeueTimestamps
- GUARDED_BY(mTimestampMutex);
+ ftl::SmallMap<uint64_t /* bufferId */, nsecs_t, kDequeueTimestampsMapSizeHint>
+ mDequeueTimestamps GUARDED_BY(mTimestampMutex);
// Keep track of SurfaceControls that have submitted a transaction and BBQ is waiting on a
// callback for them.