启动过程总览
SurfaceFlinger 系列文章持续更新中(公众号:阿豪讲Framework):
- 如何调试 SurfaceFlinger
- SurfaceFlinger 概述
- 启动过程总览
- SurfaceFlinger 对象初始化
- ........
本文基于 AOSP android-15.0.0_r20 版本源码和 pixel6 手机分析。
# 1. SurfaceFlinger 进程 main 函数执行流程分析
开机时,init 进程启动后,会解析 system/core/rootdir/init.rc
文件,在 init.rc 文件中,会启动 core class 服务:
on boot
class_start core
1
2
2
SurfaceFlinger 对应的 rc 文件定义在 frameworks/native/services/surfaceflinger/surfaceflinger.rc
:
service surfaceflinger /system/bin/surfaceflinger
class core animation
user system
group graphics drmrpc readproc
capabilities SYS_NICE
onrestart restart --only-if-running zygote
task_profiles HighPerformance
1
2
3
4
5
6
7
2
3
4
5
6
7
surfaceflinger 是 core class 的,也就是说,surfaceflinger 进程会在开机的 boot 阶段启动。
surfaceflinger 进程对应的可执行文件是 /system/bin/surfaceflinger
,可执行文件对应的源码是 frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
。对应的 Android.bp 是 /frameworks/native/services/surfaceflinger/Android.bp
:
# 2. SurfaceFligner 主函数实现
源文件中主函数的实现如下:
// frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
int main(int, char**) {
// 注册 SIGPIPE 信号的处理函数
signal(SIGPIPE, SIG_IGN);
// 配置 hwbinder 线程池,线程数量为 1
// 配置 HWBinder 线程池最大线程数为 1
hardware::configureRpcThreadpool(1 /* maxThreads */,
false /* callerWillJoin */);
// 启动 Graphics Allocator Hal 服务
// 通过系统属性控制,是否启动,一般不在这里启动
// 通过系统属性控制是否启动,一般没有在这里启动
startGraphicsAllocatorService();
// 配置 binder 线程池,线程数量为 1
// When SF is launched in its own process, limit the number of
// binder threads to 4.
ProcessState::self()->setThreadPoolMaxThreadCount(4);
// 设置 uclamp.min 属性,确保重要线程(如 RenderEngine)获得足够的 CPU 资源
// 为所有线程设置最小调度属性
// 设置线程优先级
// 有兴趣的同学可以看看 https://paul.pub/android-process-schedule/
// Set uclamp.min setting on all threads, maybe an overkill but we want
// to cover important threads like RenderEngine.
if (SurfaceFlinger::setSchedAttr(true) != NO_ERROR) {
ALOGW("Failed to set uclamp.min during boot: %s", strerror(errno));
}
// 实时调度优先级配置
// 设置 binder 线程池的优先级
// The binder threadpool we start will inherit sched policy and priority
// of (this) creating thread. We want the binder thread pool to have
// SCHED_FIFO policy and priority 1 (lowest RT priority)
// Once the pool is created we reset this thread's priority back to
// original.
int newPriority = 0;
int origPolicy = sched_getscheduler(0);
struct sched_param origSchedParam;
int errorInPriorityModification = sched_getparam(0, &origSchedParam);
if (errorInPriorityModification == 0) {
int policy = SCHED_FIFO;
newPriority = sched_get_priority_min(policy);
struct sched_param param;
param.sched_priority = newPriority;
errorInPriorityModification = sched_setscheduler(0, policy, ¶m);
}
// 初始化驱动,启动 Binder 线程池
// start the thread pool
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
// Reset current thread's policy and priority
if (errorInPriorityModification == 0) {
errorInPriorityModification = sched_setscheduler(0, origPolicy, &origSchedParam);
} else {
ALOGE("Failed to set SurfaceFlinger binder threadpool priority to SCHED_FIFO");
}
// 关注点 1
// 初始化一个 SurfaceFlinger 对象,SurfaceFlinger 本身是一个 Binder 服务端对象
// instantiate surfaceflinger
sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
// 调度策略
// Set the minimum policy of surfaceflinger node to be SCHED_FIFO.
// So any thread with policy/priority lower than {SCHED_FIFO, 1}, will run
// at least with SCHED_FIFO policy and priority 1.
if (errorInPriorityModification == 0) {
flinger->setMinSchedulerPolicy(SCHED_FIFO, newPriority);
}
// 设置进程为高优先级以及前台调度策略
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
set_sched_policy(0, SP_FOREGROUND);
// 关注点 2
// SurfaceFlinger 初始化
// initialize before clients can connect
flinger->init();
// 关注点 3
// 发布 Binder 服务
// publish surface flinger
// 注册了一个叫 SurfaceFlinger 的 binder 服务
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
// 注册了一个叫 SurfaceFlingerAIDL 的 binder 服务
// new 了一个 SurfaceComposerAIDL 对象
// publish gui::ISurfaceComposer, the new AIDL interface
sp<SurfaceComposerAIDL> composerAIDL = sp<SurfaceComposerAIDL>::make(flinger);
sm->addService(String16("SurfaceFlingerAIDL"), composerAIDL, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
<<<<<<< HEAD
=======
// 关注点4
>>>>>>> 7a7e319 (sf)
// 启动 DisplayService 服务
startDisplayService(); // dependency on SF getting registered above
// 进程调度模式设置为实时进程的FIFO
if (SurfaceFlinger::setSchedFifo(true) != NO_ERROR) {
ALOGW("Failed to set SCHED_FIFO during boot: %s", strerror(errno));
}
<<<<<<< HEAD
// 关注点 4
=======
// 关注点 5
>>>>>>> 7a7e319 (sf)
// 进入事件循环
// run surface flinger in this thread
flinger->run();
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
后续章节主要分析标注了关注点的 6 个地方:
- 关注点1,初始化 SurfaceFlinger 对象
- 关注点2,SurfaceFlinger init 过程
- 关注点3,发布 Binder 服务 <<<<<<< HEAD
- 关注点4,进入事件循环 =======
- 关注点4,启动 DisplayService 服务
- 关注点5,进入事件循环
7a7e319 (sf)
整体流程如上图所示,其中红色为后续重点分析部分