本文首发来自微信公众号 程序员华仔

---------------------

做IOS开发,特别是做界面部分的同学,不得不掌握图形的渲染原理。这里包括不限于图形渲染机制、离屏渲染、png图片渲染等重要问题。

下面以一个系列文章分享下。

屏幕图像显示原理

讲到渲染,就要从计算机的屏幕图像显示开始。在计算机的发展过程中,屏幕图像显示的发展又分了两个阶段:随机扫描,光栅扫描。

随机扫描

电子束是随机的移动,即电子束可以按照显示命令任意方向上自由移动。例如要在计算机上显示一个三角形,那么电子束就按照三角形的边的位置,直接移动,从而绘制出需要的图形。这种扫描方式只能绘制直线、三角形等简单图形,要绘制人物、风景等复杂图形就实现不了。只能通过光栅扫描来实现了。

光栅扫描

电子束依照固定的扫描线和规定的扫描顺序进行扫描。电子束先从荧光屏左上角开始,向右扫一条水平线,然后迅速地回扫到左边偏下一点的位置,再扫第二条水平线,照此固定的路径及顺序扫下去,直到最后一条水平线,从而完成了整个屏幕的扫描。这也是我们常说的逐行扫描。通过这种方式就能绘制人物、风景等复杂图形了。

总结成一句话:随机扫描、光栅扫描都是将二进制数据转换成可见的视图。

渲染的部件

这里我们还需要搞清楚一点:我们计算机渲染是由哪个部件来完成的, CPU还是GPU?答案是GPU。若从普通用户的角度来说,那就是我们的显卡(包括独立显卡和集成显卡)来完成的。

那为什么是GPU呢?一个原因是GPU擅长于简单的大规模并发计算和协同处理,二是CPU偏向于复杂的控制运算。就好比GPU是小学生,处理一些简单的加减运算,CPU就像大学教授,懂微积分运算。像图形渲染属于简单的运算,只要找来十几个小学生计算就可以了, 没有必要去找大学教授用微积分来计算。

但这里特别说明下:IOS平台的png格式的图片解码是由CPU来完成的,而非GPU。这点先记下。后面会讲到。

GPU渲染流水线:

经过前面的讲述,图形经过GPU就会变成我们需要显示的图片。那它内部是怎么个过程呢?

GPU 图形渲染具体分以下六个阶段:

Step1.顶点着色器(Vertex Shader)

Step2.形状装配(Shape Assembly)

Step3.几何着色器(Geometry Shader)

Step4.光栅化(Rasterization)

Step5.片段着色器(Fragment Shader)

Step6.测试与混合(Tests and Blending)

这个过程很复杂,就不详细的讲述。反正通过以上六个步骤,就能得到我们需要显示的图片。

帧缓冲区

经过前面六步处理,数据都会进入帧缓冲区,再从帧缓冲区到显示控制器,最后在屏幕上显示。

帧缓冲区是一个很重要的概念,所有要显示的图片都要经过它,它本身是一块内存缓冲区,其中包含完整视频帧中所有像素的数据。其大小由图形的分辨率、色深或调色板大小来决定。

上面讲了各个具体的概念,再统一起来讲下图形渲染机制。

渲染机制

以IOS开发中UIButton设置一张背景图片为例,先调用了UIButton的SetImage函数,该函数会调用Core Animation 框架,该框架又调用OpenGL ES/Metal底层库,然后进入GPU模块,再经过GPU的渲染流水线,形成图形并放入帧缓冲区中,最终由显示控制器处理并显示在屏幕上。以下是图示

小结:

1.现在的图形/图像都是光栅扫描完成.

2.图形/图像的渲染是由GPU完成的。

3.图像/图形的渲染流程是:图片经过OpenGL ES/Metal底层库进入GPU模块,再经过GPU的渲染流水线,形成的位图图形并放入帧缓冲区中,最后由显示控制器负责显示。

图片撕裂

具体图片撕裂样式见下图。

出现此问题的原因:在显示控制器还在光栅视频帧A时,GPU已经完成了B帧的处理,然后会把B帧的数据放入帧缓冲区。这样显示控制器在光栅屏幕的时候,拿到的是B帧数据。从而导致了屏幕的上部分是A帧(旧数据),下部分是B帧(新数据).

那针对这个问题,怎么解决呢?其实也简单,就是在刷A帧的时候,帧缓冲区的数据不更新,直到屏幕中A帧最后一条刷新了。这就是垂直扫描的同步信号。简单来说,是对帧缓冲区加了一把锁,在起始扫描A帧的时候,加上锁(不允许更新帧缓冲区),当扫描到A帧的最后一行时,发送一个垂直同步信号,释放锁。

视频卡顿

当一屏幕扫描完,垂直扫描信号发出,但是CPU/GPU还没有完成新一帧的渲染工作,那么显示控制器还是继续显示上一帧的数据,这个现象就是卡顿,也叫掉帧。解决这个问题的方法是多缓冲区,其中iOS设备采用的时候双缓冲区(Double Buffering),安卓设备是采用三缓冲区.比较单缓冲区,多缓冲区能减少卡顿次数.

其实呢,视频卡顿本质来说是:CPU/GPU处理速度太慢,光栅一屏数据,还没有完成新图片的渲染。这个时候,我们就要想想我们业务做了些什么业务?让CPU/GPU这么耗时。

