Android SurfaceFlinger——服务启动流程(二)

news2024/10/7 6:45:34

        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/surfaceflinger
    class core animation
    user system
    group graphics drmrpc readproc
    // 允许调整进程优先级
    capabilities SYS_NICE
    // 如果surfaceflinger服务重启,且zygote服务正在运行,则同时重启zygote服务
    onrestart restart --only-if-running zygote
    // 指定服务的任务性能配置为HighPerformance
    task_profiles HighPerformance
    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

         这里主要用于定义 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 的启动是一个复杂但有序的过程,涉及了从底层硬件初始化到高层服务注册的一系列步骤,确保系统能够高效、稳定地进行图形显示。

流程图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1849602.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue3中的常见组件通信(超详细版)

Vue3中的常见组件通信 概述 ​ 在vue3中常见的组件通信有props、mitt、v-model、 r e f s 、 refs、 refs、parent、provide、inject、pinia、slot等。不同的组件关系用不同的传递方式。常见的撘配形式如下表所示。 组件关系传递方式父传子1. props2. v-model3. $refs4. 默认…

[Django学习]前端+后端两种方式处理图片流数据

方式1&#xff1a;数据库存放图片地址,图片存放在Django项目文件中 1.首先&#xff0c;我们现在models.py文件中定义模型来存放该图片数据,前端传来的数据都会存放在Django项目文件里的images文件夹下 from django.db import modelsclass Image(models.Model):title models.C…

深度神经网络——什么是小样本学习?

引言 小样本学习是指使用极少量的训练数据来开发人工智能模型的各种算法和技术。小样本学习致力于让人工智能模型在接触相对较少的训练实例后识别和分类新数据。小样本训练与训练机器学习模型的传统方法形成鲜明对比&#xff0c;传统方法通常使用大量训练数据。小样本学习是 主…

aws的alb,多个域名绑定多个网站实践

例如首次创建的alb负载均衡只有www.xxx.com 需要添加 负载 test2.xxx.com aws的Route 53产品解析到负载均衡 www.xxx.com 添加CNAME&#xff0c;到负载均衡的dns字段axx test2.xxx.com 添加CNAME&#xff0c;到负载均衡的dns字段axx 主要介绍目标组和规则 创建alb就不介…

MacOS 中 Agent 图标删除

这个是战网没有完全卸载赶紧导致的 在访达中点击前往文件夹&#xff0c;输入&#xff1a; /Users/Shared将对应的目录删掉即可。会提示需要输入密码。

Java 从零开始写一个简单的图书管理系统

了解一下 先来了解要实现一个怎样的图书管理系统 从中可以看到有操作的 使用者 和 不同 的 功能 而不同的使用者有不同的 菜单 那要如何实现呢&#xff1f; 请继续看下去 如何实现 首先了解我们 需要什么 图书系统需要 书&#xff0c;放书的 书架 &#xff0c;用户 中有 管…

Nutch爬虫在大数据采集中的应用案例

引言 在当今信息爆炸的时代&#xff0c;大数据的价值日益凸显。网络作为信息的海洋&#xff0c;蕴藏着丰富的数据资源。Nutch&#xff0c;作为一个开源的Java编写的网络爬虫框架&#xff0c;以其高效的数据采集能力和良好的可扩展性&#xff0c;成为大数据采集的重要工具。本文…

系统烧写工具--MfgTool

系统烧写工具--MfgTool 1 介绍1.1 概述1.2 UUU 特性1.3 UUU 功能1.4 UUU 命令1.5 MFGTools 功能 2 MFGTools 目录结构及说明2.1 MFGTools 目录结构重要文件烧写自己系统 2.2 说明2.3 分析配置文件2.3.1 UiCfg.ini2.3.2 cfg.ini2.3.3 ucl2.xml 3 MfgTool 工作流程4 烧录流程4.1 …

mysql--安装跳过验证修改密码安全加固

安装mysql 配置mysql的yum源 [rootVM-0-14-rockylinux ~]# tee /etc/yum.repos.d/mysql.repo << EOF > [MYSQL] > namemysql > baseurlhttps://mirrors.tuna.tsinghua.edu.cn/mysql/yum/mysql-5.7-community-el7-x86_64 > gpgcheck0 > EOF yum安装mysq…

