07.显示系统:第004课_SurfaceFlinger内部机制:第009节_APP提交(unlockAndPost)Buffer的过程_提交过程
在我们测试程序中,可以看到:
surface->unlockAndPost();
该为对显示数据的提交,其内部详细的调用过程:
从左下角A5处开始看起。
进入Surface.cpp文件找到unlockAndPost函数:
status_t Surface::unlockAndPost()
/*入队列*/
err = queueBuffer(mLockedBuffer.get(), fd);
/*调用代理对象的queueBuffer,导致一个binder的远程调用,*/
status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
上述的远程调用,就会导致SurfaceFlinger进程中的BufferQueueProducer发生动作,进入BufferQueueProducer.cpp,找到其中对应的queueBuffer函数:
/*放入队列*/
status_t BufferQueueProducer::queueBuffer(int slot,const QueueBufferInput &input, QueueBufferOutput *output)
BufferItem item;
/*从mSlots[slot]中取出一项,构造item*/
item.mAcquireCalled = mSlots[slot].mAcquireCalled;
item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
/*构造完成之后放入队列*/
mCore->mQueue.push_back(item);
/*其为一个BufferQueue::ProxyConsumerListener对象*/
frameAvailableListener = mCore->mConsumerListener;
.....
frameAvailableListener->onFrameAvailable(item);
下面贴出一个草图关系:
这里的frameAvailableListener 为图中下面的Listener。frameAvailableListener 为Proxy对象,Proxy中存在一个mConsumer = SurfaceFlingerConsumer,frameAvailableListener->onFrameAvailable(item);函数会取出SurfaceFlingerConsumer对象,然后调用消费者的相关函数,进入BufferQueue.cpp文件,可以找到onFrameAvailable函数的实现:
void BufferQueue::ProxyConsumerListener::onFrameAvailable(
sp<ConsumerListener> listener(mConsumerListener.promote());
/*进入到消费者*/
listener->onFrameAvailable(item);
其onFrameAvailable的实现为ConsumerBase.cpp:
void ConsumerBase::onFrameAvailable(const BufferItem& item) {
CB_LOGV("onFrameAvailable");
sp<FrameAvailableListener> listener;
{ // scope for the lock
Mutex::Autolock lock(mMutex);
/*mFrameAvailableListener为一个Loyer对象,进入Layer*/
listener = mFrameAvailableListener.promote();
}
if (listener != NULL) {
CB_LOGV("actually calling onFrameAvailable");
/*该函数在Layer.cpp实现*/
listener->onFrameAvailable(item);
}
}
在Layer.cpp找到onFrameAvailable函数如下
void Layer::onFrameAvailable(const BufferItem& item) {
/*进入到SurfaceFlinger*/
mFlinger->signalLayerUpdate();
/*导致其他线程被唤醒,通知SurfaceFlinger显示数据更新了*/
mEventQueue.invalidate();
从上面我们总结出通知过程为:生产者-》消费者-》Layer-》SurfaceFlinger,APP产生的显示数据,通过这样的一个传递过程,最终传递给SurfaceFlinger进程。
mFlinger->signalLayerUpdate();函数,从名字上看,我们知道他是告诉SurfaceFlinger进程,内容已经更新了,会唤醒另外一个线程。怎么唤醒,唤醒之后又会做什么。在后面的小节会大家进行分析。