这个onVSyncReceived函数不复杂,感觉就是打开vsync,关掉vsync,但是要弄明白,还是要从surfaceflinger的初始化开始:
先简单概括下vsync信号的传递:首先是HWComposer产生vsync,通过回调hook_vsync,在通过mEventHandler.onVSyncReceived(disp,timestamp);到surfaceflinger的onVSyncReceived,接着到DispSync的threadLoop,通过回调mCallback->onDispSyncEvent到,DispSyncSource中的onDispSyncEvent,然后到EventThread中的onVSyncEvent,最后在EventThread的threadLoop中通过postEvent把vsync传给需要的用户,这里主要是surfaceflinger的合成线程和应用程序的渲染线程。
下面详细分析这个过程:
void SurfaceFlinger::init() {
sp<VSyncSource>vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
vsyncPhaseOffsetNs,true, "app");
mEventThread= new EventThread(vsyncSrc, *this);
sp<VSyncSource>sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
sfVsyncPhaseOffsetNs,true, "sf");
mSFEventThread= new EventThread(sfVsyncSrc, *this);
mEventQueue.setEventThread(mSFEventThread);
}
这里创建了2个EventThread线程,一个跟app的渲染线程有关,每个app都对应一个渲染线程RenderThread,这个线程也需要接收vsync事件,具体就是通过在RenderThread中创建DisplayEventReceiver实例,通过这个mDisplayEventReceiver调用surfaceflinger的函数:createDisplayEventConnection,这个函数会注册回调到EventThread中,这样EventThread就可以把vsync通知到RenderThread;
一个跟surfaceflinger的合成线程有关,同时把这个EventThread跟surfaceflinger的事件管理mEventQueue建立了联系,具体就是通过函数:mEventQueue.setEventThread(mSFEventThread);
创建EventThread时,还有2个类:DispSyncSource和DispSync,其实app和surfaceflinger使用的vsync信号并不是真正的硬件vsync,而是属于sw vsync,这两个sw vsync是根据硬件HWCvsync添加一定的偏移计算出来的,目的是为了防止app和surfaceflinger同时被唤醒进行渲染、合成显示,造成争夺cpu资源。完成这个任务就是DispSync,DispSync利用显示设备的硬件vsync信号周期性的特征,在硬件vsync信号特定的偏移处周期性执行回调函数,也就是说只要硬件的vsync周期性地到来,DispSync就会在vsync信号到来的特定时间偏移点,调用相应的回调函数。每次收到一个硬件产生的vsync信号,都会判断是否有必要继续产生硬件vsync,这个判断是通过:addPresentFence和addResyncSample来确定的,只有认为与硬件的vsync信号有偏离时,才要启动硬件产生vsync,否则就关闭硬件的vsync,它代表硬件的vsync信号。具体代码如下:
void SurfaceFlinger::onVSyncReceived(inttype, nsecs_t timestamp) {
//这里是接收到硬件vsync后,判断是否要硬件继续产生vsync,是就调用:enableHardwareVsync();否则调用:disableHardwareVsync(false)
needsHwVsync =mPrimaryDispSync.addResyncSample(timestamp);
if (needsHwVsync){
enableHardwareVsync();
} else {
disableHardwareVsync(false); }
}
classDispSyncSource : public VSyncSource, private DispSync::Callback {}
另外一个类:DispSyncSource,它继承自VSyncSource,并实现了DispSync的回调接口,DispSyncSource代表了一个vsync源,实际是通过DispSync定义的事件模型来维护一个vsync信号源,当有vsync信号时,就通知到EventThread类,DispSyncSource可以认为是DispSync跟EventThread之间的桥梁,vsync源是否依赖于硬件真实的vsync,EventThread不用关心。
在surfaceflinger初始化时,除了2个EventThread外,还有一个线程:EventControlThread,
这个线程是控制打开、关闭硬件的vsync源。
bool EventControlThread::threadLoop() {
mFlinger->setVsyncEnabled(HWC_DISPLAY_PRIMARY,mVsyncEnabled);
mFlinger->eventControl(HWC_DISPLAY_PRIMARY,SurfaceFlinger::EVENT_VSYNC,
mVsyncEnabled);
}
void SurfaceFlinger::eventControl(int disp,int event, int enabled) {
getHwComposer().eventControl(disp,event, enabled);
}
EventThread,EventControlThread这两个线程实例化时都会执行其onFirstRef方法,然后run起来,都进入了wait,等待后续被唤醒,什么时候被唤醒,下面的分析中会有答案。
接下来看下vsync是怎样触发了surfaceflinger的合成、显示工作的。
先从init中的这句调用开始:mEventQueue.setEventThread(mSFEventThread);
mEventQueue(MessageQueue)是surfaceflinger的消息循环机制的管理者,这个函数调用就把MessageQueue跟EventThread建立了连接,这样surfaceflinger才能真正收到HWC的vsync信号。
void MessageQueue::setEventThread(constsp<EventThread>& eventThread){
//首先通过eventThread创建了一个Connection,这个Connection会保存在一个容器中:mDisplayEventConnections,接着得到了vsync信号通知的BitTube,本质上是UDS,然后监听这个BitTube中的socket,并指定了回调函数:MessageQueue::cb_eventReceiver,这样一旦把vsync写入到BitTube,cb_eventReceiver就会被调用,这就实现了进程间通信。
mEventThread = eventThread;
mEvents= eventThread->createEventConnection();
mEventTube= mEvents->getDataChannel();
mLooper->addFd(mEventTube->getFd(),0, Looper::EVENT_INPUT,
MessageQueue::cb_eventReceiver,this);
}
在继续分析vsync的处理前,先看surfaceflinger的init中一段跟显示初始化相关的代码。就是:initializeDisplays();
void SurfaceFlinger::initializeDisplays() {
flinger->onInitializeDisplays(); -->void SurfaceFlinger::onInitializeDisplays(){} --> void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,);
}
void SurfaceFlinger:: setPowerModeInternal (…){
// setPowerModeInternal这个函数在屏幕点亮时也会被调用,
if(currentMode == HWC_POWER_MODE_OFF) {
mEventThread->onScreenAcquired();
resyncToHardwareVsync(true);
}
}
//前面说过,EventThread运行后就wait了,这里的mCondition.broadcast()会唤醒这个线程。
void EventThread::onScreenAcquired() {
mCondition.broadcast();
}
//这个函数的功能就是打开HWC的vsync功能,
void SurfaceFlinger::resyncToHardwareVsync(boolmakeAvailable) {
//获取Hwc的信号发送间隔,然后设置到mPrimaryDispSync
constnsecs_t period = getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
mPrimaryDispSync.setPeriod(period);
//调用mEventControlThread打开HWC的vsync功能。
if(!mPrimaryHWVsyncEnabled) {
mPrimaryDispSync.beginResync();
mEventControlThread->setVsyncEnabled(true);
//在onVSyncReceived时,mPrimaryHWVsyncEnabled这个值是其中一个判断条件。
mPrimaryHWVsyncEnabled= true;
}
}
下面就分析EventThread这个线程的核心函数:threadLoop。
// threadLoop中先调用了waitForEvent,然后循环分发vsync给监听者。
bool EventThread::threadLoop() {
signalConnections= waitForEvent(&event);
constsize_t count = signalConnections.size();
for(size_t i=0 ; i<count ; i++) {
constsp<Connection>& conn(signalConnections[i]);
status_terr = conn->postEvent(event);
}
}
// waitForEvent中也有关闭、开启vsync信号的调用,真正开关vsync的是EventControlThread,这里的调用enableVSyncLocked、disableVSyncLocked并不是真的开关硬件的vsync功能,只是向DispSync添加和删除信号的监听者,通过添加监听者,新的监听者就能收到Hwc的Vsync信号,而一旦删除,EventThread就不再接收消息,就等于关闭了vsync信号。
Vector<sp<EventThread::Connection> > EventThread::waitForEvent(){
if(timestamp && !waitForVSync) {
disableVSyncLocked();
} else if(!timestamp && waitForVSync) {
enableVSyncLocked();
}
}
void EventThread::enableVSyncLocked() {
mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));
mVSyncSource->setVSyncEnabled(true);
}
virtual void DispSyncSource ::setVSyncEnabled(boolenable) {
if(enable) {
status_terr = mDispSync->addEventListener(mName, mPhaseOffset,
static_cast<DispSync::Callback*>(this));
} else {
status_t err =mDispSync->removeEventListener(static_cast<DispSync::Callback*>(this));
}
}
接下来waitforEvent会通过mCondition.waitRelative(),mCondition.wait()进入等待,等待vsync信号的到来。
下面看当vsync到来时,系统到底是怎么处理的?
不管vsync是硬件发出、还是软件发出,surfaceflinger(EventHandler)收到vsync后的处理函数都是:onVSyncReceived。
void SurfaceFlinger::onVSyncReceived(inttype, nsecs_t timestamp) {
//返回值会决定是否要关闭硬件的vsync
needsHwVsync= mPrimaryDispSync.addResyncSample(timestamp);
if(needsHwVsync) {
enableHardwareVsync();
}else {
disableHardwareVsync(false); }
}
先看addResyncSample,这个函数一方面会唤醒DispSyncThread线程,调用注册的回调,另一方面返回值决定是否关闭Hwc的vsync源。只关注重点函数的调用。
bool DispSync::addResyncSample(nsecs_ttimestamp) {
updateModelLocked();
}
void DispSync::updateModelLocked() {
// mThread就是DispSyncThread,mCond.signal()会唤醒处于等待中的这个线程
mThread->updateModel(mPeriod,mPhase, mReferenceTime);à mCond.signal();
// mModelUpdated这个值为true,会让addResyncSample的返回值为false,进而会调用disableHardwareVsync(false);关闭Hwc的vsync源,关闭了vsync源后,关闭vsync后,Hwc不会再周期性的调用SurfaceFlinger::onVSyncReceived了,等于说后续是DispSync代替Hwc维护了一个vsync源。什么时候可能会再次打开?一种情况是每次点亮屏幕时,还有一种情况就是处理显示合成时会判断要不要打开Hwc的vsync源,具体是函数在函数:SurfaceFlinger::postComposition中。
mModelUpdated= true;
}
接着看DispSyncThread醒来后,怎样执行回调函数的?
virtual bool DispSyncThread::threadLoop() {
//计算下一次的vsync时间
targetTime= computeNextEventTimeLocked(now);
// gatherCallbackInvocationsLocked是从mEventListeners中取出之前注册的监听者,放到容器callbackInvocations中,而监听者的来源,在EventThread中已经分析了,就是通过waitForEventà enableVSyncLockedà setVSyncEnabledà addEventListener添加的。
callbackInvocations= gatherCallbackInvocationsLocked(now);
//调用容器中的所有回调。
fireCallbackInvocations(callbackInvocations);
}
void fireCallbackInvocations(constVector<CallbackInvocation>& callbacks) {
for(size_t i = 0; i < callbacks.size(); i++) {
callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime); }
}
这里的onDispSyncEvent就是EventThread的函数。
void EventThread::onVSyncEvent(nsecs_ttimestamp) {
//设置事件的类型,唤醒EventThread线程,进入threadLoop中。
mVSyncEvent[0].header.type= DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
mCondition.broadcast();
}
//通过postEvent循环分发事件给监听者。
bool EventThread::threadLoop() {
constsize_t count = signalConnections.size();
for(size_t i=0 ; i<count ; i++) {
constsp<Connection>& conn(signalConnections[i]);
status_terr = conn->postEvent(event);
}
}
status_tEventThread::Connection::postEvent(){
ssize_tsize = DisplayEventReceiver::sendEvents(mChannel, &event, 1);
}
//当往BitTube中的socket写数据时,之前注册的回调函数:MessageQueue::cb_eventReceiver就会被调用
ssize_tDisplayEventReceiver::sendEvents(const sp<BitTube>& dataChannel,…){
returnBitTube::sendObjects(dataChannel, events, count);
}
// MessageQueue中,经过looper,handler,handleMessage的分发处理,最终以INVALIDATE消息的形式进入了SurfaceFlinger的onMessageReceived,
int MessageQueue::cb_eventReceiver(int fd,int events, void* data) {
MessageQueue*queue = reinterpret_cast<MessageQueue *>(data);
returnqueue->eventReceiver(fd, events);
}
voidMessageQueue::Handler::handleMessage(const Message& message) {
mQueue.mFlinger->onMessageReceived(message.what);
}
//到这里vsync的产生、接收就分析完了。