fix: recover preview from WebGL context loss on Linux/Wayland#19
fix: recover preview from WebGL context loss on Linux/Wayland#19EtienneLescot wants to merge 3 commits into
Conversation
On Manjaro / CachyOS (Linux/Wayland with Mesa/EGL) the preview Pixi app can lose its WebGL context during heavy GPU usage from the exporter — most likely the `VideoEncoder`'s `prefer-hardware` path or the Linux-only CPU readback in `frameRenderer.ts.readbackVideoCanvas`. The wallpaper is rendered to a 2D canvas (`frameRenderer.ts:212`, "Background renders separately, not in PixiJS") and survives the context loss, but the video sprite lives inside the lost Pixi GL context and never reappears. That is the "only background remains" symptom in issue #8. Fix: attach a `webglcontextlost` listener to the preview Pixi canvas. `preventDefault()` opts in to Chromium's restoration attempt, and bumping a `pixiGeneration` state tears the broken app down via the existing `useEffect` cleanup so the next mount rebuilds it from scratch with a fresh WebGL context. The recovery is logged for diagnostics ("[VideoPlayback] WebGL context lost, recreating Pixi app"), which will now reach the terminal thanks to the console-message forwarding added to `electron/main.ts` in PR #11. Extracted the handler into `createWebGLContextLostHandler` for unit testability and added a small focused test that covers the two invariants the bug hinges on: the event's `preventDefault` is called and the regenerate callback fires. Tested: - npx tsc --noEmit - npm run lint - npm test (244 passed, +3 new) - npm run build-vite
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthrough
ChangesWebGL Context Loss Recovery
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
- Add ROADMAP.md at repo root for top-level discoverability. - Stability queue pulled from open issues / PRs on getopenscreen/openscreen (#8, #21, #22, #19, #18, #24). - AI direction framed as opt-in / off by default, with per-feature tags. - Extend .github/workflows/discord.yaml with a roadmap-notify job that posts an embed to the #🗺️・roadmap Discord channel whenever a PR changes ROADMAP.md (or docs/roadmap.md). Mirrors the existing PR -> #pr-reviews sync pattern. Activated by setting the DISCORD_ROADMAP_WEBHOOK_URL repo secret; silently skipped otherwise so CI never breaks.
- Add ROADMAP.md at repo root for top-level discoverability. - Stability queue pulled from open issues / PRs on getopenscreen/openscreen (#8, #21, #22, #19, #18, #24). - AI direction framed as opt-in / off by default, with per-feature tags. - Link the new roadmap from the README Community section. - Extend .github/workflows/discord.yaml with a roadmap-notify job that posts an embed to the #🗺️・roadmap Discord channel whenever a PR changes ROADMAP.md (or docs/roadmap.md). Mirrors the existing PR -> #pr-reviews sync pattern. Activated by setting the DISCORD_ROADMAP_WEBHOOK_URL repo secret; silently skipped otherwise so CI never breaks.
- Add ROADMAP.md at repo root for top-level discoverability. - Stability queue pulled from open issues / PRs on getopenscreen/openscreen (#8, #21, #22, #19, #18, #24). - AI direction framed as opt-in / off by default, with per-feature tags. - Link the new roadmap from the README Community section. - Extend .github/workflows/discord.yaml with a roadmap-notify job that posts an embed to the #🗺️・roadmap Discord channel whenever a PR changes ROADMAP.md (or docs/roadmap.md). Mirrors the existing PR -> #pr-reviews sync pattern. Activated by setting the DISCORD_ROADMAP_WEBHOOK_URL repo secret; silently skipped otherwise so CI never breaks.
Summary
webglcontextlostlistener to the preview Pixi canvas inVideoPlayback.tsx.event.preventDefault()(to opt in to Chromium's restoration attempt) and bumps apixiGenerationstate so the existinguseEffectcleanup tears the broken app down. The next mount rebuilds it from scratch with a fresh WebGL context.frameRenderer.ts:212) survives the context loss, so this fix makes the "only background remains" symptom in issue [Bug]: Video disappears from editor after exporting (only background remains) #8 self-healing.createWebGLContextLostHandlerfor unit testability and addedVideoPlayback.test.tswith three focused tests (preventDefault is called, regenerate fires, generation is logged).webglcontextlostandwebglcontextrestoredevents so the recovery is visible in the terminal — combined with the console-message forwarding from PR [codex] Add export preview diagnostics #11, this gives a complete trace of any future loss/restoration on Linux.Why
The bug only reproduces on Manjaro / CachyOS (Arch Linux + KDE Wayland, Mesa/EGL) and only after MP4 export —
VideoEncoderuses theprefer-hardwarepath on Linux (videoExporter.ts:681), and the FrameRenderer also takes a Linux-specific CPU-readback branch (videoExporter.ts:397andframeRenderer.ts:914).grep webglcontextlostagainst the codebase before this PR returned 0 hits: the preview never registered a recovery listener, so once the GL context died the video sprite stayed gone. The wallpaper kept rendering becauseframeRenderer.ts:212deliberately composites it on a plain 2D canvas outside of PixiJS, which is why the symptom is "wallpaper stays, video disappears" instead of a fully black preview.Trade-offs
prefer-softwareon Linux. Software H.264 is 3–10× slower on this workload and would have been a real UX regression for Manjaro users for a problem we had not yet confirmed. This fix keeps the encoder preferences untouched and makes the bug self-heal at the renderer instead.Test plan
npx tsc --noEmit— cleannpm run lint— cleannpm test— 244 passed (3 new inVideoPlayback.test.ts)npm run build-vite— cleanFollow-ups
["prefer-software", "prefer-hardware"](the same order Windows uses atvideoExporter.ts:679).webglcontextlostlistener to the FrameRenderer's Pixi canvas inframeRenderer.tsas well. It only matters during export, where a lost context currently shows as a single green/empty frame, so it is much lower priority.Related
Summary by CodeRabbit
Bug Fixes
Tests