在上小节中,讲解了Vsync机制的框架,有了框架再去分析源代码,才不会迷失方向,毕竟andriod是的源代码是十分的复杂与庞大,我们先来回顾一下,下面是上小节的框图: 通过上小节我们知道,Vsync信号可以由软件产生,也能由硬件产生,如果由软件产生,他会存在一个线程。danVsync信号到来会发送给DispSyncThread线程。
DispSyncThread会把Vsync虚拟化,分成Vsync-APP与Vsync-SF两个信号,这两个信号分别发送给EventThreadForVsync-APP与EventThreadForSF两个线程,
当一个应用程序需要更新他的界面时,会向EventThreadForVsync-APP发出请求,请求得到一个Vsync信号,当应用程序得到一个Vsync信号之后,他构造好画面,并且会把这些信号发送给SurfaceFlinger,SurfaceFlinger接收之后,也会向EventThreadForSF等待一个Vsync信号,当得到Vsync-SF时之后,进行界面合成,然后发送给硬件进行显示。
下面我们分析,暂时不理会APP,那么我们会涉及五个线程,产生Vsync信号的VSyncThread线程,以及DispSyncThread,SurfaceFlinger,EventThreadForVsync-APP,EventThreadForSF。
上面我们提到的线程,都位于一个SurfaceFlinger.cpp进程之中,那么他是怎么创建出来的呢?下面是一个十分详细的流程图: 现在我们开始分析源代码,打开main_surfaceflinger.cpp:
int main(int, char**) {
/*创建了一个SurfaceFlinger对象,其中包含了一个DispSync mPrimaryDispSync;*/
sp flinger = new SurfaceFlinger();
可以看到其会创建一个DispSync mPrimaryDispSync成员,在DispSync .cpp中:
/*创建一个线程mThread*/
DispSync::DispSync(const char* name) :mName(name),mRefreshSkipCount(0),mThread(new DispSyncThread(name)) {
/*调用其中的run函数*/
mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
这个线程就是我们前面提到五个线程中,其中的DispSyncThread线程,他的主要工作是把Vsync虚拟化成Vsync-APP与Vsync-SF两个信号。现在我们知道了这个线程是怎么被创建出来的。后续我们在来分析其内部实现。
VSyncThread我们再次回到main_surfaceflinger.cpp的main函数:
int main(int, char**) {
/*创建了一个SurfaceFlinger对象,其中包含了一个DispSync mPrimaryDispSync;*/
sp flinger = new SurfaceFlinger();
flinger->init();
创建SurfaceFlinger对象,其flinger 为一个sp 指针,在第一次被引用的时候,会调用onFirstRef函数:
void SurfaceFlinger::onFirstRef()
mEventQueue.init(this);
该些函数后续分析,我们先来看看flinger->init();函数:
void SurfaceFlinger::init() {
mHwc = new HWComposer(this,*static_cast(this));
进入HWComposer的构造函数:
HWComposer::HWComposer(
/*加载各种模块*/
int fberr = loadFbHalModule();
/*如果需要VSyncThread线程*/
if (needVSyncThread) {
// we don't have VSYNC support, we need to fake it
/*创建一个VSyncThread线程*/
mVSyncThread = new VSyncThread(*this);
}
这里的VSyncThread线程,就是之前五个线程之中,用来产生软件Vsync信号的。当开发板不支持硬件产生的时候,则由该线程产生。其中VSyncThread也存在onFirstRef函数:
void HWComposer::VSyncThread::onFirstRef() {
run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
}
可以看起其运行了一个run函数,后续我们再来详细分析。
EventThread我们回到:
void SurfaceFlinger::init() {
mHwc = new HWComposer(this,*static_cast(this));
/*分别对应EventThreadForVsync-APP,EventThreadForSF两个线程*/
sp vsyncSrc = new DispSyncSource(&mPrimaryDispSync,vsyncPhaseOffsetNs, true, "app");
mEventThread = new EventThread(vsyncSrc, *this);
sp sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,sfVsyncPhaseOffsetNs, true, "sf");
mSFEventThread = new EventThread(sfVsyncSrc, *this);
可以看到其定义了两个sp类型的指针,但是构造函数传入的参数是有区别的,分别为"app"与"sf"。该参数会影响上小节提到的延时值offsel。
先在我们找到了四个线程,还差最后一个,我们回到main函数。
SurfaceFlinger可以在函数的末尾,找到
flinger->run();
do {
waitForEvent();
} while (true);
即主线程就是SurfaceFlinger线程,他可以等待应用程序给他发送数据,另外也可以等待EventThread给他发送数据,去和EventThread之间有个connection,我们其是怎么被创建出来的:
void SurfaceFlinger::init() {
sp sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,sfVsyncPhaseOffsetNs, true, "sf");
mSFEventThread = new EventThread(sfVsyncSrc, *this);
mEventQueue.setEventThread(mSFEventThread);
/*创建连接*/
mEvents = eventThread->createEventConnection();
mEventTube = mEvents->getDataChannel();
/*可以得知在EventThread与SurfaceFlinger线程之间,各存在一个文件句柄,实现数据交换*/
mLooper->addFd(mEventTube->getFd(), 0, Looper::EVENT_INPUT,MessageQueue::cb_eventReceiver, this);
其上的 mLooper->addFd(mEventTube->getFd(), 0, Looper::EVENT_INPUT,MessageQueue::cb_eventReceiver, this);比较重要,在后续过程中,我们会进行详细的分析。其是用来处理EventThread发送给SurfaceFlinger的Vsync信号