You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
maximetinu opened this issue
Nov 8, 2023
· 2 comments
· May be fixed by #12690
Labels
A-RenderingDrawing game state to the screenC-BugAn unexpected or incorrect behaviorO-WebSpecific to web (WASM) buildsO-WebGL2Specific to the WebGL2 render APIO-WebGPUSpecific to the WebGPU render APIP-CrashA sudden unexpected crash
There are several reasons why a WebGL context may be lost, making it necessary to re-establish the context before resuming rendering. Examples include:
Two or more pages are using the GPU, but together place too high a demand on the GPU, so the browser tells the two contexts that they've lost the connection, then selects one of the two to restore access for.
The user's computer has multiple graphics processors (such as a laptop with both mobile and desktop class GPUs, the former used primarily when on battery power), and the user or system decides to switch GPUs. In this case, all contexts are lost, then restored after switching GPUs.
Another page running in the user's browser performs an operation using the GPU that takes too long, causing the browser to decide to reset the GPU in order to break the stall. This would cause every WebGL context to be lost throughout the entire browser.
The user updates their graphics driver on an operating system that allows graphics drivers to be updated without restarting the system.
There can be natural, expected, reasons why a graphic context in an HTML canvas can be lost, so a web-app built on top of Bevy should be able to handle these scenarios without crashing.
In the case of Bevy, in any of the examples at version 0.11.3 targeting wasm, running on WebGL2, if we simulate a context lost like that, the whole Bevy app will crash. This is an example running move_sprite.rs:
What solution would you like?
Ideally, when the context is lost, Bevy should try to restore it instead of crashing. And, if it succeeds, Bevy should re-create all the previous graphic resources to the GPU (because, when the context is lost, all the graphic resources are lost too).
Since re-creating all the resources is a hard task, a good enough solution, at least for my use case, would be to halt all the rendering, to at least prevent the app from crashing, even if it has to keep running without graphics. This is ideal in my scenario as a fallback emergency mode to not kick the user off in the middle of a work session from other features happening on the web, that depend on the Bevy app running on the HTML canvas. As long as the simulation keeps running, they'd be fine until they're able to refresh the tab and regain the graphics.
So, a valid alternative could be to opt-in to not crash upon graphic context lost, and instead disable all the rendering. However, disabling the rendering may be coupled with this ongoing PR about separating tick updates and redraws
Additional context
Since I'm not familiar with WebGPU, I don't know how this all applies to it, or if it has any sense of losing/recovering context like WebGL2 have.
This mainly applies to WebGL2. I have seen comments suggesting that, even if in theory the graphics context should be restorable and re-creatable, in practice it isn't most of the times, requiring a full reload of the tab, and hence a full reload of the app. So, maybe WebGPU has a better way to handle this.
In my experience, I didn't even considered worth it implementing a full recover. But halting the graphics to not crash the whole app is a more than good alternative in most of the cases.
maximetinu
changed the title
Bevy should recover from WebGL Context Lost
Bevy should recover from WebGL Context Lost or WebGPU Device Lost
Nov 10, 2023
I was never able to check if webgpu was crashing as well when losing access to the GPU, because webgpu didn't have such extension to simulate a context loss.
I have now discovered a new way to simulate it, which works in Google Chrome: to write chrome://gpucrash/ on the address bar and press enter.
If I do that in a WebGL2 example, it crashes as usual.
But, here comes the news: if I do that in a WebGPU example, it works, the app just keep working as usual, the systems keeps running, the browser just prints a warning like GPU connection lost and the app shows a black canvas, but everything keeps working.
This makes me wonder: if wgpu (or webgpu itself) is already handling such event... Wouldn't it be wgpu crate responsibility to handle WebGL2 context losses in the same way as well, to have the same functionality between the 2 web rendering backends? 🤔
A-RenderingDrawing game state to the screenC-BugAn unexpected or incorrect behaviorO-WebSpecific to web (WASM) buildsO-WebGL2Specific to the WebGL2 render APIO-WebGPUSpecific to the WebGPU render APIP-CrashA sudden unexpected crash
Uh oh!
There was an error while loading. Please reload this page.
My experience described below is based on WebGL2, but apparently this is the equivalent in WebGPU: losing a device https://developer.mozilla.org/en-US/docs/Web/API/GPUDevice/lost
What problem does this solve or what need does it fill?
According to this MDN web spec: https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/isContextLost#usage_notes
There can be natural, expected, reasons why a graphic context in an HTML canvas can be lost, so a web-app built on top of Bevy should be able to handle these scenarios without crashing.
Other web game engines, like Babylon.js, support automatically recovering from a context lost: see here for a live example of that
In the case of Bevy, in any of the examples at version 0.11.3 targeting wasm, running on WebGL2, if we simulate a context lost like that, the whole Bevy app will crash. This is an example running
move_sprite.rs
:What solution would you like?
Ideally, when the context is lost, Bevy should try to restore it instead of crashing. And, if it succeeds, Bevy should re-create all the previous graphic resources to the GPU (because, when the context is lost, all the graphic resources are lost too).
This seems to be what Babylon.js is doing.
What alternative(s) have you considered?
Since re-creating all the resources is a hard task, a good enough solution, at least for my use case, would be to halt all the rendering, to at least prevent the app from crashing, even if it has to keep running without graphics. This is ideal in my scenario as a fallback emergency mode to not kick the user off in the middle of a work session from other features happening on the web, that depend on the Bevy app running on the HTML canvas. As long as the simulation keeps running, they'd be fine until they're able to refresh the tab and regain the graphics.
So, a valid alternative could be to opt-in to not crash upon graphic context lost, and instead disable all the rendering. However, disabling the rendering may be coupled with this ongoing PR about separating tick updates and redraws
Additional context
Since I'm not familiar with WebGPU, I don't know how this all applies to it, or if it has any sense of losing/recovering context like WebGL2 have.
This mainly applies to WebGL2. I have seen comments suggesting that, even if in theory the graphics context should be restorable and re-creatable, in practice it isn't most of the times, requiring a full reload of the tab, and hence a full reload of the app. So, maybe WebGPU has a better way to handle this.
In my experience, I didn't even considered worth it implementing a full recover. But halting the graphics to not crash the whole app is a more than good alternative in most of the cases.
This conversation started in this Discord message.
The text was updated successfully, but these errors were encountered: