[Android禅修之路] SurfaceFlinger的启动过程
theme: channing-cyan
[Android禅修之路] SurfaceFlinger的启动过程
一 概述
SurfaceFlinger 是系统服务的一种,所以它的启动方式也是和其他系统服务一样的,在 Android 中,有系统服务有两种启动方式。
- 由 ServiceManager 启动
- 配置在 rc 文件中单独启动
对于 SurfaceFlinger 来说,它使用的是第二种方式。
当然,系统服务的启动原理这里并不会深入,我们需要关注的,是 SurfaceFlinger 启动的过程。Android 系统在启动时,会通过 surfaceflinger.rc 文件来启动 SurfaceFlinger 服务,SurfaceFlinger 源文件配置在 frameworks/native/services/surfaceflinger/Android.bp
文件中。Android.bp 是 Android 新版本的编译配置文件,通过 Android.bp 文件的指定,最终会执行main_surfaceflinger.cpp
文件中的 main 函数。所以我们从 SurfaceFlinger 启动的第一个 main 函数开始看。
二 main_surfaceflinger
2.1 main_surfaceflinger:main
```cpp int main(int, char**) { signal(SIGPIPE, SIG_IGN);
// 设置 hwbinder 通信的最大线程数:
hardware::configureRpcThreadpool(1 /* maxThreads */,
false /* callerWillJoin */);
// //启动Graphics Allocator服务,这个是用于 GraphicBuffer 分配的
startGraphicsAllocatorService();
//现在 SF 进程的 Binder 线程数为4
ProcessState::self()->setThreadPoolMaxThreadCount(4);
// 启动线程池
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
// 创建 SF 对象
sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
// 设置线程优先级
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
// 设置调度策略,优先级
set_sched_policy(0, SP_FOREGROUND);
if (cpusets_enabled()) set_cpuset_policy(0, SP_SYSTEM);
// 初始化 SF
flinger->init();
// 发布 SF 系统服务到 ServiceManager
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
// 启动 DisplayService
startDisplayService();
struct sched_param param = {0};
param.sched_priority = 2;
if (sched_setscheduler(0, SCHED_FIFO, ¶m) != 0) {
ALOGE("Couldn't set SCHED_FIFO");
}
// 启动 SF 线程
flinger->run();
return 0;
} ```
main函数中的逻辑较长,这里可以简单分为一下几步
- 设置hwbinder中的最大线程数为4,这个hwbinder其实就是binder,如果看的是早期的Android代码,就不会有hwbinder这个概念,hwbinder是Android对binder的进一步划分,比如binder,hwbinder,vndbinder,这里我们看作binder即可
- 启动Graphics Allocator服务
- 通过surfaceflinger::createSurfaceFlinger创建SurfaceFlinger
- 初始化SurfaceFlinger
- 发布SurfaceFlinger服务到ServiceManager
- 启动DisplayService
- 调用SurfaceFlinger的run方法
关于 SurfaceFlinger 有很多重要的地方,这里我们先简单的分析它的启动过程即可
在 SurfaceFlinger 启动的过程中,主要做的就是启动 SurfaceFlinger 系统服务,并将它发布到 ServiceManager 中,并启动了它自己的 Binder 线程。当然,在这附带的过程中,还启动了一些其他 SurfaceFlinger 会依赖的服务。例如 Graphics Allocator 就是一个非常重要的服务,后面我们会单独提到,不过这些服务暂时不是本篇的重点。
与 SurfaceFlinger 启动和初始化相关的其实就两行代码,只需要关注与它们就行
c
// 1. 创建 SurfaceFlinger 对象
sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
// 2. 调用 SurfaceFlinger 的初始化函数
flinger->init();
2.2 SurfaceFlinger的定义
在看着两行代码之前,我们先看一下 SurfaceFlinger 这个类的定义:
c
[frameworks/native/services/surfaceflinger/SurfaceFlinger.h]
class SurfaceFlinger : public BnSurfaceComposer,
public PriorityDumper,
public ClientCache::ErasedRecipient,
private IBinder::DeathRecipient,
private HWC2::ComposerCallback {
- 首先 SurfaceFlinger 继承的类中有一个 BnSurfaceComposer,看到Bn开头,就知道它是一个Binder通信的实现类,对应的还有Bp应该就在应用端
- 然后还看到它实现了一个 HWC2 的回调函数,HWC2 是和硬件相关的,这个回调函数处理的就是 Vsync 相关的逻辑
当然, SurfaceFlinger 这个类的实现了哪些类,我们并不需要全部记住,之后如果不记得了,回头看一眼便是。
三 SurfaceFlinger.cpp
3.1 SurfaceFlingerFactory
SurfaceFlinger 的创建使用的是一个工厂类 SurfaceFlingerFactory,这个工厂类实际上就是调用的 SurfaceFlinger 构造函数,参数为工厂本身。
c
sp<SurfaceFlinger> createSurfaceFlinger() {
...
return new SurfaceFlinger(factory);
}
这里将 SurfaceFlingerFactory 对象传进了 SurfaceFlinger 的构造函数,后面在 SurfaceFlinger 创建其他的对象时,都会使用这个 SurfaceFlingerFactory 来创建。
3.2 SurfaceFlinger 的构造函数
SurfaceFlinger 的构造函数比较简单,只是做了一些成员变量的初始化工作,它通过 SurfaceFlingerFactory 对象创建了一大堆自己依赖的对象,这里我们先略过对这些成员变量的介绍,对于这些成员变量,后续用到的时候再进行说明。
cpp
[frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp]
SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
: mFactory(factory),
mPhaseOffsets(mFactory.createPhaseOffsets()),
mInterceptor(mFactory.createSurfaceInterceptor(this)),
mTimeStats(mFactory.createTimeStats()),
mEventQueue(mFactory.createMessageQueue()),
mCompositionEngine(mFactory.createCompositionEngine()) {}
3.3 SurfaceFlinger::init
接下来就是在 main 函数中调用的 init 函数,这个也是 SurfaceFlinger 主要初始化的工作
```c
[frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp]
void SurfaceFlinger::init() {
...
// 1 首先启动EventThread,EventThread有两个,分别是App EventThread和SF EventThread
// getFactory()拿到的是SurfaceFlingerDefaultFactory
mAppConnectionHandle =
mScheduler->createConnection("app", mVsyncModulator.getOffsets().app,
mPhaseOffsets->getOffsetThresholdForNextVsync(),
resyncCallback,
impl::EventThread::InterceptVSyncsCallback());
mSfConnectionHandle =
mScheduler->createConnection("sf", mVsyncModulator.getOffsets().sf,
mPhaseOffsets->getOffsetThresholdForNextVsync(),
resyncCallback, this {
mInterceptor->saveVSyncEvent(timestamp);
});
...
// 2 初始化EGL
// 2.1 EGL 配置
int32_t renderEngineFeature = 0;
renderEngineFeature |= (useColorManagement ?
renderengine::RenderEngine::USE_COLOR_MANAGEMENT : 0);
renderEngineFeature |= (useContextPriority ?
renderengine::RenderEngine::USE_HIGH_PRIORITY_CONTEXT : 0);
renderEngineFeature |=
(enable_protected_contents(false) ? renderengine::RenderEngine::ENABLE_PROTECTED_CONTEXT
: 0);
// 2.2 EGL创建
mCompositionEngine->setRenderEngine(
renderengine::RenderEngine::create(static_cast<int32_t>(defaultCompositionPixelFormat),
renderEngineFeature, maxFrameBufferAcquiredBuffers));
// 2.3 创建HWComposer
mCompositionEngine->setHwComposer(getFactory().createHWComposer(getBE().mHwcServiceName));
mCompositionEngine->getHwComposer().registerCallback(this, getBE().mComposerSequenceId);
//3 处理热插拔事件
processDisplayHotplugEventsLocked();
const auto display = getDefaultDisplayDeviceLocked();
// 启用VR Flinger则执行,一般是false
if (useVrFlinger) {
auto vrFlingerRequestDisplayCallback = [this](bool requestDisplay) {
postMessageAsync(new LambdaMessage([=] {
ALOGI("VR request display mode: requestDisplay=%d", requestDisplay);
mVrFlingerRequestsDisplay = requestDisplay;
signalTransaction();
}));
};
mVrFlinger = dvr::VrFlinger::Create(getHwComposer().getComposer(),
getHwComposer()
.fromPhysicalDisplayId(*display->getId())
.value_or(0),
vrFlingerRequestDisplayCallback);
}
mDrawingState = mCurrentState;
// 4 初始化事件
initializeDisplays();
getRenderEngine().primeCache();
const bool presentFenceReliable =
!getHwComposer().hasCapability(HWC2::Capability::PresentFenceIsNotReliable);
//5 开机动画
mStartPropertySetThread = getFactory().createStartPropertySetThread(presentFenceReliable);
...
} ```
这里出现了很多其他知识相关的地方,例如 SurfaceFlinger 中的 EventQueue 机制,Vsync 机制,硬件 Vsync 和 软件 Vsync 的回调等等,这些机制都非常复杂,我们暂时先把它记录下来,后续针对每种机制再单独说明。这里我们暂时假设自己了解这些,已学习主要流程为主。
init 函数中的逻辑很多,这里简单整理一下: 1. 创建一个Scheduler 2. 构造一个回调函数ResyncCallback 3. 创建两个连接处理器ConnectionHandle, 1. 首先是创建两个EventThread, 分别是app EventThread和 sf EventThread 2. EventThread中有一个VSync的回调 3. EventThread中有一个Thread, 这个Thread是一个死循环, 用于监听VSync事件,并且消费分发,在没有事件的时候等待 4. 然后通过这个EventThread进行连接,调用Scheduler中的createConnectionInternal 4. 将 mSfConnectionHandle 对应的 EventThreadConnection 注入 mEventQueue 5. 设置Vsync 监控和区域采样 6. 初始化EGL(配置, 创建) 7. 处理热插拔事件 8. 初始化事件 9. 开机动画
3.4 SurfaceFlinger 初始化中的其他操作
其实除了 init 函数做的一些初始化之外,还有其他地方也做了一些初始化。例如通过 Binder 机制,当 SurfaceFlinger 第一次生成强指针的时候,会调用到 onFirstRef 函数。通过 ServiceManager 发布系统服务,会通过 Binder 的死亡代理调用到 binderDied 函数,这里我们也是将他们列举出来。
```cpp void SurfaceFlinger::onFirstRef() { // 初始化消息队列 mEventQueue->init(this); }
void SurfaceFlinger::binderDied(const wp
// 重新初始化显示设备
initializeDisplays();
// 启动 Boot 动画
startBootAnim();
} ```
四 总结
SurfaceFlinger 的启动流程大体来说还是比较简单,但是里面涉及到的其他机制非常多,如果我们全部深入,又容易陷入源码的海洋,最终忘记自己最初的目的,所以这一篇我们仅仅只是了解 SurfaceFlinger 的启动过程,对于里面涉及到的 SurfaceFlinger 的机制,我们先假设自己已经掌握,等到我们掌握了 SurfaceFlinger 的整体工作流程之后,再来针对里面的机制进行单点突破,最后再将这些机制带入到整体的流程中。
- Activity启动源码解析(Android12)
- 从MediaServer看Binder的使用方式(一)
- 从MediaServer看Binder的使用方式(二)
- [Android禅修之路] 解读Layer
- [Android禅修之路] Android图形系统,从Activity到Surface
- [Android禅修之路] 解读 GraphicBuffer 之 Framework 层
- [Android禅修之路] 解读SurfaceFlinger中的BufferQueue
- [Android禅修之路] SurfaceFlinger 合成中的工作
- [Android禅修之路] SurfaceFlinger 中的一些对象
- [Android禅修之路] SurfaceFlinger 合成前的预处理
- [Android禅修之路] SurfaceFlinger合成总览
- [Android禅修之路] SurfaceFlinger的启动过程
- [Android禅修之路] Android 图形系统开篇