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

Commit 35b4e383 authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Wait for buffer allocation

In dequeueBuffer, if we don't have a free slot but are in the
process of allocating, we wait for that to complete instead of
kicking off our own allocation, as it's likely that the allocation
from allocateBuffers is able to finish earlier than if we'd kick
off our own allocation.

Test: Swipe up, see less initial buffer dequeue delay
Fixes: 111517695
Change-Id: I735d68e87fc7e2ff5b7ec3595f0ced5a94ebbf9c
parent 6ae55032
Loading
Loading
Loading
Loading
+17 −1
Original line number Original line Diff line number Diff line
@@ -59,7 +59,8 @@ BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core,
    mNextCallbackTicket(0),
    mNextCallbackTicket(0),
    mCurrentCallbackTicket(0),
    mCurrentCallbackTicket(0),
    mCallbackCondition(),
    mCallbackCondition(),
    mDequeueTimeout(-1) {}
    mDequeueTimeout(-1),
    mDequeueWaitingForAllocation(false) {}


BufferQueueProducer::~BufferQueueProducer() {}
BufferQueueProducer::~BufferQueueProducer() {}


@@ -383,6 +384,15 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou
    { // Autolock scope
    { // Autolock scope
        std::unique_lock<std::mutex> lock(mCore->mMutex);
        std::unique_lock<std::mutex> lock(mCore->mMutex);


        // If we don't have a free buffer, but we are currently allocating, we wait until allocation
        // is finished such that we don't allocate in parallel.
        if (mCore->mFreeBuffers.empty() && mCore->mIsAllocating) {
            mDequeueWaitingForAllocation = true;
            mCore->waitWhileAllocatingLocked(lock);
            mDequeueWaitingForAllocation = false;
            mDequeueWaitingForAllocationCondition.notify_all();
        }

        if (format == 0) {
        if (format == 0) {
            format = mCore->mDefaultBufferFormat;
            format = mCore->mDefaultBufferFormat;
        }
        }
@@ -1421,6 +1431,12 @@ void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height,
            mCore->mIsAllocating = false;
            mCore->mIsAllocating = false;
            mCore->mIsAllocatingCondition.notify_all();
            mCore->mIsAllocatingCondition.notify_all();
            VALIDATE_CONSISTENCY();
            VALIDATE_CONSISTENCY();

            // If dequeue is waiting for to allocate a buffer, release the lock until it's not
            // waiting anymore so it can use the buffer we just allocated.
            while (mDequeueWaitingForAllocation) {
                mDequeueWaitingForAllocationCondition.wait(lock);
            }
        } // Autolock scope
        } // Autolock scope
    }
    }
}
}
+7 −0
Original line number Original line Diff line number Diff line
@@ -253,6 +253,13 @@ private:
    // slot is not yet available.
    // slot is not yet available.
    nsecs_t mDequeueTimeout;
    nsecs_t mDequeueTimeout;


    // If set to true, dequeueBuffer() is currently waiting for buffer allocation to complete.
    bool mDequeueWaitingForAllocation;

    // Condition variable to signal allocateBuffers() that dequeueBuffer() is no longer waiting for
    // allocation to complete.
    std::condition_variable mDequeueWaitingForAllocationCondition;

}; // class BufferQueueProducer
}; // class BufferQueueProducer


} // namespace android
} // namespace android