首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

SurfaceFlinger01-SurfaceFlinger概述及启动过程

  • 25-04-23 10:20
  • 2360
  • 14189
juejin.cn

前言

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通信——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部分,类图表示如下:

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

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()函数中,主要执行了以下操作:

  1. 创建SurfaceFlinger类实例;
  2. SurfaceFlinger::init()中进行初始化操作;
  3. 创建SurfaceComposerAIDL,并注册到ServiceManager中;
  4. 启动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服务的注册。

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

注:本文转载自juejin.cn的Android采码蜂的文章"https://juejin.cn/post/7453731782749454372"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

140
Android
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top