像素如何显示在屏幕上的?

1. 概述
写这篇总结的目的是想让大家了解眼睛看到屏幕上漂亮的颜色和图片背后所发生的事情。其实题目取的有点夸张,因为这里涉及到的知识非常多,所以这篇文章会我挑一些重要的内容来讲。

2. 什么是像素
简单的讲像素就是组成数字图像的基本单元。我们看到的图像其实都是由一个个像素组成的。每个像素可有各自的颜色值,像素可分成红、绿、蓝三原色像素(RGB色域),或者青、品红、黄和黑(CMYK色域,印刷行业以及打印机中常见)。我们手机、电脑、以及电视等屏幕上的像素是由红,绿,蓝三种颜色组件构成的。单位面积内的像素越多代表分辨率越高。

800万像素 3,264 × 2,448=7,990,272
1000万像素 3648 × 2,736=9,980,928

3. 软件组成

1.png

GPU(图像处理单元)一般都用来处理图像。他具有很高的并发性,这也是为什么它能同时更新所有的像素,并呈现到显示器上。

3.1 GPU 与 CPU 的比较
理解 GPU 和 CPU 之间区别的一种简单方式是比较它们如何处理任务。本质上 CPU 由专为顺序串行处理而优化的几个核心组成,而 GPU 则拥有一个由数以千计的更小、更高效的核心(专为同时处理多重任务而设计)组成的大规模并行计算架构。

GPU 具有非常出色的浮点计算性能,工作效率上比 CPU 更省电。
CPU 可以做很多不同的事情,但是合成图像上却比不过 GPU。
另外还有可能大家都不知道的是:现在热门的机器学习,深度学习都用是 GPU,各大平台也在推出 GPU 云计算服务。

3.2 那么为什么是 GPU 呢?
主要原因是:深度学习需要很高的内在并行度、大量的浮点计算能力以及矩阵预算,深度学习的工作 99% 都可以类比成将不同的矩阵进行相乘或者矩阵和向量进行相乘。刚好 GPU 可以提供这些能力,并且在相同的精度下,相对传统 CPU 的方式,拥有更快的处理速度、更少的服务器投入和更低的功耗。
http://www.nvidia.cn/object/machine-learning-cn.html

3.3 OpenGL
OpenGL(Open Graphics Library) ,它是在1992年第一次发布的(20多年前的事了)第一个和图形硬件(GPU)交流的标准化方式,简单的说就是提供图像 2D 和 3D 图形渲染的 API 的底层图形库。他虽然非常底层,但是当这是一个重大的飞跃,程序员不再需要为每个GPU重写他们的驱动应用了。
OpenGL 之上扩展出很多东西。(看上面的架构图)在 iOS 上,几乎所有的东西都是通过 Core Animation 绘制出来,Core Animation 是基于Core Graphics 和 Core Animation 的更上层的抽象。

对于一些专门的应用,尤其是游戏,可能直接和 OpenGL/OpenGL ES 交流。

这些框架都是运行在 GPU 上的,所以要记住 GPU 是一个非常强大的图形硬件,并且在显示像素方面起着核心作用。

**4. 参与的硬件,阐述需要遇到的挑战 **


3.png

第一个挑战正如上面这张简单的图片:GPU 需要将每一个 frame 的图层(位图:可以直接理解成一个画面)合成在一起(一秒60次),每一个图层会占用 VRAM(video RAM),GPU 在合成方面非常高效,但是某些合成任务却比其他更复杂,并且 GPU在 16.7ms(1/60s)内能做的工作也是有限的。

下一个挑战就是将数据传输到 GPU 上。为了让 GPU 访问数据,需要将数据从 RAM 移动到 VRAM 上。这就是提及到的上传数据到 GPU。这看起来貌似微不足道,但是一些大型的图层却会非常耗时。

最后,从一个比较实际的例子讲一下整个流程:CPU 开始运行你的程序,你可能会让 CPU 从 本地加载一张 PNG 的图片并且解压它。这所有的事情都在 CPU 上进行,然后当你需要显示解压缩后的图片时,它需要以某种方式上传到 GPU。还有一些看似平凡的,比如显示文本,对 CPU 来说却是一件非常复杂的事情,所以 CPU 会调用 GPU 上的 一些框架(Core Text 和 Core Graphics)去生成一个位图,作为一个图层上传到 GPU 并准备显示出来。当你滚动或者在屏幕上移动文本时,同样的图层能够被复用,CPU 只需简单的告诉 GPU 新的位置就行了,GPU 就可以重用存在的图层了,并不需要重新渲染,位图也不需要重新上传到 GPU。

5. 图像的合成
在图形世界中,大家都知道,一张完整的画面是有很多个图层组合在一起的,但实际的物理设备上只有一个屏幕,所以对于屏幕上的每一个像素,GPU 需要算出怎么混合这些图层来得到像素 RGB 的值。

