[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
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 启动和初始化相关的其实就两行代码,只需要关注与它们就行
// 1. 创建 SurfaceFlinger 对象
sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
// 2. 调用 SurfaceFlinger 的初始化函数
flinger->init();
2.2 SurfaceFlinger的定义
在看着两行代码之前,我们先看一下 SurfaceFlinger 这个类的定义:
[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 构造函数,参数为工厂本身。
sp<SurfaceFlinger> createSurfaceFlinger() {
...
return new SurfaceFlinger(factory);
}
这里将 SurfaceFlingerFactory 对象传进了 SurfaceFlinger 的构造函数,后面在 SurfaceFlinger 创建其他的对象时,都会使用这个 SurfaceFlingerFactory 来创建。
3.2 SurfaceFlinger 的构造函数
SurfaceFlinger 的构造函数比较简单,只是做了一些成员变量的初始化工作,它通过 SurfaceFlingerFactory 对象创建了一大堆自己依赖的对象,这里我们先略过对这些成员变量的介绍,对于这些成员变量,后续用到的时候再进行说明。
[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 主要初始化的工作
[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](nsecs_t timestamp) {
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 函数中的逻辑很多,这里简单整理一下:
- 创建一个Scheduler
- 构造一个回调函数ResyncCallback
- 创建两个连接处理器ConnectionHandle,
- 首先是创建两个EventThread, 分别是app EventThread和 sf EventThread
- EventThread中有一个VSync的回调
- EventThread中有一个Thread, 这个Thread是一个死循环, 用于监听VSync事件,并且消费分发,在没有事件的时候等待
- 然后通过这个EventThread进行连接,调用Scheduler中的createConnectionInternal
- 将 mSfConnectionHandle 对应的 EventThreadConnection 注入 mEventQueue
- 设置Vsync 监控和区域采样
- 初始化EGL(配置, 创建)
- 处理热插拔事件
- 初始化事件
- 开机动画
3.4 SurfaceFlinger 初始化中的其他操作
其实除了 init 函数做的一些初始化之外,还有其他地方也做了一些初始化。例如通过 Binder 机制,当 SurfaceFlinger 第一次生成强指针的时候,会调用到 onFirstRef 函数。通过 ServiceManager 发布系统服务,会通过 Binder 的死亡代理调用到 binderDied 函数,这里我们也是将他们列举出来。
void SurfaceFlinger::onFirstRef()
{
// 初始化消息队列
mEventQueue->init(this);
}
void SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
{
// 重新初始化显示设备
initializeDisplays();
// 启动 Boot 动画
startBootAnim();
}
四 总结
SurfaceFlinger 的启动流程大体来说还是比较简单,但是里面涉及到的其他机制非常多,如果我们全部深入,又容易陷入源码的海洋,最终忘记自己最初的目的,所以这一篇我们仅仅只是了解 SurfaceFlinger 的启动过程,对于里面涉及到的 SurfaceFlinger 的机制,我们先假设自己已经掌握,等到我们掌握了 SurfaceFlinger 的整体工作流程之后,再来针对里面的机制进行单点突破,最后再将这些机制带入到整体的流程中。