在实际情况下,iOS设备采用了垂直同步信号+双缓冲区 两个方案来解决图形的撕裂和卡顿问题。

-----好的,篇幅太长,先分享到这里。

参考资料:

深度好文:关于图形渲染以及离屏渲染

【连载】IOS开发-图形渲染(一)相关推荐

  1. IOS开发语言Swift入门连载---类型转换

    IOS开发语言Swift入门连载-类型转换 类型转换可以判断实例的类型,也可以将实例看做是其父类或者子类的实例. 类型转换在 Swift 中使用is 和 as 操作符实现.这两个操作符提供了一种简单达 ...

  2. 零基础如何学习 iOS 开发?

    我创建了一个 CS193P - SwiftUI 和 iOS 开发的学习群组,有兴趣可以加入,群内学习者以北美为主,因此聊天请使用英语,谢谢.加入 Slack 群组 正文: 建议从 SwiftUI 开始 ...

  3. iOS资源帖-优秀博客、iOS开发技术文、学习网站

    原链接:https://www.jianshu.com/p/619c61d9c8fb 一些博客 王巍 Objc中国发起人.Line工程师 ibireme YYKit作者 bang JSPatch作者 ...

  4. 《iOS开发实战 从入门到上架App Store(第2版)》书籍目录

    第1章 开发准备 1.1 iOS 10新特性简述 1.1.1 新增触觉反馈编程接口 1.1.2 SiriKit框架的开放 1.1.3 引入Messages App 1.1.4 通知框架的整合与扩展 1 ...

  5. iOS开发~卡顿优化

    应用卡顿是让人头疼的问题,不像闪退一样直观明了,可以直接通过异常信号或调用栈分析得到,常常让人无处下手.好的用户体验需要我们把细节做到位,画面掉帧会导致卡顿感,造成不好的印象.卡顿是如何造成的,下面详 ...

  6. IOS开发UISearchBar失去第一响应者身份后,取消按钮不执行点击事件的问题

    在iOS开发中,使用UISearchBar的时候,当搜索框失去焦点的时候,取消按钮是默认不能点击的,如图按钮的颜色是灰色的:    这是因为此时取消按钮的enabled属性被设置为NO了,那么当我们需 ...

  7. iOS开发UI篇—transframe属性(形变)

    iOS开发UI篇-transframe属性(形变) 1. transform属性 在OC中,通过transform属性可以修改对象的平移.缩放比例和旋转角度 常用的创建transform结构体方法分两 ...

  8. 【ios开发/Xcode】使用UITableView完成学生信息及成绩的显示

    [ios开发/Xcode]使用UITableView完成学生信息及成绩的显示 设计思想 实现效果 源代码 设计思想 首先创建所有页面的故事版,包括,登录.注册与成绩页面 接着设置故事版的关联代码,如下 ...

  9. 【ios开发/Xcode】实现登录注册

    [ios开发/Xcode]实现登录注册 实现效果 源代码 实现效果 首先进入初始界面,输入账号Linchuantao,密码Linchuantao,显示登录失败(如下左图),因此需要进行注册,点击左下角 ...

最新文章

  1. unity字符串换行符_Unity中Text中首行缩进两个字符和换行的代码
  2. 2010年基于Linux的10大技术趋势
  3. 金山称清理专家遭微软误杀:正积极协商解决
  4. Word 2003安全模式修复程序
  5. 容器学习 之 容器的组件(三)
  6. 模块定义文件导出类_浓缩的就是精华——ES6模块精炼讲解
  7. 列表页时间日期标签靠显示html,帝国CMS列表页面list.var分别调用年月日,显示个性时间日期...
  8. 2016年2月23日----Javascript运算符
  9. 数据接口请求异常:error_springboot2.2.X手册:构建多元化的API接口,我们这样子设计
  10. spring教程笔记5
  11. 安装Esxi6.5时出现 menu.c32:not a COM32R image 的处理方法
  12. 部署项目在Tomcat出现,tomcat报错More than one fragment with the name [org_apache_tomcat_websocket]
  13. 仪器计量校准机构的CNAS和CMA有哪些区别?分别具有什么作用?
  14. 在日本转职需要到入管办理转职手续
  15. php发送文本邮件和带附件邮件
  16. python中append函数解析_对python中的pop函数和append函数详解
  17. Excel从身份证号提取生日
  18. EPS HSS、HLR、IMS HSS有什么区别?分别用于什么场景
  19. layui表头样式_layui表格的样式设置
  20. npm login e401问题(npm ERR! Unable to authenticate, need: BASIC realm=“Sonatype Nexus Repository Mana)

热门文章

  1. 合伙人股权设计的9点常识
  2. 音视频开发进阶|第六讲:色彩和色彩空间·下篇
  3. 2019年全国职业院校技能大赛—大数据技术与应用
  4. Python爬虫新手入门教学(十八):爬取yy全站小视频
  5. 喝茶有讲究:各种茶的功效
  6. Java导入Excel数据
  7. HTML a 标签的 href 属性
  8. 陶瓷金属牙冠-市场现状及未来发展趋势
  9. 面试题:写两个线程,一个线程打印1~26,另一个线程打印字母A-Z,交替打印数字和字母
  10. 16路4k相机拍照的jpeg照片共有多大