SurfaceFlinger 是 Android 系统中的一个核心服务,负责管理图形缓冲区的合成和屏幕显示,是 Android 图形系统的关键组件。
一、启动流程
SurfaceFlinger 作为一个系统服务,在 Android 启动早期由 init 进程通过 servicemanager 启动。它是作为用户空间的一部分运行的,通常拥有 root 权限。在初始化阶段,SurfaceFlinger 通常还需要完成以下工作:
- 设置其运行环境,包括创建必要的线程(如主线程、处理消息的线程等)、初始化硬件模块(如 GPU 驱动)、以及配置显示设备等。
- 建立 DisplayHardware,SurfaceFlinger 会与硬件抽象层(HAL)交互,通过 HAL 与具体的显示硬件设备进行通信。这包括查询硬件支持的显示模式、分辨率、刷新率等信息,并根据系统配置选择合适的显示模式。
- 创建 ComposerClient,在某些Android版本中,SurfaceFlinger 会通过HWC(Hardware Composer)与图形硬件直接交互。它会创建一个 ComposerClient 实例来管理硬件合成器,这个过程涉及与硬件加速器的初始化和设置。
- 初始化 LayerManager,SurfaceFlinger 维护了一个 LayerManager,用于管理所有的 Surface(即图层层)。在初始化时,它会创建根 Layer,这个 Layer 代表整个屏幕,并为后续的窗口和 Surface 创建做准备。
- 设置色彩管理,包括加载色彩配置文件,确保屏幕颜色准确无误地显示。
- 建立与 SurfaceControl 的连接,SurfaceControl 是应用程序与 SurfaceFlinger 通信的接口。初始化时,SurfaceFlinger 会准备好接受来自应用程序的 Surface 创建、更新和销毁请求。
- 事件监听与处理机制,设置 VSync(垂直同步)信号监听,确保每一帧的绘制都在最佳时间点进行,减少撕裂现象。同时,初始化事件处理机制,准备处理来自系统和其他服务的命令和事件。
- 安全性设置,SurfaceFlinger 还会进行一些安全性方面的初始化,比如设置 SELinux 策略,确保其运行时的权限和访问控制符合系统安全要求。
整个初始化过程确保了 SurfaceFlinger 能够准备好处理图形数据的接收、合成和显示,为 Android 应用的 UI 渲染提供基础服务。
要了解 SurfaceFlinger 的启动流程需要看看 SurfaceFlinger 对应模块目录下的 bp 文件。
1、Android.bp
源码位置:/frameworks/native/services/surfaceflinger/Android.bp
……
cc_defaults {name: "libsurfaceflinger_defaults",defaults: ["surfaceflinger_defaults","skia_renderengine_deps",],……shared_libs: [……"android.hardware.graphics.allocator@2.0","android.hardware.graphics.allocator@3.0",……"android.hardware.graphics.composer@2.1","android.hardware.graphics.composer@2.2","android.hardware.graphics.composer@2.3","android.hardware.graphics.composer@2.4","android.hardware.graphics.composer3-V1-ndk",……"libbinder","libbinder_ndk","libcutils","libEGL","libfmq","libGLESv1_CM","libGLESv2",……],……
}
……
filegroup {name: "libsurfaceflinger_sources",srcs: [// cpp源代码文件……],
}
……
filegroup {name: "surfaceflinger_binary_sources",srcs: [":libsurfaceflinger_sources","main_surfaceflinger.cpp",],
}cc_binary {name: "surfaceflinger",defaults: ["libsurfaceflinger_binary"],init_rc: ["surfaceflinger.rc"],srcs: [":surfaceflinger_binary_sources",// 注意:SurfaceFlingerFactory不在文件组中,因此可以很容易地替换它。"SurfaceFlingerFactory.cpp",],shared_libs: ["libSurfaceFlingerProp",],logtags: ["EventLog/EventLogTags.logtags"],
}
……
这里我们可以看到几个核心的内容:
- android.hardware.graphics.allocator@2.0:图形内存分配器抽象硬件层的实现。
- android.hardware.graphics.composer@2.x:hwc 图层合成抽象硬件层实现。
- binder、opengles、hwbinder(抽象硬件层的 binder)等。
- 设定了SurfaceFlinger 的在 Android 启动初期需要加载的 init.rc 文件——surfaceflinger.rc。
- SurfaceFlinger 的主函数入口 main_surfaceflinger.cpp。
在了解了 SurfaceFlinger 模块的 bp 文件后,对于 SurfaceFlinger 的启动流程,我们知道该服务是通过解析 surfaceflinger.rc 进行启动的,并且服务的主函数入口在 main_surfaceflinger.cpp 中。
2、surfaceflinger.rc
源码位置:/frameworks/native/services/surfaceflinger/surfaceflinger.rc
service surfaceflinger /system/bin/surfaceflingerclass core animationuser systemgroup graphics drmrpc readproc// 允许调整进程优先级capabilities SYS_NICE// 如果surfaceflinger服务重启,且zygote服务正在运行,则同时重启zygote服务onrestart restart --only-if-running zygote// 指定服务的任务性能配置为HighPerformancetask_profiles HighPerformancesocket pdx/system/vr/display/client stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0socket pdx/system/vr/display/manager stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0socket pdx/system/vr/display/vsync stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0
这里主要用于定义 surfaceflinger 服务的属性和权限设置,同时还启动了三个 socket,分别用于虚拟现实(VR)显示的客户端连接、管理端连接以及垂直同步(vsync)信号。配置确保了 surfaceflinger 服务能够在 Android 系统中安全高效地运行,处理图形显示和 VR 相关的功能。
3、main_surfaceflinger.cpp
源码位置:/frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
int main(int, char**) {signal(SIGPIPE, SIG_IGN);// 初始化硬件相关的RPC线程池hardware::configureRpcThreadpool(1 /* maxThreads */, false /* callerWillJoin */);// 启动图形内存分配服务startGraphicsAllocatorService();// 将Binder线程池的最大线程数设置为4,适用于SurfaceFlinger独立进程场景。ProcessState::self()->setThreadPoolMaxThreadCount(4);……// 启动线程池sp<ProcessState> ps(ProcessState::self());ps->startThreadPool();……// 创建SurfaceFlinger对象sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();……// 提升当前进程的调度优先级setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);set_sched_policy(0, SP_FOREGROUND);// 根据是否启用CPU集,调整SurfaceFlinger相关线程的CPU使用策略,避免不必要的大核使用if (cpusets_enabled()) set_cpuset_policy(0, SP_SYSTEM);// 初始化SurfaceFlinger,准备接收客户端连接。flinger->init();// 通过IServiceManager向系统服务管理器注册SurfaceFlinger及其AIDL接口。sp<IServiceManager> sm(defaultServiceManager());sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);sp<SurfaceComposerAIDL> composerAIDL = new SurfaceComposerAIDL(flinger);sm->addService(String16("SurfaceFlingerAIDL"), composerAIDL, false,IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);// 启动Display服务startDisplayService(); // 依赖于上面注册的SF// 确保SurfaceFlinger运行在SCHED_FIFO调度策略下if (SurfaceFlinger::setSchedFifo(true) != NO_ERROR) {ALOGW("Couldn't set to SCHED_FIFO: %s", strerror(errno));}// 运行SurfaceFlinger,进入主循环,处理图形显示相关的任务。flinger->run();return 0;
}
整个过程涉及了线程管理、资源分配、进程优先级调整等多个方面,确保 SurfaceFlinger 能够高效、稳定地提供图形显示服务。这里有如下几个核心方法:
- startGraphicsAllocatorService:初始化 Hal 层的图元生成器服务。
- 初始化 ProcessState,也就是把该进程映射到 Binder 驱动程序。
- SurfaceFlinger 实例化。
- set_sched_policy 设置为前台进程。
- SurfaceFlinger 调用 init 方法。
- 因为 SurfaceFlinger 本质上也是一个 Binder 服务,因此添加到 ServiceManager 进程中。
- 初始化 GpuService,也添加到 ServiceManager 进程中。
- 启动 DisplayService。
- sched_setscheduler 把进程调度模式设置为实时进程的 FIFO。
- 调用 SurfaceFlinger 的 run 方法。
二、总结
初始化阶段
由 init 进程启动:SurfaceFlinger 服务作为 Android 系统中的一个关键服务,是由 init 进程根据 init.rc 配置文件启动的。在这个阶段,init 进程会 fork 出一个新的进程来运行 SurfaceFlinger 服务。
执行main函数
main_surfaceflinger.cpp:SurfaceFlinger 的生命周期从其 C++ 主入口点 main() 函数开始。这个函数执行一系列初始化操作,包括但不限于:
- 创建线程池:为了高效处理多任务,SurfaceFlinger 会创建一个线程池。
- 设置进程和线程优先级:确保 SurfaceFlinger 具有合适的调度优先级以满足实时显示需求。
- 初始化硬件模块:如 HWC(Hardware Composer)和 EGL(Embedded Graphics Library)等,这些对于图形渲染至关重要。
- 创建 SurfaceFlinger 对象:这是服务的核心实例,负责管理显示和图层的合成。
- Binder 初始化:SurfaceFlinger 服务会检查并准备 Binder 机制,这是 Android 系统中进程间通信(IPC)的关键部分。这允许其他应用和服务通过 Binder 接口与 SurfaceFlinger 交互。
- ServiceManage r 注册:SurfaceFlinger 通过 Binder 向 ServiceManager 注册自己,使其对整个系统可用。这样,其他组件如 Window Manager 等可以发现并连接到 SurfaceFlinger 服务。
- 启动线程和循环:初始化完成后,SurfaceFlinger 进入主事件循环,监听和处理来自客户端的请求,如创建新的 Surface,更新图层属性,以及执行实际的屏幕合成操作。
综上所述,SurfaceFlinger 的启动是一个复杂但有序的过程,涉及了从底层硬件初始化到高层服务注册的一系列步骤,确保系统能够高效、稳定地进行图形显示。