1. 概述

一帧是如何显示的?

  • 简单来说,SurfaceFlinger用于合成显示图层,再将其刷入到HWComposer封装的显示设备中就可以显示了
  • 对于一帧内容,先等App UI画完了,SurfaceFlinger再出场对其进行合并渲染后放入framebuffer,最后整到屏幕上。
  • 当显示驱动支持时,VSYNC由硬件定时发送到HWComposer中;否则HWComposer会新起一个线程模拟发送VSYNC信号,其原理也十分简单,就是定期唤起线程发送信号。

Surface跟Layer

  • Layer是一个图层
  • Surface实际显示在手机上的某一个图像,这个图像可能由多个Layer组成

Vsync-app 跟 Vsync-sf

  • VSYNC-app用于控制APP绘制UI的节奏,其实就是SF中app-DispSyncSource根据自己需要,转发DispSync的sync信号。
  • VSYNC-sf用于控制SF合成Layer的节奏,可以理解为sf对应的DispSyncSource发出的sync信号,再触发EventThread的回调并转换成事件写入写端,最后触发读端的回调MessageQueue::cb_eventReceiver(),SF开始合成显示图层

2. 流程

屏幕的刷新过程是每一行从左到右(行刷新,水平刷新,Horizontal Scanning),从上到下(屏幕刷新,垂直刷新,Vertical Scanning)。当整个屏幕刷新完毕,即一个垂直刷新周期完成,会有短暂的空白期,此时发出 VSync 信号。所以,VSync 中的 V 指的是垂直刷新中的垂直-Vertical。

Android系统每隔16ms发出VSYNC信号,触发对UI进行渲染,VSync是Vertical Synchronization(垂直同步)的缩写,是一种在PC上很早就广泛使用的技术,可以简单的把它认为是一种定时中断。而在Android 4.1(JB)中已经开始引入VSync机制,用来同步渲染,让AppUI和SurfaceFlinger可以按硬件产生的VSync节奏进行工作。
  
一般来说,在同一个 View Hierarchy 内的不同 View 共用一个 Window,也就是共用同一个 Surface。

每个 Surface 都会有一个 BufferQueue 缓存队列,但是这个队列会由 SurfaceFlinger 管理,通过匿名共享内存机制与 App 应用层交互。

整个流程如下:

双缓冲模式:

  • 最开始是双缓冲模式,每个 Surface 对应的 BufferQueue 内部都有两个 Graphic Buffer,一个用于绘制一个用于显示。在显示buffer A的数据时,CPU/GPU就开始在buffer B中准备下一帧数据:
  • 但是不能保证每一帧CPU、GPU都运行状态良好,可能由于资源抢占等性能问题导致某一帧GPU掉链子,vsync信号到来时buffer B的数据还没准备好,而此时Display又在显示buffer A的数据,导致后面CPU/GPU没有新的buffer着手准备数据,空白时间无事可做,后面Jank频出:

三缓冲模式:

  • 所以从 Android 4.1 开始, VSYNC 则更进一步,现在 VSYNC 脉冲信号开始用于下一帧的所有处理。
  • Project Butter 首先对 Android Display 系统的 SurfaceFlinger 进行了改造,目标是提供 VSYNC 中断。每收到 VSYNC 中断后,CPU 会立即准备 Buffer 数据,由于大部分显示设备刷新频率都是 60 Hz(一秒刷新 60 次),也就是说一帧数据的准备工作都要在 16ms 内完成。
  • 如果理解了双缓冲机制的原理,那就非常容易理解什么是三缓冲区了。如果只有两个 Graphic Buffer 缓冲区 A 和 B,如果 CPU / GPU 绘制过程较长,超过一个 VSYNC 信号周期。
  • androidstudio中sync是什么 android sync在哪_数据

  • 在第二个 16 ms 时间段内,Display 本应该显示 B 帧,但却因为 GPU 还在处理 B 帧,导致 A 帧被重复显示。
  • 同理,在第二个 16 ms 时间段内,CPU 无所事事,因为 A Buffer 被 Display 在使用。B Buffer 被 GPU 在使用。注意,一旦过了 VSYNC 时间点,CPU 就不能被触发处理绘制工作了。
  • androidstudio中sync是什么 android sync在哪_数据_02

  • 简单来说,三重缓冲机制就是在双缓冲机制基础上增加了一个 Graphic Buffer 缓冲区,这样可以最大限度的利用空闲时间,带来的坏处是多使用的一个 Graphic Buffer 所占用的内存。