屏幕刷新机制简单问(没有代码,请放心享用)

简介: 周一好呀,今天给大家带来一点轻松简单的内容,没有代码,请享用~

前言


周一好呀,今天给大家带来一点轻松简单的内容,没有代码,请享用~


本文起因呢,是因为周末在群里聊到关于屏幕刷新,同步屏障的问题,于是想到我们还没说过屏幕刷新方面的问题,就来聊聊了。新来的朋友如果有建议,想法也欢迎来微信讨论群讨论。(公众号首页—联系我—加讨论群)


  • 高刷手机,60hz,120hz指的是什么?
  • 屏幕的刷新过程。
  • 帧率,VSYNC是什么?
  • 单缓存,双缓存,三缓存。
  • 代码中修改了UI,屏幕是怎么进行刷新的?
  • 如果界面保持静止不变,屏幕会刷新吗?图像会被重新绘制吗?


高刷手机,60hz,120hz指的是什么


指的是屏幕的刷新频率,也就是一秒内屏幕刷新的次数。刷新频率这个参数是手机出厂就决定的,取决于硬件的固定参数。


高刷手机,一般就是指高刷新率屏幕,也就是大于一般的60hz,比如90hz,120hz等等。它的特点就在于每秒刷新的频率更高,使得画面更加流畅,顺滑,就算出现丢帧等情况,画面还能保证一个稳定性。


屏幕的刷新过程。


屏幕的刷新过程是每一行从左到右,从上到下,顺序显示像素点。当整个屏幕刷新完毕,即一个垂直刷新周期完成,会有短暂的空白期,此时发出VSync 信号。如果是60hz的手机,那么每次屏幕刷新的过程占用时间就是16ms(1000/60)左右。


一般一个图形界面的绘制,需要CPU准备数据,然后GPU进行绘制,绘制完写入缓存区,然后屏幕按照刷新频率来从这个缓存区中取图形显示。


所以整个刷新过程是CPU,GPU,屏幕(Display)三方合作的工作关系。


帧率,VSYNC是什么


帧率,就是GPU一秒内绘制操作的帧数,单位是fps。游戏中比较常见,越大也就代表越流畅。所以这个参数并不是固定值,但是如果屏幕刷新频率是60hz,你的帧率大于60fps也就浪费了,所以一般情况下最好是帧率和屏幕刷新频率保持一致,即同样是60fps。这样就能保证一个比较平滑的视觉动画。


VSync,垂直同步,在Android4.1引进,是一种定时发送绘制信号的机制,它的作用就是让帧率和屏幕刷新率保持一致,防止跳帧卡顿等等。玩过lol的朋友应该都知道,设置界面就可以开启垂直同步选项。


正常如果没有开启vsync,屏幕刷新有可能会出现什么问题呢?


3.png


如图,由于CPU,GPU绘制图像的时间不定,所以就有可能会发生卡顿情况,也就是下一帧的数据没准备好,无法正常显示到屏幕上。


如果我们开启vsync,也就是给CPU和GPU规定了开始绘制帧数据的时间。开启后,系统会每16ms就发送一次vsync信号,CPU收到信号就开始处理数据,然后GPU绘制图像。这样就把16ms最大化的利用起来了,只要CPU和GPU16ms之内把下一帧数据处理好,那么屏幕就能从缓存区中拿到下一帧数据并显示出来了。如图:


4.png


所以vsync信号就是为了保证16ms绘制出一帧的数据出来。使得屏幕每16ms刷新一次,就能用到最新的帧数据了。这样画面就是比较流畅的了。


这整个过程其实就在Choreographer类中实现的,包括同步屏障的使用也在其中,下次会具体讲到。


单缓存,双缓存,三缓存


  • 单缓存。就是CPU计算好的数据交给GPU,然后GPU进行图像绘制,最后放到缓存区。而屏幕就直接从这个缓存区中拿到数据并显示。


但是这样做有个问题就是,因为Display和GPU都是操作的同一个缓存,就会出现同一个画面中有不同帧的数据。比如屏幕刷新的时候,第二帧还没绘制完,那么缓存中就有第二帧数据还有第一帧残留的数据,这样显示出来的画面就有两个帧的画面了,比如画面撕裂


  • 双缓存。这个双缓存就是设计出来解决单缓存问题的。既然Display和GPU不能共用一个缓存,那么就设计两个缓存就可以啦。


FrameBuffer来做显示输出,也就是屏幕每次从这个缓存中取图形数据。BackBuffer用来放下一帧的画面,也就是CPU每次绘制数据到这个缓存中。然后当CPU完整绘制完下一帧图形,也就是BackBuffer准备好,屏幕也显示完上一帧数据的时候,就进行缓存交换,把数据同步到FrameBuffer。而这个缓存交换点,就是vsync信号时刻。


三缓存。Android4.1 引入,一般来说,双缓存就能够使用了,但是为什么还有一个三缓存呢?看图:


5.png

双缓存情况下,如果CPU/GPU处理数据过慢,就会发生上图的情况。也就是vsync信号来的时候,上一帧数据还没绘制完,于是A数据图片显示了两帧的时间,而且由于vsync来的时候cpu才开始处理数据,而图上vsync来的时候,GPU还在处理数据,导致GPU处理完了之后,无法触发下一帧数据的处理,浪费了一大半时间。后面情况类似,只要CPU/GPU处理数据过慢,就会发生Jank(卡顿等问题)


