Camera3BufferManager::onBufferReleased
了解了这几个Map之间的关系,也不难理解如下逻辑。这里需要特别注意所有的操作都是用的友元方法,会直接更新到本体类。
加入知识星球与更多Camera同学交流
– 星球名称:深入浅出Android Camera
– 星球ID: 17296815
status_t Camera3BufferManager::onBufferReleased(int streamId, int streamSetId) {
Mutex::Autolock l(mLock);
// Camera3BufferManager会在收到这个回调时候,统计当前的stream的handout的buffer count。此处也是释放。
StreamSet& streamSet = mStreamSetMap.editValueFor(streamSetId);
BufferCountMap& handOutBufferCounts = streamSet.handoutBufferCountMap;
size_t& bufferCount = handOutBufferCounts.editValueFor(streamId);
bufferCount--;
/*
* 此处只是handout的buffer count减一,注意此处的attachedbuffer count并没有减一.
* 这就是这两者的不同,attached buffer count包含”handout”给client的,
* 也包含client release回来的.
* */
return OK;
}
那么什么时候会调用onBufferReleased
呢?
第一步,在configureQueueLocked
中添加release时候的listener。即mBufferReleasedListener
描述的Camera3OutputStream::BufferReleasedListener
类。这个类含有onBufferReleaseed
函数。
status_t Camera3OutputStream::configureQueueLocked() {
res = mConsumer->connect(NATIVE_WINDOW_API_CAMERA, /*listener*/mBufferReleasedListener);//注册一个release时候consuemr可以调用Camera3OutputStream的回调函数.
}
那个listener去哪儿了?
- Connect中有记录listener的部分
status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
int api/*4*/, bool producerControlledByApp, QueueBufferOutput *output) {
Mutex::Autolock lock(mCore->mMutex);
mConsumerName = mCore->mConsumerName;
int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode,
mDequeueTimeout < 0 ?
mCore->mConsumerControlledByApp && producerControlledByApp : false,
mCore->mMaxBufferCount) -
mCore->getMaxBufferCountLocked();
switch (api) {
case NATIVE_WINDOW_API_EGL:
case NATIVE_WINDOW_API_CPU:
case NATIVE_WINDOW_API_MEDIA:
case NATIVE_WINDOW_API_CAMERA:
mCore->mConnectedApi = api;
output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
mCore->mTransformHint,
static_cast<uint32_t>(mCore->mQueue.size()),
mCore->mFrameCounter + 1);
// Set up a death notification so that we can disconnect
// automatically if the remote producer dies
if (listener != NULL &&
IInterface::asBinder(listener)->remoteBinder() != NULL) {
status = IInterface::asBinder(listener)->linkToDeath(
static_cast<IBinder::DeathRecipient*>(this));
}
//把Camera3OutputStream类的mBufferReleasedListener结构的listener暂存起来
mCore->mConnectedProducerListener = listener;
break;
default:
}
mCore->mConnectedPid = IPCThreadState::self()->getCallingPid();
mCore->mBufferHasBeenQueued = false;
mCore->mDequeueBufferCannotBlock = false;
}
- 那listener我直到它被保存起来了,可是什么时候使用listener呢?
- 在comsumer使用完buffer需要release时,从
mActiveBuffers
中取出来一个slot,放到mFreeBuffers
中,并调用listener的onReleaseBuffer
函数。
- 在comsumer使用完buffer需要release时,从
status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
const sp<Fence>& releaseFence, EGLDisplay eglDisplay,
EGLSyncKHR eglFence) {
sp<IProducerListener> listener;
{ // Autolock scope
Mutex::Autolock lock(mCore->mMutex);
// 如果在release前时候,buf又被重新alloc了,那忽略这次release行为。
// 特别对于shared类型的buf,高概率在release过程中出现的queue和acquire请求。这时候忽略这次的release行为。
if (frameNumber != mSlots[slot].mFrameNumber &&
!mSlots[slot].mBufferState.isShared()) {
return STALE_BUFFER_SLOT;
}
mSlots[slot].mEglDisplay = eglDisplay;
mSlots[slot].mEglFence = eglFence;
mSlots[slot].mFence = releaseFence;
mSlots[slot].mBufferState.release();
// 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); // 把待释放的buf放到freeBuffers中
}
// 此时正好取出暂存的回调函数.
listener = mCore->mConnectedProducerListener;//取出connect时候准备的Listener
mCore->mDequeueCondition.broadcast();
} // Autolock scope
// 调用回调.
if (listener != NULL) {
listener->onBufferReleased();// 执行Camera3BufferManage的onBufferReleased
}
return NO_ERROR;
}
- 说了半天的那个神秘的listener是什么?
- Listener是
Camera3OutputStream::BufferReleasedListener
类,Camera3OutputStream::BufferReleasedListener
类是Camera3OutputStream
类的子类,而Camera3OutputStream::BufferReleasedListener
类的成员函数onReleaseBuffer
即为在release时候调用的回调函数。
- Listener是
void Camera3OutputStream::BufferReleasedListener::onBufferReleased() {
sp<Camera3OutputStream> stream = mParent.promote();
Mutex::Autolock l(stream->mLock);
status_t res = stream->mBufferManager->onBufferReleased(
stream->getId(), stream->getStreamSetId());
}