基础知识

CPU、GPU

  • CPU:中央处理器,首要担任计算数据,在Android中首要用于三大制作流程中Surface的计算进程。
  • GPU:图像处理器,首要担任对图形数据进行烘托,在Android中首要用于将CPU计算好的Surface数据组成后放到buffer中,让显现器进行读取呈现到屏幕上。

逐行扫描

屏幕在改写buffer的时分,并不是一次性扫描完结,而是从左到右,从上到下的一个读取进程,次序显现一屏的每个像素点,按60HZ的屏幕改写率来算,这个进程只有16.66666…ms。

  • 从初始方位(榜首行左上角)开端扫描,从左到右,进行水平扫描(Horizontal Scanning)
  • 每一行扫描完结,扫描线会切换到下一行起点,这个切换进程叫做水平消隐,简称 hblank(horizontal blank interval),并发送水平同步信号(horizontal synchronization,又称行同步)
  • 依次类推,整个屏幕(一个笔直周期)扫描完结后,显现器就能够呈现一帧的画面
  • 屏幕最终一行(一个笔直周期)扫描完结后,需要重返左上角初始方位,这个进程叫笔直消隐,简称 vblank(vertical blank interval)
  • 扫描线回到初始方位之后,预备扫描下一帧,一起宣布笔直同步信号(vertical synchronization,又称场同步)。

Android屏幕刷新机制

显卡帧率

表明GPU在1s中内能够烘托多少帧到buffer中,单位是fps,这里要了解的是帧率是一个动态的,比方咱们平时说的60fps,只是1s内最多能够烘托60帧,假设咱们屏幕是停止的,则GPU此刻就没有任何操作,帧率就为0.

屏幕改写频率

屏幕改写频率:屏幕在1s内去buffer中取数据的次数,单位为HZ,常见屏幕改写率为60HZ。屏幕改写率是一个固定值和硬件参数有关。也便是以这个频率宣布 笔直同步信号,奉告 GPU 能够往 buffer 里写数据了,即烘托下一帧。

屏幕改写机制演变进程

单buffer

GPU和显现器共用一块buffer

screen tearing 屏幕撕裂、画面撕裂

当只有一个buffer时,GPU 向 buffer 中写入数据,屏幕从 buffer 中取图像数据、改写后显现,理想的状况是显卡帧率和屏幕改写频率相等,每制作一帧,屏幕显现一帧。而实际状况是,二者之间没有必然的巨细联系,假如没有同步机制,很容易呈现问题。
当显卡帧率大于屏幕改写频率,屏幕预备改写第2帧的时分,GPU 已经在生成第3帧了,就会掩盖第2帧的部分数据。
当屏幕开端改写第2帧的时分,缓冲区中的数据一部分是第3帧数据,一部分是第2帧的数据,显现出来的图像就会呈现显着的偏差,称为屏幕撕裂,其本质是显卡帧率和屏幕改写频率不一致所导致。

双buffer

安卓4.1之前
基本原理便是采用两块buffer。
GPU写入的缓存为:Back Buffer
屏幕改写运用的缓存为:Frame Buffer
因为运用双buffer,屏幕改写时,frame buffer不会产生变化,经过交流buffer来完成帧数据切换。 什么时分就行buffer交流呢,当设备屏幕改写结束后到下一帧改写前,因为没有屏幕改写,所以这段时刻便是缓存交流的最佳时刻。
此刻硬件屏幕会宣布一个脉冲信号,奉告GPU和CPU能够交流了,这个便是Vsync信号,笔直同步信号。 不可否认,双缓冲能够在很大程度上降低screen tearing错误,但是呢,仍是会呈现一些其他问题。

Jank 掉帧

假如在Vsync到来时back buffer并没有预备好,就不会进行缓存的交流,屏幕显现的仍是前一帧画面,即两个改写周期显现的是同一帧数据,称为Jank掉帧。

Android屏幕刷新机制
产生jank的原因是:在第2帧CPU处理数据的时分太晚了,GPU没有及时将数据写入到buffer中,导致jank的产生。
CPU处理数据和GPU写入buffer的时机比较随意。

Project Butter 黄油工程

安卓4.1 体系在收到VSync信号之后,立刻进行CPU的制作以及GPU的buffer写入。最大极限的减少jank的产生。

Android屏幕刷新机制
假如显卡帧率大于屏幕改写频率,也便是屏幕在改写一帧的时刻内,CPU和GPU能够充分利用改写一帧的时刻处理完数据并写入buffer中,那么这个计划是完美的,显现效果将很好。

Android屏幕刷新机制
因为主线程做了一些相对复杂耗时逻辑,导致CPU和GPU的处理时刻超越屏幕改写一帧的时刻,因为此刻back buffer写入的是B帧数据,在交流buffer前不能被掩盖,而frame buffer被Display用来做改写用,所以在B帧写入back buffer完结到下一个VSync信号到来之前两个buffer都被占用了,CPU无法持续制作,这段时刻就会被空着,所以又呈现了三缓存。

三buffer

Android屏幕刷新机制
最大程度防止CPU空闲的状况。

Choreographer

体系在收到VSync信号之后,会立刻进行CPU的制作以及GPU的buffer写入。在安卓体系中由Choreographer完成。

  • 在Choreographer的结构函数中会创立一个FrameDisplayEventReceiver类目标,这个目标完成了onVSync办法,用于VSync信号回调。
  • FrameDisplayEventReceiver这个目标的父类结构办法中会调用nativeInit办法将当时FrameDisplayEventReceiver目标传递给native层,native层回来一个地址mReceiverPtr给上层。
  • 主线程在scheduleVsync办法中调用nativeScheduleVsync,并传入2中回来的mReceiverPtr,这样就在native层就正式注册了一个FrameDisplayEventReceiver目标。
  • native层在GPU的唆使下会定时回调FrameDisplayEventReceiver的onVSync办法,然后完成了:在VSync信号到来时,当即履行doFrame办法。
  • doFrame办法中会履行输入事情,动画事情,layout/measure/draw流程并提交数据给GPU。

参考文献:
/post/716385…
blog.csdn.net/litefish/ar…
www.jianshu.com/p/996bca12e…