前面的小节中,我们讲解了Vsync机制机制的框架,无论SurfaceFlinger还是APP应用程序,对Vsync的使用,都是按需进行的:
比如应用程序把新界面发送给SurfaceFlinger之后,SurfaceFlinger就需要得到一个Vsync信号,他就会把这个需求发送给EventThread,EventThread再转发给DispSyncThread,DispSyncThread收到硬件Vsync信号,或者软件Vsync信号之后,发会休眠一段时间,把信号虚拟化成Vsync-APP与Vsync-SF,然后发送给对应的EventThread,EventThread在发送给SurfaceFlinger,然后SurfaceFlinge在进行图片合成。 该小节我们对surface使用vsync的过程进行分析。
surface使用vsync可以分为以下几个步骤:
1.APP发送数据给SurfaceFlinger。 2.SurfaceFlinger发送请求给EventThread(sf)。 3.EventThread在发送请求给DispSyncThread 4.软件或者硬件的Vsync会唤醒DispSyncThread。 5.DispSyncThread发送信号给EventThread,EventThread发送信号给SurfaceFlinger,然后SurfaceFlinger在对图片进行处理(如:合成等等)
下面是是一个详细的代码调用过程: 在左上角标号1的处开始阅读
为了大家快速的了解,下面是一个草图。我们将围绕这这个草图进行讲解。
首先是应用程序APP发送数据给SurfaceFlinger,SurfaceFlinger跟EventThread存在一个connection的连接,SurfaceFlinger会向EventThread提出请求,这个请求会转发给DispSyncThread,DispSyncThread会被软件(一个线程VsyncThread)或者硬件产生的Vsync信号唤醒,
1.APP发送数据给SurfaceFlinger与SurfaceFlinger发送请求给EventThread(sf)我们首先来看看APP发送数据给SurfaceFlinger的过程,其详细过程,我们在之前的章节中。已经进行了讲解,故此,这里只做简单的分析。
打开SurfaceFlinger.cpp文件,找到signalLayerUpdate函数:
/*当检测到有数据需要更新的时候,就会调用该函数*/
void SurfaceFlinger::signalLayerUpdate() {
mEventQueue.invalidate();
/*请求得到下一个vsync信号,其中mEvents为Connection*/
mEvents->requestNextVsync();
可以看到其上mEvents为Connection类型,requestNextVsync函数在EventThread.cpp中实现:
void EventThread::requestNextVsync(
/*如果countcount count = 0;
/*发送一个广播,其目的是为了唤醒某一个线程*/
mCondition.broadcast();
}
注意requestNextVsync是EventThread中的线程,但是在SurfaceFlinger进程中使用,也就是说,SurfaceFlinger利用EventThread中提供的函数唤醒EventThread线程。 下面我们开始讲解第三个步骤。
EventThread再发送请求给DispSyncThread之前我们提到,SurfaceFlinger把信号请求发送给EventThread,EventThread在把这个请求发送给DispSyncThread。
在EventThread.cpp中存在函数ThreadLoop:
bool EventThread::threadLoop() {
/*1.发出Vsync信号请求,然后等待Vsync信号,其内部会判断所有Connection的count
如果count大于0,这代表需要得到Vsync信号*/
signalConnections = waitForEvent(&event);
/*得到一个connection*/
sp connection(mDisplayEventConnections[i].promote());
/*如果connection->count >= 0,则代表需要下一个vsync信号*/
waitForVSync = true;
enableVSyncLocked();
/*给DispSyncThread设置回调函数Callback*/
mVSyncSource->setCallback(static_cast(this));
mVSyncSource->setVSyncEnabled(true);
/*等待vsync信号*/
mCondition.wait(mLock);
/*发送信号给SurfaceFlinger*/
status_t err = conn->postEvent(event);
从上面我们可以看到,当connection->count >= 0时,代表需要Vsync信号,其会为DispSyncThread线程设置一个回调函数Callback,当DispSyncThread接收到信号之后,就会调用该回调函数。
4.软件或者硬件的Vsync会唤醒DispSyncThread从上面我们知道EventThread发送给请求给DispSyncThread之后进入休眠状态,DispSyncThread一般也处于休眠状态,其会被一个Vsync信号唤醒,我们暂时不理会硬件的sync信号,我们来看看软件的sync信号如何产生。
打开frameworks\native\services\surfaceflinger\DisplayHardware目录下的SoftVsyncObserver.cpp文件:
bool SoftVsyncObserver::threadLoop()
spec.tv_sec = next_vsync / 1000000000;
spec.tv_nsec = next_vsync % 1000000000;
err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
/*发出Vsync信号*/
mDisplayDevice.onVsync(next_vsync);
mHwc.vsync(DEVICE_VIRTUAL, timestamp);
软件产生的方式比较简单,就是循环延时发出信号,然后会唤醒DispSyncThread线程,DispSyncThread发送信号给EventThread,EventThread调用
void SurfaceFlinger::onVSyncReceived(int32_t type, nsecs_t timestamp) {
函数唤醒SurfaceFlinger线程。在DispSync.cpp中:
virtual bool threadLoop() {
/**计算最近的EventThread的时间Listeer*/
targetTime = computeNextEventTimeLocked(now);
nsecs_t t = computeListenerNextEventTimeLocked(mEventListeners[i],
/*现在的时间少于目标时间,则等待*/
if (now count >= 0时,向DispSyncThread注册Callback。Callback最终会导致EventThread中的onVSyncEvent被调用:
void EventThread::onVSyncEvent(nsecs_t timestamp) {
/*发出一个广播*/
mCondition.broadcast();
实际就是通过广播唤醒EventThread(ThreadLoop)线程。
SurfaceFlinger接收到Vsync信号之后会调用MessageQueue.cpp中:
int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
MessageQueue* queue = reinterpret_cast(data);
queue->eventReceiver(fd, events);
mHandler->dispatchInvalidate();
/*发送一个消息*/
mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
发送消息之后:
void MessageQueue::Handler::handleMessage(const Message& message) {
mQueue.mFlinger->onMessageReceived(message.what);
handleMessage会进行处理。其中onMessageReceived在SurfaceFlinger.cpp中实现:
void SurfaceFlinger::onMessageReceived(int32_t what) {
signalLayerUpdate();
refreshNeeded |= handleMessageInvalidate();
handleMessageRefresh();