接下来就是怎样把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的服务。boot是init程序启动后触发的第一个事件。
接着surfaceflinger起来后的代码:
/* main_surfaceflinger.cpp */
int main(int, char**) {
//大多数程序都是需要IPC的,这里也需要,但是使用Binder机制是很繁琐的,所以Android为程序进程使用Binder机制封装了两个实现类:ProcessState、IPCThreadState,其中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,一个handler,looper中的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,它的职责之一就是产生Vsync。Surfaceflinger初始化时创建HWComposer的实例。
Frameworks/native/services/surfaceflinger/displayhardware/HWComposer.cpp
/*HWComposer.cpp*/
HWComposer::HWComposer(){
//默认需要软件模拟
boolneedVSyncThread = true;
//加载hwc的hal模块,
loadHwcModule();àhw_get_module(HWC_HARDWARE_MODULE_ID, &module);
//如果成功加载HWC_HARDWARE_MODULE_ID的hal模块,并顺利打开了设备,就采用硬件源产出信号。
if(mHwc) {
if(mHwc->registerProcs) {
//注册硬件回调,后续如果有硬件产生,硬件模块通过回调通知到HWComposer,如:
hook_invalidate,hook_vsync
mCBContext->procs.invalidate= &hook_invalidate;
mCBContext->procs.vsync= &hook_vsync;
mHwc->registerProcs(mHwc,&mCBContext->procs);
}
}
}
void HWComposer::vsync(int disp, int64_ttimestamp) {
//Hwcomposer把vsync信息传给了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); }