小米电池休眠自动解除 手机充不进电7个小妙招( 七 )



而 signalChanges 又是由多个回调所驱动:

其中:
runloopObserverCallback 为一个 BeforeWaiting 的 MainRunLoop observer 驱动 。runloopTimerCallback 由 mk_timer 驱动,对应的 mach_port 不明,测试发现其回调频率在 1Hz 左右,但也会不断变化,猜测是某种系统计时器 。inputGroupSignaledCallback 由 mk_timer 驱动,对应的 mach_port 正是 VSync 信号 。

4.requestRegistrySignaledCallback 由 UIScrollView 在即将开始滑动时驱动 。

通过上面的分析,笔者有理由认为在 iOS 15 上应用的渲染驱动机制出现了比较大的变化 。其中之一便是 DisplayLink 的驱动源的改变 。
结论iOS 15 上 Apple 改变了在 ProMotion 设备的渲染事件循环的驱动方式,CoreAnimation 的事务提交不再由完全由 RunLoop 驱动,而是涉及了多个信号源系统动态帧率选择的机制会综合考虑使用方设置的 API(如 preferredFrameRateRange)和实际展示的内容的变化频率 。具体对 CADisplayLink 而言:内容低速变化时 , CADisplayLink 解锁高刷新率仅影响自身的回调频率 , 系统仍可能选择较低的屏幕刷新率来降低功耗内容中高速变化时 , CADisplayLink 解锁高刷新率可以让系统选择更高的刷新频率,甚至实现锁定 120Hz 的刷新关于如何界定低速/中高速,笔者在下文中 CAAnimation 设置动态帧率 部分做了一些试验,可作为参考 。
同时,默认配置的 CADisplayLink 回调频率最高为 60Hz,无法监控更高频率的刷新事件 。
3.ProMotion 设备中,DisplayLink 不再由 VSync 信号直接驱动,而是在新引入的渲染事件循环中执行 。新版本 iOS 系统实现了某种更复杂的机制来尽可能满足使用者设置的偏好频率进行回调,但并不保证它与 VSync 信号的强关联性 。这意味着默认的 CADisplayLink 的回调频率与实际帧率并不匹配 , 之前基于 CADisplayLink 进行帧率监控的方案在 ProMotion 设备上变得不再可行 。
动态帧率的应用场景监控动态帧率下的流畅度表现业界中一般采用 CADisplayLink 对应用的流畅度进行监控 。由于 CADisplayLink 的行为在 iOS 15 上的变化,原先的监控方案无法评估 ProMotion 屏幕在超过 60Hz 时的表现 。
根据上面的探索结论 , 目前笔者设想了三种针对 ProMotion 设备的兼容性修改方案:
方案一 [Pass]对于任何设备都以 60Hz 为优化目标 , 只考虑刷新间隔长于 16.67ms 的情况 。换句话说,在屏幕以 120Hz 刷新时,对于丢 1 帧的情况也认为不丢帧,因为此时两帧之间的间隔仍然小于 16.67ms,理论上用户感知不大 。
优点:
方案简单,仅需设置 preferredFramesPerSecond 为固定值 60 即可兼容之前的指标 。依然可以计算 FPS 指标 , 对于刷新率高于 60Hz 的情况统一认为刷新率为 60Hz缺点:
由于只能监控最高 60Hz 的情况,无法评估更高刷新率下一些微小丢帧对用户体验带来的影响,也无法评估对高刷屏的一些优化所带来的技术影响在低刷新率时,MainRunLoop 依然会以 60Hz 运行,对功耗有一定影响方案二 [Pass]通过一些手段,可以替换驱动 display_timer_callback 的 Source 1 信号的回调 , 使用它来准确监听 VSync 信号,实现对动态帧率的准确监控 。
优点:
理论上最精确的监控方案对功耗的影响最小,回调频率只有在屏幕刷新率实际升高时才会随之提升缺点:

推荐阅读