SurfaceFlinger01-SurfaceFlinger概述及启动过程

2,320 阅读15分钟

前言

surfaceflinger作为Android系统一个重要进程,是Android图形显示系统中很核心的一部分组件,负责管理所有在屏幕上显示的内容。

在整个图形显示架构中,surfaceflinger起着承上启下的作用。作为一个IPC服务,所有应用需要显示的UI都会给到surfaceflinger,经过surfaceflinger处理后交给底层硬件HWC完成合成与显示。

同时,surfaceflinger进程作为硬件HWC唯一的“客户端”,跟HWC进行数据的交互,实现软件侧屏幕的管理。比如物理屏的加载、屏幕参数的获取、虚拟屏管理、VSYNC信号调度、色彩管理等,都离不开surfaceflinger。

流程图.jpg

从本篇文章开始,将会对surfaceflinger进程涉及业务流程和原理进行系统地分析。本篇文章中先对surfaceflinger进程进行基本的介绍,以及对该进程启动流程进行分析。

一、核心类介绍

在这篇文章中,我们对surfaceflinger进程的核心类从两方面进行说明:

  • 跨进程通信(IPC)相关类组件;
  • 按功能划分的类组件。

1.1、IPC相关类

surfaceflinger即作为一个独立进程,也是进行IPC的系统服务。surfaceflinger中通过两个接口来实现IPC通信——ISurfaceComposergui::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部分,类图表示如下:

image.png

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的启动参数:

// 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/<name>的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中,核心逻辑如下:

// frameworks/native/services/SurfaceFlinger/main_SurfaceFlinger.cpp

int main(int, char**) {
    ......
    // 创建SurfaceFlinger实例
    sp<SurfaceFlinger> flinger = SurfaceFlinger::createSurfaceFlinger();

    // 执行初始化操作
    flinger->init();

    // 将SF注册到ServiceManager中
    sp<IServiceManager> sm(defaultServiceManager());
    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
                   IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);

    // 创建SurfaceComposerAIDL,并注册到ServiceManager中
    sp<SurfaceComposerAIDL> 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()函数中,主要执行了以下操作:

  1. 创建SurfaceFlinger类实例;
  2. SurfaceFlinger::init()中进行初始化操作;
  3. 创建SurfaceComposerAIDL,并注册到ServiceManager中;
  4. 启动SurfaceFlinger主线程。

四、SurfaceFlinger()构造方法

main()函数执行后,会通过SurfaceFlinger::createSurfaceFlinger()创建SurfaceFlinger实例,并触发其构造方法的执行:

// frameworks/native/services/SurfaceFlinger/SurfaceFlingerFactory.cpp

namespace android::SurfaceFlinger {

sp<SurfaceFlinger> createSurfaceFlinger() {
    static DefaultFactory factory;

    return sp<SurfaceFlinger>::make(factory);
}

} // namespace android::SurfaceFlinger

SurfaceFlinger类构造方法如下:

// frameworks/native/services/SurfaceFlinger/SurfaceFlinger.cpp

SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
      : mFactory(factory),        // SurfaceFlingerFactory对象
        mPid(getpid()),           // 获得sf进程id
        mTimeStats(std::make_shared<impl::TimeStats>()), // 时间戳相关统计类
        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<Hwc2::impl::PowerAdvisor>(*this)),
        // 窗口信息监听
        mWindowInfosListenerInvoker(sp<WindowInfosListenerInvoker>::make(*this)) {
}


SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization) {
    ALOGI("SurfaceFlinger is starting");
    // 各功能属性初始化,此处略去
    ......
}

在以上两个构造方法中,会进行部分类和变量的初始化、以及一些属性的读取工作,其中包括创建CompositionEngine对象。

4.1、创建CompositionEngine实例

CompositionEngine负责所有屏幕上所有图层的初步合成相关操作,SurfaceFlinger中完成Layer属性设置后,将输出传递给CompositionEngine,经过CompositionEngine的处理输出OutputLayer,并最终送给HWC进行合成。它通过创建器进行创建:

// frameworks/native/services/SurfaceFlinger/SurfaceFlingerDefaultFactory.cpp
std::unique_ptr<compositionengine::CompositionEngine> DefaultFactory::createCompositionEngine() {
    return compositionengine::impl::createCompositionEngine();
}

// frameworks/native/services/SurfaceFlinger/CompositionEngine/src/CompositionEngine.cpp
std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() {
    return std::make_unique<CompositionEngine>();
}

