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;
}
FREE
BufferSlot,因为是 FreeSlotCaller::Attach
,所以优先从 mFreeSlots
查找。mGraphicBuffer
,调用 attachProducer()
变更 BufferState 为 DEQUEUED
等。mActiveBuffers
。