07.显示系统:第005课_Vsync机制:第002节_Vsync框架第003节_初始化代码分析

在上小节中,讲解了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:

DispSyncThread创建

int main(int, char**) {
	/*创建了一个SurfaceFlinger对象,其中包含了一个DispSync mPrimaryDispSync;*/
	sp<SurfaceFlinger> 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<SurfaceFlinger> 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<HWComposer::EventHandler *>(this));

进入HWComposer的构造函数:

扫描二维码关注公众号,回复: 5858705 查看本文章
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<HWComposer::EventHandler *>(this));
	/*分别对应EventThreadForVsync-APP,EventThreadForSF两个线程*/
    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);

可以看到其定义了两个sp类型的指针,但是构造函数传入的参数是有区别的,分别为"app"与"sf"。该参数会影响上小节提到的延时值offsel。

先在我们找到了四个线程,还差最后一个,我们回到main函数。

SurfaceFlinger

可以在函数的末尾,找到

flinger->run();
    do {
        waitForEvent();
    } while (true);

即主线程就是SurfaceFlinger线程,他可以等待应用程序给他发送数据,另外也可以等待EventThread给他发送数据,去和EventThread之间有个connection,我们其是怎么被创建出来的:

void SurfaceFlinger::init() {
	sp<VSyncSource> 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信号

猜你喜欢

转载自blog.csdn.net/weixin_43013761/article/details/89027038