Flutter难点问题之GPU后台Crash

背景介绍众所周知,在众多跨平台方案中,Flutter的渲染一致性一直是它的一大亮点,可谓是真正的实现了像素级别的控制。这主要归功于Flutter的架构设计,它基于Skia来实现渲染,而后者...
摘要由CSDN通过智能技术生成

背景介绍

众所周知,在众多跨平台方案中,Flutter的渲染一致性一直是它的一大亮点,可谓是真正的实现了像素级别的控制。这主要归功于Flutter的架构设计,它基于Skia来实现渲染,而后者则以OpenGLES、Metal或Vulkan作为后端,这在最大程度上保证了不同平台的渲染一致性。Flutter的这个架构设计非常先进,当然,同其他项目一样,Flutter也不可避免的存在一些bug。今天我想和大家聊的,就是一个Flutter在iOS后台时访问GPU导致Crash的问题。本文将先对GPU后台Crash发生的原因进行说明,再介绍官方对此问题的修复方案,最后分享闲鱼在此基础上如何在其他三个场景解决该问题。

闲鱼App在使用Flutter开发项目的过程中,发现了一个与Flutter相关的iOS Crash,这个Crash的具体堆栈如下:

16313e109306c47c375b37654ac8b562.png

根据堆栈中的_gpus_ReturnNotPermittedKillClient可知,App是因为在后台访问了GPU导致了Crash,或许有些同学不太明白,为什么App在后台访问GPU会导致Crash呢?这其实是和iOS系统的策略有关。iOS系统是禁止后台的App访问GPU的,主要是为了保证前台正在运行的App的性能体验。因为GPU在系统看来是非常宝贵且有限的资源,如果App退到后台之后还继续疯狂使用GPU的话,那么前台App的性能可能就无法得到保障了。那么就有同学问了,如果App并没有遵循这个规范,在退到后台之后,继续使用Metal或OpenGLES访问GPU,会发生什么事情呢?答案很简单,会直接Crash。

由于Flutter使用了Skia作为渲染引擎,而后者在iOS则以Metal或OpenGLES作为后端,因此免不了要和GPU打交道,而在LayerTree光栅化上屏或者图片解码上传纹理时,都会使用到GPU,因此如果没有做好相应的保护措施的话,App就有可能Crash。

官方的修复方案

Flutter应用日益增多,开发者们慢慢发现了这个问题,并向官方提了相应的Issue。陆陆续续有开发者向Flutter官方反馈GPU后台Crash的问题,这引起了官方的注意,官方决定跟踪和解决这个问题。那么这个问题该如何解决呢?解决这个问题的关键,就是在收到UIApplicationDidEnterBackgroundNotification这个通知后,不要再执行任何可能会访问到GPU的操作。但是这个通知是在主线程收到的,而真正去访问GPU的则是Raster线程或IO线程,那么该如何通知它们呢?为此,Google软件工程师Aaron Clarke(github名为gaaclarke)设计了一个新的同步机制: SyncSwitch。SyncSwitch简单来说就是可以在一个线程去设置一个类型为bool的value,另一个线程的代码分为两个分支,根据value的值来确定具体走哪个分支。我们先来看看SyncSwitch是如何设计与实现的,以下是SyncSwitch的构造函数和两个API:

06262e03b90e24232755fc4d5b395790.png

当iOS的前后台状态发生改变时,可以通过SetSwitch来设置value来表示GPU是否可用。而逻辑需要根据iOS在前台或者在后台走不同分支时,则调用Execute方法来走对应的逻辑。

以下是作为Execute方法参数的结构体Handlers的代码:

06469c8e2c126099618c502d9767738a.png

以下是上述方法的具体实现,我们可以看到逻辑比较简单,主要就是在SetSwitchExecude时加锁,然后根据value值去调用true_handler或者false_handler

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值