屏幕成像原理

iOS图形显示基本知识

从一个像素点到真正显示在屏幕上,iOS到底在里面做了哪些工作,涉及到哪些Frameworks与Libraries?这是这一章想搞明白的问题。

1.1 图形显示原理

屏幕渲染相关 CRT(Cathode ray tube) 显示器LCD(Liquid-crystal display) 显示器
可以参考文章
图像想显示到屏幕上使人肉眼可见都需借助像素的力量。简单地说,每个像素由红,绿,蓝三种颜色组成,它们密集的排布在手机屏幕上,将任何图形通过不同的色值表现出来。

计算机显示的流程大致可以描述为将图像转化为一系列像素点的排列然后打印在屏幕上,由图像转化为像素点的过程又可以称之为光栅化,就是从矢量的点线面的描述,变成像素的描述。

image.png

回溯历史,可以从过去的 CRT 显示器原理说起。CRT 的电子枪按照上面方式,从上到下一行行扫描,扫描完成后显示器就呈现一帧画面,随后电子枪回到初始位置继续下一次扫描。为了把显示器的显示过程和系统的视频控制器进行同步,显示器(或者其他硬件)会用硬件时钟产生一系列的定时信号。当电子枪换到新的一行,准备进行扫描时,显示器会发出一个水平同步信号(horizonal synchronization),简称 HSync;而当一帧画面绘制完成后,电子枪回复到原位,准备画下一帧前,显示器会发出一个垂直同步信号(vertical synchronization),简称 VSync。显示器通常以固定频率进行刷新,这个刷新率就是 VSync 信号产生的频率。尽管现在的设备大都是液晶显示屏了,但原理仍然没有变。1

如在 iPhone5 的上就有1,136×640=727,040个像素,而在15寸Retain的MBP上,这一数字达到15.5百万以上,当你滚动整个屏幕的时候,数以百万计的颜色单元必须以每秒60次的速度刷新,计算量可想而知。

1.2 iOS的显示架构

从软件层面上,iOS借助Core GraohicsCore AnimationCore Image完成图形的处理,它们又都是借助OpenGL ES来完成底层的工作,其结构如下图所示:

image.png

Display 的上一层便是图形处理单元 GPU,GPU 是一个专门为图形高并发计算而量身定做的处理单元。这也是为什么它能同时更新所有的像素,并呈现到显示器上。它并发的本性让它能高效的将不同纹理合成起来。因为涉及到各种图形矩阵的计算,它跟CPU最直观的区别在于浮点计算能力要超出CPU很多。所以在开发中,我们应该尽量让CPU负责主线程的UI调动,把图形显示相关的工作交给GPU来处理,因为涉及到光栅化等一些工作时,CPU也会参与进来,这点在后面再详细描述。

GPU Driver 是直接和 GPU 交流的代码块。不同的GPU是不同的性能怪兽,但是驱动使他们在下一个层级上显示的更为统一,典型的下一层级有 OpenGL/OpenGL ES.

OpenGL(Open Graphics Library) 是一个提供了 2D 和 3D 图形渲染的 API。GPU 是一块非常特殊的硬件,OpenGL 和 GPU 密切的工作以提高GPU的能力,并实现硬件加速渲染。

OpenGL 之上扩展出很多东西。在 iOS 上,几乎所有的东西都是通过 Core Animation 绘制出来,然而在 OS X 上,绕过 Core Animation 直接使用 Core Graphics 绘制的情况并不少见。2

在硬件层面的调度我们可以看下图所示:

image.png

计算机系统中 CPU、GPU、显示器是以上面这种方式协同工作的。CPU 计算好显示内容提交到 GPU,GPU 渲染完成后将渲染结果放入帧缓冲区,随后视频控制器会按照 VSync 信号逐行读取帧缓冲区的数据,经过可能的数模转换传递给显示器显示。

在最简单的情况下,帧缓冲区只有一个,这时帧缓冲区的读取和刷新都都会有比较大的效率问题。为了解决效率问题,显示系统通常会引入两个缓冲区,即双缓冲机制。在这种情况下,GPU 会预先渲染好一帧放入一个缓冲区内,让视频控制器读取,当下一帧渲染好后,GPU 会直接把视频控制器的指针指向第二个缓冲器。如此一来效率会有很大的提升。

