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

Commit 670b3f73 authored by Vishnu Nair's avatar Vishnu Nair
Browse files

Add buffer rejection logic to BlastBufferQueue

If the client sets the buffer scaling mode to freeze, then we want to
reject any buffers that do not match default width and size of the
buffer.

Additionally, we add logic to wait for the first callback before
acquiring a second buffer this is to ensure we will present the first
buffer if multiple buffers are queued in succession.

Test: atest SurfaceViewBufferTests
Bug: 168504870
Change-Id: I987f8ce4047a6f7f52726cfd404fbe9d565f83a2
parent 6b7c5c94
Loading
Loading
Loading
Loading
+27 −5
Original line number Diff line number Diff line
@@ -166,8 +166,8 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence
                                           const std::vector<SurfaceControlStats>& stats) {
    std::unique_lock _lock{mMutex};
    ATRACE_CALL();

    BQA_LOGV("transactionCallback");
    mInitialCallbackReceived = true;

    if (!stats.empty()) {
        mTransformHint = stats[0].transformHint;
@@ -185,7 +185,7 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence
        if (!stats.empty()) {
            mPendingReleaseItem.releaseFence = stats[0].previousReleaseFence;
        } else {
            ALOGE("Warning: no SurfaceControlStats returned in BLASTBufferQueue callback");
            BQA_LOGE("Warning: no SurfaceControlStats returned in BLASTBufferQueue callback");
            mPendingReleaseItem.releaseFence = nullptr;
        }
        mBufferItemConsumer->releaseBuffer(mPendingReleaseItem.item,
@@ -198,7 +198,7 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence
    }

    if (mSubmitted.empty()) {
        ALOGE("ERROR: callback with no corresponding submitted buffer item");
        BQA_LOGE("ERROR: callback with no corresponding submitted buffer item");
    }
    mPendingReleaseItem.item = std::move(mSubmitted.front());
    mSubmitted.pop();
@@ -213,12 +213,18 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) {
    ATRACE_CALL();
    BQA_LOGV("processNextBufferLocked useNextTransaction=%s", toString(useNextTransaction));

    if (mNumFrameAvailable == 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS + 1) {
    // Wait to acquire a buffer if there are no frames available or 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.
    if (mNumFrameAvailable == 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS + 1 ||
        (!mInitialCallbackReceived && mNumAcquired == 1)) {
        BQA_LOGV("processNextBufferLocked waiting for frame available or callback");
        return;
    }

    if (mSurfaceControl == nullptr) {
        ALOGE("ERROR : surface control is null");
        BQA_LOGE("ERROR : surface control is null");
        return;
    }

@@ -245,6 +251,13 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) {
        return;
    }

    if (rejectBuffer(bufferItem)) {
        BQA_LOGE("rejecting buffer: configured width=%d, height=%d, buffer{w=%d, h=%d}", mWidth,
                 mHeight, buffer->getWidth(), buffer->getHeight());
        mBufferItemConsumer->releaseBuffer(bufferItem, Fence::NO_FENCE);
        return;
    }

    mNumAcquired++;
    mSubmitted.push(bufferItem);

@@ -311,4 +324,13 @@ void BLASTBufferQueue::setNextTransaction(SurfaceComposerClient::Transaction* t)
    mNextTransaction = t;
}

bool BLASTBufferQueue::rejectBuffer(const BufferItem& item) const {
    if (item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE) {
        // Only reject buffers if scaling mode is freeze.
        return false;
    }

    // reject buffers if the buffer size doesn't match.
    return item.mGraphicBuffer->getWidth() != mWidth || item.mGraphicBuffer->getHeight() != mHeight;
}
} // namespace android
+3 −0
Original line number Diff line number Diff line
@@ -94,6 +94,8 @@ private:

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

    std::string mName;
    sp<SurfaceControl> mSurfaceControl;
@@ -107,6 +109,7 @@ private:

    int32_t mNumFrameAvailable GUARDED_BY(mMutex);
    int32_t mNumAcquired GUARDED_BY(mMutex);
    bool mInitialCallbackReceived GUARDED_BY(mMutex) = false;
    struct PendingReleaseItem {
        BufferItem item;
        sp<Fence> releaseFence;