summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Anton Ivanov <aii@google.com> 2025-02-05 17:39:41 -0800
committer Anton Ivanov <aii@google.com> 2025-02-07 01:45:32 +0000
commit7016de508cdae8dc94b1ff60e5292859642e4aac (patch)
treec6e4cc7e8971aa19ff50aba3d4cfdde0cd08792c
parent469494a0210239dd8c29304d2786b9f1770ce981 (diff)
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
-rw-r--r--include/ftl/small_map.h6
-rw-r--r--libs/gui/BLASTBufferQueue.cpp16
-rw-r--r--libs/gui/include/gui/BLASTBufferQueue.h11
3 files changed, 21 insertions, 12 deletions
diff --git a/include/ftl/small_map.h b/include/ftl/small_map.h
index 83d5967464..96d35cd21e 100644
--- a/include/ftl/small_map.h
+++ b/include/ftl/small_map.h
@@ -234,6 +234,12 @@ class SmallMap final {
//
bool erase(const key_type& key) { return erase(key, begin()); }
+ // Removes a mapping.
+ //
+ // The last() and end() iterators, as well as those to the erased mapping, are invalidated.
+ //
+ void erase(iterator it) { map_.unstable_erase(it); }
+
// Removes all mappings.
//
// All iterators are invalidated.
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 0848fac293..c770db9cf3 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -415,14 +415,12 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence
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 @@ status_t BLASTBufferQueue::acquireNextBufferLocked(
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::onFrameReplaced(const BufferItem& item) {
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 b97a49616d..cdc2150a26 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 @@ private:
// 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 @@ private:
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.