iOS渲染概述

App图形图像的渲染流程

我们在使用UIVIew,Image等组件的时候,是怎么一步步渲染到屏幕上的呢?动画又是怎么实现的?

这里我们先了解几个概念:

1.CPU:CPU主要负责的是逻辑运算,如图像的布局,文本的计算和排版,图片格式的转换和解码,图像的绘制等。

2.GPU:GPU主要负责图片渲染的运算,它可以把CPU计算好的显示内容进行纹理渲染,然后把渲染后的内容放入Frame Buffer(帧缓存区)。

注意:GPU相比通用计算的CPU来讲,其有两个优势:

  • 处理图片计算的能力要强的多,因为硬件支持T&L(Transform and Lighting,多边形转换与光源处理)
  • 并发能力比CPU也要大 详细对比如下:

3.帧缓存区(双缓冲机制):GPU渲染后的内容会被放到当前屏幕的帧缓存区,不需要额外开辟空间,我们知道 iPhone 的屏幕刷新率是 60Hz,也就是刷新一帧的时间是 16.67 ms, 每隔这段时间视频控制器就会去读一次缓存区的内容来显示。 如果GPU性能出现问题,无法在这段时间将更新渲染结果到帧缓存区,那么下一个时间段还是会呈现上一帧的画面,这就是掉帧。

4.视频控制器:视频控制器会读取帧缓冲区中的内容,GPU在开始时会绘制后缓存区中的内容,然后视频控制器读取完内容后,就会去读取后缓存区的内容,然后GPU再绘制前缓存区的内容。也就是说对前后缓存区的读取是交替进行。

其基本渲染流程如下:

GPU中的数据从哪里来?

对于iOS的UIKit,答案就是OpenGL和Metal

OpenGL是苹果最初的采用的渲染框架,其具有跨平台、性能好,包大小可控等优点,但是随着图形技术的发展,其他也暴露出很多问题:

  • 现代 GPU 的渲染管线已经发生变化。
  • 不支持多线程操作。
  • 不支持异步处理。

因此苹果重新设计了Metal框架,其优势如下:

  • 更高效的 GPU 交互,更低的 CPU 负荷。
  • 支持多线程操作,以及线程间资源共享能力。
  • 支持资源和同步的控制。

在UIKit中,OpenGL的数据主要从以下三个库获得:

  • Core Graphics : 基于Quartz的绘图引擎,用于运行时绘制图像
  • Core Image : 处理图像
  • Core Animation : 核心动画和图层渲染能力

那么我们可以知道iOS平台的渲染框架如下:

这时候你可能会有疑问:我们实际开发中好像并没有直接调用Core Graphics, Core Animation这些框架,而是使用UIIMageView,UIView这些类,那么UIKit框架又是怎么调用Core框架来渲染的呢?

UIKit实现

在介绍UIKit是怎么一步步渲染之前,得先了解UIView和CALayer的区别

UIVIew和CALayer

UIVIew和CALayer体现出了职责分离的思想,其中,UIView负责触摸事件的处理(继承自UIResponder ),CALayer负责渲染层(继承自NSObject)。之所以这样设计,是因为Mac系统使用的是AppKit,但是无论是UIKit还是AppKit,底层渲染都是使用CoreAnimation。

在创建UIVIew时,系统会创建一个layer绑定在View的属性上,当我们修改View的圆角、边框等属性时,其实是UIVIew封装了Layer的修改方法,最终的渲染还是在Layer上,而触摸响应的实现,还是有UIVIew来完成。

CoreAnimation流水线

最终的绘制都是通过CALayer来完成,那么Core Animation是如何一步步将CALayer绘制出来呢?

  • 当App需要变更UI的时候,即视图树(也就是UIVIew)发生变化,这时候对应的图层树(也就是Layer)也会跟随变化,CoreAnimation会提交事务来渲染最终的效果
  • 这时候RenderServer会把数据反序列化为渲染树的内容,然后提交给GPU来渲染
  • GPU收到数据,进行它最擅长的图形数据计算,然后把数据给屏幕
  • 最终,屏幕完成了RGBA在每个像素点上的变更

这里只是一帧的工作,而系统是通过流水线的方式,使得每一帧都能有最新的内容呈现,如图:

相关推荐
AITOP1001 小时前
高德联合千问开源AGenUI:让Agent UI同时跑在iOS、安卓和鸿蒙上
ui·ios·开源
2501_916008894 小时前
ChatGPT前端开发学习指南:Visual Studio Code与谷歌浏览器安装配置详解
ide·vscode·ios·小程序·uni-app·编辑器·iphone
UXbot4 小时前
AI原型设计工具如何从PRD自动生成交互原型
前端·低代码·ui·交互·ai编程·原型模式
MonkeyKing5 小时前
iOS 图片内存优化实战:解码、downSample、纹理内存与大图展示全解析
ios
十五年专注C++开发5 小时前
QFluentKit: 一个基于 Qt Widgets 的 Fluent Design 风格 UI 组件库
开发语言·c++·qt·ui·qfluentkit
ZC跨境爬虫5 小时前
跟着MDN学HTML_day_47:(Document接口)
前端·javascript·ui·html·ecmascript·音视频
Ulyanov6 小时前
《从质点到位姿:基于Python与PyVista的导弹制导控制全栈仿真》: 基石——3-DOF质点弹道的高保真建模与数值稳定性分析
开发语言·python·算法·ui·系统仿真
ZC跨境爬虫7 小时前
跟着MDN学HTML_day_49:(ShadowRoot接口)
前端·javascript·ui·html·ecmascript·媒体
00后程序员张7 小时前
iOS开发中Xcode安装不完整问题解决方案与配置指南
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
sakiko_7 小时前
Swift学习笔记26-使用第三方库
笔记·学习·swift