一、撕裂
图像撕裂.png发生原因: CPU 和 GPU 的计算能力跟不上现在的帧率,此时才会有可能发生撕裂。
撕裂产生的原因.png
当第一帧图像扫描到某个位置时,GPU拿到新的数据并存储到帧缓冲区,这时候视频控制器从帧缓冲区扫描新拿到的一帧的图像。即撕裂是两张图片组合而来,原因就是视频控制器显示速度小于GPU处理图形的速度。
注:一般出现在低端设备 加载一个高FPS的视频/游戏场景,在iOS设备上并不常见。或者非常低端的iOS设备上,加载一个APP界面上出现非常高频的动画效果以及图层复杂度高且涵盖了动画效果。
二、解决撕裂
苹果采用:双缓存区 DoubleBuffering +垂直同步信号 Vsync
双缓存: GPU 开辟AB两个帧缓冲区
垂直同步信号: 帧缓存区加锁 防止出现撕裂情况(当前帧缓存区的数据显示到屏幕后,再显示下一缓存区数据)
执行流程就是当A帧缓冲区拿到第一帧数据,给A缓冲区加上一把锁,屏幕控制器从A拿到数据并逐行扫描完成,A帧缓冲区解锁,并且屏幕控制器指向B帧缓冲区,B帧缓冲区加锁并逐行扫描显示,在屏幕控制器扫描B帧缓冲区的时候,A帧缓冲区拿到GPU传过来的新一帧数据,以此类推,解决撕裂问题
注:双缓存+垂直同步信号并没有真正的撕裂解决问题,制标不制本。真正是问题是CPU和GPU计算能力达不到帧率(所以用再多的缓存区也只是打补丁。但可以解决很少见的撕裂问题)
三、掉帧
启用:双缓存+垂直同步信号后解决了撕裂 ,会引起新问题掉帧
掉帧是重复渲染同一帧数据
注:我们在解决撕裂问题时,只是让别人看不到撕裂,会等待,重复显示一桢
为了减少掉帧(注意不是解决,掉帧问题只能尽量的减少,而不是解决,三级缓冲区也有可能出现掉帧),引入三级缓存区,三级缓冲区是为了充分利用CPU/GPU的空余时间,开辟ABC三个帧缓冲区,A显示屏幕, B也渲染好,C再从GPU拿取渲染数据,当屏幕缓冲区和帧缓冲区都弄好了,然后视频控制器再指向帧缓冲区的另外一个,再显示,这样交替,达到减少掉帧的情况,这样做就比二级缓冲区多了一个确认的操作
总结屏幕卡顿的原因:
1.CPU 和 GPU 渲染流水线耗时过长 导致 -> 图像撕裂
2.垂直同步信号 Vsync + 双缓存区 DoubleBuffering 以掉帧为代价-> 解决图像撕裂
3.三缓存区:合理使用CPU和GPU 减少掉帧次数
网友评论