内容
帧
如上图, CRT的成像原理是: 线圈控制电⼦偏转⽅向, 从左到右为1⾏, 从上到下为⼀帧。每 张图⽚都是⼀帧, ⼀帧图像由⽆数像素点组成。
屏幕刷新率
1s内屏幕刷新的次数(1s显⽰多少帧图像), 单位: Hz。 ⼀般⼿机的常⽤刷新率包括:
60Hz, 90Hz, 120Hz等。我们知道, 在60Hz的设备上, 每间隔16.67ms会发送⼀次
VSYNC垂直同步脉冲, 那在120Hz的设备上, 脉冲发送的间隔就是8.335ms(VSYNC的发送
间隔是随刷新率变化的)。
帧率
GPU在1s内绘制的帧数, 单位: FPS(Frame Per Second)。在电影界采⽤ 24 帧的速度
⾜够使画⾯运⾏的⾮常流畅。⽽ Android 系统则采⽤更加流程的 60 fps,即每秒钟GPU最
多绘制 60 帧画⾯。帧率是动态变化的,例如当画⾯静⽌时,GPU 是没有绘制操作的,屏幕
刷新的还是buffer中的数据,即GPU最后操作的帧数据。
画面撕裂
⼀个屏幕内的数据来⾃2个不同的帧,画⾯会出现撕裂感。
逐行扫描
显⽰器并不是⼀次性将画⾯显⽰到屏幕上,⽽是从左到右边,从上到下逐⾏扫描,顺序
显⽰整屏的⼀个个像素点,不过这⼀过程快到⼈眼⽆法察觉到变化。以 60 Hz 刷新率的屏幕
为例,这⼀过程即 1000 / 60 ≈ 16ms。如下图
帧缓冲区
通常, 显⽰器会以恒定的频率从池读取画⾯, 以保证稳定的图像输出。与此同时, 显
卡也会往池写画⾯, 以供显⽰器读取。
⼀张显卡⼀般包含主副缓冲区, 也称为前后缓冲区(Front/Back)。连接到显⽰器的缓
冲区是Front Buffer, 显⽰器从中读取数据显⽰; 连接到显卡或GPU的缓冲区是Back
Buffer, 显卡向其中写⼊渲染好的数据。
当Back缓冲区渲染完成后,数据选择器即切换连接(交换地址),把最新的画⾯提供给显⽰器。
从显卡到屏幕的流程:
双缓冲
在上述的基础概念中提到了画⾯撕裂, 撕裂的原因是什么?
在60Hz的设备上,每16.6ms从buffer取数据显⽰完⼀帧,理想情况下帧率和刷新频率
保持⼀致,即每绘制完成⼀帧,显⽰器显⽰⼀帧。但是CPU/GPU写数据是不可控的,所以
会出现buffer⾥有些数据根本没显⽰出来就被重写了,即buffer⾥的数据可能是来⾃不同的
帧的, 当屏幕刷新时,此时它并不知道buffer的状态,因此从buffer抓取的帧并不是完整的
⼀帧画⾯,即出现画⾯撕裂。
简单说就是Display在显⽰的过程中,buffer内数据被CPU/GPU修改,导致画⾯撕裂。
那么画⾯撕裂的问题如何解决呢? 答案就是 VSYNC + 双缓冲 。 由于图像绘制和屏幕读取 使⽤的是同个buffer,所以屏幕刷新时可能读取到的是不完整的⼀帧画面。
双缓冲 让绘制和显⽰拥有各⾃的buffer:GPU 始终将完成的⼀帧图像数据写⼊到 Back Buffer,⽽显 ⽰器使⽤ Frame Buffer,当屏幕刷新时,Frame Buffer 并不会发⽣变化,当Backbuffer准备就绪 后,它们才进⾏交换。如下图:
什么时机Back Buffer和Frame Buffer进⾏swap?
只能是等到屏幕处理完⼀帧数据后,才可以进⾏替换。假如是 Back buffer准备完成⼀帧数据以后就进⾏,那么如果此时屏幕还没有完整显⽰上⼀帧内 容的话,肯定是会出问题的。
VBI(VerticalBlanking Interval)
当扫描完⼀个屏幕后,设备需要重新回到第⼀⾏以进⼊下⼀次的循环,此时有⼀段时间
空隙,称为VerticalBlanking Interval(VBI)。
这个时间点就是我们进⾏缓冲区交换的最佳时间。因为此时屏幕没有在刷新,也就避免
了交换过程中出现 screen tearing的状况。
VSYNC(VerticalSynchronization)
利⽤VBI时期出现的vertical sync pulse(垂直同步脉冲)来保证双缓冲在最佳时间点
才进⾏交换。另外,交换是指各⾃的内存地址,可以认为该操作是瞬间完成。
VSync 信号是由 HWC 硬件模块根据屏幕刷新率产⽣的, 我们把它称为HW-VSYNC-0, 可以把它理解为⼀种定时中断。实际在Android中使⽤的是由HW-VSYNC-0模拟的信号: SF_VSYNC与APP-VSYNC。
该模拟信号是为了提⾼对于硬件信号应⽤的灵活性以及渲染效率⽽定义的软件模型