Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7016de50 authored by Anton Ivanov's avatar Anton Ivanov
Browse files

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
parent 469494a0
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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.
+7 −9
Original line number Diff line number Diff line
@@ -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) {
+8 −3
Original line number Diff line number Diff line
@@ -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.