SurfaceFlinger服务的启动
SurfaceFlinger服务负责管理系统的帧缓冲区设备,并且负责渲染系统的UI,即各个应用程序的UI。因此,Android应用程序就需要通过Binder进程间通信机制来请求它来渲染自己的UI。
当用户对手机进行操作时, 对应的数据流依次为:HW Spage、Input Driver、Input system、System logic、SurfaceFlinger(SF)、Display system、LCM Driver。当数据流中的某个环节出现问题的时候都可能造成死机。 关于SF问题的排查:1、MTK机器上当我们按音量上下键可以正常显示调整情况,基本可以排除死机原因不是SurfaceFlinger引起的;2、从抓取到的MTK log中我们也可以看出它被创建的时候` SurfaceFlinger: EventThread Client Pid (1580) created`以及` SurfaceFlinger: [SF client] NEW(0xae090960) for (804:system_server)`,说明SF是由system_server进程启动的服务之一。SF中已经导入了Watchdog 机制, 审查SurfaceFlinger 是否有卡住的情况, 对应在main log 里面会打印如:[SF-WD] detect SF maybe hang!!!这样的LOG, 并且会纪录卡顿的时机,如果持续卡顿,毫无疑问, SurfaceFlinger 已经卡住。
基于上述的认识,我们下面开始简单了解SurfaceFlinger服务的启动流程。
先放上一张SF服务启动的思维导图~~~:
一、SurfaceFlinger的main()函数
Path:./frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
int main(int, char**) {
signal(SIGPIPE, SIG_IGN);
// When SF is launched in its own process, limit the number of
// binder threads to 4.
ProcessState::self()->setThreadPoolMaxThreadCount(4); //设置Binder线程池最大线程数为4
// start the thread pool
sp
ps->startThreadPool();
// instantiate surfaceflinger
sp
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY); //设置参数
set_sched_policy(0, SP_FOREGROUND);
set_cpuset_policy(0, SP_SYSTEM);
// initialize before clients can connect
flinger->init(); //调用SF的init()函数
// publish surface flinger //注册SF服务到ServiceManager中
sp
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
// publish GpuService
sp
sm->addService(String16(GpuService::SERVICE_NAME), gpuservice, false);
// run surface flinger in this thread
flinger->run(); //其实运行在EventThread线程上
return 0;
}
Note:main()函数中主要是将SF服务注册到ServiceManager中,然后调用SurfaceFlinger的init()方法进一步完成一些初始化工作。
SurfaceFlinger/init()
void SurfaceFlinger::init() {
ALOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
{ // Autolock scope
Mutex::Autolock _l(mStateLock);
// initialize EGL for the default display
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(mEGLDisplay, NULL, NULL);
//start the EventThread
sp
vsyncPhaseOffsetNs, true, "app");
mEventThread = new EventThread(vsyncSrc, *this);
sp
sfVsyncPhaseOffsetNs, true, "sf");
mSFEventThread = new EventThread(sfVsyncSrc, *this);
mEventQueue.setEventThread(mSFEventThread);
#endif
// Get a RenderEngine for the given display / config (can't fail)
mRenderEngine = RenderEngine::create(mEGLDisplay,
HAL_PIXEL_FORMAT_RGBA_8888);
}
..........
sp
mPrimaryDispSync.setResync(resync);
#endif // MTK_EMULATOR_SUPPORT
// start the EventThread
sp
sPropertiesState.mAppVSyncOffset, true, "app");
mEventThread = new EventThread(vsyncSrc, *this);
sp
sPropertiesState.mSfVSyncOffset, true, "sf", true);
.................
// initialize our drawing state
mDrawingState = mCurrentState;
// set initial conditions (e.g. unblank default device)
initializeDisplays();
// start boot animation
startBootAnim();
ALOGV("Done initializing");
}
Note: init函数主要工作为:
初始化EGL图形库。
启动EventThread。监听和处理SurfaceFlinger中的事件。
3.创建显示设备的抽象代表,负责和显示设备打交道。
4. 创建显示设备对象。
5.设置软件VSync信号周期。
6.初始化显示设备,调用initializeDisplays完成。
7.启动开机动画,调用了startBootAnim函数,只是设置了两个属性,其中一个ctl.start是启动了bootanim进程。
SurfaceFlinger/init()
void SurfaceFlinger::run() {
do {
waitForEvent();
} while (true);
}
void SurfaceFlinger::waitForEvent() {
mEventQueue.waitMessage();
}
Note:mEventQueue是EventThread的实例对象,它会一直等待消息的到来,开始渲染UI。
总结:其实在init()中创建显示设备过程,会涉及到SurfaceFlinger服务的控制台事件监控线程的创建过程;以及UI线程渲染的过程就不再一一分析。这里主要分析的是SF服务的一个启动。其次,在开关机中,如果我们能够看到开机动画的显示,说明SF服务已经启动起来了。