OpenGL 二 - 002、屏幕撕裂与掉帧

一、图片显示

GPU 渲染 --> 数据存帧缓存区 --> 显示控制器读取帧缓存区数据(位图,一帧帧读取) --> 数模转换(大学课程已忘记...) --> 逐行扫描、显示

二、屏幕撕裂

1、撕裂原因

显示的完美路程是:每扫描一张图 --> 不断刷新不断扫描,一边扫描、一边读取 --> 扫了最新的就正好显示,数据实时。

但是,渲染过程中,CPU GPU 处理有一定的时间上的缓存,读取时帧缓存区中仍是旧的数据 --> 那么读取时则读出老的数据 --> 显示老数据  ---> 继续扫描、数据更新 --> 再读取时数据更新完成 --> 读取到新数据 --> 进行显示 ==》 导致上下显示的分别是旧数据和新数据,进而图片可能出现撕裂效果。下图蓝框,老旧数据图片显示异常。

 

2、屏幕撕裂解决方案

苹果:垂直同步Vsync + 双缓存区

  垂直同步Vsync:帧缓存区加锁,防止撕裂 --> 扫描过程中 必须把整个图片扫完,不论新旧都扫完为止,使之察觉不到撕裂。

  双缓存区:撕裂原因 - CPU/GPU 计算时,是需要时间的 --> 双缓存区   下图流程

   2个缓存区依次交替,从根本上解决撕裂。

三、掉帧

双缓存区解决了撕裂(CPU/GPU 速度问题其实并未解决)。但是他引发了另一个问题 : 掉帧

接收 Vsync 信号,但若CPU/GPU 还没处理完新的图片数据 --> 帧缓存区拿不到数据 --> 重复渲染显示同一帧数据 - 掉帧

 

 解决掉帧:三缓存区(只要安卓使用了三缓存区,苹果是双缓存区) - CPU/GPU相对来说会有个闲置时间 --> 同样是治标不治本,也是有可能出现掉帧。

撕裂的本质原因是 CPU/GPU 的计算能力跟不上帧率(60FPS),而苹果的 vsync垂直信号和双缓存区只是让我们察觉不到撕裂,只是偶尔会察觉掉帧,并非真正完全解决了的问题,治标不治本,类似于打补丁。但是,现实使用中,我们也很少会遇到。例:超级复杂高清的多图层叠加的动画放在 phone4 上可能会比较容易察觉到这个问题。

掉帧,也是CPU GPU计算能力,计算跟不上,出现一个等待(重复显示某帧)。

显示一个简单的 imageView 是不会出现撕裂or掉帧的,我们在iOS设备上看到撕裂的几率极其小。

 

四、屏幕卡顿原因

  1、CPU/GPU 流水线计算耗时长 --> 掉帧

  2、垂直同步Vsync + 双缓存区 强制同步,以掉帧为代价,解决屏幕撕裂

  3、三缓存区只能更合理的使用CPU/GPU,减少掉帧次数,并不能完全解决

 五、iOS下得渲染流程

  Apple 官方:If you are writing iOS apps, you are using Core Animation whether you know it or not. And if you are writing OS X apps, you can take advantage of Core Animation with extremely little effort. Core Animation sits beneath AppKit and UIKit and is integrated tightly into the view workflows of Cocoa and Cocoa Touch. Of course, Core Animation also has interfaces that extend the capabilities exposed by your app’s views and give you more fine-grained control over your app’s animations.

核心动画 CoreAnimation 渲染 (渲染流程 推荐博客:链接地址)

  CoreAnimation:渲染、构建 和 实现动画 -- Render, compose, and animate visual elements.

layer 和 view 区别(推荐博客中也有讲解 赞):

 view:1、绘制/动画;2、布局/view管理3、交互事件的管理响应等 UIview 基于 UIlayer 的封装的。APPKit/UIKit

 layer:渲染/动画。只负责显示 -- 位图 

  

posted @ 2020-07-07 20:49  张张_z  阅读(1028)  评论(0编辑  收藏  举报