OpenGL了解渲染原理

大纲

  • CPU与GPU的职责和区别
  • 计算机渲染原理
  • 屏幕成像与卡顿
  • iOS下的渲染框架
  • View 与 CALayer 的关系
  • CoreAnimation渲染

CPU与GPU的职责和区别

CPU

  • 运算核心、控制核心,资源调配,处理逻辑复杂的内容,相当于指挥者,依赖性高
  • 架构:计算单元、控制单元、高级缓存

不是真正的并发,是时间片的快速切换

GPU

  • 绘图运算的微处理器,GSLS语法,简单,不擅长处理逻辑复杂,跳转复杂,擅长单一,并行处理,类似于小工人,有很多的计算单元,真正的高并发,依赖性非常低的任务
  • 架构:很多的计算单元,实现高并发,快速处理图像、视频计算

计算机渲染原理

计算机显示演变:

  • 随机扫描显示:时间复杂度与图片复杂度成正比
  • 光栅扫描显示:屏幕左上方,向右向后逐行横向扫描,和图像复杂度无关

渲染系统:

  • 显示器(内容来自帧缓存区)

  • 视频控制器(控制刷新的部件,负责帧缓存区与显示器的对应关系,进行显示绘制)

  • 帧缓存区(双缓存、三缓存等) 帧缓存、显存(显示内存)

显存:存储处理后的渲染数据或即将显示的渲染数据

视觉暂留:一秒16帧,就会认为是连贯的,60帧是高清画质

渲染流程

  • 系统总线把图片数据提交给CPU解码,CPU解码完拷贝一份解码数据给显示处理器,放在显示处理器存储器(显存)帧缓存区,帧缓存区存放的是即将显示的渲染数据,显示控制器根据垂直同步Vsyn信号向帧缓存区获取渲染数据,然后提交给显示器显示

屏幕成像与卡顿

屏幕撕裂

img
  • 显示控制器向帧缓存区获取渲染数据,从屏幕左上方,向右向后逐行横向扫描,然后提交给显示器,进行显示,当上一帧的渲染数据获取到了一半,帧缓存区完成新的渲染数据,显示控制器在帧缓存区获取到后半段的数据就是新的渲染数据,前一半是旧的渲染数据,后半段是新的渲染数据,最后提交给显示器显示,就会造成屏幕撕裂

如何防止屏幕撕裂?

  • 垂直同步Vsync+双缓存:,垂直同步相当于加了一个锁,只有当当前渲染数据渲染完毕,才会继续渲染下一个新的渲染数据,防止屏幕撕裂,是以屏幕掉帧、卡顿为代价

  • 三缓存区:合理使用CPU与GPU,减少掉帧的次数

什么是掉帧/卡顿?简单来说就是 屏幕重复显示同一帧数据的情况就是掉帧

如下图所示:当前屏幕显示的是A,显示控制器在收到垂直信号Vsync后,从帧缓存区获取渲染数据,由于CPU和GPU处理的B还没有准备好,帧缓存区的内容还是A,在帧缓存区拿到的还是A,所以最终,屏幕显示的仍然是A

img

View 与 CALayer 的关系

参考自作者Style_月月

首先分别简单说下UIView和CALayer各自的作用

UIView

  • UIView属于UIKIt
  • 负责绘制图形和动画操作
  • 用于界面布局和子视图的管理
  • 处理用户的点击事件

CALayer

  • CALayer属于CoreAnimation
  • 只负责显示,且显示的是位图
  • CALayer既用于UIKit,也用于APPKit

UIKit是iOS平台的渲染框架,APPKit是Mac OSX系统下的渲染框架,

由于iOS和Mac两个系统的界面布局并不是一致的,iOS是基于多点触控的交互方式,而Mac OSX是基于鼠标键盘的交互方式,且分别在对应的框架中做了布局的操作,所以并不需要layer载体去布局,且不用迎合任何布局方式。

【面试题】UIView和CALayer的关系

  • UIView基于UIKit框架,可以处理用户触摸事件,并管理子视图
  • CALayer基于CoreAnimation,而CoreAnimation是基于QuartzCode的。所以CALayer只负责显示,不能处理用户的触摸事件
  • 从父类来说,CALayer继承的是NSObject,而UIView是直接继承自UIResponder的,所以UIVIew相比CALayer而言,只是多了事件处理功能,
  • 从底层来说,UIView属于UIKit的组件,而UIKit的组件到最后都会被分解成layer,存储到图层树中
  • 在应用层面来说,需要与用户交互时,使用UIView,不需要交互时,使用两者都可以

UIView和CALayer的渲染

界面触发的方式有两种

  • 通过loadView中子View的drawRect方法触发:会回调CoreAnimation中监听Runloop的BeforeWaiting的RunloopObserver,通过RunloopObserver来进一步调用CoreAnimation内部的CA::Transaction::commit(),进而一步步走到drawRect方法
  • 用户点击事件触发:唤醒Runloop,由source1处理(__IOHIDEventSystemClientQueueCallback),并且在下一个runloop里由source0转发给UIApplication(_UIApplicationHandleEventQueue),从而能通过source0里的事件队列来调用CoreAnimation内部的CA::Transaction::commit();方法,进而一步一步的调用drawRect

最终都会走到CoreAnimation中的CA::Transaction::commit()方法,从而来触发UIView和CALayer的渲染

这时,已经到了CoreAnimation的内部,即调用CA::Transaction::commit();来创建CATrasaction,然后进一步调用 CALayer drawInContext:()

回调CALayer的Delegate(UIView),问UIView没有需要画的内容,即回调到drawRect:方法

在drawRect:方法里可以通过CoreGraphics函数或UIKit中对CoreGraphics封装的方法进行画图操作

将绘制好的位图交由CALayer,由OpenGL ES 传送到GPU的帧缓冲区

等屏幕接收到垂直信号后,就读取帧缓冲区的数据,显示到屏幕上

iOS下的渲染框架

  • CoreGraphics
  • CoreAnimation
  • CoreImage

不论是CoreGraphics、CoreAnimation还是CoreImage,最终都是通过OpenGL ES或者OpenGL Metal驱动GPU进行干活渲染绘制

CoreAnimation渲染

img

CoreAnimation过程:

  • Application处理Handle Event各种事件
  • Commit Transaction提交事务给Render Server渲染服务
  • Render Server进行解码,在下一个RunLoop到来的时候进行绘制

OpenGL

  • 绘制提交给OpenGL来处理
  • 通过OpenGL驱动GPU干活
  • GPU拿到顶点数据传给顶点着色器
  • 顶点着色器后进行图元装配
  • 图元装配完进行光栅化
  • 光栅化获取到像素范围,把颜色附着到像素点上去
  • 然后把数据传给片元着色器
  • 最后进行屏幕显示
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容