基础知识
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,又称场同步)。
显卡帧率
表明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掉帧。
产生jank的原因是:在第2帧CPU处理数据的时分太晚了,GPU没有及时将数据写入到buffer中,导致jank的产生。
CPU处理数据和GPU写入buffer的时机比较随意。
Project Butter 黄油工程
安卓4.1 体系在收到VSync信号之后,立刻进行CPU的制作以及GPU的buffer写入。最大极限的减少jank的产生。
假如显卡帧率大于屏幕改写频率,也便是屏幕在改写一帧的时刻内,CPU和GPU能够充分利用改写一帧的时刻处理完数据并写入buffer中,那么这个计划是完美的,显现效果将很好。
因为主线程做了一些相对复杂耗时逻辑,导致CPU和GPU的处理时刻超越屏幕改写一帧的时刻,因为此刻back buffer写入的是B帧数据,在交流buffer前不能被掩盖,而frame buffer被Display用来做改写用,所以在B帧写入back buffer完结到下一个VSync信号到来之前两个buffer都被占用了,CPU无法持续制作,这段时刻就会被空着,所以又呈现了三缓存。
三buffer
最大程度防止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…