前言
surfaceflinger作为Android系统一个重要进程,是Android图形显示系统中很核心的一部分组件,负责管理所有在屏幕上显示的内容。
在整个图形显示架构中,surfaceflinger起着承上启下的作用。作为一个IPC服务,所有应用需要显示的UI都会给到surfaceflinger,经过surfaceflinger处理后交给底层硬件HWC完成合成与显示。
同时,surfaceflinger进程作为硬件HWC唯一的“客户端”,跟HWC进行数据的交互,实现软件侧屏幕的管理。比如物理屏的加载、屏幕参数的获取、虚拟屏管理、VSYNC信号调度、色彩管理等,都离不开surfaceflinger。
从本篇文章开始,将会对surfaceflinger进程涉及业务流程和原理进行系统地分析。本篇文章中先对surfaceflinger进程进行基本的介绍,以及对该进程启动流程进行分析。
一、核心类介绍
在这篇文章中,我们对surfaceflinger进程的核心类从两方面进行说明:
- 跨进程通信(IPC)相关类组件;
- 按功能划分的类组件。
1.1、IPC相关类
surfaceflinger即作为一个独立进程,也是进行IPC的系统服务。surfaceflinger中通过两个接口来实现IPC通信——ISurfaceComposer
和gui::ISurfaceComposer
,其类图表示如下:
1.1.1、ISurfaceComposer接口
ISurfaceComposer
继承于IInterface的IPC接口,SurfaceFlinger类间接实现了该接口,surfaceflinger进程和system_server进程的大部分通信工作都由它完成;
BnSurfaceComposer
实现了ISurfaceComposer
和BBinder接口,相当于Java层IPC类中的“Stub类”,重写了BBinder基类中的onTransact()
方法;
SurfaceFlinger
作为surfaceflinger进程核心类,进程main()
函数执行后就会创建该类对应实例。同时,该类实现了Binder接口ISurfaceComposer
,因此可以直接和其他进程(主要是system_server
)进行IPC通信。
1.1.2、gui::ISurfaceComposer接口
gui::ISurfaceComposer
是Android T开始新增的一个通过aidl文件生成的接口,继承于IInterface,通过aidl文件生成,它将之前一部分android::ISurfaceComposer接口中的定义的方法移动到了该接口中,其目的是为了减轻SurfaceFlinger类跨进程负担。对应的aidl文件路径为:frameworks/native/libs/gui/aidl/android/gui/ISurfaceComposer.aidl;
gui::BnSurfaceComposer
实现了android::gui::ISurfaceComposer
、BBinder,重写了onTransact()
方法;
SurfaceComposerAIDL:gui::ISurfaceComposer
的实现类,用于sf进程和其他进程间进行IPC通信。
android::gui::ISurfaceComposer是由AIDL文件生成的,从功能来看也跟android::ISurfaceComposer重叠,个人认为应该是为重构做铺垫,或许在未来版本上直接迁移到android::gui::ISurfaceComposer上。
关于SurfaceFlinger跨进程通信实现细节,见《SurfaceFlinger02-surfaceflinger跨进程交互 》。
1.2、按功能划分类
根据功能模块来划分,可以对surfaceflinger进程简略分6部分,类图表示如下:
1.2.1、SurfaceFlinger::Factory创建器组件
创建器负责创建各类接口的实现类对象或指针:
- SurfaceFlinger::Factory:创建器顶层接口,用于创建sf中的各类组件对象;
- SurfaceFlinger::DefaultFactory:实现了SurfaceFlinger::Factory,用于创建SurfaceFlinger进程各接口的标准实现,如HWComposer、DisplayDevice、CompositionEngine、BurfferQueue等都是通过DefaultFactory创建;
1.2.2、SurfaceFlinger类
SurfaceFlinger类是SurfaceFlinger进程中最核心的类,除了继承上述提到的BnSurfaceComposer类外,还实现了其他多个接口:
HWC2::ComposerCallback
:用于接收来自Hardware Composer HAL 的事件回调,如热插拔事件、VSYNC事件等;ICompositor
:定义了合成相关方法的接口,用于Scheduler类收到VSYNC信号后向SurfaceFlinger调用执行事务提交与合成;scheduler::ISchedulerCallback
:定义了VSYNC调度状态相关方法的接口,用于Scheduler类向SurfaceFlinger调用同步VSYNC、DisplayMode等跟屏幕模式相关状态;
1.2.3、HWC组件
HWC组件负责跟Hardware Composer HAL进行交互。
HWComposer
:定义了SurfaceFlinger和HAL Composer通信的所有方法的顶层接口;impl::HWComposer
:HWComposer的具体实现类;Hwc2::Composer
:代表实际的HAL composer的抽象接口,从Android 7.0之后由HWC切到了HWC2;android::Hwc2::AidlComposer
:实现了Hwc2::Composer接口、以AIDL方式进行IPC的包裹类;android::Hwc2::HidlComposer
:实现了Hwc2::Composer接口、以HIDL方式进行IPC的包裹类。
AOSP从android T开始推荐使用AIDL方式进行HWC HAL 实现;
1.2.4、 合成引擎组件
CompositionEngine部分负责图层初步的筛选、整合工作, 应用进程传递的图层会在CompositionEngine中进行筛选,对参数进行应用,并保存在每个屏幕对应的输出对象(Output)上。
compositionengine::CompositionEngine
:封装了所有用于进行屏幕合成输出的接口;compositionengine::impl::CompositionEngine
:compositionengine::CompositionEngine的具体实现类;
1.2.5、渲染引擎组件
渲染引擎负责对图层进行绘制和渲染。从严格意义上来讲,它并不算是surfaceflinger进程内的组件,而是作为一个独立的库存在,但确是专门为surfaceflinger进程设计,用于在GPU合成时,对图层进行渲染和绘制。
renderengine::RenderEngine
:渲染引擎的抽象接口,用于在GPU合成时渲染合成图层;renderengine::skia::SkiaRenderEngine
:实现了renderengine::RenderEngine、通过Skia API实现的渲染引擎,默认使用的渲染引擎;
1.2.6、调度器
负责VSYNC调度、线程事件轮询等任务。
impl::MessageQueue
:等同于Java层消息处理机制中的MessageQueue,用于线程间消息处理;scheduler::Scheduler
:sf进程中的统一调度器,消息事件轮询、VSYNC信号接收,并在接收到VSYNC后触发事务提交、合成操作;scheduler::VSYNCModulator
:根据刷新率调度VSYNC信号。
二、surfaceflinger.rc文件定义
sf进程的启动是通过Android Init 语言配置启动,由init进程启动,在surfaceflinger.rc中,定义了SurfaceFlinger的启动参数:
rc代码解读复制代码// frameworks/native/services/SurfaceFlinger/surfaceflinger.rc service surfaceflinger /system/bin/surfaceflinger # 指定进程名和路径 class core animation # 指定SurfaceFlinger进程运行的类别名,同一类别下的服务同时启动、同时结束 user system # 启动该进程前指定用户,默认为root group graphics drmrpc readproc # 启动该进程前指定用户组,默认为root capabilities SYS_NICE # 减小线程的nice值,值越小,优先级越高 onrestart restart --only-if-running zygote # 发生重启时执行指定命令 task_profiles HighPerformance # 设置task profile # 创建一个/dev/socket/
的socket,并将fd传递给SurfaceFlinger socket pdx/system/vr/display/client stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0 socket pdx/system/vr/display/manager stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0 socket pdx/system/vr/display/VSYNC stream 0666 system graphics u:object_r:pdx_display_VSYNC_endpoint_socket:s0
Android init 语法可以参考:cs.android.com/android/pla…
三、main()函数的执行
init进程通过上述rc配置文件启动surfacelingfer可执行文件,并执行对应的main()
函数,函数定义位于main_SurfaceFlinger.cpp
中,核心逻辑如下:
cpp 代码解读复制代码// frameworks/native/services/SurfaceFlinger/main_SurfaceFlinger.cpp
int main(int, char**) {
......
// 创建SurfaceFlinger实例
sp flinger = SurfaceFlinger::createSurfaceFlinger();
// 执行初始化操作
flinger->init();
// 将SF注册到ServiceManager中
sp sm(defaultServiceManager()) ;
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
// 创建SurfaceComposerAIDL,并注册到ServiceManager中
sp composerAIDL = new SurfaceComposerAIDL(flinger);
sm->addService(String16("SurfaceFlingerAIDL"), composerAIDL, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
// 启动SurfaceFlinger主线程
flinger->run();
return 0;
}
在main()函数中,主要执行了以下操作:
- 创建SurfaceFlinger类实例;
SurfaceFlinger::init()
中进行初始化操作;- 创建SurfaceComposerAIDL,并注册到ServiceManager中;
- 启动SurfaceFlinger主线程。
四、SurfaceFlinger()构造方法
main()函数执行后,会通过SurfaceFlinger::createSurfaceFlinger()
创建SurfaceFlinger实例,并触发其构造方法的执行:
cpp 代码解读复制代码// frameworks/native/services/SurfaceFlinger/SurfaceFlingerFactory.cpp
namespace android::SurfaceFlinger {
sp createSurfaceFlinger() {
static DefaultFactory factory;
return sp::make(factory);
}
} // namespace android::SurfaceFlinger
SurfaceFlinger类构造方法如下:
cpp 代码解读复制代码// frameworks/native/services/SurfaceFlinger/SurfaceFlinger.cpp
SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
: mFactory(factory), // SurfaceFlingerFactory对象
mPid(getpid()), // 获得sf进程id
mTimeStats(std::make_shared()), // 时间戳相关统计类
mFrameTracer(mFactory.createFrameTracer()), // 帧统计相关类
mFrameTimeline(mFactory.createFrameTimeline(mTimeStats, mPid)),
mCompositionEngine(mFactory.createCompositionEngine()),// 创建CompositionEngine实例
mHwcServiceName(base::GetProperty("debug.sf.hwc_service_name"s, "default"s)),
mTunnelModeEnabledReporter(new TunnelModeEnabledReporter()),
mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)),
// 默认屏幕默认density
mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)),
// 功耗优化策略
mPowerAdvisor(std::make_unique(*this)),
// 窗口信息监听
mWindowInfosListenerInvoker(sp::make(*this)) {
}
SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization) {
ALOGI("SurfaceFlinger is starting");
// 各功能属性初始化,此处略去
......
}
在以上两个构造方法中,会进行部分类和变量的初始化、以及一些属性的读取工作,其中包括创建CompositionEngine对象。
4.1、创建CompositionEngine实例
CompositionEngine负责所有屏幕上所有图层的初步合成相关操作,SurfaceFlinger中完成Layer属性设置后,将输出传递给CompositionEngine,经过CompositionEngine的处理输出OutputLayer,并最终送给HWC进行合成。它通过创建器进行创建:
cpp 代码解读复制代码// frameworks/native/services/SurfaceFlinger/SurfaceFlingerDefaultFactory.cpp
std::unique_ptr DefaultFactory::createCompositionEngine() {
return compositionengine::impl::createCompositionEngine();
}
// frameworks/native/services/SurfaceFlinger/CompositionEngine/src/CompositionEngine.cpp
std::unique_ptr createCompositionEngine() {
return std::make_unique();
}
当SurfaceFlinger构造方法执行完毕,SurfaceFlinger对象创建完成,接下来执行SurfaceFlinger::init()
方法,进行初始化相关操作。
五、SurfaceFlinger::init()初始化
SurfaceFlinger::init()
方法如下:
cpp 代码解读复制代码// frameworks/native/services/SurfaceFlinger/SurfaceFlinger.cpp
void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) {
Mutex::Autolock lock(mStateLock);
// 创建RenderEngine
auto builder = renderengine::RenderEngineCreationArgs::Builder()
// 设置Pixel格式为RGBA_8888
.setPixelFormat(static_cast<int32_t>(defaultCompositionPixelFormat))
// 设置帧缓冲区大小,triple buffer为3
.setImageCacheSize(maxFrameBufferAcquiredBuffers)
// 是否使用color manager,默认true
.setUseColorManagerment(useColorManagement)
// 是否支持受保护内容(DRM), 默认true,基本都支持
.setEnableProtectedContext(enable_protected_contents(false))
// ToneMapping相关
.setPrecacheToneMapperShaderOnly(false)
// 是否支持背景模糊,默认true
.setSupportsBackgroundBlur(mSupportsBlur)
// 设置优先级
.setContextPriority(
useContextPriority
? renderengine::RenderEngine::ContextPriority::REALTIME
: renderengine::RenderEngine::ContextPriority::MEDIUM);
// 设置渲染引擎类型,默认SKIA_GL_THREADED(skia异步渲染), 此处用于调试
if (auto type = chooseRenderEngineTypeViaSysProp()) {
builder.setRenderEngineType(type.value());
}
// 创建RenderEngine对象
mRenderEngine = renderengine::RenderEngine::create(builder.build());
// 将RenderEngine设置给CompositionEngine
mCompositionEngine->setRenderEngine(mRenderEngine.get());
mMaxRenderTargetSize =
std::min(getRenderEngine().getMaxTextureSize(), getRenderEngine().getMaxViewportDims());
mCompositionEngine->setTimeStats(mTimeStats);
// 创建HWComposer实例
mCompositionEngine->setHwComposer(getFactory().createHWComposer(mHwcServiceName));
// 设置HWComposer回调
mCompositionEngine->getHwComposer().setCallback(*this);
// 将RenderEngine设置给CompositionEngine
ClientCache::getInstance().setRenderEngine(&getRenderEngine());
// 通过热插拔加载屏幕
LOG_ALWAYS_FATAL_IF(!configureLocked(),
"Initial display configuration failed: HWC did not hotplug");
// 加载默认屏
sp<const DisplayDevice> display;
if (const auto indexOpt = mCurrentState.getDisplayIndex(getPrimaryDisplayIdLocked())) {
const auto& displays = mCurrentState.displays;
const auto& token = displays.keyAt(*indexOpt);
const auto& state = displays.valueAt(*indexOpt);
processDisplayAdded(token, state);
mDrawingState.displays.add(token, state);
display = getDefaultDisplayDeviceLocked();
}
// 创建Scheduler
initScheduler(display);
dispatchDisplayHotplugEvent(display->getPhysicalId(), true);
// 加载其他屏
processDisplayChangesLocked();
// initialize our drawing state
mDrawingState = mCurrentState;
onActiveDisplayChangedLocked(nullptr, *display);
static_cast<void>(mScheduler->schedule(
[this]() FTL_FAKE_GUARD(kMainThreadContext) { initializeDisplays(); }));
// Inform native graphics APIs whether the present timestamp is supported:
const bool presentFenceReliable =
!getHwComposer().hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE);
mStartPropertySetThread = getFactory().createStartPropertySetThread(presentFenceReliable);
}
在init()
方法中,将会创建RenderEngine、HWComposer、加载默认物理屏等操作,并和CompositionEngine完成关联。
5.1、初始化RenderEngine
RenderEngine是渲染引擎的抽象包装接口。在SurfaceFlinger中创建RenderEngine实例,主要是用于GPU合成。当HWC合成时,会在应用进程内完成绘制操作,并直接将图形缓冲数据送给HWC进行合成,但如果是GPU方式合成,会通过RenderEngine再执行一次渲染操作,将多个图层的数据重新绘制到一个图形缓冲区后送给HWC。
创建RenderEngine时,以构造器的方式,通过RenderEngineCreationArgs
来进行创建:
cpp 代码解读复制代码// frameworks/native/libs/renderengine/RenderEngine.cpp
std::unique_ptr RenderEngine::create(const RenderEngineCreationArgs& args) {
switch (args.renderEngineType) {
case RenderEngineType::THREADED:
......
case RenderEngineType::SKIA_GL:
......
case RenderEngineType::SKIA_VK:
......
case RenderEngineType::SKIA_GL_THREADED: {
// Skia 异步渲染实现,即创建一个新的线程执行渲染操作
ALOGD("Threaded RenderEngine with SkiaGL Backend");
return renderengine::threaded::RenderEngineThreaded::create(
[args]() {
return android::renderengine::skia::SkiaGLRenderEngine::create(args);
},
args.renderEngineType);
}
case RenderEngineType::SKIA_VK_THREADED:
......
case RenderEngineType::GLES:
default:
ALOGD("RenderEngine with GLES Backend");
return renderengine::gl::GLESRenderEngine::create(args);
}
}
Android中提供了多种渲染引擎实现:
cpp 代码解读复制代码// frameworks/native/libs/renderengine/include/renderengine/RenderEngine.h
enum class RenderEngineType {
GLES = 1, // OpenGLES 渲染
THREADED = 2, // OpenGLES异步渲染
SKIA_GL = 3, // Skia 渲染
SKIA_GL_THREADED = 4, // Skia异步渲染
SKIA_VK = 5, // Valkan渲染
SKIA_VK_THREADED = 6, // Valkan异步渲染
};
Android14及之前版本中默认使用Skia异步渲染的实现方式。异步指创建一个新的线程来执行渲染操作。这里主要看下创建流程,SkiaGLRenderEngine构造方法如下:
cpp 代码解读复制代码// frameworks/native/libs/renderengine/skia/SkiaGLRenderEngine.cpp
std::unique_ptr SkiaGLRenderEngine::create(
const RenderEngineCreationArgs& args) {
// initialize EGL for the default display
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (!eglInitialize(display, nullptr, nullptr)) {
}
const auto eglVersion = eglQueryString(display, EGL_VERSION);
const auto eglExtensions = eglQueryString(display, EGL_EXTENSIONS);
auto& extensions = gl::GLExtensions::getInstance();
extensions.initWithEGLStrings(eglVersion, eglExtensions);
// The code assumes that ES2 or later is available if this extension is
// supported.
EGLConfig config = EGL_NO_CONFIG_KHR;
if (!extensions.hasNoConfigContext()) {
config = chooseEglConfig(display, args.pixelFormat, /*logConfig*/ true);
}
EGLContext protectedContext = EGL_NO_CONTEXT;
const std::optional priority = createContextPriority(args);
if (args.enableProtectedContext && extensions.hasProtectedContent()) {
protectedContext =
createEglContext(display, config, nullptr, priority, Protection::PROTECTED);
}
EGLContext ctxt =
createEglContext(display, config, protectedContext, priority, Protection::UNPROTECTED);
EGLSurface placeholder = EGL_NO_SURFACE;
if (!extensions.hasSurfacelessContext()) {
placeholder = createPlaceholderEglPbufferSurface(display, config, args.pixelFormat,
Protection::UNPROTECTED);
LOG_ALWAYS_FATAL_IF(placeholder == EGL_NO_SURFACE, "can't create placeholder pbuffer");
}
EGLBoolean success = eglMakeCurrent(display, placeholder, placeholder, ctxt);
LOG_ALWAYS_FATAL_IF(!success, "can't make placeholder pbuffer current");
extensions.initWithGLStrings(glGetString(GL_VENDOR), glGetString(GL_RENDERER),
glGetString(GL_VERSION), glGetString(GL_EXTENSIONS));
EGLSurface protectedPlaceholder = EGL_NO_SURFACE;
if (protectedContext != EGL_NO_CONTEXT && !extensions.hasSurfacelessContext()) {
protectedPlaceholder = createPlaceholderEglPbufferSurface(display, config, args.pixelFormat,
Protection::PROTECTED);
}
// initialize the renderer while GL is current
std::unique_ptr engine(new SkiaGLRenderEngine(args, display, ctxt,
placeholder, protectedContext,
protectedPlaceholder));
engine->ensureGrContextsCreated();
return engine;
}
SkiaGLRenderEngine::SkiaGLRenderEngine(const RenderEngineCreationArgs& args, EGLDisplay display,
EGLContext ctxt, EGLSurface placeholder,
EGLContext protectedContext, EGLSurface protectedPlaceholder)
: SkiaRenderEngine(args.renderEngineType,
static_cast(args.pixelFormat),
args.useColorManagement, args.supportsBackgroundBlur),
mEGLDisplay(display),
mEGLContext(ctxt),
mPlaceholderSurface(placeholder),
mProtectedEGLContext(protectedContext),
mProtectedPlaceholderSurface(protectedPlaceholder) { }
这里通过各种EGL API,完成RenderEngine的创建。
5.2、初始化HWComposer组件
HWComposer是硬件合成器(HWC)HAL的抽象包装接口。HWC负责执行一部分合成工作,SF会把图形缓冲数据先交给HWC,让其进行标记、合成,然后SurfaceFlinger再根据HWC返回的标记结果决定是否让GPU进行合成。
HWC HAL有两种实现方式:
- HIDL 接口:以HIDL方式实现的HWC HAL;
- AIDL接口:以AIDL方式实现的HWC HAL;
从Android T开始,AOSP推荐使用AIDL 的方式实现HWC HAL,后续会逐渐废弃HIDL接口。
详细可参考AOSP官方文档:source.android.com/docs/core/g…
在init()
方法中,在创建HWComposer实例时,会和对应的HWC HAL 接口连接,用于SurfaceFlinger和HWC间的IPC通信:
cpp 代码解读复制代码 // frameworks/native/services/SurfaceFlinger/SurfaceFlinger.cpp
// 创建HWComposer
mCompositionEngine->setHwComposer(getFactory().createHWComposer(mHwcServiceName));
// 注册HWComposer Callback
mCompositionEngine->getHwComposer().setCallback(*this);
下面分别来看创建HWCompower过程和注册HWCompower Callback过程。
5.2.1、创建HWCompower实例
HWComposer实例也是在DefaultFactory中通过DefaultFactory::createHWComposer(std::string& name)
创建:
cpp 代码解读复制代码// frameworks/native/services/SurfaceFlinger/SurfaceFlinger.cpp
std::unique_ptr DefaultFactory::createHWComposer(const std::string& serviceName) {
return std::make_unique(serviceName);
}
之后将执行HWComposer构造方法:
cpp 代码解读复制代码// frameworks/native/services/SurfaceFlinger/DisplayHardware/HWComposer.cpp
HWComposer::HWComposer(std::unique_ptr composer)
: mComposer(std::move(composer)),
// 最大虚拟屏尺寸
mMaxVirtualDisplayDimension(static_cast<size_t>(sysprop::max_virtual_display_dimension(0))),
mUpdateDeviceProductInfoOnHotplugReconnect(
sysprop::update_device_product_info_on_hotplug_reconnect(false)) {}
HWComposer::HWComposer(const std::string& composerServiceName)
// 创建Hwc2::Composer
: HWComposer(Hwc2::Composer::create(composerServiceName)) {}
在HWComposer构造方法中,又会创建Hwc2::Composer对象:
cpp 代码解读复制代码// frameworks/native/services/SurfaceFlinger/DisplayHardware/ComposerHal.cpp
std::unique_ptr Composer::create(const std::string& serviceName) {
if (AidlComposer::isDeclared(serviceName)) {
return std::make_unique(serviceName);
}
return std::make_unique(serviceName);
}
AidlComposer和HidlComposer分别是HWC HAL的AIDL实现和HIDL实现的包装类。AidlComposer::AidlComposer()
方法如下:
cpp 代码解读复制代码// frameworks/native/services/SurfaceFlinger/DisplayHardware/AidlComposerHal.cpp
AidlComposer::AidlComposer(const std::string& serviceName) {
// 获取HAL层 Hardware Composer service实例
mAidlComposer = AidlIComposer::fromBinder(
ndk::SpAIBinder(AServiceManager_waitForService(instance(serviceName).c_str())));
......
// 获取AidlComposerClient对象
if (!mAidlComposer->createClient(&mAidlComposerClient).isOk()) {
return;
}
// 添加默认ComposerClientReader,用于指定是否支持多线程合成
addReader(translate(kSingleReaderKey));
}
以上方法中,获得了AidlIComposer对象和AidlComposerClient对象,它们将用于之后跟HAL层的交互。
创建完成HWComposer后,将HWC实例传递给CompositionEngine:
cpp 代码解读复制代码// frameworks/native/services/SurfaceFlinger/CompositionEngine/src/CompositionEngine.cpp
void CompositionEngine::setHwComposer(std::unique_ptr hwComposer) {
mHwComposer = std::move(hwComposer);
}
5.2.2、注册HWC回调
完成HWComposer对象创建后,会设置一个HWC2::ComposerCallback类型Callback,用于接收来自硬件HWC相关事件,如热插拔、VSYNC等事件,都是通过它向SurfaceFlinger传递:
cpp 代码解读复制代码// frameworks/native/services/SurfaceFlinger/DisplayHardware/HWC2.h
struct ComposerCallback {
// 发生热插拔事件时回调
virtual void onComposerHalHotplug(hal::HWDisplayId, hal::Connection) = 0;
// 发生刷新率变化时回调
virtual void onComposerHalRefresh(hal::HWDisplayId) = 0;
// 发生硬件VSYNC信号时回调
virtual void onComposerHalVSYNC(hal::HWDisplayId, nsecs_t timestamp,
std::optional) = 0;
// 硬件VSYNC周期变化时回调
virtual void onComposerHalVSYNCPeriodTimingChanged(hal::HWDisplayId,
const hal::VSYNCPeriodChangeTimeline&) = 0;
virtual void onComposerHalSeamlessPossible(hal::HWDisplayId) = 0;
// 进入IDLE状态时回调
virtual void onComposerHalVSYNCIdle(hal::HWDisplayId) = 0;
virtual void onRefreshRateChangedDebug(const RefreshRateChangedDebugData&) = 0;
protected:
~ComposerCallback() = default;
};
这个接口中的方法一般运行在hwbinder线程内,不过当第一次注册该接口时,会主动触发一次热插拔事件,以便用于默认屏的加载。
注册接口方法如下:
cpp 代码解读复制代码// frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp
void HWComposer::setCallback(HWC2::ComposerCallback& callback) {
// 加载屏幕相关配置
loadCapabilities();
loadLayerMetadataSupport();
loadOverlayProperties();
loadHdrConversionCapabilities();
......
mRegisteredCallback = true;
// 向AidlComposer发起注册
mComposer->registerCallback(callback);
}
// frameworks/native/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
void AidlComposer::registerCallback(HWC2::ComposerCallback& callback) {
......
// 向HWC HAL注册Callback
mAidlComposerCallback = ndk::SharedRefBase::make(callback);
const auto status = mAidlComposerClient->registerCallback(mAidlComposerCallback);
......
}
5.3、加载默认屏
在HWC2::ComposerCallback完成注册后,会主动触发一次热插拔事件,SurfaceFlinger中将利用这次热插拔事件来完成默认屏的加载。
热插拔事件通过ComposerCallback::onComposerHalHotplug()
方法通知到SurfaceFlinger类中,SF作为ComposerCallback
的子类,实现了该方法:
cpp 代码解读复制代码// frameworks/native/services/SurfaceFlinger/SurfaceFlinger.cpp
void SurfaceFlinger::onComposerHalHotplug(hal::HWDisplayId hwcDisplayId,
hal::Connection connection) {
{
std::lock_guard lock(mHotplugMutex) ;
// 将hotplug事件保存在mPendingHotplugEvents中
mPendingHotplugEvents.push_back(HotplugEvent{hwcDisplayId, connection});
}
......
}
这里会将传递的参数封装到HotplugEvent中,然后放在mPendingHotplugEvents列表中。在接下来的configureLocked()
方法中,将从mPendingHotplugEvents中取出事件,并进行默认屏幕的加载:
cpp 代码解读复制代码// frameworks/native/services/SurfaceFlinger/SurfaceFlinger.cpp
bool SurfaceFlinger::configureLocked() {
std::vector events;
{
std::lock_guard lock(mHotplugMutex) ;
events = std::move(mPendingHotplugEvents);
}
// 将HotplugEvent传递给HWComposer对象
for (const auto [hwcDisplayId, connection] : events) {
// 加载默认屏硬件参数
if (auto info = getHwComposer().onHotplug(hwcDisplayId, connection)) {
const auto displayId = info->id;
const bool connected = connection == hal::Connection::CONNECTED;
}
}
return !events.empty();
}
通过以上方法,会从HWC HAL中完成屏幕硬件参数的加载,之后通过processDisplayAdded()
方法完成默认屏幕的创建。
关于屏幕加载流程单独进行分析,见《SurfaceFlinger02-默认屏加载过程 》。
5.4、初始化Scheduler组件
Scheduler作为SurfaceFlinger中的调度器,用于进行消息事件轮询、VSYNC信号的接收,并在接收到VSYNC后触发事务提交、合成操作。
在初始化Scheduler过程中,会对VSYNC偏移配置、VSYNC-app、VSYNC-sf等进行初始化,这部分流程细节,在VSYNC模型相关文章中进行分析。
六、注册Binder服务
完成初始化后,在main()
函数的最后,对SurfaceFlinger进程的Binder服务在Servicemanager中进行了注册:
cpp 代码解读复制代码// frameworks/native/services/SurfaceFlinger/main_SurfaceFlinger.cpp
int main(int, char**) {
......
// 将SF注册到ServiceManager中
sp sm(defaultServiceManager()) ;
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
// 创建SurfaceComposerAIDL,并发布到ServiceManager中
sp composerAIDL = new SurfaceComposerAIDL(flinger);
sm->addService(String16("SurfaceFlingerAIDL"), composerAIDL, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
......
return 0;
}
注册后,其他进程就可以和SurfaceFlinger进行IPC通信。在system_server/应用进程中,更多地通过SurfaceComoserClient和SurfaceFlinger进行通信,其内部就是通过以上两个服务调用,将数据在两进程间进行传递。
SurfaceFlinger进程跨进程交互细节,见《SurfaceFlinger02-surfaceflinger跨进程交互 》。
以上就是surfaceflinger进程的一个整体概述和启动过程介绍,在启动过程中,依次对CompostionEngine、HWComposer组件、屏幕加载、等Scheduler组件进行了初始化,并完成IPC服务的注册。
整个启动过程关键动作时序图如下:
评论记录:
回复评论: