GUI显示系统之SurfaceFlinger--- Gralloc与Framebuffer

本文详细介绍了Android GUI系统中的SurfaceFlinger,特别是Gralloc和Framebuffer的角色。Gralloc作为硬件抽象层,用于管理帧缓冲区,而Framebuffer是Linux内核提供的显示抽象层。文章讨论了Gralloc的加载过程、提供的接口,以及如何通过Gralloc和Framebuffer交互来实现图形缓冲区的分配和屏幕显示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


GUI显示系统之SurfaceFlinger其它部分完整章节:

http://blog.youkuaiyun.com/uiop78uiop78/article/details/8954508



第1章  GUI系统之SurfaceFlinger

在进入GUI系统的学习前,建议大家可以先阅读本书应用篇中的“OpenGLES”章节,并参阅OpenGL ES官方指南。因为Android的GUI系统是基于OpenGL/EGL来实现的,如果没有一定基础的话,分析源码时有可能会“事倍功半”。

1.1 Gralloc与Framebuffer

相信做过Linux开发的人对framebuffer不会太陌生,它是内核系统提供的一个与硬件无关的显示抽象层。之所以称之为buffer,是由于它也是系统存储空间的一部分,是一块包含屏幕显示信息的缓冲区。由此可见,在“一切都是文件”的Linux系统中,Framebuffer被看成了终端monitor的“化身”。它借助于文件系统向上层提供统一而方便的操作接口,从而让用户空间程序可以不用修改就能适应多种屏幕——无论这些屏幕是哪家厂商、什么型号,都由framebuffer内部来兼容。

在Android系统中,framebuffer提供的设备文件节点是/dev/graphics/fb*。因为理论上支持多个屏幕显示,所以fb按数字序号进行排列,即fb0、fb1等等。其中第一个fb0是主显示屏幕,必须存在。如下是某设备的fb设备截图:

 

图 11‑1 fb节点

 

根据前面章节学习过的知识,Android中各子系统通常不会直接基于Linux驱动来实现,而是由HAL层间接引用底层架构,在显示系统中也同样如此——它借助于HAL层来操作帧缓冲区,而完成这一中介任务的就是Gralloc,下面我们分几个方面来介绍。

<1>  Gralloc的加载

Gralloc对应的模块是由FramebufferNativeWindow(OpenGLES的本地窗口之一,后面小节有详细介绍)在构造时加载的,即:

hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);

这个hw_get_module函数我们在前面已经见过很多次了,它是上层加载HAL库的入口,这里传入的模块ID名为:

#define GRALLOC_HARDWARE_MODULE_ID  "gralloc"

按照hw_get_module的作法,它会在如下路径中查找与ID值匹配的库:

#define HAL_LIBRARY_PATH1 "/system/lib/hw"

#define HAL_LIBRARY_PATH2 "/vendor/lib/hw"

lib库名有如下几种形式:

    gralloc.[ro.hardware].so

    gralloc.[ro.product.board].so

    gralloc.[ro.board.platform].so

    gralloc.[ro.arch].so

或者当上述的系统属性组成的文件名都不存在时,就使用默认的:

    gralloc.default.so

最后这个库是Android原生态的实现,位置在hardware/libhardware/modules/gralloc/中,它由gralloc.cpp、framebuffer.cpp和mapper.cpp三个主要源文件编译生成。

 

<2>  Gralloc提供的接口

Gralloc对应的库被加载后,我们来看下它都提供了哪些接口方法。

由于Gralloc代表的是一个hw_module_t,这是HAL中统一定义的硬件模块描述体,所以和其它module所能提供的接口是完全一致的:

<think>好的,我需要帮助用户了解如何通过`adb shell dumpsys SurfaceFlinger --latency`命令获取延迟数据。首先,我应该回顾用户提供的引用内容,特别是引用[2][3],因为它们直接提到了这个命令的使用方法。 根据引用[2],用户需要先查询当前的SurfaceView,找到对应的窗口名,然后执行命令`adb shell dumpsys SurfaceFlinger --latency 窗口名`。引用[3][4]提到,这个命令生成的数据可以用来计算FPS评估流畅度,可能需要通过脚本处理原始数据。 接下来,我需要分步骤解释如何获取窗口名,执行命令,并处理数据。首先,用户可能需要使用`adb shell dumpsys SurfaceFlinger | grep + 包名`来找到正确的窗口名,如引用[1]所述。然后,执行延迟命令,并解释输出数据的含义,比如时间戳帧间隔。 此外,用户可能需要将数据保存到本地进行分析,使用脚本计算FPS。引用[4]提到有现有的shell脚本工具,可以推荐用户参考或使用这些工具进行二次开发。需要确保步骤清晰,包括命令示例注意事项,比如Android版本兼容性,如引用[4]提到的Android 14仍适用。 最后,生成相关问题,覆盖可能的后续疑问,如数据处理方法、不同Android版本的差异、其他性能分析工具等。确保引用正确,比如引用[3][4]关于脚本FPS计算的内容。</think>以下是通过`adb shell dumpsys SurfaceFlinger --latency`获取延迟数据的步骤说明: ### 一、获取窗口名 1. **执行命令**:首先通过包名查找对应的窗口标识符 ```bash adb shell dumpsys SurfaceFlinger | grep + 包名 ``` 例如:`adb shell dumpsys SurfaceFlinger | grep com.tencent.mm`(查询微信的窗口名)[^1] 2. **解析结果**:输出结果中会显示类似`SurfaceView[...]/xxx@包名`的字符串,需复制完整的`SurfaceView[...]`部分作为窗口名 ### 二、获取延迟数据 1. **执行延迟命令**:将上一步获取的窗口名填入参数 ```bash adb shell dumpsys SurfaceFlinger --latency "SurfaceView[...]/xxx@包名" ``` 2. **数据输出**:命令会输出三列时间戳数据,格式如下: $$ timestamp \quad timestamp \quad timestamp $$ - 第一列:应用提交帧的时间(纳秒) - 第二列:垂直同步信号(VSYNC)时间 - 第三列:帧完成渲染时间[^3] ### 三、数据保存分析 1. **重定向到文件**: ```bash adb shell dumpsys SurfaceFlinger --latency "窗口名" > latency_data.txt ``` 2. **计算FPS**:通过脚本解析时间差 ```bash # 示例计算每秒帧数 tail -n 100 latency_data.txt | awk '{if (NR>1 && $1>$prev) sum+=1; prev=$1} END {print sum/1}' ``` ### 四、注意事项 - **Android版本兼容性**:该命令在Android 14仍有效,但不同版本数据格式可能微调[^4] - **数据有效性**:建议连续执行5次命令后取稳定值 - **采样时长**:需保持屏幕处于被测应用界面至少10秒
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值