SurfaceFlinger 服务的启动过程分析
SurfaceFlinger 服务是在 System 进程中启动的,并且负责统一管理设备的帧缓冲区。
SurfaceFlinger 服务在启动的过程中,会创建两个线程,其中一个线程用来监控控制台事件,
而另外一个线程用来渲染系统的 UI。
System 进程是由 Zygote 进程启动的,并且是以 Java 层的 SystemServer 类的静态成员函
数 main 为入口函数的。SurfaceFlinger 服务的启动过程,如图 1 所示。
图 1 SurfaceFlinger 服务的启动过程
1
SurfaceFlinger 服务的启动过程可以划分为 8 个步骤,
Step 1. SystemServer.main
public class SystemServer
{
......
native public static void init1(String[] args);
public static void main(String[] args) {
......
System.loadLibrary("android_servers");
init1(args);
}
......
}
public class SystemServer
{
......
native public static void init1(String[] args);
public static void main(String[] args) {
......
System.loadLibrary("android_servers");
init1(args);
}
......
}
这个函数定义在文件 frameworks/base/services/java/com/android/server/SystemServer.java
中。
SystemServer 类的静态成员函数 main 首先将 android_servers 库加载到 System 进程中
来,接着调用另外一个静态成员函数 init1 来启动那些使用 C++语言来实现的系统服务。
SystemServer 类 的静 态 成 员 函数 init1 是一 个 JNI 方 法 , 它是 由 C++层 的 函数
android_server_SystemServer_init1 来实现的,
Step 2. SystemServer.init1
static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
{
system_init();
}
2
static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
{
system_init();
}
这个函数定义在文件 frameworks/base/services/jni/com_android_server_SystemServer.cpp 中。
SystemServer 类的静态成员函数 init1 调用另外一个函数 system_init 来启动那些使用 C++
语 言 来 实 现 的 系 统 服 务 , 它 的 实 现 在 文 件
frameworks/base/cmds/system_server/library/system_init.cpp 中,如下所示:
status_t system_init()
{
LOGI("Entered system_init()");
sp
proc(ProcessState::self());
......
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsurfaceflinger", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// Start the SurfaceFlinger
SurfaceFlinger::instantiate();
}
......
if (proc->supportsProcesses()) {
LOGI("System server: entering thread pool.\n");
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
LOGI("System server: exiting thread pool.\n");
}
return NO_ERROR;
}
status_t system_init()
{
LOGI("Entered system_init()");
sp proc(ProcessState::self());
......
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsurfaceflinger", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
3
// Start the SurfaceFlinger
SurfaceFlinger::instantiate();
}
......
if (proc->supportsProcesses()) {
LOGI("System server: entering thread pool.\n");
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
LOGI("System server: exiting thread pool.\n");
}
return NO_ERROR;
}
函数首先获得 System 进程中的一个 ProcessState 单例,并且保存在变量 proc 中,后面
会通过调用它的成员函数 supportsProcesses 来判断系统是否支持 Binder 进程间通信机制。
在 Android 系统中,每一个需要使用 Binder 进程间通信机制的进程内部都有一个 ProcessState
单例,它是用来和 Binder 驱动程序建立连接的,函数接下来就检查系统中是否存在一个名
称为“system_init.startsurfaceflinger”的属性。如果存在的话,就将它的值获取回来,并且保
存在缓冲区 proBuf 中。如果不存在的话,那么函数 property_get 就会将缓冲区 proBuf 的值
设 置 为 “1” 。 当 缓 冲 区 proBuf 的 值 等 于 “1” 的 时 候 , 就 表 示 需 要 在 System 进 程 中 将
SurfaceFlinger 服务启动起来,这是通过调用 SurfaceFlinger 类的静态成员函数 instantiate 来
实现的。
函数最后检查系统是否支持 Binder 进程间通信机制。如果支持的话,那么接下来就会
调用当前进程中的 ProcessState 单例的成员函数 startThreadPool 来启动一个 Binder 线程池,
并且调用当前线程中的 IPCThreadState 单例来将当前线程加入到前面所启动的 Binder 线程池
中去。System 进程前面在初始化运行时库的过程中,已经调用过当前进程中的 ProcessState
单例的成员函数 startThreadPool 来启动 Binder 线程池了,因此,这里其实只是将当前线程
加入到这个 Binder 线程池中去。有了这个 Binder 线程池之后,SurfaceFlinger 服务在启动完
成之后,就可以为系统中的其他组件或者进程提供服务了。
假设系统存在一个名称为“system_init.startsurfaceflinger”的属性,并且它的值等于“1”,
接下来继续分析 SurfaceFlinger 类的静态成员函数 instantiate 的实现,以便可以了解
SurfaceFlinger 服务的启动过程。由于 SurfaceFlinger 类的静态成员函数 instantiate 是从父类
BinderService 继承下来的,因此,接下来我们要分析的实际上是 BinderService 类的静态成员
函数 instantiate 的实现。
Step 3. BinderService.instantiate
template
class BinderService
{
public:
......
static void instantiate() { publish(); }
4
......
};
template
class BinderService
{
public:
......
static void instantiate() { publish(); }
......
};
这个函数定义在文件 frameworks/base/include/binder/BinderService.h 中。
BinderService 类的静态成员函数 instantiate 的实现很简单,它只是调用 BinderService 类
的另外一个静态成员函数 publish 来继续执行启动 SurfaceFlinger 服务的操作。
Step 4. BinderService.publish
template
class BinderService
{
public:
static status_t publish() {
sp sm(defaultServiceManager());
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
}
......
};
template
class BinderService
{
public:
static status_t publish() {
sp sm(defaultServiceManager());
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
}
......
};
这个函数定义在文件 frameworks/base/include/binder/BinderService.h 中。
BinderService 是一个模板类,它有一个模板参数 SERVICE。当 BinderService 类被
SurfaceFlinger 类继承时,模板参数 SERVICE 的值就等于 SurfaceFlinger。因此,BinderService
类的静态成员函数 publish 所执行的操作就是创建一个 SurfaceFlinger 实例,用来作为系统的
5
SurfaceFlinger 服务,并且将这个服务注册到 Service Manager 中去,这样系统中的其它组件
或者进程就可以通过 Service Manager 来获得 SurfaceFlinger 服务的 Binder 代理对象,进而使
用它所提供的服务。
SurfaceFlinger 服务的创建过程。
Step 5. new SurfaceFlinger
SurfaceFlinger::SurfaceFlinger()
: BnSurfaceComposer(), Thread(false),
......
{
init();
}
SurfaceFlinger::SurfaceFlinger()
: BnSurfaceComposer(), Thread(false),
......
{
init();
}
这个函数定义在文件 frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp 中。
SurfaceFlinger 类继承了 BnSurfaceComposer 类,而后者是一个实现了 ISurfaceComposer
接口的 Binder 本地对象类。此外,SurfaceFlinger 类还继承了 Thread 类,后者是用来创建一
个线程的,这个线程就是 UI 渲染线程,它的线程执行体函数为 SurfaceFlinger 类的成员函数
threadLoop。后面在分析 SurfaceFlinger 服务渲染 UI 的过程时,我们再分析 SurfaceFlinger 类
的成员函数 threadLoop 的实现。注意,在初始化 SurfaceFlinger 的父类 Thread 时,传进去的
参数为 false,表示先不要将 SurfaceFlinger 服务的 UI 渲染线程启动起来,等到后面再启动。
SurfaceFlinger 服务在创建的过程中,会调用 SurfaceFlinger 类的成员函数 init 来执行初
始化的操作。
Step 6. SurfaceFlinger.init
void SurfaceFlinger::init()
{
LOGI("SurfaceFlinger is starting");
// debugging stuff...
char value[PROPERTY_VALUE_MAX];
property_get("debug.sf.showupdates", value, "0");
mDebugRegion = atoi(value);
property_get("debug.sf.showbackground", value, "0");
mDebugBackground = atoi(value);
LOGI_IF(mDebugRegion, "showupdates enabled");
LOGI_IF(mDebugBackground, "showbackground enabled");
}
void SurfaceFlinger::init()
6
{
LOGI("SurfaceFlinger is starting");
// debugging stuff...
char value[PROPERTY_VALUE_MAX];
property_get("debug.sf.showupdates", value, "0");
mDebugRegion = atoi(value);
property_get("debug.sf.showbackground", value, "0");
mDebugBackground = atoi(value);
LOGI_IF(mDebugRegion, "showupdates enabled");
LOGI_IF(mDebugBackground, "showbackground enabled");
}
这个函数定义在文件 frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp 中。
SurfaceFlinger 类的成员函数 init 的实现很简单,它分别获得系统中两个名称为
“debug.sf.showupdates” 和 “debug.sf.showbackground” 的 属 性 的 值 , 并 且 分 别 保 存 在
SurfaceFlinger 类的成员变量 mDebugRegion 和 mDebugBackground 中。这两个成员变量是与
调试相关的,我们不关心。
这一步执行完成之后,返回到前面的 Step 4 中,即 BinderService 类的静态成员函数
publish 中,这时候在前面的 Step 5 中所创建的一个 SurfaceFlinger 实例就会被注册到 Service
Manager 中,这是通过调用 Service Manager 的 Binder 代理对象的成员函数 addService 来实
现的。由于 Service Manager 的 Binder 代理对象的成员函数 addService 的第二个参数是一个
类型为 IBinder 的强指针引用。当一个对象第一次被一个强指针引用时,那么这个对象的成
员函数 onFirstRef 就会被调用。因此,接下来前面所创建的 SurfaceFlinger 实例的成员函数
onFirstRef 就会被调用,以便可以继续执行初始化操作。
Step 7. SurfaceFlinger.onFirstRef
void SurfaceFlinger::onFirstRef()
{
run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
// Wait for the main thread to be done with its initialization
mReadyToRunBarrier.wait();
}
void SurfaceFlinger::onFirstRef()
{
run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
// Wait for the main thread to be done with its initialization
mReadyToRunBarrier.wait();
}
这个函数定义在文件 frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp 中。
函数首先调用从父类继承下来的成员函数 run 来启动一个名秒为“SurfaceFlinger”的线
7
程,用来执行 UI 渲染操作。这就是前面我们所说的 UI 渲染线程了。这个 UI 渲染线程创建
完成之后,首先会调用 SurfaceFlinger 类的成员函数 readyToRun 来执行一些初始化操作,接
着再循环调用 SurfaceFlinger 类的成员函数 threadLoop 来作为线程的执行体。
mReadyToRunBarrier 是 SurfaceFlinger 类的一个成员变量,它的类型是 Barrier,用来描
述一个屏障,是通过条件变量来实现的。我们可以把它看作是一个线程同步工具,即阻塞当
前线程,直到 SurfaceFlinger 服务的 UI 渲染线程执行完成初始化操作为止。
Step 8. SurfaceFlinger.oreadyToRun
这个函数定义在文件 frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp 文件中,
用来初始化 SurfaceFlinger 服务的 UI 渲染线程,
status_t SurfaceFlinger::readyToRun()
{
LOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
// we only support one display currently
int dpy = 0;
{
// initialize the main display
GraphicPlane& plane(graphicPlane(dpy));
DisplayHardware* const hw = new DisplayHardware(this, dpy);
plane.setDisplayHardware(hw);
}
status_t SurfaceFlinger::readyToRun()
{
LOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
// we only support one display currently
int dpy = 0;
{
// initialize the main display
GraphicPlane& plane(graphicPlane(dpy));
DisplayHardware* const hw = new DisplayHardware(this, dpy);
plane.setDisplayHardware(hw);
}
这段代码首先创建了一个 DisplayHardware 对象 hw,用来描述设备的显示屏,并且用
这个 DisplayHardware 对象来初始化 SurfaceFlinger 类的成员变量 mGraphicPlanes 所描述的一
个 GraphicPlane 数组的第一个元素。在 DisplayHardware 对象 hw 的创建过程中,会创建另外
一个线程,用来监控控制台事件,即监控硬件帧缓冲区的睡眠和唤醒事件。
// create the shared control-block
8