lock(mCore->mMutex); if (mCore->mIsAbandoned) { BQ_LOGE("attachBuffer: BufferQueue has been abandoned"); return NO_INIT; } if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { BQ_LOGE("attachBuffer: BufferQueue has no connected producer"); return NO_INIT; } if (mCore->mSharedBufferMode) { BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode"); return BAD_VALUE; } if (buffer->getGenerationNumber() != mCore->mGenerationNumber) { BQ_LOGE("attachBuffer: generation number mismatc"> lock(mCore->mMutex); if (mCore->mIsAbandoned) { BQ_LOGE("attachBuffer: BufferQueue has been abandoned"); return NO_INIT; } if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { BQ_LOGE("attachBuffer: BufferQueue has no connected producer"); return NO_INIT; } if (mCore->mSharedBufferMode) { BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode"); return BAD_VALUE; } if (buffer->getGenerationNumber() != mCore->mGenerationNumber) { BQ_LOGE("attachBuffer: generation number mismatc"> lock(mCore->mMutex); if (mCore->mIsAbandoned) { BQ_LOGE("attachBuffer: BufferQueue has been abandoned"); return NO_INIT; } if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { BQ_LOGE("attachBuffer: BufferQueue has no connected producer"); return NO_INIT; } if (mCore->mSharedBufferMode) { BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode"); return BAD_VALUE; } if (buffer->getGenerationNumber() != mCore->mGenerationNumber) { BQ_LOGE("attachBuffer: generation number mismatc">
status_t BufferQueueProducer::attachBuffer(int* outSlot,
        const sp<android::GraphicBuffer>& buffer) {
    ATRACE_CALL();

    if (outSlot == nullptr) {
        BQ_LOGE("attachBuffer: outSlot must not be NULL");
        return BAD_VALUE;
    } else if (buffer == nullptr) {
        BQ_LOGE("attachBuffer: cannot attach NULL buffer");
        return BAD_VALUE;
    }

    std::unique_lock<std::mutex> lock(mCore->mMutex);

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

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

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

    if (buffer->getGenerationNumber() != mCore->mGenerationNumber) {
        BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] "
                "[queue %u]", buffer->getGenerationNumber(),
                mCore->mGenerationNumber);
        return BAD_VALUE;
    }

    mCore->waitWhileAllocatingLocked(lock);

    status_t returnFlags = NO_ERROR;
    int found;
    status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Attach, lock, &found);
    if (status != NO_ERROR) {
        return status;
    }

    // This should not happen
    if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
        BQ_LOGE("attachBuffer: no available buffer slots");
        return -EBUSY;
    }

    *outSlot = found;
    ATRACE_BUFFER_INDEX(*outSlot);
    BQ_LOGV("attachBuffer: returning slot %d flags=%#x",
            *outSlot, returnFlags);

    mSlots[*outSlot].mGraphicBuffer = buffer;
    mSlots[*outSlot].mBufferState.attachProducer();
    mSlots[*outSlot].mEglFence = EGL_NO_SYNC_KHR;
    mSlots[*outSlot].mFence = Fence::NO_FENCE;
    mSlots[*outSlot].mRequestBufferCalled = true;
    mSlots[*outSlot].mAcquireCalled = false;
    mSlots[*outSlot].mNeedsReallocation = false;
    mCore->mActiveBuffers.insert(found);
    VALIDATE_CONSISTENCY();

    return returnFlags;
}