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

本文深入解析了SurfaceFlinger的工作原理,包括其启动过程、消息处理机制以及如何利用Vsync信号来处理BufferQueue中的数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接下来就是怎样把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);                   }

SurfaceFlingerSurfaceFlinger SurfaceFlinger SurfaceFlinger SurfaceFlinger SurfaceFlingerSurfaceFlinger 服务是在 服务是在 服务是在 SystemSystemSystemSystemSystem 进程中启动的,并且负责统一管理设备帧缓冲区。 进程中启动的,并且负责统一管理设备帧缓冲区。 进程中启动的,并且负责统一管理设备帧缓冲区。 进程中启动的,并且负责统一管理设备帧缓冲区。 进程中启动的,并且负责统一管理设备帧缓冲区。 进程中启动的,并且负责统一管理设备帧缓冲区。 进程中启动的,并且负责统一管理设备帧缓冲区。 进程中启动的,并且负责统一管理设备帧缓冲区。 进程中启动的,并且负责统一管理设备帧缓冲区。 进程中启动的,并且负责统一管理设备帧缓冲区。 进程中启动的,并且负责统一管理设备帧缓冲区。 进程中启动的,并且负责统一管理设备帧缓冲区。 进程中启动的,并且负责统一管理设备帧缓冲区。 进程中启动的,并且负责统一管理设备帧缓冲区。 进程中启动的,并且负责统一管理设备帧缓冲区。 进程中启动的,并且负责统一管理设备帧缓冲区。 进程中启动的,并且负责统一管理设备帧缓冲区。 进程中启动的,并且负责统一管理设备帧缓冲区。 SurfaceFlingerSurfaceFlinger SurfaceFlinger SurfaceFlinger SurfaceFlinger SurfaceFlingerSurfaceFlinger 服务在启动过程中, 会创建两个线其一用来监控制台事件服务在启动过程中, 会创建两个线其一用来监控制台事件服务在启动过程中, 会创建两个线其一用来监控制台事件服务在启动过程中, 会创建两个线其一用来监控制台事件服务在启动过程中, 会创建两个线其一用来监控制台事件服务在启动过程中, 会创建两个线其一用来监控制台事件服务在启动过程中, 会创建两个线其一用来监控制台事件服务在启动过程中, 会创建两个线其一用来监控制台事件服务在启动过程中, 会创建两个线其一用来监控制台事件服务在启动过程中, 会创建两个线其一用来监控制台事件服务在启动过程中, 会创建两个线其一用来监控制台事件服务在启动过程中, 会创建两个线其一用来监控制台事件服务在启动过程中, 会创建两个线其一用来监控制台事件服务在启动过程中, 会创建两个线其一用来监控制台事件服务在启动过程中, 会创建两个线其一用来监控制台事件服务在启动过程中, 会创建两个线其一用来监控制台事件而另外一个线程用来渲染系统的 而另外一个线程用来渲染系统的 而另外一个线程用来渲染系统的 而另外一个线程用来渲染系统的 而另外一个线程用来渲染系统的 而另外一个线程用来渲染系统的 而另外一个线程用来渲染系统的 UI 。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值