1.3 iOS图形显示流程

我们可以再从上层看一下iOS中不同的Frameworks和Libraries之间的一些联系:

image.png

在最顶层的就是UIKit,一个在iOS中用来管理用户图形交互的Objc高级的框架,它由一系列的集合类构成,例如UIButton、UILabel,每一个都负责他们指定的UI Control角色。UIKit本身构建在一个叫Core Animation的框架之上。最后一部分是Core Graphics,曾经在Quartz(一个基于CPU的绘制引擎,在OS X系统上初次露脸)中被引入。这两个较为底层的框架都是用C语言编写的。

我们经常说到的硬件加速其实是指OpenGL,Core Animation/UIKit基于GPU之上对计算机图形合成以及绘制的实现,直到目前为止,iOS上的硬件加速能力还是大大领先与android,后者由于依赖CPU的绘制,绝大多数的动画实现都会让人感觉明显的卡顿3

CoreAnimation的渲染流程可以用下图来概括:

image.png

在GPU的渲染过程中,我们能看到顶点着色器与像素着色器参与到图像的处理。

在objc.io中有一篇文章进一步地阐明了顶点着色器与像素着色器 (GPU 加速下的图像处理)4

1.4 补充知识

1.4.1 图像多层次的合成—为何设置透明会增加GPU工作量5

合成 | Blended

在图形世界中,合成是一个描述不同位图如何放到一起来创建你最终在屏幕上看到图像的过程。

一个不透明的红色盖在蓝色上那我们看到的就是一个蓝色,但一个半透明的红色盖在蓝色让我们得到的却是一个紫色,这便是合成所要做的工作。

我们可以用下面这个公式来计算每一个像素:

R = S + D * ( 1 – Sa )

结果的颜色是源色彩(顶端纹理)+目标颜色(低一层的纹理)*(1-源颜色的透明度)。在这个公式中所有的颜色都假定已经预先乘以了他们的透明度。

假定两个纹理都完全不透明,比如 alpha=1.如果目标纹理(低一层的纹理)是蓝色(RGB=0,0,1),并且源纹理(顶层的纹理)颜色是红色(RGB=1,0,0),因为 Sa 为1,所以结果为:

R = S

如果源颜色层为50%的透明,比如 alpha=0.5,既然 alpha 组成部分需要预先乘进 RGB 的值中,那么 S 的 RGB 值为(0.5, 0, 0),公式看起来便会像这样:

image.png

所以当源纹理是完全不透明的时候,目标像素就等于源纹理。这可以省下 GPU 很大的工作量

这也是为什么 CALayer 有一个叫做 opaque 的属性了。如果这个属性为 NO,GPU 将不会做任何合成,而是简单从这个层拷贝,不需要考虑它下方的任何东西(因为都被它遮挡住了)。

1.4.2 图层对齐—为何图片缩放会增加GPU工作量

当所有的像素是对齐的时候我们得到相对简单的计算公式。每当 GPU 需要计算出屏幕上一个像素是什么颜色的时候,它只需要考虑在这个像素之上的所有 layer 中对应的单个像素,并把这些像素合并到一起。或者,如果最顶层的纹理是不透明的(即图层树的最底层),这时候 GPU 就可以简单的拷贝它的像素到屏幕上。

当一个 layer 上所有的像素和屏幕上的像素完美的对应整齐,那这个 layer 就是像素对齐的。主要有两个原因可能会造成不对齐。第一个便是滚动;当一个纹理上下滚动的时候,纹理的像素便不会和屏幕的像素排列对齐。另一个原因便是当纹理的起点不在一个像素的边界上。

在这两种情况下,GPU 需要再做额外的计算。它需要将源纹理上多个像素混合起来,生成一个用来合成的值。当所有的像素都是对齐的时候,GPU 只剩下很少的工作要做。

Core Animation 工具和模拟器有一个叫做 color misaligned images 的选项,当这些在你的 CALayer 实例中发生的时候,这个功能便可向你展示。

关于iOS设备的一些尺寸限制可以看这里:iOSRes

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容