fix: resolve green MP4 exports on CachyOS/Arch Linux (Wayland)#330
fix: resolve green MP4 exports on CachyOS/Arch Linux (Wayland)#330siddharthvaddem merged 1 commit intosiddharthvaddem:mainfrom
Conversation
On Linux/Wayland the implicit GPU-to-2D texture-sharing path used by drawImage(webglCanvas) fails silently (EGL/Ozone), producing green frames. Use explicit gl.readPixels to copy from GPU to CPU memory, bypassing that path.
📝 WalkthroughWalkthrough
Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 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 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3b5ad5064e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/lib/exporter/frameRenderer.ts`:
- Around line 704-719: The current path in compositeWithShadows()
unconditionally calls readbackVideoCanvas() which always does a gl.readPixels()
into a freshly allocated Uint8Array and temp buffer then flips rows and
putImageData, causing synchronous stalls and per-frame allocations; change this
so the default path uses the existing drawImage() branch and only uses the
readbackVideoCanvas() code when a platform/workaround flag (detect affected
Wayland/Linux cases) is set, and when readback is enabled reuse buffers across
frames by promoting buf and the row temp buffer to reusable properties (cache a
Uint8Array for pixel data and a row-sized temp Uint8Array) instead of allocating
them inside readbackVideoCanvas(), and avoid repeated ImageData allocations by
reusing a single ImageData / Uint8ClampedArray view where possible before
calling this.rasterCtx.putImageData; keep references to compositeWithShadows()
and readbackVideoCanvas() to locate the change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 7e8c45f0-1a34-4572-83fa-b2fb6c7b55f8
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (1)
src/lib/exporter/frameRenderer.ts
Description
On Linux/Wayland (specifically CachyOS/Arch with KDE), exported MP4 videos are solid green despite audio working correctly. This fix uses explicit
gl.readPixels()to copy pixel data from the WebGL framebuffer to CPU memory, bypassing the broken shared-image path entirely.Motivation
PR #281 resolved green MP4 exports on Ubuntu by reading raw pixels at the
VideoFrameconstruction step. However, on CachyOS/Arch Linux with Wayland/KDE, the corruption occurs one layer deeper inFrameRenderer.compositeWithShadows(), wherectx.drawImage(webglCanvas, ...)copies the PixiJS WebGL canvas onto the 2D composite canvas. By the time theVideoFramefix reads pixels, the composite canvas already contains corrupted data.This PR fixes the compositing layer by reading back the WebGL framebuffer directly via
gl.readPixels(), which always performs an explicit GPU-to-CPU copy.Type of Change
Related Issue(s)
#264
Checklist
Summary by CodeRabbit