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

Commit eee4c9cb authored by Melody Hsu's avatar Melody Hsu
Browse files

Time duration blocked on dequeueBuffer for stuffing recovery

Start buffer stuffing recovery only when severely buffer stuffed.
Determined based on how long BBQ waits on buffer release. Waits
shorter than this may simply be false positives for buffer stuffing
recovery due to timing and should be ignored.

Bug: b/294922229
Test: Manually check perfetto traces, presubmit, SysUi performance tests
Flag: android.view.flags.buffer_stuffing_recovery
Change-Id: Ic8c01edaebd599724fc7a9a67630069c05b567c1
parent e7158108
Loading
Loading
Loading
Loading
+12 −7
Original line number Diff line number Diff line
@@ -1221,16 +1221,12 @@ public:
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
    status_t waitForBufferRelease(std::unique_lock<std::mutex>& bufferQueueLock,
                                  nsecs_t timeout) const override {
        const auto startTime = std::chrono::steady_clock::now();
        sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
        if (!bbq) {
            return OK;
        }

        // Provide a callback for Choreographer to start buffer stuffing recovery when blocked
        // on buffer release.
        std::function<void()> callbackCopy = bbq->getWaitForBufferReleaseCallback();
        if (callbackCopy) callbackCopy();

        // BufferQueue has already checked if we have a free buffer. If there's an unread interrupt,
        // we want to ignore it. This must be done before unlocking the BufferQueue lock to ensure
        // we don't miss an interrupt.
@@ -1252,6 +1248,14 @@ public:
        }

        bbq->releaseBufferCallback(id, fence, maxAcquiredBufferCount);
        const nsecs_t durationNanos = std::chrono::duration_cast<std::chrono::nanoseconds>(
                                              std::chrono::steady_clock::now() - startTime)
                                              .count();
        // Provide a callback for Choreographer to start buffer stuffing recovery when blocked
        // on buffer release.
        std::function<void(const nsecs_t)> callbackCopy = bbq->getWaitForBufferReleaseCallback();
        if (callbackCopy) callbackCopy(durationNanos);

        return OK;
    }
#endif
@@ -1343,12 +1347,13 @@ void BLASTBufferQueue::setApplyToken(sp<IBinder> applyToken) {
    mApplyToken = std::move(applyToken);
}

void BLASTBufferQueue::setWaitForBufferReleaseCallback(std::function<void()> callback) {
void BLASTBufferQueue::setWaitForBufferReleaseCallback(
        std::function<void(const nsecs_t)> callback) {
    std::lock_guard _lock{mWaitForBufferReleaseMutex};
    mWaitForBufferReleaseCallback = std::move(callback);
}

std::function<void()> BLASTBufferQueue::getWaitForBufferReleaseCallback() const {
std::function<void(const nsecs_t)> BLASTBufferQueue::getWaitForBufferReleaseCallback() const {
    std::lock_guard _lock{mWaitForBufferReleaseMutex};
    return mWaitForBufferReleaseCallback;
}
+4 −3
Original line number Diff line number Diff line
@@ -143,9 +143,9 @@ public:
    void setTransactionHangCallback(std::function<void(const std::string&)> callback);
    void setApplyToken(sp<IBinder>);

    void setWaitForBufferReleaseCallback(std::function<void()> callback)
    void setWaitForBufferReleaseCallback(std::function<void(const nsecs_t)> callback)
            EXCLUDES(mWaitForBufferReleaseMutex);
    std::function<void()> getWaitForBufferReleaseCallback() const
    std::function<void(const nsecs_t)> getWaitForBufferReleaseCallback() const
            EXCLUDES(mWaitForBufferReleaseMutex);

    virtual ~BLASTBufferQueue();
@@ -329,7 +329,8 @@ private:

    std::unordered_set<uint64_t> mSyncedFrameNumbers GUARDED_BY(mMutex);

    std::function<void()> mWaitForBufferReleaseCallback GUARDED_BY(mWaitForBufferReleaseMutex);
    std::function<void(const nsecs_t)> mWaitForBufferReleaseCallback
            GUARDED_BY(mWaitForBufferReleaseMutex);
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
    // BufferReleaseChannel is used to communicate buffer releases from SurfaceFlinger to the
    // client.