listener; { // Autolock scope std::unique_lock lock(mCore->mMutex); mCore->waitWhileAllocatingLocked(lock); if (mCore->mIsAbandoned) { BQ_LOGE("setMaxDequeuedBufferCount: BufferQueue has been " "abandoned"); return NO_INIT; } if (maxDequeuedBuffers == mCore->mMaxDequeuedBufferCount) { return NO_ERROR; } // The new maxDequeuedBuffer count should not be violated by the number // of currently dequeued buffers int dequeuedCount = 0; for (int s : mCore->mActiveBuffers) { if (mSlots[s].mBufferState.isDequeued()) { dequeuedCount++; } } if (dequeuedCount "> listener; { // Autolock scope std::unique_lock lock(mCore->mMutex); mCore->waitWhileAllocatingLocked(lock); if (mCore->mIsAbandoned) { BQ_LOGE("setMaxDequeuedBufferCount: BufferQueue has been " "abandoned"); return NO_INIT; } if (maxDequeuedBuffers == mCore->mMaxDequeuedBufferCount) { return NO_ERROR; } // The new maxDequeuedBuffer count should not be violated by the number // of currently dequeued buffers int dequeuedCount = 0; for (int s : mCore->mActiveBuffers) { if (mSlots[s].mBufferState.isDequeued()) { dequeuedCount++; } } if (dequeuedCount "> listener; { // Autolock scope std::unique_lock lock(mCore->mMutex); mCore->waitWhileAllocatingLocked(lock); if (mCore->mIsAbandoned) { BQ_LOGE("setMaxDequeuedBufferCount: BufferQueue has been " "abandoned"); return NO_INIT; } if (maxDequeuedBuffers == mCore->mMaxDequeuedBufferCount) { return NO_ERROR; } // The new maxDequeuedBuffer count should not be violated by the number // of currently dequeued buffers int dequeuedCount = 0; for (int s : mCore->mActiveBuffers) { if (mSlots[s].mBufferState.isDequeued()) { dequeuedCount++; } } if (dequeuedCount ">
status_t BufferQueueProducer::setMaxDequeuedBufferCount(
        int maxDequeuedBuffers) {
    ATRACE_CALL();
    BQ_LOGV("setMaxDequeuedBufferCount: maxDequeuedBuffers = %d",
            maxDequeuedBuffers);

    sp<IConsumerListener> listener;
    { // Autolock scope
        std::unique_lock<std::mutex> lock(mCore->mMutex);
        mCore->waitWhileAllocatingLocked(lock);

        if (mCore->mIsAbandoned) {
            BQ_LOGE("setMaxDequeuedBufferCount: BufferQueue has been "
                    "abandoned");
            return NO_INIT;
        }

        if (maxDequeuedBuffers == mCore->mMaxDequeuedBufferCount) {
            return NO_ERROR;
        }

        // The new maxDequeuedBuffer count should not be violated by the number
        // of currently dequeued buffers
        int dequeuedCount = 0;
        for (int s : mCore->mActiveBuffers) {
            if (mSlots[s].mBufferState.isDequeued()) {
                dequeuedCount++;
            }
        }
        if (dequeuedCount > maxDequeuedBuffers) {
            BQ_LOGE("setMaxDequeuedBufferCount: the requested maxDequeuedBuffer"
                    "count (%d) exceeds the current dequeued buffer count (%d)",
                    maxDequeuedBuffers, dequeuedCount);
            return BAD_VALUE;
        }
        int bufferCount = mCore->getMinUndequeuedBufferCountLocked();
        bufferCount += maxDequeuedBuffers;

        if (bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) {
            BQ_LOGE("setMaxDequeuedBufferCount: bufferCount %d too large "
                    "(max %d)", bufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS);
            return BAD_VALUE;
        }

        const int minBufferSlots = mCore->getMinMaxBufferCountLocked();
        if (bufferCount < minBufferSlots) {
            BQ_LOGE("setMaxDequeuedBufferCount: requested buffer count %d is "
                    "less than minimum %d", bufferCount, minBufferSlots);
            return BAD_VALUE;
        }

        if (bufferCount > mCore->mMaxBufferCount) {
            BQ_LOGE("setMaxDequeuedBufferCount: %d dequeued buffers would "
                    "exceed the maxBufferCount (%d) (maxAcquired %d async %d "
                    "mDequeuedBufferCannotBlock %d)", maxDequeuedBuffers,
                    mCore->mMaxBufferCount, mCore->mMaxAcquiredBufferCount,
                    mCore->mAsyncMode, mCore->mDequeueBufferCannotBlock);
            return BAD_VALUE;
        }
  • 检查非 DEQUEUED slot 个数和新的 maxDequeuedBuffers 之和,即新的 slot 总个数,是否不符合最小/最大值。
        int delta = maxDequeuedBuffers - mCore->mMaxDequeuedBufferCount;
        if (!mCore->adjustAvailableSlotsLocked(delta)) {
            return BAD_VALUE;
        }
        mCore->mMaxDequeuedBufferCount = maxDequeuedBuffers;
        VALIDATE_CONSISTENCY();
        if (delta < 0) {
            listener = mCore->mConsumerListener;
        }
        mCore->mDequeueCondition.notify_all();
    } // Autolock scope

    // Call back without lock held
    if (listener != nullptr) {
        listener->onBuffersReleased();
    }

    return NO_ERROR;
}