Android Display性能问题教战手册5-SF/HWC内存使用问题

系列文章请扫关注公众号!

Android Display Graphics系列文章-汇总

本文主要包括部分:

1、dma-buf问题初步判定方法

2、SF/HWC dma-buf debug

3、SF/HWC与对比机内存使用对比问题

本文主要分析SurfaceFlinger、Hardware composer内存使用问题,及dma-buf的debug技巧。

Overview

dma-buf是一个多进程间的buffer共享的机制, 本节主要介绍针对display部分相关的dma-buf如何做初步的分析

在Android中Buffer需要在多个进程间传递使用的Module有很多, 但用量比较明显,无法回避的主要都在MM相关module中, 其中显示Graphic图形使用的Buffer是最为频繁的, Buffer会在APP sytemserver / Surface GPU SurfaceFlinger hwcomposer kernel display DRM driver 等module间进行传递使用, 所以Graphic的相关Module是最容易被Call到需要来厘清dma-buf使用情况的

1、dma-buf问题初步判定方法

怎样判定当前的内存问题是dma-buf相关的问题呢? 

在meminfo中的 EGL mtrack  部分就是代表 dma buf的用量, 如果这部分用量异常则需要厘清dma buf的使用情况

dma-buf使用异常会与哪些问题相关?

1,内存分配不出引发的异常 各种exception,   图像卡死等现象,伴有低内存的, 经过内存owner分析以后无其他内存异常的

2,   内存占用异常  主要指在一些预期不会使用很多内存的场景, 出现较大的dma-buf占用

3,   buffer相关fd异常  目前对于fd主要会报异常的就是fdsan, 或者有些exception发生前突然出现fd error等

发生异常时如何进一步查看dma-buf的使用信息呢?

1, 有发生exception,  且能获取到db的情况

       Hang : SYS_DMA_HEAP_RAW

       SWT/Other: DMABUF_HEAP_INFO / ION_DMABUF_SYSTEM_INFO

       OOM/KE/JE:SYS_KERNEL_LOG(search keyword:  "dma_heap: mtk_debug")

2,    没有发生exception或没有db的情况:

        此种情况一般基本要求是device保有内存使用异常的现场未恢复,  进阶要求是有找到一些复现操作路径,并且可以观察到EGL mtrack部分随着使用在持续增长且不会自动减少

制作adb脚本去循环cat meminfo,  并持续比较和观察EGL mtrack部分,  可以设定增长到一定Size即主动去kill -11  [SurfaceFlinger Pid]  来产生NE,   以固定到问题现场并提取到db

 如果不方便触发和提取到db,可以通过以下cmd去cat到当前一些dmabuf的info出来     

                adb shell cat /proc/dma_heap/all_heaps all_dma_heaps.txt        此文件为MTK平台独有,在MTK平台debug时推荐优先查看

                adb shell /system/bin/dma_buf_dump > dmabuf_dump.txt         此文件会按进程分开列出每个进程的dma buf持有情况

                adb shell dmabuf_dump -a > dmabuf_dump_a.txt       该文件为Android默认节点, 其列表形式比较容易查看Fd ref/ Map ref count持有情况

                adb shell dmabuf_dump -b > dmabuf_dump_b.txt      该文件为Android默认节点, 主要时按per buffer进行统计汇总

2、SF/HWC dma-buf debug

SF/HWC作为图形系统的传递中枢, Buffer的使用异常通常都会有surfaceflinger和composer的中间持有, 这也是此类问题为什么会常常需要SF/HWC owner参与梳理的原因

SF/HWC的梳理step by step:  

1,    首先通过all_dma_heaps可以观察整体状况

  此处dump首先会列出dma buffer的主要user,  我们主要关注surfaceflinger和composer的使用量是否有异常

PID     PSS(KB)   RSS(KB)

 3236    25272     47712

 2935    103267    127272

1443    37533     108432

1225    4         4

984     102401    371176

906     232617    330476

893     48        48

-----EGL memtrack data end

--sum: userspace_pss:501143 KB rss:985120 KB