python项目(课设)——飞机大战小游戏项目源码(pygame)

主程序 import pygame from plane_sprites import * class PlaneGame: """ 游戏类 """ def __init__(self): print("游戏初始化") # 初始化字体模块 pygame.font.init() # 创建游戏…

eclipse中svn从分支合并到主干及冲突解决

1、将分支先commit&#xff0c;然后再update&#xff0c;然后再clean一下&#xff0c;将项目多余的target都清理掉。 2、将branches切换到trunk 3、工程上右键-》Team-》合并&#xff08;或Merge&#xff09; 4、默认选项&#xff0c;点击Next 5、有未提交的改动&#xff0c;…

兴顺物流管理系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;驾驶员管理&#xff0c;物流资讯管理&#xff0c;车辆管理&#xff0c;基础数据管理 员工账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;物流资讯管理&…

尚品汇-(三)

maven之packaging标签 &#xff08;1&#xff09;项目创建父模块 首先设置 下Maven Maven&#xff1a;仓库地址&#xff1a;这里是腾讯云仓库 作为父模块&#xff0c;src没用&#xff0c;干掉src 这里我们是Maven创建的项目&#xff0c;想要项目变成SpringBoot的项目&#xf…

Mybatis 系列全解(1)——全网免费最细最全,手把手教,学完就可做项目!

Mybatis 系列全解&#xff08;1&#xff09; 1. 第一个小程序2. CURD 增删改查3. 模糊查询4. 配置解析4.1 核心配置文件4.2 环境配置4.3 属性4.4 类型别名4.5 设置4.6 映射器 mappers 1. 第一个小程序 1&#xff09;创建一个数据库&#xff0c;一个表&#xff0c;填入一些数据…

uni app 树状结构数据展示

树状数据展示&#xff0c;可以点击item 将点击数据给父组件 &#xff0c;满足自己需求。不喜勿喷&#xff0c;很简单可以根据自己需求改哈&#xff0c;不要问&#xff0c;点赞收藏就好。其实可以和上一篇文章uni app 自定义 带popup弹窗的input组件-CSDN博客结合使用&#xff…

LabVIEW项目管理中如何平衡成本、时间和质量

在LabVIEW项目管理中&#xff0c;平衡成本、时间和质量是实现项目成功的关键。通过制定详细的项目计划、合理分配资源、严格控制进度、进行质量保证和灵活应对变化&#xff0c;项目管理者可以有效地协调这三者的关系&#xff0c;确保项目按时、按质、按预算完成。 1. 制定详细…

Reid系列论文学习——换装Reid

今天要学习的有关Reid的论文是2019年提出的一篇名为&#xff1a;Beyond Scalar Neuron: Adopting Vector-Neuron Capsules for Long-Term Person Re-Identification. 论文链接&#xff1a;https://opus.lib.uts.edu.au/bitstream/10453/137156/4/Binder1.pdf Code链接&#x…

搜索python包的说明

当我发现bug时&#xff0c;就怀疑是sns包的版本问题了&#xff08;原代码是原作者以前成功运行的代码&#xff09;&#xff0c;于是直接到网上搜&#xff0c;找到对应的说明文档 根据该示例代码进行改写&#xff1a; 达成目的。

Elasticsearch 数据提取 - 最适合这项工作的工具是什么?

作者&#xff1a;来自 Elastic Josh Asres 了解在 Elasticsearch 中为你的搜索用例提取数据的所有不同方式。 对于搜索用例&#xff0c;高效采集和处理来自各种来源的数据的能力至关重要。无论你处理的是 SQL 数据库、CRM 还是任何自定义数据源&#xff0c;选择正确的数据采集…

2024年全国青少信息素养大赛python编程复赛集训第八天编程题分享

整理资料解析答案非常不容易,感谢各位大佬给个点赞和分享吧,谢谢 今天题目较难:适合初中组 大家如果不想阅读前边的比赛内容介绍,可以直接跳过:拉到底部看集训题目 (一)比赛内容: 【小学组】 1.了解输入与输出的概念,掌握使用基本输入输出和简单运算 为主的标准函…