lock(mCore->mMutex); if (mCore->mIsAbandoned) { BQ_LOGE("cancelBuffer: BufferQueue has been abandoned"); return NO_INIT; } if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { BQ_LOGE("cancelBuffer: BufferQueue has no connected producer"); return NO_INIT; } if (mCore->mSharedBufferMode) { BQ_LOGE("cancelBuffer: cannot cancel a buffer in shared buffer mode"); return BAD_VALUE; } if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)", slot, BufferQueueDefs::NUM_BUFFER_SLOTS); return BAD_VALUE; } else if (!mSlots[slot].mBufferState.isDequeued()) { BQ_LOGE("cancelBuffer: slot %d is not owned by the producer " "> lock(mCore->mMutex); if (mCore->mIsAbandoned) { BQ_LOGE("cancelBuffer: BufferQueue has been abandoned"); return NO_INIT; } if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { BQ_LOGE("cancelBuffer: BufferQueue has no connected producer"); return NO_INIT; } if (mCore->mSharedBufferMode) { BQ_LOGE("cancelBuffer: cannot cancel a buffer in shared buffer mode"); return BAD_VALUE; } if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)", slot, BufferQueueDefs::NUM_BUFFER_SLOTS); return BAD_VALUE; } else if (!mSlots[slot].mBufferState.isDequeued()) { BQ_LOGE("cancelBuffer: slot %d is not owned by the producer " "> lock(mCore->mMutex); if (mCore->mIsAbandoned) { BQ_LOGE("cancelBuffer: BufferQueue has been abandoned"); return NO_INIT; } if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { BQ_LOGE("cancelBuffer: BufferQueue has no connected producer"); return NO_INIT; } if (mCore->mSharedBufferMode) { BQ_LOGE("cancelBuffer: cannot cancel a buffer in shared buffer mode"); return BAD_VALUE; } if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)", slot, BufferQueueDefs::NUM_BUFFER_SLOTS); return BAD_VALUE; } else if (!mSlots[slot].mBufferState.isDequeued()) { BQ_LOGE("cancelBuffer: slot %d is not owned by the producer " ">
status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
    ATRACE_CALL();
    BQ_LOGV("cancelBuffer: slot %d", slot);
    std::lock_guard<std::mutex> lock(mCore->mMutex);

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

    if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
        BQ_LOGE("cancelBuffer: BufferQueue has no connected producer");
        return NO_INIT;
    }

    if (mCore->mSharedBufferMode) {
        BQ_LOGE("cancelBuffer: cannot cancel a buffer in shared buffer mode");
        return BAD_VALUE;
    }

    if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
        BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)",
                slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
        return BAD_VALUE;
    } else if (!mSlots[slot].mBufferState.isDequeued()) {
        BQ_LOGE("cancelBuffer: slot %d is not owned by the producer "
                "(state = %s)", slot, mSlots[slot].mBufferState.string());
        return BAD_VALUE;
    } else if (fence == nullptr) {
        BQ_LOGE("cancelBuffer: fence is NULL");
        return BAD_VALUE;
    }

检查一些状态和参数。

    mSlots[slot].mBufferState.cancel();

    // After leaving shared buffer mode, the shared buffer will still be around.
    // Mark it as no longer shared if this operation causes it to be free.
    if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) {
        mSlots[slot].mBufferState.mShared = false;
    }

    // Don't put the shared buffer on the free list.
    if (!mSlots[slot].mBufferState.isShared()) {
        mCore->mActiveBuffers.erase(slot);
        mCore->mFreeBuffers.push_back(slot);
    }

    auto gb = mSlots[slot].mGraphicBuffer;
    if (mCore->mConsumerListener != nullptr && gb != nullptr) {
        mCore->mConsumerListener->onFrameCancelled(gb->getId());
    }
    mSlots[slot].mFence = fence;
    mCore->mDequeueCondition.notify_all();
    VALIDATE_CONSISTENCY();

    return NO_ERROR;
}