【问题标题】:Webgl Context Lost and not restoredWebgl 上下文丢失且未恢复
【发布时间】:2015-01-25 10:51:49
【问题描述】:

我遇到了 webgl 上下文丢失/恢复的问题。

我的应用程序非常繁重,包含大量信息、图表、列表……和地图。

在地图中,我使用 webGL 以获得最佳性能。我的代码正在正确处理丢失和恢复的上下文。

我正在启动一项大型操作,该操作会导致从服务器加载数据、解析它……这有时会使浏览器失去我的 webgl 上下文。问题是上下文永远不会恢复。当我再次执行这个大操作时,我得到了恢复事件。

我认为这与内存和垃圾收集器释放时间有关。

但我真的不知道该怎么做,以及如何解决这个问题。

【问题讨论】:

    标签: javascript memory webgl


    【解决方案1】:

    处理丢失的方法可能是重新创建画布并为 GL 部分重新初始化您的应用程序。最后,所有资源都消失了,因此重新创建上下文所增加的开销应该不会太麻烦,您可以在 webglcontextlost 事件到达时立即采取行动。

    (虽然不确定这是否是最好的主意......)

    评论 Raziza 关于 WEBGL_lose_context 的回答:

    不要像你在那里提议的那样使用这个。这个扩展只是一个调试工具,应该只用来模拟这种行为。

    (另见此处:https://www.khronos.org/registry/webgl/extensions/WEBGL_lose_context/

    顺便说一句:点赞,这样我就可以得到积分,并可能很快对答案发表评论;)

    【讨论】:

      【解决方案2】:

      找到了一种手动调用恢复上下文的方法。不知道这样做是否好/聪明,但它对我有用。

      我们通过使用扩展名WEBGL_lose_context 来做到这一点。 MDN reference

      // Loading the extension
      var ext = gl.getExtension("WEBGL_lose_context"); 
      
      ...
      // This code in the context lost event, wait 3 secs for forcing 
      // restore context
      var restoreTimeout = setTimeout(function() { 
           ext.restoreContext(); 
      }, 3000);
      
      ...
      // This code in restore context event
      // incase we got restore not from my timeout, i'm canceling it
      restoreTimeout && clearTimeout(restoreTimeout);
      

      【讨论】:

      • 我在 NW.js 中也遇到过类似的情况,在 webglcontextlost 的事件处理程序中调用 event.preventDefault() 根本没有按预期恢复上下文,使用 ext.restoreContext() 有效,但前提是您在触发上下文丢失事件之前设置了ext = gl.getExtension("WEBGL_lose_context");。 (否则调用扩展返回null
      • 我错了! .restoreContext() 仅在上下文因手动使用 .loseContext() 而丢失时才有效,否则(在自然情况下)它不会做任何事情。它是专门为模拟失去上下文而制作的。 来自the docs如果上下文没有通过loseContext() 丢失,则生成INVALID_OPERATION 错误。
      • 另一种丢失和恢复上下文的方法是简单地向您的 DOM 添加一个按钮,该按钮创建新的画布并循环获取 webgl 上下文。根据我在 chrome 中检查的内容-总共 15最旧/未使用的上下文丢失了,一旦需要显示其他上下文(我们的主要上下文),它就会恢复
      • 我的问题与自然丢失上下文有关,这意味着上下文丢失(很可能)因为不同的应用程序正在请求更多资源,因为 WebGL 是流动的,它不能保存在一个地方,所以我们得到“上下文丢失”错误。通常,按照文档中的说明,它应该像在上下文丢失事件中执行 event.preventDefault() 一样简单。但它不起作用。 .restoreContext() 绝对不会做任何事情,除非你在它之前手动调用 .loseContext()
      • 也许我没有完全理解你,但是,当 chrome/other 浏览器由于需要太多资源而失去上下文时,它基本上会失去所有数据。这意味着,缓冲区、着色器、纹理、状态以及您使用或创建的所有其他内容都将被删除。完全复位。当上下文恢复时(无论何时浏览器想要绘制您的上下文),您都会收到该事件,并且必须再次将所有数据创建/上传到 GPU,这意味着着色器、纹理......我建议的按钮只是用于调试丢失和恢复上下文代码
      猜你喜欢
      • 2021-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-26
      相关资源
      最近更新 更多