最近在知乎到收到了一个这样的问题,发问者关于 Android 和 iOS 烘托架构差异提出了疑问,而关于问题的描绘我觉得挺有意思,不知道你怎么看?
其实我觉得这个不该该是描绘里的 「SurfaceFlinger 和 backboardd 的差异」,更多应该是 Metal 和 Vulkan 的差异。
为什么这么说?首先简略区分下 Android 和 iOS framework 层面烘托框架的差异。
Android
Android 上全部内容都会烘托到 Surface 上,Surface 大部分来自 Window ,在 framework 层面调用了 Canvas.draw 之后,实践上转化为制作指令提交给 RenderThread ,RenderThread 向 GPU 发出指令,终究经过 SurfaceFlinger 组成 Layer (单个 buffer)提交 HAL 烘托。
回到对应到问题上 「各个运用先分别烘托到各自的 Surface 上,再提交到 SurfaceFlinger 做组成」,其实 Surface 上并不是真的烘托,仅仅提交了指令到 RenderThread 烘托,终究经过 SurfaceFlinger 去组成消费,所以 CPU 层面 View 仅仅构建了 DisplayList 。
其实 Android 不是在每一帧上都直接在 CPU 上履行绘图调用,这样关于动画等场景过于“深重”,所以才会有 RenderThread 的存在。
所以假如把 SurfaceFlinger 和 RenderThread 放一同才是一个完好的 Graphics Pipeline ,它们是实在担任烘托的部分。
iOS
iOS 里 CALayer 首要来自 UIView,CALayer 是显现的基础,担任烘托和动画,而问题里说到的 backboard 其实便是 iOS 上的独立进程 render server。
而 CALayer 上有个 contents 特点,它是一个 bitmap(backing store),contents 首要便是用于静态保存烘托好的内容,在需求时提取显现。
在 iOS 里,上层首要的烘托和构建流程是 Core Animation, 这个阶段首要便是在 CPU 阶段经过 Commit Transaction 处理布局然后核算好图层,视图层次结构被编码成 CALayer 发送到 render server ,之后会被 decode(解码)然后提交 GPU 制作。
简略说 CALayer 等同于一个纹理,而它的 contents 等于一个缓存区 backing store
所以其实 Core Animation 里也不是实践制作,例如 Core Animation 的 Display 阶段也仅仅依据Layout 的结果创立得到 primitives(图元) ,而 contents 里的 bitmap 是 GPU 中依据 primitives 制作得到的,所以终究制作是在 render server 。
结论
所以其实不管是 Android 在 surface 仍是 iOS Core Animation,它们都不是在上层直接经过 CPU 调用制作 ,而是在 RenderThread 和 render server 兼并完成制作,从这点看其实我们意念并没有不同,仅仅完成方式和管理模式不一样。
不过不管是 Android 的 RenderThread 仍是 iOS 的 render server ,都不是实践烘托功能的「大魔王」,由于 Metal 和 Vulkan 这些底层 API 对烘托功能影响更大。
为什么底层烘托 API 更重要,以 OpenGL 为比如,从顶点处理(vertex processing)、图元装配(triangle assembly)、光栅化(rasterization)、片段处理(fragment processing)、测验和混合(testing and blending)这样的 Graphics Pipeline 组成了一个简略的画面烘托流程。
而在这个流程里,光栅化是一个非常耗时的进程,一般是经过 GPU 来加速,而将数据从 CPU 传输到 GPU 的进程也是一个耗时进程。
例如在 Android 里,RenderThread 首要便是从 UI 线程获取输入并将它们处理到 GPU ,RenderThread 是与 GPU 通讯的单独线程。
而到了 Metal 和 Vulkan ,它们的呈现弥补了 OpenGL 许多历史问题,将烘托功能和履行功率提高了一个层级,这些改变足以让Runtime framework 上差异被疏忽,举个比如:
-
OpenGL 是单线程模型,一切的烘托操作都放在一个线程;而 Vulkan 中引入了 Command Buffer ,每个线程都能够往 Command Buffer 提交烘托指令,能够更多运用多核多线程的能力
-
OpenGL 很大一部分支持需求驱动的完成,OpenGL 驱动包办了一大堆作业,在简化上层操作的一起也牺牲了功能;Vulkan 里驱动不再担任跟踪资源和 API 验证,虽然这提高了框架运用的杂乱度,但是功能得到了大幅提高
又比如前面 iOS 所说的 render server ,我们能够简略看作是 OpenGL 或许 Metal ,而 Metal 比较 OpenGL 能够“更挨近”底层硬件,一起下降了资源开支,例如:
Metal 里资源在 CPU 和 GPU 之间的同步访问是由开发者自己担任,它供给更快捷的资源同步 API,能够有效下降 OpenGL 里纹理和缓冲区仿制时的耗时;另外 Metal 运用 GCD 在 CPU 和 GPU 之间保持同步,CPU 和 GPU 是共享内存无需仿制就能够交流数据。
能够看到 Vulkan 和 Metal 都给 Android 和 iOS 带来了巨大的功能提高,所以假如评论烘托完成带来的功能差异,现阶段更多应该是 Vulkan 和 Metal 的差异。
Vulkan VS Metal
Metal 应该是 2014 年开端在 iOS 8 设备参加,而 Vulkan 是在 2016 年 Android 7 时投入运用,事实上假如真的要对比它们两个的功能很难,由于 Vulkan 是一个通用的底层烘托 API ,它不止考虑 Android,而 Metal 专职于苹果设备,这导致它们没办法在“公正”的变量下比对。
假如要说运用上的差异,那么 Metal 其实更简略,绝大部分实践是 Metal 对 Vulkan 在概念上的兼并和简化,例如:
Metal 会自动帮助开发者处理暗地管理作业,它会履行更多自动化操作来处理加速视觉效果和增强功能等后台管理,然而 Vulkan 是更多供给 API,首要取决于开发者自主的控制。
所以从这角度说,Vulkan 似乎供给了比 Metal 更大的功能可能性,当然也更杂乱更简略写出有问题的代码。
Metal 比 Vulkan 更简略还有一个表现便是:3.10开端 Flutter 上 iOS 的 Impeller 能首发,而 3.13 了 Android 还仍旧等候的原因。
整体而言,Metal 更简略运用,而 Vulkan 更灵活可控,当然,对比 OpenGL 其实都变杂乱,特别是 Vulkan ,由于更挨近底层,所以杂乱度更高。
另外值得注意的是,有一个叫 MoltenVK 的项目,它支持将 Vulkan 映射到 iOS 和 macOS 上的 Metal 去运行,这一定程度也表明了 Vulkan 和 Metal 并不疏远。
当然,这里有个误区,你感受到的功能差异可能仅仅 App 本身写的不够好,就比如许多人写的 App 或许游戏,并不能实在体验到 OpenGL -> Metal/ Vulkan 的功能大幅提高,由于他可能连 OpenGL 的极限都没有达到
所以用自己写的 App 去评判 Metal 和 Vulkan 的优劣其实并不“公允”,许多时候可能自己你在某个平台并没做好自己该做的。