如果我们有第二个图层放在第一个图层之上,然后GPU将会把第二个图层合成到第一个图层中。有很多种不同的合成方法,但是如果我们假定两个图层的像素对齐,并且使用正常的混合模式,我们便可以用下面这个公式来计算每一个像素:

R = S + D * ( 1 – Sa )

6. 不透明 VS 透明
通过上面的公式我们可以知道:当源图层是完全不透明的时候,目标像素就等于源图层。这可以省下 GPU 很大的工作量,这样只需简单的拷贝源图层而不需要合成所有的像素值。(不需要考虑它下方的任何东西,因为都被它遮挡住了)。

7. 像素对齐VS 不重合在一起
之前我们考虑的都是基于像素对其的图片,当所有的像素是对齐的时候我们得到上诉相对简单的计算公式。我们只需要考虑在这个像素之上的所有图层中对应的单个像素,并把这些像素合并到一起。或者,如果最顶层的图层是不透明的,这时候 GPU 就可以简单的拷贝它的像素到屏幕上。
那么为什么会照成像素不对其呢?主要有两个原因可能会造成不对齐。
第一个便是缩放;当一个图层放大缩小的时候,图层的像素便不会和屏幕的像素排列对齐。
另一个原因便是当图层的起点不在一个像素的边界上。
(Plus 上是3倍像素,如果我们在编程中设置距离为 0.5 的高度就可能出现半个像素点,照成不对其)
在这两种情况下,GPU 需要再做额外的计算。它需要将源图层上多个像素混合起来,生成一个用来合成的值。当所有的像素都是对齐的时候,GPU 只剩下很少的工作要做。
8. Masks 蒙版实现“遮罩”效果
在 iOS 中Masks有几个特点:
在 Mask 范围之外的图层将不被显示
Mask 的透明度为 0 时图层不显示或不显示,当其为 0 < alpha < 1 时图层为半透明状态
我们来看一个实际例子:sketch

ResultLayer = ContentLayer * MaskLayer_Alpha

9. 离屏渲染(Offscreen Rendering)
GPU 渲染有两种方式,一种是 On-Screen Rendering:意为当前屏幕渲染,指的是GPU的渲染操作是在当前用于显示的屏幕缓冲区中进行。
另外一种是 Off-Screen Rendering: 意为离屏渲染,指的是GPU在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作。
还有一种特殊的离屏渲染方式:CPU 渲染在 iOS 中如果我们重写了 -drawRect: 方法,并且使用任何Core Graphics的技术进行了绘制操作,整个渲染过程由 CPU 完成。
当使用离屏渲染的时候会很容易照成性能消耗,主要是屏幕外缓冲区和屏幕缓冲区上下文环境的切换很耗性能。所以经常会导致我们的 App 达不到每秒达到 60 帧的标准。

10. JPEG VS PNG
每个人都知道 JPEG。它是相机的产物。它代表着照片如何存储在电脑上。
将 JPEG 数据转换成像素数据是一个非常复杂的过程,他的解压很慢,如果你将 JPEG 文件创建一个 UIImage 并且绘制到屏幕上时,将会有一个延时,因为 CPU 这时候忙于解压这个 JPEG。特别是在列表里你,每个 Cell 都需要解压 JPEG,那么你的滚动当然不会平滑会变的非常卡。

PNG读作”ping”。和 JPEG 相反,它的压缩对格式是无损的,且解码 PNG 数据比解码 JPEG 简单的多。因为是无损的,像素还原非常好,所以对于像程序中的原图(如buttons,icons),我们要用 PNG 格式的图片。

优化总结:
保持图层的像素对齐
尽量保持图层的透明度为 1
尽量避免离屏渲染
我们还是要把尽可能多的绘制工作交给 GPU 做,而让 CPU 尽可能的来执行应用程序。通常,GPU 的渲染性能要比 CPU 高效很多,同时对系统的负载和消耗也更低一些。
选择合适的图片格式

Getting Pixels onto the Screen

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

推荐阅读更多精彩内容

  • 绘制像素到屏幕上 answer-huang22 Mar 2014 分享文章 一个像素是如何绘制到屏幕上去的?有很多...
    阿狸旅途T恤阅读 1,619评论 0 7
  • 像素是如何显示在屏幕上的呢? 当然这里有很多种方式将某些东西显示到显示器上面,并且它们可能涉及到许多不同的fram...
    樗同学阅读 1,755评论 1 3
  • 卷首语 欢迎来到 objc.io 的第三期! 这一期都是关于视图层的。当然视图层有很多方面,我们需要把它们缩小到几...
    评评分分阅读 1,755评论 0 18
  • 有很多种framework以及很多种方法的组合可以在屏幕上渲染UI元素,我们在这里讨论这个过程中发生的事情,希望这...
    纵横而乐阅读 4,480评论 4 25
  • 蛮喜欢这一张的 我的眼神有一种蜜汁呆滞-_-||
    零点未至阅读 339评论 2 3