Skip to content

fix(export): render Lightning frames with WebGL and allow software H.264 - #1035

Open
Othunderlight wants to merge 1 commit into
webadderallorg:mainfrom
Othunderlight:fix/linux-lightning-export
Open

Othunderlight wants to merge 1 commit into
webadderallorg:mainfrom
Othunderlight:fix/linux-lightning-export

Conversation

@Othunderlight

@Othunderlight Othunderlight commented Sep 25, 2026 •

Copy link
Copy Markdown

Description

Lightning (Beta) export on Linux fails with Cannot read properties of undefined (reading '_resourceType'), and its Breeze fallback never engages. This PR fixes both defects behind that report.

1. The export renderer chose a different backend than the preview.

The preview always tries WebGL first (VideoPlayback.tsx), and the legacy exporter does too. The Lightning export renderer did not: with an undefined preference it ordered ["webgpu", "webgl"] whenever navigator.gpu existed — and electron/main.ts appends enable-unsafe-webgpu, so navigator.gpu is present on Linux even when the backend is unusable. PixiJS then throws inside BindGroupSystem._createBindGroup, which reads _resourceType off a filter resource that was never bound:

const resource = group.resources[j] ?? group.resources[groupLayout[j]];
if (resource._resourceType === "uniformGroup") { ... }  // resource === undefined

Every report carries Renderer: webgpu, while Renderer: webgl exports succeed — including the Legacy pipeline, which is already WebGL-first.

2. Breeze could never pass its own encoder probe on Linux.

The Annex B support check only tried prefer-hardware, while electron/gpuSwitches.ts disables VaapiVideoDecoder/VaapiVideoEncoder on Linux. So the probe rejected every Linux machine even though software H.264 works — producing the Breeze fallback: H.264 Annex B encoding is not supported at WxH line seen in all reports, while the log directly above it shows WebCodecs reporting avc1.640033/prefer-software as supported.

The probe now tries prefer-hardware and falls back to prefer-software, configuring the encoder with whichever config actually passed. Both exporters were updated (modernVideoExporter.ts, videoExporter.ts).

Motivation

Affects Linux users across Fedora, Arch and Ubuntu with no workaround: Lightning fails immediately and Breeze never starts, so exports only succeed via the Legacy pipeline (which some users report has since been removed from the UI).

Type of Change

  • New Feature
  • Bug Fix
  • Refactor / Code Cleanup
  • Documentation Update
  • Other (please specify)

Related Issue(s)

Overlap, for the maintainer's convenience:

The Breeze probe change is not covered by any open PR.

Screenshots / Video

No UI change. Before/after is visible in the export error report itself:

Before

Reason: Cannot read properties of undefined (reading '_resourceType')
Renderer: webgpu
Encoder path: WebCodecs (avc1.640033/prefer-software/quality)
Breeze fallback: H.264 Annex B encoding is not supported at 1080x1920.

After

Renderer: webgl
Encoder path: WebCodecs (avc1.640033/prefer-software/quality)

with Breeze available as a genuine fallback instead of a permanently rejected one.

Testing Guide

Environment: Fedora Linux 42 (GNOME, Wayland), GeForce RTX 2050 + Radeon 680M, Electron 43, 1080x1920 @ 30 FPS.

  1. npm install && npm run build:linux
  2. Open a project in the editor, export with Lightning (Beta) at 1080x1920 @ 30 FPS → previously failed with the error above, now completes.
  3. Confirm the export report shows Renderer: webgl.
  4. Run the checks CI runs:
Check Result
npx tsc --noEmit exit 0
npm run lint exit 0
npm test 1390 passed, 6 skipped
npm run build:linux exit 0 → release/Recordly-linux-x64.AppImage
npm run smoke:packaged-binaries exit 0

Please also sanity-check on macOS/Windows that export still selects WebGPU when it is explicitly requested (RECORDLY_SMOKE_EXPORT_RENDER_BACKEND=webgpu) — the change only alters the default/auto ordering.

Checklist

  • I have performed a self-review of my code.
  • I have added any necessary screenshots or videos.
  • I have linked related issue(s); no changelog file exists in this repository, so that part is not applicable.

Thank you for contributing!

