当前位置: 首页 > news >正文

【iOS】离屏渲染

前言

这里我简单学习一下有关iOS渲染的相关知识。

屏幕卡顿

在我们日常使用过程中,经常会遇到屏幕卡顿的问题。(图形撕裂、掉帧等问题)

产生原因

  • CPU和GPU在渲染的流水线中耗时过长,导致缓存区获取位图然后显示的时候,下一帧的数据还没有准备好从而产生了掉帧的现象
  • 苹果针对屏幕撕裂的为题采用的是垂直同步+双缓存机制,可以有效防止屏幕撕裂,但是同时容易产生掉帧
  • 于是在垂直同步+爽滑黁区的方案上优化为三缓存区,但是还是没办法从根本上解决掉帧问题,知识相比双缓存区掉帧的概率更小。

屏幕撕裂

屏幕成像过程

  • 首先GPU将需要显示的图像进行渲染
  • 然后将渲染后的结果以位图的形式存储到帧缓存区
  • 视频控制器从帧缓存区读取位图数据之后交给显示器,从左上角扫描显示

这个流程中,很容易出现一个屏幕撕裂的问题,如下:

在屏幕显示图形图像的过程中,是不断的从帧缓存区获取一帧一帧的数据进行显示的,在渲染过程中,如果屏幕拿到的数据是旧的,就会显示旧的数据。

在旧的数据没有读取完成时,新的一帧的数据处理好了放到缓存区之后,又会导致屏幕另一部分的显示是获取的新数据,导致屏幕上呈现图片不匹配、任务景象显示错位等情况。

苹果采用垂直同步+双缓存区的机制,强制要求同步,但是会出现掉帧问题:

  • 垂直同步:给帧缓存区加锁,当电子光束扫描的过程中,只有扫描完成之后才会继续读取下一帧的数据。
  • 双缓存区:采用两个缓存区交替当作GPU结果的存储区,当屏幕显示其中一个缓存区的时候,另一个缓存区继续等待下一个渲染结果,两个缓存区交替进行。

掉帧

在VSync信号到来之前,系统图形服务会通过CADisplayLink等机制通知App,主线程开始在CPU种计算显示内容,随后GPU进行变换、合成、渲染,完成之后会将渲染结果提交到帧缓存区中去,等待下一次同步信号到来。如果在下一个同步信号到来之前,CPU或者GPU没有处理完内容并提交,那一帧就会丢弃,等待下一次机会显示。产生掉帧。

CPU/GPU 必须在下一次 VSync 到来之前完成一帧的绘制。若未完成,显示器无法切换到新缓冲区,只能重复显示上一帧,于是产生掉帧和卡顿。

卡顿监控:

主流的卡顿监控主要有下面两种:

  • FPS监控:为了保持流畅的UI交互,App的刷新频率应该在60fps左右(iOS设备默认的刷新率)。而一次刷新的事件间隔16.67ms,如果这个时间内数据没有准备好就会产生卡顿。
  • 主线程卡顿监控:通过自线程检测主线程runloop。这个方法笔者前面在学习runloop的时候有给过具体的实现流程,这里不在赘述。主要就是通过KCFRunLoopBeforeSources和KCFRunLoopAfterWaiting之间的耗时判断。

FPS监控

参照YYKit中的YYFPSLabel,主要通过CADisplaylink实现,借助link时间差,计算一次刷新所需要的时间,然后通过刷新次数/时间差判断范围,通过不同颜色文字表示卡顿程度。本质上就是一个悬浮在窗口上的FPS实时监控器。这里测量的不是GPU最终真是输出的帧数,而是主线程实际处理了多少次CADisplaylink回调,判断主线程是否阻塞RunLoop是否卡顿、界面滚动是否流畅。

