一、动画刷新基础:人眼视觉暂留原理、帧率与刷新率概念、Android显示系统架构概览

各位同学,咱们开始第一课。

做动画刷新驱动适配,说白了就是跟屏幕上的每一帧画面打交道。你想想看,手机屏幕上的画面为什么能动起来?为什么60Hz的屏幕看起来流畅,30Hz就卡得不行?这些问题的根,都在我们今天要聊的基础里。

我个人习惯,不管做什么驱动,先把物理原理和系统架构摸透。底层的寄存器配置、中断处理、buffer管理,全都建立在这些基础之上。好,咱们直接开整。

1.1 人眼视觉暂留——动画的生理基础

动画能骗过眼睛,靠的是人眼的一个生理特性:视觉暂留(Persistence of Vision)。

说白了,就是当一幅画面从眼前消失后,大脑还会把它“留”大约1/24秒。如果下一幅画面在这个时间内出现,大脑就会觉得两幅画面是连续的,从而产生“动”的错觉。

关键数字:人眼视觉暂留时间约为 40ms ~ 50ms。也就是说,只要画面更新的间隔小于这个时间,人眼就分辨不出闪烁。

我在项目中遇到过一件事:早期调一款低端平板,屏幕刷新率只有50Hz,但动画帧率跑到了60fps。结果画面撕裂严重,用户反馈说“屏幕在抖”。后来一查,是刷新率跟不上帧率,视觉暂留效应被打破了。嗯,这里要注意,视觉暂留是动画流畅的生理下限,但不是唯一条件。

1.2 帧率(FPS)与刷新率(Hz)——两个容易搞混的概念

这两个词,我见过太多人混着用了。咱们一次说清楚。

概念 英文 定义 谁决定的
帧率 FPS (Frames Per Second) GPU/CPU每秒能生成多少帧画面 应用层、渲染管线、GPU性能
刷新率 Hz (Hertz) 屏幕硬件每秒能显示多少帧画面 屏幕面板、驱动IC、DDIC配置

举个例子:

  • 你玩《原神》,GPU拼了命跑出90fps,这叫帧率。
  • 你的手机屏幕是60Hz的,每秒只能刷新60次画面,这叫刷新率。
  • 结果呢?GPU多生成的30帧,屏幕根本来不及显示,要么丢掉,要么撕裂。

避坑指南:我曾经在适配一款90Hz屏幕时,只改了驱动里的刷新率参数,没管帧率同步。结果屏幕确实以90Hz在刷,但GPU只输出45fps,每一帧被重复显示了一次,看起来跟45Hz没区别。用户反馈“开了高刷跟没开一样”。后来加了帧率统计才发现问题。

所以,帧率和刷新率必须匹配。理想情况是:帧率 = 刷新率,或者帧率是刷新率的整数倍(比如60fps配120Hz,每帧刷两次)。否则就会出现卡顿、撕裂、掉帧。

1.3 Android显示系统架构概览——从App到屏幕的完整链路

好,现在咱们把视野拉高,看看Android系统里,一帧画面从诞生到显示,到底走了多远的路。

我画了一张架构图,你跟着箭头走一遍,基本就全明白了。

Android显示系统架构概览 Android 显示系统架构概览 应用层 (App Layer) Activity / SurfaceView / TextureView / Canvas / OpenGL ES / Vulkan 框架层 (Framework Layer) SurfaceFlinger / WindowManager / BufferQueue / Choreographer HAL 层 (Hardware Abstraction Layer) HWC (Hardware Composer) / Gralloc / Display HAL / VSync HAL 内核层 (Kernel Layer) DRM/KMS / GPU驱动 (kgsl/panfrost) / 显示控制器驱动 / 背光驱动 数据流方向:App → Framework → HAL → Kernel → 屏幕硬件

咱们从上往下捋一遍:

  1. 应用层:你的App通过Canvas、OpenGL ES或者Vulkan绘制画面。绘制结果是一块一块的图形缓冲区(GraphicBuffer)。
  2. 框架层:SurfaceFlinger是核心。它把多个App的缓冲区合成一张完整的屏幕画面。Choreographer负责协调帧率,VSync信号就是它管的。
  3. HAL层:硬件适配层。HWC(Hardware Composer)决定哪些图层由GPU合成,哪些由显示硬件直接合成。Gralloc管理图形内存。
  4. 内核层:驱动真正干活的地方。DRM/KMS管理显示模式和帧缓冲,GPU驱动处理渲染命令,显示控制器驱动控制屏幕时序。

个人经验:我刚开始做驱动时,总觉得HAL层是多余的,直接操作寄存器不香吗?后来发现,没有HAL层,上层App换一个屏幕就得改一遍驱动代码。HAL层就是那个“适配器”,让上层代码跟硬件解耦。你想想看,没有它,Android怎么支持几百种不同的屏幕面板?

1.4 关键角色:VSync——整个刷新流程的节拍器

说到刷新,绕不开VSync(垂直同步)。

VSync是屏幕硬件发出的一个脉冲信号,告诉系统:“我这一帧已经显示完了,可以准备下一帧了。” 整个Android的动画刷新,都是跟着VSync的节奏走的。

VSync类型 来源 作用
硬件VSync 显示控制器/DDIC 由屏幕硬件产生,精确到微秒级
软件VSync SurfaceFlinger 基于硬件VSync模拟,用于Choreographer调度

我记得有一次调一个第三方屏幕,硬件VSync信号不稳定,有时候丢脉冲。结果SurfaceFlinger收不到VSync,以为屏幕没准备好,就一直不发新帧。画面直接卡死。后来我在驱动里加了VSync监测,发现丢脉冲就自动补偿,才算解决。

注意:VSync信号的质量,直接影响动画流畅度。如果VSync抖动超过1ms,用户就能感觉到卡顿。所以驱动里对VSync的处理,必须用中断,不能用轮询。轮询的延迟和不确定性,在刷新适配里是致命的。

1.5 本章小结

咱们今天聊了三件事:

  • 视觉暂留是动画能成立的生理基础,40ms是底线。
  • 帧率 vs 刷新率,一个软件生成,一个硬件显示,必须匹配。
  • Android显示架构从App到屏幕,经过Framework、HAL、Kernel四层,VSync是贯穿始终的节拍器。

这些概念,后面每一章都会用到。尤其是VSync和帧率刷新率的关系,是驱动适配的核心矛盾。你把这些基础打牢了,后面调驱动、改参数、修bug,心里才有底。