前言
我们在前面的章节提到,像素通过 BufferQueue 传给了 SurfaceFlinger。但这只是“交卷”。最后的“批改”(把图像投射到物理屏幕上)是由显卡和 HWC(Hardware Composer) 共同完成的。
为什么有些复杂的 UI 不掉帧,而一些简单的阴影却会变卡?今天我们深入显卡驱动层。
一、 GPU 绘制 vs HWC 合成
在 Android 渲染中,有两种方式把图画出来:
- GPU 绘制 (GLES/Vulkan):显卡一个像素一个像素地算。适合画复杂的渐变、阴影和纹理。
- HWC 合成 (Hardware Composer):这是一种极其省电且高效的专用硬件。它不计算像素,它只负责**“叠加图层”**。
老兵 Tips:理想状态下,系统希望所有的层(状态栏、App、壁纸)都直接交给 HWC 叠加,这样 GPU 就能休眠。
二、 Overlay 平面:性能的“VIP 通道”
HWC 拥有一种名为 Overlay 的技术。
- 如果你的 App 正在播放全屏视频,系统会直接把视频的 Buffer 给 HWC,由 HWC 直接打到屏幕上。
- 优势:绕过了 GPU,没有中间商赚差价,性能最高,功耗最低。
三、 为什么阴影和圆角会让系统头疼?
在 Compose 中,我们喜欢写 Modifier.shadow() 和 Modifier.clip()。
- 离屏缓冲 (Offscreen Buffer):这些复杂的视觉效果通常需要 GPU 介入。
- 后果:系统必须把多个简单的层先合成到一个临时的 GPU 缓冲区中,再给 HWC。这增加了渲染管线的长度,导致了我们常说的“渲染压力大”。
四、 掌握真正意义上的 Overdraw 优化
作为资深架构师,你不能只看 Layout Inspector。
- HWC 压力分析:如果在某些机型上掉帧,尝试关闭不必要的透明度变换,让更多图层进入 HWC Overlay。
- 避免强制 GPU 合成:某些老旧驱动在处理超过 8 个层叠窗口时,会强制回退到 GPU 合成。在全栈开发中,注意控制复杂组件的 Layer 层级。
五、 源码及工具建议
adb shell dumpsys SurfaceFlinger:查看当前屏幕上有多少个层正在由 HWC 处理,多少个在由 GPU 处理(搜索 "Composition type")。hardware/interfaces/graphics/composer/:查看 HWC 的 HAL 层定义。
结语
屏幕上的每一个点,都是 HWC 调度下的产物。理解了底层硬件的脾气,你才能写出真正让手机“冷静”的高性能代码。
下一篇,我们要从像素回到神经系统 —— Input 系统全链路:从电信号到 Compose 的 PointerInput。