惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

宝玉的分享
宝玉的分享
Recent Commits to openclaw:main
Recent Commits to openclaw:main
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
罗磊的独立博客
V
Visual Studio Blog
爱范儿
爱范儿
H
Help Net Security
J
Java Code Geeks
I
InfoQ
Recent Announcements
Recent Announcements
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Recorded Future
Recorded Future
Jina AI
Jina AI
Microsoft Security Blog
Microsoft Security Blog
WordPress大学
WordPress大学
GbyAI
GbyAI
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Y
Y Combinator Blog
Google DeepMind News
Google DeepMind News
Scott Helme
Scott Helme
S
SegmentFault 最新的问题
S
Securelist
L
LINUX DO - 热门话题
Cyberwarzone
Cyberwarzone
C
Cisco Blogs
Simon Willison's Weblog
Simon Willison's Weblog
G
Google Developers Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 叶小钗
T
The Blog of Author Tim Ferriss
博客园_首页
B
Blog
F
Fortinet All Blogs
AWS News Blog
AWS News Blog
V
Vulnerabilities – Threatpost
S
Secure Thoughts
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Forbes - Security
Forbes - Security
S
Security @ Cisco Blogs
T
Threat Research - Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
S
Schneier on Security
Project Zero
Project Zero
Martin Fowler
Martin Fowler
C
Cybersecurity and Infrastructure Security Agency CISA
N
Netflix TechBlog - Medium
N
News and Events Feed by Topic

木土金王可

复盘 2024,年度好物分享 落地 第二十台相机:宝丽来(Polaroid)Impulse AF 第十九台相机:哈苏(Hasselblad)X1D II 第十八台相机:宝丽来(Polaroid)Macro 5 SLR 第十七台相机:康泰时(Contax)S2 稻荷山 Dave Chappelle: The Closer 语言是思想的边界 对街头卖惨表演的看法 《民主森林》 电梯英雄 2023,年度好物分享 《大画幅 4x5》复活 新加坡华侨银行(OCBC)开户指南 第十六台相机:宾得(Pentax)PC35AF-M SEDATE 第十五台相机:沙慕尼(Chamonix)4x5 F2 Xbox 连接 Studio Display Twitter、Apple、Meta 和 Reddit 广告平台使用体验 第十四台相机:康泰时(Contax)S2 你到底什么时候买相机 拍摄胶片的理由 HomePod 不能作为 Mac 音响 男性生来就是残缺的女性 第十三台相机:柯尼卡(Konica)Big Mini 301 三年,十二台相机 恐怖片很好看啊 比残忍更残忍 用 SwiftUI 重构「行动日」 推荐《女生呵护指南》 你是左派还是右派? 驯服内心的猛犸象:为什么你应该停止关心别人对你的想法 想写点什么,但又不知道该写什么 摄影构图 精致的结婚照 中文没死,是有的人死了 上海爆发 COVID-19 疫情以来我收藏的文章(持续更新) 自我审查 25 美元,成为美国计算机学会(ACM)会员 将同事送我的仙人掌转换成 3D 模型 如何让 iOS 给你的应用开后门 二零一九年夏秋之交工作生活的异动 一声一世 iOS 限制输入字数与特殊字符的巧妙方法 对于番茄学习法的误解 Swift 中的空字符串 我如何自学 iOS 开发 为什么我不喜欢社交网络 如何与人见面 为什么我不喜欢即时通讯 以配置信息(UserDefaults)的形式存储应用数据 在文件沙盒中读取与写入应用数据 在 iOS 开发中使用键值对监听(KVO)与通知(Notification) 介绍 GCD 中的线程,队列,延迟执行,线程阻断,信号量,任务组与任务对象 iOS 原生 URLSession 网络请求 什么是自动引用计数(ARC)和引用循环 在 iOS 开发中使用代理与协议 独立开发的第一个应用:行动日 为什么我会把 Google Pixel 换成 iPhone SE? 手动进行 Nexus 和 Pixel 系列手机的 OTA 更新 开启 Chromebook 的夜间模式
当我们谈论离屏渲染时,我们在谈论什么
kinnouka bokudo · 2021-06-24 · via 木土金王可

