3. Android图形栈概览
好,咱们进入第三章。显示控制器这块,说实话是车载显示里最容易出坑的地方之一。很多工程师把GPU和DPU混为一谈,结果调试的时候发现画面撕裂、帧率不稳,最后查出来是硬件分工没搞清楚。今天我就把这块掰开揉碎了讲清楚。
3.1 GPU与DPU:它们到底谁管谁?
先问个问题:你的手机或者车机屏幕上,那些绚丽的动画、流畅的导航地图,是谁画出来的?很多人第一反应是GPU。没错,GPU负责渲染——把3D模型、纹理、着色器这些算成一张张完整的帧。但渲染完了呢?谁来把这张帧送到屏幕上?
这就是DPU的事。
我打个比方。GPU像个画家,他负责在画布上画出精美的画面。DPU像个装裱师,他负责把画裱好、挂到墙上,还要保证挂得正、不歪斜、按时换。画家可以画得很慢,但装裱师必须按时把画挂出去——这就是实时性的要求。
具体到车载场景,区别更明显:
| 维度 | GPU | DPU |
|---|---|---|
| 核心任务 | 图形渲染、计算 | 显示输出、合成、时序控制 |
| 处理对象 | 顶点、像素、纹理 | 帧缓冲区、图层、显示时序 |
| 实时性要求 | 中等(帧率达标即可) | 极高(逐行扫描不能断) |
| 典型问题 | 渲染延迟、掉帧 | 撕裂、闪屏、时序错乱 |
| 车载关注点 | 功耗、热管理 | 多屏同步、安全关键显示 |
关键认知:GPU负责“画什么”,DPU负责“怎么显示”。在车载架构里,DPU往往是独立硬件模块,甚至有自己的微控制器和专用内存。我见过不少方案把GPU和DPU集成在同一个SoC里,但它们的时钟域、电源域通常是分开的——这一点在做功耗管理时特别重要。
3.2 显示流水线(Display Pipeline)架构
好了,现在我们知道GPU和DPU各司其职。那它们之间怎么配合?这就引出了显示流水线的概念。
显示流水线,说白了就是数据从GPU渲染完成到最终显示在屏幕上的完整路径。我习惯把它分成四个阶段:
- 帧缓冲区(Framebuffer):GPU渲染完的帧,先存到这里。通常是DDR中的一块区域。
- 读取与解压:DPU从帧缓冲区读取数据。如果用了压缩(比如DSC、FBC),这里要解压。
- 图层处理:多个图层在这里进行缩放、旋转、色彩转换等操作。
- 合成与输出:所有图层混合成最终画面,按显示时序发送给屏幕。
这里我画了一张图,帮你把整个流程串起来:
我的经验:调试流水线时,我最先看的是帧缓冲区读取带宽。曾经有个项目,GPU渲染只用了40%的负载,但DPU读取帧缓冲区时频繁超时——后来发现是DDR带宽被其他模块抢占了。记住:流水线的瓶颈往往不在渲染,而在数据搬运。
3.3 图层混合与合成原理
现在进入最核心的部分——图层混合。车载显示里,图层可不是一个两个。导航地图、仪表指针、HUD信息、倒车影像、媒体播放……这些都得叠在一起显示。怎么叠?谁在前谁在后?透明度怎么处理?
这就是图层混合要解决的问题。
3.3.1 图层的基本属性
每个图层都有几个关键参数:
- Z序(Z-order):决定图层的前后遮挡关系。Z值越大越靠前。
- Alpha值:透明度。0为完全透明,255为完全不透明。
- 颜色格式:ARGB8888、RGB565、YUV420等。
- 裁剪区域:只显示图层的某一部分。
你想想看,如果倒车影像图层Z序比导航地图低,那影像就会被地图挡住——这显然不合理。所以车载系统里,Z序的分配是有严格规范的。
3.3.2 混合算法:Alpha Blending
混合的核心公式其实不复杂:
// 标准 Alpha Blending 公式
// 前景色 Foreground,背景色 Background,Alpha 值归一化到 [0, 1]
Output = Foreground * Alpha + Background * (1 - Alpha)
但实际硬件实现时,要考虑的东西就多了:
- 预乘Alpha(Premultiplied Alpha):有些DPU要求图层数据已经是预乘过的,否则混合结果会偏暗。
- 伽马校正:混合应该在线性空间进行,但显示数据通常是伽马编码的。不做校正的话,半透明边缘会出现暗边。
- 抖动(Dithering):当输出色深低于输入时,用抖动来减少色带。
我曾经踩过的坑:有个项目,HUD的图标边缘总是有一圈暗边。查了两天才发现,图标素材是预乘Alpha的,但DPU配置成了非预乘模式。结果就是Alpha=0.5的像素,混合后亮度只有正确值的一半。嗯,从那以后我每次配图层参数,第一件事就是确认Alpha模式。
3.3.3 硬件合成 vs 软件合成
车载系统里,图层合成有两种方式:
| 对比项 | 硬件合成(Hardware Composer) | 软件合成(GPU合成) |
|---|---|---|
| 实现位置 | DPU内部专用硬件 | GPU通过渲染管线完成 |
| 功耗 | 低(专用电路) | 高(需要GPU参与) |
| 延迟 | 低(几行扫描线延迟) | 高(至少一帧延迟) |
| 图层数量限制 | 通常4~8层 | 理论上无限制 |
| 灵活性 | 低(固定管线) | 高(可编程) |
| 车载推荐 | 仪表、HUD等安全关键显示 | 信息娱乐、地图等非安全场景 |
我个人习惯是:能走硬件合成就不走软件合成。原因很简单——功耗和延迟。车载座舱里,仪表盘显示必须保证毫秒级的响应,用GPU绕一圈再回来,延迟就上去了。
3.3.4 多图层合成的实际流程
假设一个典型的车载显示场景:仪表盘显示车速、转速、警示灯、导航提示四个图层。硬件合成器会这样处理:
- 图层排序:按Z序排列。警示灯在最上层,导航提示次之,车速和转速在底层。
- 逐层混合:从底层开始,两两混合。先混合车速和转速,得到背景层;再叠加上导航提示;最后叠加上警示灯。
- 输出:混合结果写入输出缓冲区,等待VSync信号发送到屏幕。
这里有个细节:硬件合成器通常支持逐像素混合。也就是说,每个像素的混合权重可以不同——这为实现圆角、阴影、模糊等效果提供了可能。
核心要点:图层混合不是简单的“叠上去就行”。你要考虑Alpha模式、色彩空间、伽马校正、抖动处理。而且,不同DPU的硬件合成器能力差异很大——有的支持10层,有的只支持4层。选型时一定要确认这个参数。
3.4 本章小结
好,我们来捋一下这章的核心脉络:
- GPU vs DPU:GPU负责渲染,DPU负责显示输出。两者分工明确,但需要紧密配合。
- 显示流水线:帧缓冲区 → 读取解压 → 图层处理 → 合成输出。每个环节都可能成为瓶颈。
- 图层混合:Alpha Blending是基础,但硬件实现要考虑预乘、伽马、抖动等细节。
- 硬件合成优先:车载场景下,能走硬件合成就不走软件合成——为了功耗和延迟。