--sum: kernel rss: 3136 KB

pid table:

pid:3236   name:droid.launcher3

pid:2935   name:ndroid.systemui

pid:1443   name:system_server

pid:1225   name:binder:1225_2

pid:984    name:surfaceflinger

pid:906    name:composer@3.2-se

pid:893    name:binder:893_2

 同步观察dump中列出的top 10用量的buffer,  注意这里把 buffer name 都有打印出来,   因为Buffer最终通过BufferQueue分配使用,所以其使用进程肯定会经过surfaceflinger和composer, 此处可以进一步分辨是否有哪个名字的buffer使用量过多, 需要进一步去分析关注

dmabuf alloc total:(361/504280KB), top 10 user:
debug name                          sum of size(KB)      count of heap            
G:ColorFade#2(BLAST Consumer)2      79772                37                       
G:VRI[NotificationShade]#13(BLA     79772                13                       
G:VRI[GalleryActivity]#4(BLAST      77840                37                       
G:SurfaceView[com.android.galle     73500                37                       
FramebufferSurface                  63552                37                       
G:screenshot                        44880                12                       
G:ColorFade#3(BLAST Consumer)3      31444                35                       
G:VRI[]#14(BLAST Consumer)14        29092                10                       
G:Wallpaper#0(BLAST Consumer)0      11316                9                        
G:VRI[NavigationBar0]#1(BLAST C     4368                 64 

2, 去具体查看有嫌疑的Buffer的使用情况

3, 进一步debug ref count不归 0 的原因

        ( i )   SF/APP

      (ii)HWC 

      (iii)kernel

3、SF/HWC与对比机内存使用对比问题

SF部分主要差异就是在Buffer数量上,主要分为两点:.......

Composer进程的差异:........

=========================================================================

============================完整文章见公众号===============================

=========================================================================

<think>我们通过分析`dumpsys SurfaceFlinger`的输出内容来判断显示设备是使用GPU还是HWC合成。关键点如下: 1. **查找显示设备信息**:在输出中搜索`Display device`部分,特别是当前活动的显示设备(如内置屏幕)。 2. **查看合成方式**:在显示设备信息中,会明确标注合成方式(Composition)。常见的合成方式有: - `HWC`:表示硬件合成(Hardware Composer) - `GPU`:表示由GPU合成 3. **具体命令与输出解析**: 使用以下命令可以直接查看显示设备的合成方式: ```bash adb shell dumpsys SurfaceFlinger | grep -A 5 "Display device" ``` 或者更精确地针对内置屏幕(通常为第一个显示设备): ```bash adpusys SurfaceFlinger | grep -A 10 "Built-in Screen" ``` **示例输出**: ``` Display device: Built-in Screen ... Composition: GPU ... ``` 这里的`Composition: GPU`表示当前合成方式为GPU合成。如果显示为`Composition: HWC`,则表示硬件合成。 4. **另一种方法**:查看HWC状态部分。在输出中搜索`HWC`,可以找到类似以下信息: ``` HWC layers: type | source crop | frame | name ----------+-----------------------------------+---------------------------+------ HWC | [ 0.0, 0.0, 1080.0, 1920.0] | [ 0, 0, 1080, 1920] | com.example.app/com.example.app.MainActivity#0 ``` 这里列出的图层如果标记为`HWC`,则表示该图层由硬件合成器合成;如果标记为`GLES`,则表示由GPU合成。 5. **整体合成方式判断**:如果所有图层都能由HWC处理,则整个显示设备会使用HWC合成;否则,部分图层会回退到GPU合成(即整个设备可能标记为GPU合成)。 **注意**:一个显示设备可能同时包含HWC合成的图层和GPU合成的图层。但最终设备的合成方式(在显示设备信息中)会表明是HWC还是GPU。如果设备合成方式为GPU,则意味着至少有一个图层无法由HWC处理,导致整个合成回退到GPU。 **总结步骤**: 1. 运行命令:`adb shell dumpsys SurfaceFlinger > surface.txt` 2. 在输出文件中查找`Display device`部分,查看`Composition`字段的值。 3. 或者查找`HWC layers`部分,查看各个图层的合成方式。 **示例代码分析**: 在Android源码中,合成方式的决定逻辑位于`HWComposer.cpp`(见引用[1])。当硬件合成器无法处理某个图层时(例如超出硬件层数限制或特殊效果),该图层会被标记为`GLES`,并可能导致整个设备回退到GPU合成。 **相关问题**: 1. 如何通过`dumpsys SurfaceFlinger`分析Android系统中的图层合成性能? 2. Android中SurfaceFlinger支持哪些图层合成方式,它们的优缺点是什么? 3. 在什么情况下SurfaceFlinger会选择使用GPU而不是硬件合成器? 4. 如何在Android源码中查看HWComposer的实现逻辑? 5. 图形缓冲区的分配和释放过程在Android中是如何管理的?</think>在 Android 系统中,通过 `dumpsys SurfaceFlinger` 命令可以准确判断显示设备是使用 GPU 还是 HWC 合成。以下是具体判断方法和步骤: ### 🔍 判断方法 1. **查找显示设备信息** 在输出中搜索 `Display device` 部分,重点关注 `Composition` 字段: ```bash adb shell dumpsys SurfaceFlinger | grep -A 5 "Display device" ``` - 若显示 `Composition: GPU` → GPU 合成 - 若显示 `Composition: HWC` → 硬件合成器合成 2. **分析图层合成方式** 检查各图层的合成类型: ```bash adb shell dumpsys SurfaceFlinger | grep "HWC layer" -A 3 ``` - `HWC` 标记表示硬件合成 - `GLES` 标记表示 GPU 合成(OpenGL ES) 3. **查看 HWC 版本** HWC 版本信息可确认硬件合成能力: ```bash adb shell dumpsys SurfaceFlinger | grep "HWC version" ``` 输出类似:`HWC version: HWC2-XXX`(硬件合成器版本) ### 📊 典型输出示例 ```plaintext Display device: Built-in Screen Composition: GPU # ← 关键指标:GPU 合成 Layer count: 4 HWC version: HWC2-1.2 HWC layers: Layer 0: com.example.app Composition type: GLES # ← GPU 合成 Layer 1: StatusBar Composition type: HWC # ← 硬件合成 ``` ### ⚙️ 合成方式决策逻辑 SurfaceFlinger 按以下规则选择合成方式: 1. **优先尝试 HWC 合成** - 当图层数量 ≤ 硬件支持的层数(通常 4-8 层) - 图层无特殊效果(如旋转、透明度动画) - 输出格式匹配显示设备能力 2. **回退到 GPU 合成** 当: - 图层数量超过硬件限制 - 图层需要复杂变换(如 3D 旋转) - 混合模式超出 HWC 支持范围 - 缓冲区格式不受硬件支持(如 YUV 格式) > 💡 技术说明:决策逻辑实现在 `HWComposer.cpp` 的 `prepare()` 方法中,通过 `HWC2::Composition` 枚举值确定各图层的合成方式[^1]。 ### 📝 操作建议 1. 将完整输出保存到文件分析: ```bash adb shell dumpsys SurfaceFlinger > surface.txt ``` 2. 搜索关键词: `Display device`, `Composition:`, `HWC layers`, `GLES composition` ### 📚 相关问题 1. 如何通过 `dumpsys SurfaceFlinger` 分析 Android 系统中的图层合成性能? 2. AndroidHWC 和 GPU 合成在能效和延迟方面有何差异? 3. 开发者如何优化应用以避免合成回退到 GPU? 4. 多屏显示场景下 SurfaceFlinger 如何处理不同显示设备的合成? 5. Android 图形系统中的 Layer 生命周期如何管理? > 引用来源: > [^1]: `frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp` > [^2]: `adb shell dumpsys SurfaceFlinger` 输出重定向分析 > [^3]: SurfaceFlinger 显示合成服务架构文档
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值