Android----屏幕UI显示系统基础

屏幕显示系统基础概念

帧--->视频由连续的静态图像连续快速切换播放形成,每一张静态图像称为视频的一帧。

利用人眼的“视觉暂留现象”只要连续图像播放大于24帧/秒,即感受到的就是连续的动态图像。

帧率(fps) ---> 每秒屏幕播放的帧数,帧率低于24人眼会感觉卡顿不流畅,越高越流畅
显示器垂直分辨率:显示器垂直方向上可显示的像素数目
显示器水平分辨率:显示器水平方向上可显示的像素数目
屏幕刷新率(HZ)-->又称为场频(垂直扫描频率)

最初的CRT(阴极射线管)技术时代的屏幕,屏幕刷新像素都是从左上角开始从左到右,从上到下逐行扫描;所以完成一次垂直扫描即可完成整屏幕的刷新故而场频也称屏幕刷新率.

行频--->水平扫描率,每秒在屏幕上扫描的行数
行频 = 场频 * 垂直分辨率 * K(一个常数)

为什么会有一个常数?答案也很简单,由于每次扫描到最后一个像素后,下次又要重定位到左上角,存在一个性能损耗,所以“行频”会比“场频*垂直分辨率”大,即K一般大于1。

典型现代屏幕显示系统角色分工:

构建视图内容: 遍历所有视图,将需要绘制的操作缓存下来,交给单独的Render线程使用GPU进行硬件加速渲染。(通常在主线程中使用CPU构建)

绘制阶段 : 调用OpenGL(即使用GPU)对构建好的视图进行绘制渲染,绘制的内容保存在Graphic Buffer 并交由 SurfaceFlinger 显示。(Android 5.0+ 使用Render Thread线程,专门负责 UI 渲染和动画显示。)

显示“卡顿”类型

Tearing --> "图像撕裂",屏幕呈现的图像由两帧以上构成,画面出现撕裂感(当前帧还未完全由屏幕更新到屏幕,即被下一帧的数据替换)
Jank --> 同一个帧在屏幕上连续出现2次即通常说的卡顿
Lag --> 屏幕延时,从用户输入到屏幕呈现效果之间存在延迟

Screen Tearing原因

屏幕显示图像本质是一个粗略的生产-消费者模型:CPU&GPU生产图像数据到帧Buffer,显卡从buffer获取数据显示到屏幕。


image.png

CPU & GPU生产帧数据时间是不定的,而屏幕刷新率基本由硬件(显卡)决定通常60Hz。显示控制器从Buffer获取帧数据更新到屏幕有一个时间间隔(CRT技术的屏幕都是从屏幕左上从左到右,从上到下依次刷新屏幕像素)。

在屏幕的一个刷新周期内,buffer数据被cpu/gpu更改,就出现了图像前部分是A帧,后半部分是B帧的“撕裂Tearing”.

由于帧buffer是一个竞争性资源,CPU/GPU 与 屏幕display会争抢buffer,不同步就会导致Tearing.

显示出现tearing的本质原因是,屏幕刷新率与CPU/GPU生成图像的帧率不同步, 加入同步lock即可解决;每次屏幕或者GPU只能有一方在操作buffer.

双缓冲+VSync同步机制

单buffer+同步虽然能解决tearing,但是效率太低,GPU和屏幕竞争同一块buffer大部分时间都在互相等待中浪费了资源。

于是双buffer机制适时出现(事实上单bufer机制只存在于30年前了):
backBuffer用于CPU/GPU后台绘制,frameBuffer则用于显示,当backBuffer准备就绪后,它们才进行交换。

双缓冲解决了效率问题,但是如何解决同步问题---> 何时交换backBuffer和frameBuffer?

当扫描完一个屏幕后,设备需要重新回到第一行以进入下一次的循环,此时有一段时间空隙,称为VerticalBlanking Interval(VBI)。这个时间点就是我们进行缓冲区交换的最佳时间,因为此时屏幕没有在刷新,也就避免了交换过程中出现 screentearing的状况。VSync(垂直同步)是VerticalSynchronization的简写,它利用VBI时期出现的vertical sync pulse来保证双缓冲在最佳时间点才进行交换。

双缓冲+Vsync工作模型:

without_vsync
draw_with_vsync.png

在这种模型下,只有当 VSync 信号产生时,交换back & frame buffer,CPU/GPU 才会开始绘制。当帧率大于刷新频率时,帧率就会被迫跟刷新频率保持同步,从而避免“tearing”现象。开启VSync的本质就是强制拉平我们的GPU每秒绘制的帧数和屏幕的刷新频率。

Google在Android的实践

为改善Android上的UI体验, Google在2012年的I/O大会上宣布了Project Butter,并在Android 4.1中正式搭载了实现机制。

从Android4.1版本开始,Android对显示系统进行了重构,引入了三个核心元素:VSYNC, Tripple Buffer和Choreographer。VSYNC是Vertical Synchronized的缩写,是一种定时中断;Tripple Buffer是显示数据的缓冲区;Choreographer起调度作用,将绘制工作统一到VSYNC的某个时间点上,使应用的绘制工作有序进行。

那么Triple buffer是干啥的?
看下上面的方案,在CPU/GUP帧率大于屏幕刷新的情况下皆大欢喜,万一帧率低于屏幕刷新率呢?使用A、B代表两块buffer看下图不同情况下的工作情况:


double_buffer_with_vsync.png
double_buffer_jank.png

若以60fps为屏幕刷新率,当CPU/GPU的处理时间超过16ms时,第一个VSync到来时,缓冲区B中的数据还没有准备好,于是只能继续显示之前A缓冲区中的内容。而B完成后,又因为缺乏VSync pulse信号,它只能等待下一个signal的来临。于是在这一过程中,有一大段时间是被浪费的。当下一个VSync出现时,CPU/GPU马上执行操作,此时它可操作的buffer是A,相应的显示屏对应的就是B。这时看起来就是正常的。只不过由于执行时间仍然超过16ms,导致下一次应该执行的缓冲区交换又被推迟了——如此循环反复,便出现了越来越多的“Jank”。


triple_buffer_vsync.png

Triple Buffering是MultipleBuffering的一种,指的是系统使用3个缓冲区用于显示工作。当第一次VSync发生后,CPU不用再等待了,它会使用第三个buffer C来进行下一帧数据的准备工作,有效地降低了系统显示错误的机率。

那是Buffer的数量越多越好?那肯定是不科学的,triple buffer是为了充分发挥CPU/GPU的工作效率,降低等待是充分利用流水线思路;各项任务的处理能力上限触顶使用多的buffer也只是增加额外的buffer管理调度任务。

Choreographer的作用

上面提到了硬件会产生Vsync信号作为触发标志,如果帧率是60ms那如何统一16.6ms内的任务等待Vsync到来才执行呢?

Choreographer就是用来统一协调任务的,动画、绘制和输入事件的任务会先进入Choreographer的队列;由Choreographer申请硬件的Vsync信号,收到Vsync信号后统一回调任务队列内的任务。

参考文章

屏幕成像原理以及FPS优化Tips
Android屏幕刷新显示机制
Android绘制优化----系统显示原理
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269