显示撕裂、掉帧的原因以及苹果的处理方案显示撕裂、掉帧的原因以及苹果的处理方案

2021-08-09 13:43:04 浏览数 (1)

显示撕裂、掉帧的原因以及苹果的处理方案

本文阅读时间大约5分钟

前言

依旧还是老规矩,提出几个问题,希望看完本文后可以完美的回答:

  1. 屏幕撕裂罪魁祸首是谁?如何解决?
  2. 掉帧问题出现的原因,如何解决?

本文钟会出现很多专用的名词,不清楚可以去我另一篇文章中查看。

OpenGL (二)--OpenGL中那些晦涩难懂的名词、动词解析

屏幕扫描->显示

这是显示器的电子信号扫描图,会从左上到右下一个像素点一个像素点的扫描,于此同时也会从帧缓存区中一个像素一个像素的读取,最终完成显示。

屏幕撕裂

这个问题大家应该都遇到过,尤其喜欢玩游戏的同学更加常见,先上一张我的女神,无视上面的字是在找不到其他的了....

先说一些自己最直观的认知:这是两张图片拼接成的。可是在一个时刻为什么会出现两张图片呢?这就要从这张图片是如何渲染到屏幕上说起了。

计算机显示流程
  • 理想状态:

显示器显示完一张位图后,cpu、gpu刚好把下一张位图处理好存放到帧缓存区中,这样显示器就可以展示新的内容。

  • 现实状态

cpu、gpu的处理是根据位图的复杂程度决定的,导致这个处理时间或长或短。所以控制器读取的内容就会提前或者延后,而帧缓存区内容就会异常导致屏幕出现撕裂。对照屏幕扫描这个概念一起理解。

现在可以回答问题一:屏幕显示周期与cpu、gpu的处理周期不同步,加之显示的扫描原理,导致出现撕裂。

如何解决

为了解决撕裂,苹果大大引入了:垂直同步Vsync 双缓存区 DoubleBuffering来彻底解决撕裂问题,如何理解呢?

  • 垂直同步,既然之前会出现两者周期不同步的问题,那么对帧缓存区加入一个同步信号,保证:
  • 当前位图已经完全扫描、显示完成,在帧缓存区中才会放入新的位图;
  • 如果下一帧位图还没有渲染完成,那么原位图不会被销毁,继续进行下次扫描。
  • 双缓存区,为GPU在增加一个缓存区域,当然显示控制器也会交叉读取两个帧缓存区内的内容。这是一种拿空间换时间的策略,当然这样做的好处:
  • 不浪费cpu、gpu的资源,为提前渲染好的位图有一个区域保存,cpu、gpu就可以进行下一帧的处理。
  • 减少掉帧的出现。

现在就可以彻底回答问题一了。

掉帧

可以说掉帧是为了解决撕裂问题而带来的副作用,但是在我看来掉帧还可以“眨眼补帧”,但是撕裂的体验就会非常差了。

Snip20200707_15.png

对图做一个简单解释:

  1. 每一个竖线分段代表16.67ms,因为大多数设备的刷新频率是60HZ,所以需要16.67ms之内就要处理好下一帧的位图数据。马上推出的120HZ-iPhone要真香了。
  2. 前两步出现了两次A,那第二次出现A就是掉帧,因为B没有处理好。后面2次B也是同理。

对于问题二,就很好解释了:cpu、gpu来不及处理下一帧数据,导致下个显示周期只能重复显示当前帧的位图。当然它也是为了解决屏幕撕裂带来的副作用。

如何优化

因为处理任务的不确定性,计算机永远都无法保证在一个周期内能完成所有任务,所以掉帧问题就目前技术是无法根本解决的,只能是优化。

目前苹果大大使用三缓存区的方案来进一步减少掉帧的出现,因为缓存区越多cpu、gpu的利用率就越高,出现卡顿的频率也会越少。

后序

相信在科学技术、硬件技术的发展下,这个问题可以得到完美的解决。

0 人点赞