cesium 解决 WebGLRenderingContext 丢失问题

7 篇文章 0 订阅
6 篇文章 2 订阅

通常来说,对于大多数使用场景,页面上只需要创建一个 cesium 的 viewer 就够用了。

但是架不住,某些情况下,会需要多个 viewer 的存在。

了解 cesium 的童鞋应该知道,一般情况下,一个 viewer 对应着一个 webgl context,如果有多个就会存在多个 WebGLRenderingContext。

如果还不了解 WebGLRenderingContext 是什么的童鞋,建议去了解学习下 webgl 相关的知识,下面送上学习链接:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext

对于大部分浏览器而言,都会对单个页面同时激活的 WebGL contexts 有限制,可以参考下面的讨论页:
https://bugzilla.mozilla.org/show_bug.cgi?id=1421481

例如,在火狐浏览器的代码里,就做了如下限制,对于 pc 而言,单个页面同时激活的 WebGL contexts 不能超过 16 个。
在这里插入图片描述

所以,为了使我们的程序能够保持正常的运行状态,我们必须要保证我们的页面应用严格的遵循这一原则。

我们可以写一个小应用, 进行测试,看一下,对于我们常用的浏览器,是否都会存在这个情况。

我们的应用,分为左右两侧,左侧是一个一直存在的 viewer,右侧是一个不断销毁和创建的 viewer 区域。

可以看到,当我们右侧第17次创建 viewer 的时候,左侧的 viewer 抛出异常错误。
在这里插入图片描述

打开控制台,可以看到,浏览器提示激活了太多的 webgl contexts,最老的 context 将会丢失掉。
在这里插入图片描述

由此我们推测,虽然我们每次都调用了 viewer.destroy() 方法,来销毁掉 viewer,并不等同于 webgl context 也被销毁掉了。
在这里插入图片描述

那么,webgl context 有没有提供 api 让我们能够手动销毁掉创建出来的 context 呢?

经过一番查找和研究,发现还是有的:https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context

在这里插入图片描述

可以调用 WebGLRenderingContext getExtension 接口,拿到对应的 extension,然后调用 loseContext 方法,能让该 webgl context 失效掉。

这么说,其实我们 destory 掉 viewer 以后,cesium 源码里并没有调用上面这个方法,让对应的 webgl context 失效掉。

我们打开 vscode,对 cesium 的源码进行全局检索,检索关键字 WEBGL_lose_context ,可以发现在我们的 cesium 1.85 的源码里,并没有找到相关的代码。
在这里插入图片描述

所以,结论就很明显了,正如我们前面所猜想的那样,我们调用 destory 销毁 viewer 的时候,当前 viewer 所用的 webgl context 并没有被释放掉,还是会占用资源。

所以,我们稍微对销毁逻辑做一些优化,改成下面这样
在这里插入图片描述

我们在 destory 掉 viewer 以后,手动调用 gl.getExtension("WEBGL_lose_context").loseContext(); 方法。

在这里插入图片描述

可以看到,代码像上面那样改动了以后,在不断销毁、创建 viewer 的过程中,我们最开始被创建出来的 viewer 已经不会丢失 webgl context 了,这样就完美的解决了我们的问题。

  • 9
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值