Summary by CodeRabbit

  • Improvements
    • Video exports can use software encoding when hardware-accelerated H.264 is unavailable. If neither encoding option is supported, export falls back from the native path.
    • Graphics rendering now tries WebGL before WebGPU by default. When WebGPU is explicitly preferred, it is tried first.

Lightning exports failed on Linux with "Cannot read properties of undefined
(reading '_resourceType')". The export renderer preferred WebGPU whenever
navigator.gpu existed, but the preview renderer always prefers WebGL, so
exports ran on a backend that never worked on this machine. PixiJS then read
a missing filter resource in BindGroupSystem._createBindGroup and threw.

Breeze was separately unreachable on Linux: its Annex B encoder probe only
tried prefer-hardware, while electron/gpuSwitches.ts disables
VaapiVideoDecoder and VaapiVideoEncoder on Linux, so the probe rejected the
software encoder that WebCodecs had already reported as supported.

- Default the export renderer to WebGL-first to match VideoPlayback.tsx;
  keep WebGPU available when explicitly requested.
- Probe Breeze with prefer-hardware and fall back to prefer-software, and
  configure the encoder with whichever config passed.
@coderabbitai

coderabbitai Bot commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: webadderallorg/Recordly/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 9961bad5-755d-4f5b-a151-e650375671ad

📥 Commits

Reviewing files that changed from the base of the PR and between 1888428 and 622de2a.

📒 Files selected for processing (3)
  • src/lib/exporter/modernFrameRenderer.ts
  • src/lib/exporter/modernVideoExporter.ts
  • src/lib/exporter/videoExporter.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

The renderer backend order now defaults to WebGL before WebGPU, unless WebGPU is explicitly preferred. Both video exporters now check software-accelerated H.264 support when hardware-preferred encoding is unsupported.

Changes

Export selection

Layer / File(s) Summary
Renderer backend order
src/lib/exporter/modernFrameRenderer.ts
WebGL is tried before WebGPU by default. An explicit WebGPU preference tries WebGPU first.
Native H.264 acceleration fallback
src/lib/exporter/modernVideoExporter.ts, src/lib/exporter/videoExporter.ts
Both exporters check software-acceleration support when hardware-preferred H.264 is unsupported. They use software encoding when supported; otherwise, they return false.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~15 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: webadderall

Merge Risk: ⚪ Minimal · up to 622de

No identified issue currently blocks merging the export fallback changes.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 622de

Exporting with software encoding can now start a native encoding process on more machines. The older export path may leave that process or its temporary file behind if finalization times out. No new remote access or privilege grant was established.

Retained concerns

  • Low · reliability · inferred: Software fallback newly exposes more exports to a legacy finalization path that relinquishes the native session ID before a timed finish completes. If the renderer times out while the native operation remains pending, its cleanup cannot cancel that session, weakening process and temporary-file containment.
Security review details

Security Blast Radius

  • inferred — The newly reachable native work is an export process and temporary output on the user's desktop. The examined change does not establish a remote caller, a new native command, or a broader service-level exposure.

Trust Boundaries and Controls

  • observed — Renderer-produced chunks cross the existing Electron IPC boundary under a session ID. The native write handler looks up that ID but assigns the requesting sender to the session rather than checking it against the creator; this behavior predates the software-selection change, and an independently attackable sender was not established.

Resilience and Maintainability Implications

  • inferred — A legacy renderer-side finalization timeout can lose the cancellation handle while the native handler remains pending. Native-side failure cleanup is a countermeasure when that handler actually rejects.

Hardening Proposals

  • proposed — Keep the legacy session cancellation handle until native finish settles, and cancel the session when renderer-side finalization times out. Separately, verify the intended IPC sender-ownership policy before treating a session ID as sufficient authorization.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies both primary changes: WebGL-first Lightning frame rendering and software H.264 support for export.
Description check ✅ Passed The description is complete and follows the repository template. It explains the defects, motivation, implementation, related issues, testing steps, results, and checklist status.
Linked Issues check ✅ Passed The changes address both linked issues [#644] and [#948]. modernFrameRenderer.ts now selects WebGL before WebGPU by default, while an explicit webgpu preference still selects WebGPU first and reta…
Out of Scope Changes check ✅ Passed The reviewed changes are limited to the Lightning renderer backend order and native H.264 encoder support checks in the two exporter implementations. These changes directly support the failures descri…
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 3…
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants