View、Window、WindowManager---VSYNC信号

转载
Android 之理解 VSYNC 信号
Android应用性能优化系列视频双语字幕讲解 By Google
Android Project Butter分析

在阅读Matrix源码时, 发现Matrix会hook Choreographer这个类, 然后跟进这个Choreographer类, 又涉及到VSYNC这个概念, 先对这个VSYNC概念进行整理.

以下所有内容全部为从各种文章东拼西凑而来.

包含以下这些概念:

1. 刷新率
2. 帧速率
3. 屏幕撕裂
4. 双缓冲
5. Triple Buffering
1. 刷新率

  屏幕在一秒内刷新画面的次数, 刷新率取决于硬件的固定参数, 单位Hz. 例如常见的60Hz, 即每秒钟刷新60次.
逐行扫描: 显示器并不是一次性将画面显示到屏幕上, 而是从左到右, 从上到下逐行扫描显示, 不过这一过程快到人眼无法察觉到变化, 以60Hz刷新率的屏幕为例, 即1000 / 60 = 16ms.

2. 帧速率

  表示GPU在一秒内绘制操作的帧数. 例如电影采用24fps、Android系统采用60fps, 即一秒钟绘制30 / 60帧的画面

3. 屏幕撕裂

  刷新频率和帧速率需要一起合作, 才能使图形内容呈现在屏幕上, GPU会获取图形数据进行绘制, 然后硬件负责把图像内容呈现到屏幕上, 这一过程在应用程序的生命周期内一遍又一遍的发生.

流程简述为:
CPU准备图形数据 -> GPU获取图形数据并绘制 -> 显示器显示数据

  如果刷新频率和帧率不能保持同步, 例如帧速率实际比刷新率快, 例如帧速率是120fps, 显示器的刷新频率是60Hz. 此时将会发生一些视觉上的问题.
  由于显示器提取画面是从左到右, 从上到下逐行扫描提取图像显示, 这一过程需要16ms(1000 / 60), 当GPU利用一块内存区域写入帧数据时, 从顶部开始新一帧覆盖前一帧, 并立刻输出一行内容. 当屏幕刷新时, 它并不知道图像缓冲区的状态, 因此它从GPU抓取的帧并不是完整的数据. 也就是它有一半的前一帧和一半的当前帧, 这种情况称之为屏幕撕裂
  理想情况下, 希望显示器在完成一帧绘制之后再从GPU获取到下一帧图像数据, 但是由于帧率和刷新频率不一致导致显示器在绘图过程中, GPU已经开始加载下一帧图像数据. 屏幕撕裂是由于帧率和刷新频率不一致到情况导致.

4. 双缓冲

  解决屏幕撕裂的问题是双缓冲, 即GPU和显示器都有各自的工作缓冲区. GPU始终将完成的一帧绘制数据写入到Back Buffer, 而显示器使用Frame Buffer. 当屏幕刷新时, Frame Buffer并不会发生变化. Back Buffer根据屏幕的刷新将数据拷贝到Frame Buffer中, 这便是VSYNC

  在Android4.1之前, Android使用双缓冲机制. 同一个View Hierarchy内的View都会共用一个Window, 也就是共用一个Surface.
  而每个Surface都会有一个BufferQueue缓存队列, 但是这个队列会由SurfaceFlinger管理, 通过匿名共享内存与App应用层交互.

流程如下:

  • 每个Surface对应的BufferQueue内部都有两个Graphic Buffer, 一个用于绘制, 一个用于显示. 系统会把内容放到离屏缓冲区(OffScreen Buffer), 在需要显示时, 才把离屏缓冲区的内容通过Swap Buffer复制到Front Graphic Buffer中.
  • 这样SurfaceFlinger就拿到了某个Surface最终要显示的内容, 但是同一时间我们可能会有多个Surface. 这里面可能是不同应用的Surface, 也可能是同一个应用里面类似SurfaceView和TextureView, 它们都会有自己单独的Surface.
  • 这个时候SurfaceFlinger把所有Surface要显示的内容统一交给Hardware Composer, 它会根据位置、Z-Order顺序等信息合成为最终屏幕需要显示的内容, 而这个内容会交给系统的帧缓冲区Frame Buffer来显示.
4.1 Android4.1之前未使用VSYNC的双缓冲机制

流程如下:

  • 1.时间从0开始, 进入第一个16ms, Display显示第0帧, CPU处理完第一帧后, GPU紧接其后继续处理第一帧, 三者互不干扰
  • 2.进入到第二个16ms, 因为早在上一个16ms时间内, 第一帧已经由CPU、GPU处理完毕, 故Display可以直接显示第一帧. 显示没有问题, 但在本16ms期间, CPU和GPU却并未及时去绘制第二帧数据, 而是在本周期快结束时, CPU/GPU才去处理第二帧的数据.
  • 3.时间进入第三个16ms, 此时Display应该显示第二帧的数据, 但由于CPU和GPU还没有处理完第二帧数据, 故Display只能继续显示第一帧数据, 结果使得第一帧多画了一次(对应时间段标注了一个Jank)
  • 4.通过上述分析可知, 此处发生的Jank的关键问题在于, 为何第1个16ms段内, CPU/GPU没有及时处理第二帧数据? 原因是CPU可能在忙别的事情(比如某个应用通过sleep固定时间来实现动画的逐帧显示), 不知道到该处理UI绘制的时间了, 可CPU一旦想起来要处理第二帧数据时, 时间又错过了.

Android使用VSYNC来阻止屏幕撕裂, 对于Android4.0来说, CPU可能会因为在忙其他的事情, 导致没来得及处理UI绘制. 所以从4.1开始VSYNC则更进一步, VSYNC脉冲现在用于开始下一帧的所有处理.

4.2 Android4.1之后引入VSYNC机制
  • 1.这样应用总是在VSYNC边界上开始绘制, 而SurfaceFlinger总是在VSYNC边界上进行合成. 这样便可以消除卡顿, 并提升图形的视觉表现.
  • 2.结合图中的内容, 也就是说在显示当前数据的同时, CPU/GPU开始准备下一帧数据的绘制, 如果在16ms内完成, 也就可以保证屏幕显示下一帧图形时能够有数据可取.
  • 3.从图中可以看出CPU和GPU基本上都能在16ms内处理完数据, 也就是说CPU和GPU可以的fps(frames per second)要高于Display的fps. 由于CPU和GPU只有在接收到VSYNC信号时, 才会开始处理数据, 因此CPU和GPU的fps被拉低到和Display的fps相同的水平.
4.3 CPU和GPU的fps低于Display的fps
  • 1.在第二个16ms内, Display本来应该展示帧, 但是因为GPU还在处理B帧, 导致Display只能重复展示A帧.
  • 2.在第四个16ms时, Display本来需要展示A帧, 但是又因为GPU此时还没有处理完A帧数据, 导致Display继续展示B帧
  • 3.一旦过了VSYNC的时间点, CPU就不能被触发以处理绘制工作
  • 4.因为只有两个Buffer, 例如在第二个16ms内, Display和GPU分别占据着一个Buffer, 导致CPU只能处于空闲状态.
4.4 Triple Buffer(三缓冲区)
  • 1.在第二个16ms内, 虽然Display还是会重复展示A帧数据, 但是后续展示还是流畅的.
  • 2.但是结合图中可以看出CPU准备的C帧数据在第4个16ms内才会被Display展示. 因此也并不是Buffer越多越好.

至此, VCYNS概念算是东拼西凑勉勉强强copy完成, 接下来继续东拼西凑Choreographer, 待这些基本概念弄清楚之后再继续Matrix---FrameTracer的分析.

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