所以这时候就引入了第三个缓存,如图:


6.png


如图所示,在vsync来的时候,如果GPU还没处理好数据帧B的图形,这时候第三个缓存区可以来处理后面C帧的数据,然后第二个vsync信号来的时候,虽然第三缓存区还在用作处理C帧数据,但是之前的BackBuffer又可以来缓存下一帧的数据了。


这样一来,虽然A帧数据还是显示了两个时间点,但是后面由于有新Buffer的加入,可以保证后续图像显示能正常平滑的显示了。就相当于多了一个劳动力,可以最大限度利用好时间。


代码中修改了UI,屏幕是怎么进行刷新的?


当我们用代码修改了UI,比如使用了setText,修改Textview的值。这时候屏幕不会马上绘制刷新。而是会调用到invalidate方法请求重绘,然后会向VSYNC服务发送请求,等到下一个VSYNC信号触发的时候,就开始上面说过的流程,也就是处理数据,绘制图像,具体所做的工作就是测量—布局—绘制。接着,屏幕就可以拿到缓存区中绘制好的图像并显示到屏幕上了。


所以任何UI的改变,都要遵从上述所说的VSYNC机制,只是这个过程很短。当然为了保证最快时间绘制到屏幕上,而不让其他消息影响到VSYNC的响应速度,就加入了同步屏障。


如果界面保持静止不变,屏幕会刷新吗?图像会被重新绘制吗?


首先,屏幕刷新频率这个是不会变的,也就是每隔16ms左右就会进行一次刷新,而刷新的帧数据就是我们的程序内部在接收到刷新的vsync信号之后,经过计算绘制后的图像数据。


但是,app并不是每一个vsync信号都能接收到的,只有当应用有绘制需求的时候,才会通过scheduledVsync 方法申请VSYNC信号,然后下一个屏幕刷新的信号才能被我们的程序所接收到,也就是Choreographer类的onVsync方法才能被执行,然后就开始测量—布局—绘制等工作了。


所以,如果界面不变化,我们的程序就收不到VSYNC信号,也就无法处理数据进行绘制了。只有当需要改变界面的时候,才会去申请这个屏幕刷新服务,才能接收到VSYNC信号。这种情况下,屏幕还会进行刷新,只不过刷新的都是同样的图像数据。


参考


https://juejin.cn/post/6863756420380196877

https://www.cnblogs.com/frrj/archive/2018/07/30/brief-info-of-android-display.htmlhttps://www.jianshu.com/p/10db590ed9a6


相关实践学习
部署Stable Diffusion玩转AI绘画(GPU云服务器)
本实验通过在ECS上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。
目录
相关文章
uniapp小程序单页面改变手机电量,头部通知的颜色效果demo(整理)
uniapp小程序单页面改变手机电量,头部通知的颜色效果demo(整理)
|
3月前
|
Web App开发
成功解决Chrome浏览器 控制台下看不到接口信息的问题
这篇文章提供了解决Chrome浏览器控制台不显示接口信息问题的方法,包括检查过滤设置和确保“保留日志”开关已打开。
成功解决Chrome浏览器 控制台下看不到接口信息的问题
|
5月前
|
小程序 API
技术心得记录:微信小程序之图片频繁变化,几秒之后输出结果(适用于抽奖)
技术心得记录:微信小程序之图片频繁变化,几秒之后输出结果(适用于抽奖)
28 0
|
6月前
|
测试技术 iOS开发
蓝条下压和消失导致页面错乱问题解决方案
蓝条下压和消失导致页面错乱问题解决方案
47 0
|
6月前
|
Android开发
个人热点蓝条出现和消失时,页面下压和恢复导致页面混乱及蓝条下压页面底部控件看不到的问题
个人热点蓝条出现和消失时,页面下压和恢复导致页面混乱及蓝条下压页面底部控件看不到的问题
58 0
|
6月前
|
JavaScript
uniapp计算视频学习进程,并且下次回来继续播放(不能快进)
uniapp计算视频学习进程,并且下次回来继续播放(不能快进)
213 0
|
Android开发 芯片
RK3399平台开发系列讲解(系统修改记录篇)1.17、Android系统永不休眠修改步骤(一般是为了开发便利)
RK3399平台开发系列讲解(系统修改记录篇)1.17、Android系统永不休眠修改步骤(一般是为了开发便利)
166 0
RK3399平台开发系列讲解(系统修改记录篇)1.17、Android系统永不休眠修改步骤(一般是为了开发便利)
|
iOS开发
iOS开发 - 写一个刷新的控件(未封装,适合新手学习,查看原理)
iOS开发 - 写一个刷新的控件(未封装,适合新手学习,查看原理)
149 0
iOS开发 - 写一个刷新的控件(未封装,适合新手学习,查看原理)
|
小程序 前端开发 iOS开发
小程序页面左右滑动如何解决
小程序页面左右滑动如何解决
|
Android开发
被后台杀死后,Android应用如何重新走闪屏逻辑
被后台杀死后,Android应用如何重新走闪屏逻辑
598 0
被后台杀死后,Android应用如何重新走闪屏逻辑