feat(webgl): handle WebGL context loss#48
Merged
Conversation
On low-RAM devices running Chromium 123+, the GPU context is dropped when the app is backgrounded, after which gl.create* calls return null and the engine crashes. Detect webglcontextlost/webglcontextrestored on the canvas, preventDefault to allow restoration, pause the render loop while the context is lost, and emit contextLost/contextRestored events so consumers can react (typically by reloading the app). In-engine GL resource recovery is intentionally out of scope; the draw loop is already crash-safe via the existing bindTextures guard. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The previous restore handler resumed the render loop on webglcontextrestored without rebuilding the now-dead GL resources, which would render against an invalid context. Since the engine cannot rebuild GPU state in place, the supported recovery is an app reload. Stop opting into restoration: remove the preventDefault() call (which was the browser's request-to-restore signal), the webglcontextrestored listener, Stage.setContextRestored, and the contextRestored event type. isContextLost is now a one-way latch that halts the loop until reload. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
On low-RAM devices running Chromium 123+, the GPU context is dropped when the app is backgrounded for >5s (Chromium change 5285836). After that,
gl.createTexture()and friends returnnulland the engine crashes — common on Android TV / Fire TV. This adds pragmatic core handling for WebGL context loss, mirroring the approach settled on in rdkcentral/Lightning#469.What changed
WebGlRenderer): attach awebglcontextlostlistener on the canvas that notifies the Stage.WebPlatform): once the context is lost,runLoopissues no GL calls and stops rescheduling itself, so the engine never touches a dead context.Stage): a one-wayisContextLostlatch andsetContextLost(), which emitscontextLoston the event bus.RendererMain):RendererMainContextLostEvent+@firesdocs, sorenderer.on('contextLost', …)is typed.BROWSERS.md): new "WebGL Context Loss" section with the recommended app-side handler.Design note: no restore path
We deliberately do not call
event.preventDefault()onwebglcontextlost(the browser's request-to-restore signal) and do not listen forwebglcontextrestored. The engine cannot rebuild its GPU resources (textures, programs, buffers) in place — an earlier draft resumed the loop on restore, which would have rendered against dead handles. Since the supported recovery is an app reload, opting into restoration would only leave a non-reloading consumer with a frozen app on a fresh-but-empty context. Full in-engine recovery (re-fetching texture sources, recompiling programs, re-uploading) is intentionally out of scope; the draw loop is already crash-safe via the existingbindTexturesguard.Test plan
pnpm test— full unit suite passes (232 tests, incl. newStage.contextLoss.test.tsandWebPlatform.contextLoss.test.ts)pnpm build— tsc cleangl.getExtension('WEBGL_lose_context').loseContext()🤖 Generated with Claude Code