当SurfaceFlinger构造方法执行完毕,SurfaceFlinger对象创建完成,接下来执行SurfaceFlinger::init()方法,进行初始化相关操作。

五、SurfaceFlinger::init()初始化

SurfaceFlinger::init()方法如下:

// 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来进行创建:

// frameworks/native/libs/renderengine/RenderEngine.cpp

std::unique_ptr<RenderEngine> 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中提供了多种渲染引擎实现:

// 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构造方法如下:

// frameworks/native/libs/renderengine/skia/SkiaGLRenderEngine.cpp

std::unique_ptr<SkiaGLRenderEngine> 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<RenderEngine::ContextPriority> 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<SkiaGLRenderEngine> 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<PixelFormat>(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通信:

    // 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)创建:

// frameworks/native/services/SurfaceFlinger/SurfaceFlinger.cpp

std::unique_ptr<HWComposer> DefaultFactory::createHWComposer(const std::string& serviceName) {
    return std::make_unique<android::impl::HWComposer>(serviceName);
}

之后将执行HWComposer构造方法:

// frameworks/native/services/SurfaceFlinger/DisplayHardware/HWComposer.cpp

HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> 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对象:

// frameworks/native/services/SurfaceFlinger/DisplayHardware/ComposerHal.cpp

std::unique_ptr<Composer> Composer::create(const std::string& serviceName) {
    if (AidlComposer::isDeclared(serviceName)) {
        return std::make_unique<AidlComposer>(serviceName);
    }

    return std::make_unique<HidlComposer>(serviceName);
}

AidlComposer和HidlComposer分别是HWC HAL的AIDL实现和HIDL实现的包装类。AidlComposer::AidlComposer()方法如下:

// 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<Display>(kSingleReaderKey));
}

以上方法中,获得了AidlIComposer对象和AidlComposerClient对象,它们将用于之后跟HAL层的交互。

创建完成HWComposer后,将HWC实例传递给CompositionEngine:

// frameworks/native/services/SurfaceFlinger/CompositionEngine/src/CompositionEngine.cpp

void CompositionEngine::setHwComposer(std::unique_ptr<HWComposer> hwComposer) {
    mHwComposer = std::move(hwComposer);
}

5.2.2、注册HWC回调

完成HWComposer对象创建后,会设置一个HWC2::ComposerCallback类型Callback,用于接收来自硬件HWC相关事件,如热插拔、VSYNC等事件,都是通过它向SurfaceFlinger传递:

// 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<hal::VSYNCPeriodNanos>) = 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线程内,不过当第一次注册该接口时,会主动触发一次热插拔事件,以便用于默认屏的加载。

注册接口方法如下:

// 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<AidlIComposerCallbackWrapper>(callback);
    const auto status = mAidlComposerClient->registerCallback(mAidlComposerCallback);
    ......
}

5.3、加载默认屏

在HWC2::ComposerCallback完成注册后,会主动触发一次热插拔事件,SurfaceFlinger中将利用这次热插拔事件来完成默认屏的加载。

热插拔事件通过ComposerCallback::onComposerHalHotplug()方法通知到SurfaceFlinger类中,SF作为ComposerCallback的子类,实现了该方法:

// frameworks/native/services/SurfaceFlinger/SurfaceFlinger.cpp

void SurfaceFlinger::onComposerHalHotplug(hal::HWDisplayId hwcDisplayId,
                                          hal::Connection connection) {
    {
        std::lock_guard<std::mutex> lock(mHotplugMutex);
        // 将hotplug事件保存在mPendingHotplugEvents中
        mPendingHotplugEvents.push_back(HotplugEvent{hwcDisplayId, connection});
    }
    ......
}

这里会将传递的参数封装到HotplugEvent中,然后放在mPendingHotplugEvents列表中。在接下来的configureLocked()方法中,将从mPendingHotplugEvents中取出事件,并进行默认屏幕的加载:

// frameworks/native/services/SurfaceFlinger/SurfaceFlinger.cpp

bool SurfaceFlinger::configureLocked() {
    std::vector<HotplugEvent> events;
    {
        std::lock_guard<std::mutex> 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中进行了注册:

// frameworks/native/services/SurfaceFlinger/main_SurfaceFlinger.cpp

int main(int, char**) {
    ......
    // 将SF注册到ServiceManager中
    sp<IServiceManager> sm(defaultServiceManager());
    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
                   IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);

    // 创建SurfaceComposerAIDL,并发布到ServiceManager中
    sp<SurfaceComposerAIDL> 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服务的注册。

整个启动过程关键动作时序图如下: