iOS 收藏篇

iOS 图形渲染流程

2020-07-05  本文已影响0人  东篱采桑人

iOS开发中,经常创建很多视图控件来进行界面布局,那这些视图控件是怎么显示到屏幕上的呢?其实在设置了 UIView 的相关属性后,是经过了一个图形渲染流程,才最终可以在屏幕上成像。本文主要介绍两部分内容:

一、图形渲染技术栈

下图所示为iOS图形渲染技术栈,App使用Core GrapicsCore AnimationCore Image等框架来绘制可视化内容。这些框架需要通过Metal(iOS12之前是通过OpenGL ES)来调用GPU进行绘制,最后将绘制好的内容显示在屏幕上。

先来简单认识下这些渲染框架:

UIKit是iOS的基础视图框架,可以用来构建和管理界面可视化内容,响应用户交互事件。

UIKit自身并不具备在屏幕成像的能力,其主要负责对用户交互事件的响应(后面有时间再补一篇事件的传递和响应)。

UIKit中的每一个视图控件内部都有一个关联的 CALayer(后面有时间补一篇UIView和CALayer的联系),对视图控件的任何布局设置,本质上都是对其关联的CALayer进行操作。CALayer是App界面可视化内容的载体。

UIKit只支持iOS。

Core Animation在开发中经常被用来实现动画效果,本质上是一个复合引擎,主要功能包含:渲染构建实现动画。它的职责是尽可能快地组合屏幕上不同的可视内容,这个组合过程是将这些内容分解成一个个独立的图层,并存储在一个叫做图层树的体系之中。和UIKit不同,Core Animation是直接作用于CALayer的。

Core Animation支持iOS和macOS。

Core Graphics 是一个基于Quartz 2D的高级绘图引擎,提供大量的低层次轻量级的2D渲染API。可以用来处理基于路径的绘图,转换,颜色管理,离屏渲染,图案,渐变和阴影,图像数据管理,图像创建,图像遮罩以及PDF文档的生成和解析。

Core Graphics支持iOS和macOS,在Mac OS X中,Core Graphics 还包括用于处理显示硬件,低级用户输入事件和窗口系统的服务。

Core Image是iOS5中引入的一个图片处理框架,里面提供了很多强大高效的图像处理功能。Core Image 可以用来十分轻松地实现滤镜以及图像识别等功能。

OpenGL ES(OpenGL for Embedded Systems),是OpenGL三维图形API的⼦集,针对⼿机、Pad和游戏主机等嵌⼊式设备⽽设计,去除了许多不必要和性能较低的API接⼝。在 Metal 推出之前,iOS相关渲染框架都是基于 OpenGL ES 的。

Metal是Apple在WWDC 2014上为游戏开发者推出的新技术框架 ,只支持Apple相关平台。和OpenGL相比,Metal 能够为3D图像提高10倍的渲染性能。从iOS12开始,渲染框架底层都是基于 Metal 实现的。

GPU(Graphics Processing Unit),是一种可进行绘图、运算的专用微处理器,它的高度并行结构使其在大块数据并行处理的算法中比通用 CPU 更有效。

二、Core Animation Pipeline

前面提到过,对UIKit中视图控件的任何布局设置,本质上都是对其关联的CALayer进行操作,而对CALayer的属性设置都是通过在图层的内容或几何图形上启动不同的动画来进行的(即通过Core Animation来完成)。

因此,屏幕上的可视内容都是需要先经过Core Animation分解成不同的图层并生成图层树, 然后再对这些图层树进行渲染,最终显示到屏幕上,这个过程被称为Core Animation Pipeline(Core Animation流水线)。

上图描绘了Core Animation流水线的大概流程:App处理完事件,由Core Animation将渲染任务及相关数据提交给Render Server。Render Server生成渲染指令后,再调用GPU渲染,最后由iOS的图像设备进行显示。

接下来,详细介绍Core Animation流水线中每个阶段负责处理的任务:

1. Application

在这个阶段,App响应用户事件后(如点击操作、滑动列表等),若需要更新界面内容,会通过CPU完成对显示内容的计算,如:布局计算、图片解码、图像绘制等。在完成对显示内容的计算之后,App将间接通过UIKit或直接通过Core Animation来更新图层树,最后将图层编码后的数据提交给Render Server。主要经历了下面两个步骤:

1.1 Handle Events

App响应事件,并进行处理。

1.2 Commit Transaction

这个阶段细分成下面4步:

构建视图,包括:layoutSubviews方法的重载,addSubview: 方法填充子视图等。CPU在这里完成视图布局的相关计算。

绘制视图,本质是绘制位图,设置最终成像的图元数据。重载drawRect方法可以完成自定义视图的绘制。CPU在这里完成图像绘制的相关计算。

这个步骤会做一些额外的Core Animation工作,比如图像解码图像转换。CPU会在这里对View里的图片进行解码,若CPU不支持该图片格式,则会先进行图像转换,再解码。

将图层进行编码打包,并提交给Render Server。由于图层是以树的结构存在,所以打包操作会递归执行。

2. Render Server

Render Server,即渲染服务器,主要完成两个任务:

解码,将传入的图层信息进行解析并反序列化成渲染树render tree)。

根据渲染树中图层的相关设置属性来生成相应的渲染指令(MetalOpenGL ES),并将渲染相关信息传给GPU。

3. GPU

GPU接收到Render Server传来的渲染信息后,会在收到显示器发送新的VSync信号后才进行渲染,并将渲染结果输出到帧缓冲区(即显存)。

4. Display

在接受到显示器发出的新的VSync信号后,视频控制器会逐行读取帧缓冲区中的数据,再经过一定的数模转换传递给显示器显示。这个阶段的详情步骤可阅读iOS 屏幕图像显示原理

三、总结

综上可知,App界面内容显示到屏幕上的流程如下:

  1. App响应交互事件,如:用户的点击操作,需要更新界面布局。
  2. App通过CPU完成对显示内容的计算,如:布局计算、图片解码、图像绘制等。在完成计算后,App更新图层树,并将图层树进行编码打包,然后将数据提交给Render Server
  3. Render Server将图层数据解码后,生成相应的渲染指令,然后将渲染信息传给GPU
  4. GPU完成渲染后会将渲染结果存入帧缓存区,再由视频控制器逐行读取数据,经由数模转换后将图像显示在屏幕上。

参考

1. iOS 图像渲染原理
2. 深入理解 iOS Rendering Process
3. Getting Pixels onto the Screen中文版(iOS 开发:绘制像素到屏幕)
4. Core Animation Programming Guide

扩展阅读

iOS 屏幕图像显示原理

上一篇下一篇

猜你喜欢

热点阅读