当我们谈论离屏渲染时,我们在谈论什么

本文将会介绍有关离屏渲染的基础知识,但在正式开始之前,先粗略介绍下 iPhone 的屏幕显示原理,这样有助于更好地理解离屏渲染。图像显示到屏幕上,大概会经历以下几个步骤:

  1. CPU 告诉 GPU 需要显示的内容
  2. GPU 按照 CPU 的要求,将 Layer 渲染进 Frame Buffer(帧缓冲区)
  3. 渲染完成后,Video Controller(视频控制器)把渲染结果(作为一帧)显示到屏幕上

由于 iPhone 的刷新率是 60Hz,所以上述过程正常情况下每秒会发生 60 次。这也就是大概的 iPhone 屏幕显示原理。

离屏渲染

前文中提到「GPU 会将 Layer 渲染进 Frame Buffer」,这是正常的渲染流程,被称为 On-Screen Rendering(当前屏幕渲染)。而离屏渲染与正常渲染流程的唯一不同就在于,当 GPU 在渲染时,由于一些原因,不能将 Layer 渲染进 Frame Buffer,而是需要创建一个 Offscreen Buffer(离屏缓冲区)来参与渲染,然后再将渲染结果放入 Frame Buffer,这个过程就被称为 Off-Screen Rendering(离屏渲染)。

因为离屏渲染需要创建新缓冲区、多次切换上下文环境(从 On-Screen 切换到 Off-Screen)以及每秒将会进行 60 次这样的繁重操作,所以大量的离屏渲染会引起性能问题、降低显示帧率、造成卡顿。

为什么会发生离屏渲染

关于为什么会发生离屏渲染,其实我没有找到官方的解释,但是因为 GPU 在渲染时遵循画家算法,也就是说对于每一层 Layer,都会被依次渲染进 Frame Buffer,后一层不断覆盖前一层,被覆盖的地方的数据会永久丢失,并且切不可逆。

根据这一点可以推测出:GPU 在渲染每一层 Layer 时,绝对无法得知它的上一层和下一层 Layer 的信息,也无法修改它们,所以在遇到无法依次渲染的情况时,就不得不新建一个 Offscreen Buffer 来储存渲染的中间结果,从而发生离屏渲染。

造成离屏渲染的原因与解决办法

1. shadow(阴影)

因为 shadow 必须知道其上层 Layer 的形状才能渲染,而上层 Layer 又必须等其下层 Layer 渲染完成才能渲染,所以就不得不新建一个 Offscreen Buffer 参与渲染。

解决办法就是设置 Layer 的 .shadowPath,这样可以使 GPU 在渲染阴影 Layer 时,不用知道其上层 Layer 形状就可以完成阴影路径的渲染。

2. cornerRadius + clipsToBounds(圆角与裁切圆角以外内容)

在 Layer 被渲染时,其上层 Layer 还没有被渲染,所以无法完成裁切圆角以外内容,所以也需要新建一个 Offscreen Buffer 参与渲染。

解决办法是使用 UIBezierPathCAShapeLayer 设置圆角。

3. group opacity(群组透明)、mask(遮罩)、UIBlurEffect(高斯模糊)与allowsEdgeAntialiasing(抗锯齿)

在所有 Layer 的渲染完成后,再应用透明度,与分别为每层 Layer 应用透明度再渲染得到的结果是不同的,与透明度相关以及抗锯齿的渲染都无可避免的需要一个 Offscreen Buffer 参与渲染。

4. shouldRasterize(栅格化)

shouldRasterize 相当于主动进行离屏渲染,目的是为了将渲染结果保存在一起,使下一帧可以直接复用,避免重复渲染。

后续

关于离屏渲染还有很多细节,本文并没有提及,感兴趣的读者可以从 CPU 渲染与 shouldRasterize 属性深入研究下去。

2021 年 6 月 24 日