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

Commit bf25577c authored by Vishnu Nair's avatar Vishnu Nair
Browse files

BlastBufferQueue: Fix wait in onFrameAvailable

Use the same logic in both onFrameAvailable and processNextBufferLocked
to check if we can acquire a buffer. Otherwise, there is a chance we
will not be waiting long enough in onFrameAvailable.

Also add error logs if we return unexpectedly when trying to acquire a
buffer.
Test: go/wm-smoke with blast enabled
Test: atest SurfaceViewBufferTests
Change-Id: I2f8afa2fc2efb0371ccc86b422524e474e3f6170

Change-Id: Ibf2733725f7a4334eff38b516f0f5cec87dfd493
parent 7eb670ae
Loading
Loading
Loading
Loading
+14 −6
Original line number Diff line number Diff line
@@ -213,12 +213,9 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) {
    ATRACE_CALL();
    BQA_LOGV("processNextBufferLocked useNextTransaction=%s", toString(useNextTransaction));

    // Wait to acquire a buffer if there are no frames available or we have acquired the maximum
    // Wait to acquire a buffer if there are no frames available or we have acquired the max
    // number of buffers.
    // As a special case, we wait for the first callback before acquiring the second buffer so we
    // can ensure the first buffer is presented if multiple buffers are queued in succession.
    if (mNumFrameAvailable == 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS + 1 ||
        (!mInitialCallbackReceived && mNumAcquired == 1)) {
    if (mNumFrameAvailable == 0 || maxBuffersAcquired()) {
        BQA_LOGV("processNextBufferLocked waiting for frame available or callback");
        return;
    }
@@ -241,6 +238,7 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) {

    status_t status = mBufferItemConsumer->acquireBuffer(&bufferItem, -1, false);
    if (status != OK) {
        BQA_LOGE("Failed to acquire a buffer, err=%s", statusToString(status).c_str());
        return;
    }
    auto buffer = bufferItem.mGraphicBuffer;
@@ -248,6 +246,7 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) {

    if (buffer == nullptr) {
        mBufferItemConsumer->releaseBuffer(bufferItem, Fence::NO_FENCE);
        BQA_LOGE("Buffer was empty");
        return;
    }

@@ -311,7 +310,7 @@ void BLASTBufferQueue::onFrameAvailable(const BufferItem& /*item*/) {
             toString(nextTransactionSet), toString(mFlushShadowQueue));

    if (nextTransactionSet || mFlushShadowQueue) {
        while (mNumFrameAvailable > 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS + 1) {
        while (mNumFrameAvailable > 0 || maxBuffersAcquired()) {
            BQA_LOGV("waiting in onFrameAvailable...");
            mCallbackCV.wait(_lock);
        }
@@ -344,4 +343,13 @@ bool BLASTBufferQueue::rejectBuffer(const BufferItem& item) const {
    // reject buffers if the buffer size doesn't match.
    return bufWidth != mWidth || bufHeight != mHeight;
}

// Check if we have acquired the maximum number of buffers.
// As a special case, we wait for the first callback before acquiring the second buffer so we
// can ensure the first buffer is presented if multiple buffers are queued in succession.
bool BLASTBufferQueue::maxBuffersAcquired() const {
    return mNumAcquired == MAX_ACQUIRED_BUFFERS + 1 ||
            (!mInitialCallbackReceived && mNumAcquired == 1);
}

} // namespace android
+3 −2
Original line number Diff line number Diff line
@@ -94,9 +94,10 @@ private:
    BLASTBufferQueue(const BLASTBufferQueue& rhs);

    void processNextBufferLocked(bool useNextTransaction) REQUIRES(mMutex);
    Rect computeCrop(const BufferItem& item);
    Rect computeCrop(const BufferItem& item) REQUIRES(mMutex);
    // Return true if we need to reject the buffer based on the scaling mode and the buffer size.
    bool rejectBuffer(const BufferItem& item) const;
    bool rejectBuffer(const BufferItem& item) const REQUIRES(mMutex);
    bool maxBuffersAcquired() const REQUIRES(mMutex);

    std::string mName;
    sp<SurfaceControl> mSurfaceControl;