App的启动过程(8)surfaceflinger的启动

来源:互联网 发布:pcl icp源码 编辑:程序博客网 时间:2024/06/07 17:39

接下来就是怎样把BufferQueue中数据,也就是GraphicBuffer中的数据显示到屏幕上,这就是surfaceflinger做的事情。

         先说surfaceflinger的启动,Android7.0上,应该是在接下init.rc脚本时启动的,启动后运行的是main_surfaceflinger.cpp

/*surfaceflinger.rc*/

service surfaceflinger/system/bin/surfaceflinger

   class core

   user system

   group graphics drmrpc readproc

   onrestart restart zygote

   writepid /dev/stune/foreground/tasks

surfaceflinger这个服务指定的class名是core,同一个class的所有服务是同时启动和停止的。在看init.rc中,什么时候启动了所有的core服务。

/* init.rc */

on boot

         …

         class_startcore

可以看到在boot这个触发事件产生时,依次执行了这个Actions的多个命令,最后通过class_start core启动所有class名是core的服务。bootinit程序启动后触发的第一个事件。

接着surfaceflinger起来后的代码:

/* main_surfaceflinger.cpp */

int main(int, char**) {

//大多数程序都是需要IPC的,这里也需要,但是使用Binder机制是很繁琐的,所以Android为程序进程使用Binder机制封装了两个实现类:ProcessStateIPCThreadState,其中ProcessState负责打开Binder驱动,进行mmap等准备工作;IPCThreadState负责具体线程跟Binder驱动进行命令交互。

sp<ProcessState>ps(ProcessState::self());   

//这里会间接调用IPCThreadState

ps->startThreadPool();àIPCThreadState::self()->joinThreadPool(mIsMain);

//实例化surfaceflinger,然后初始化,并把它注册到servicemanager,然后run

         sp<SurfaceFlinger>flinger = DisplayUtils::getInstance()->getSFInstance();

         flinger->init();

         sm->addService(String16(SurfaceFlinger::getServiceName()),flinger, false);

         flinger->run();

}

进入到surfaceflinger类中,代码中有两个:surfaceflinger.cpp应用是android原生的;SurfaceFlinger_hwc1.cpp这个应该是不同平台自己定义的。

/* SurfaceFlinger.cpp */

因为SurfaceFlinger是强指针,最先执行的是:

void SurfaceFlinger::onFirstRef(){

//初始化了事件队列

   mEventQueue.init(this);

}

void SurfaceFlinger::init() {

//穿件EventThread线程,绑定到mEventQueue

         mSFEventThread= new EventThread(sfVsyncSrc, *this);

         mEventQueue.setEventThread(mSFEventThread);

}

void SurfaceFlinger::run() {

//线程运行起来后,是一个死循环,等待消息,取消息,处理消息

         waitForEvent();àwaitMessage()@MessageQueue

}

这里的MessageQueue并不是常见的消息队列,mEventQueue更像是消息循环机制的管理者,其中包含了一个looper,一个handlerlooper中的mMessageEnvelopes这个容器才是真正存储消息的地方;

/* MessageQueue.cpp */

void MessageQueue::waitMessage() {

         int32_tret = mLooper->pollOnce(-1);

}

handler也不是常见的那个handler,而是Messagequeue中自定义的一个事件处理器,是专门为surfaceflinger设计的,handler收到消息,进一步回调surfaceflinger中的onMessageReceived

void MessageQueue::Handler::handleMessage(constMessage& message) {

         switch(message.what) {

                   caseINVALIDATE:

                            mQueue.mFlinger->onMessageReceived(message.what);

}        }

Surfaceflinger就是基于这个消息处理框架来完成各应用程序的显示请求的。

         说完了surfaceflinger的启动,接着看surfaceflinger怎样处理BufferQueue的,这里要先说一个Vsync的概念。不讨论引入Vsync的原因,只看Vsync信号的产生、分发及处理。

         Vsync的产生可以由硬件主动发出,也可以软件模拟。

surfaceflinger 子目录下有一个HWComposer,它的职责之一就是产生VsyncSurfaceflinger初始化时创建HWComposer的实例。

Frameworks/native/services/surfaceflinger/displayhardware/HWComposer.cpp

/*HWComposer.cpp*/

HWComposer::HWComposer(){

//默认需要软件模拟

         boolneedVSyncThread = true;

//加载hwchal模块,

         loadHwcModule();àhw_get_module(HWC_HARDWARE_MODULE_ID, &module);

//如果成功加载HWC_HARDWARE_MODULE_IDhal模块,并顺利打开了设备,就采用硬件源产出信号。

         if(mHwc) {

                   if(mHwc->registerProcs) {

//注册硬件回调,后续如果有硬件产生,硬件模块通过回调通知到HWComposer,如:

hook_invalidatehook_vsync

                            mCBContext->procs.invalidate= &hook_invalidate;

                            mCBContext->procs.vsync= &hook_vsync;

                            mHwc->registerProcs(mHwc,&mCBContext->procs);

                   }

}

}

void HWComposer::vsync(int disp, int64_ttimestamp) {

//Hwcomposervsync信息传给了mEventHandler,这个mEventHandler就是surfaceflinger

         mEventHandler.onVSyncReceived(disp,timestamp);

}

//surfaceflinger在实例化HWComposer时,传入了EventHandler,并且surfaceflinger继承了HWComposer::EventHandler

void SurfaceFlinger::init() {

         mHwc= new HWComposer(this, *static_cast<HWComposer::EventHandler *>(this));

}

这样vsync信号就从硬件传到了surfaceflinger中。

软件模拟vsync,就是创建一个VSyncThread线程,

mVSyncThread =new VSyncThread(*this);

bool HWComposer::VSyncThread::threadLoop(){

//线程run后,执行threadLoop,因为mEnabled默认是false,所以会线程会wait,知道被唤醒。mEnabled是控制vsync的开关。

         while(!mEnabled) {

mCondition.wait(mLock);}

//睡眠一定的时间,时间到了,执行跟硬件源一样的回调。

err =clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);

mHwc.mEventHandler.onVSyncReceived(0,next_vsync);

}

下面看surfaceflinger如何处理这个vsync信号。

void SurfaceFlinger::onVSyncReceived(inttype, nsecs_t timestamp) {

         if(type == 0 && mPrimaryHWVsyncEnabled) {

                   needsHwVsync= mPrimaryDispSync.addResyncSample(timestamp);   }

         if(needsHwVsync) {

                   enableHardwareVsync();

         }else {

                   disableHardwareVsync(false);                   }

原创粉丝点击