#import"ZYLFPSLabel.h"#import<QuartzCore/QuartzCore.h>/// FPS 标签在 window 上的唯一 tag,用于 show 时去重。staticNSIntegerconstkZYLFPSLabelTag=2026071401;/// FPS 文案刷新间隔。////// CADisplayLink 每一帧都会回调,如果每帧都改 UI,数字会抖动得很厉害,/// 也会让监控本身引入不必要的额外开销。0.25 秒是一个比较灵敏、同时又稳定的窗口。staticCFTimeIntervalconstkZYLFPSUpdateInterval=0.25;@interfaceZYLFPSLabel()/// CADisplayLink 会在屏幕每次准备刷新时向 target 发送 selector。/// 它的 timestamp 是当前这次回调对应的时间点,适合用来计算一段时间内实际刷新了多少次。@property(nonatomic,strong)CADisplayLink*displayLink;/// 统计窗口内 CADisplayLink 回调的次数。/// 理想 60Hz 屏幕上,1 秒大约回调 60 次;120Hz 屏幕上,1 秒大约回调 120 次。@property(nonatomic,assign)NSUInteger frameCount;/// 上一次刷新 FPS 文案的时间点。/// 当 timestamp - lastTime 达到 kZYLFPSUpdateInterval 时,计算并展示一次 FPS。@property(nonatomic,assign)CFTimeInterval lastTime;@end@implementationZYLFPSLabel+(instancetype)sharedFPSLabel{staticZYLFPSLabel*label=nil;staticdispatch_once_t onceToken;dispatch_once(&onceToken,^{label=[[ZYLFPSLabel alloc]initWithFrame:CGRectMake(12,88,78,28)];});returnlabel;}-(instancetype)initWithFrame:(CGRect
http://www.jsqmd.com/news/1208872/

相关文章:

  • 企业自动化选型:RPA、Workflow、Agent到底有什么区别?——深度拆解企业级AI Agent与传统自动化的技术范式演进
  • 论文里的气象数据从哪来?揭秘高水平研究背后的“数据基础设施”
  • VMware安装操作系统KylinOS V10
  • 有质量的海报灯箱广告牌怎么选?实体店老板最关心的20个采购问题全解答 - 品牌报告
  • SAM 2模型解析:医疗影像分割实战与优化
  • 望友DFX软件赋能优特科技:破解人才断层与流程割裂,实现PCBA设计零缺陷
  • CH32X035芯片U盘固件更新方案与实现
  • Claude Code安装配置与核心功能实战指南:内置浏览器与智能代码补全
  • Kimi K2.6:用自然语言调度React+Three.js+Shader工程链路
  • AI智能体开发:Harness与Loop工程的核心差异与实践
  • 第二阶段:SPI 控制器注册
  • 微信里哪个小程序能免费去水印:实测几款工具的真实体验 - 科技热点发布
  • SpringBoot双重防御体系:SpringSecurity集成XSS与SQL注入协同防护实践
  • Stable Diffusion模型瘦身终极方案,单卡3090跑动12GB SDXL-LyCORIS模型(附量化精度损失对照表)
  • 抖音去水印在线工具推荐哪个好?免费多端实测对比 - 科技热点发布
  • 突破尼龙印花瓶颈:免模压起皱浆如何重构纺织特种工艺的降本逻辑
  • MyBatis-Plus字段自动加解密实践:无侵入保护敏感数据
  • 能跨系统操作的企业级自动化工具有哪些?不依赖API的那种 | 2026主流AI Agent与超自动化方案深度解析
  • 中级爵士舞网课选择指南:如何评估难度与最大化学习效果
  • 类器官模型能否预测双抗疗效?患者来源淋巴瘤3D球状体联合空间单细胞蛋白组解析耐药机制
  • 游戏运营数据指标有哪些?从产品、数据、结算和运营支持判断
  • 信号线串联电阻的设计原理与应用场景
  • 游戏机制深度测评:僵尸4水淹场景下的行为分析与性能测试
  • 电力参数一体化计算平台V2.0
  • 抖音一键去水印免费:这几款工具不用下载APP实测 - 科技热点发布
  • 抖音视频怎么在线去水印:官方方法与在线工具逐一实测 - 科技热点发布
  • AI全栈工程师成长计划:20个企业级项目实战指南
  • 欧米茄中国官方售后服务中心|官方电话和维修地址权威信息公告(2026年7月最新) - 欧米茄官方服务中心
  • 2026年7月最新亨得利官方服务项目及价格查询|地址和电话权威信息声明 - 亨得利官方博客
  • 技术小白的Vibe Coding实战:我手搓了一个“扫雷”小游戏