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

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.
This commit is contained in:
Othunderlight committed 2026-09-25 06:03:10 +03:00
1 parent 3864596ae5
commit 493e52b29f
3 files changed
+49 -17

No files matched your search

+6 -7
View File
@@ -623,14 +623,13 @@ export class FrameRenderer {
};
const preferredRenderBackend = this.config.preferredRenderBackend;
// Default to WebGL to match the preview renderer (VideoPlayback.tsx) and
// the legacy export renderer, so exported frames render on the same
// backend users see while editing. WebGPU remains available when it is
// explicitly requested; unproven WebGPU support has failed mid-export
// inside PixiJS bind-group setup on some Linux drivers.
const backendOrder: ExportRenderBackend[] =
preferredRenderBackend === "webgl"
? ["webgl", "webgpu"]
: preferredRenderBackend === "webgpu"
? ["webgpu", "webgl"]
: typeof navigator !== "undefined" && "gpu" in navigator
? ["webgpu", "webgl"]
: ["webgl"];
preferredRenderBackend === "webgpu" ? ["webgpu", "webgl"] : ["webgl", "webgpu"];
const failures: PixiRendererAttempt[] = [];
for (const backend of backendOrder) {
+22 -5
View File
@@ -2780,21 +2780,38 @@ export class ModernVideoExporter {
return false;
}
const encoderConfig: VideoEncoderConfig = {
const buildEncoderConfig = (
hardwareAcceleration: VideoEncoderConfig["hardwareAcceleration"],
): VideoEncoderConfig => ({
codec: "avc1.640034",
width: this.config.width,
height: this.config.height,
bitrate: this.config.bitrate,
framerate: this.config.frameRate,
hardwareAcceleration: "prefer-hardware",
hardwareAcceleration,
avc: { format: "annexb" },
};
});
// Prefer hardware H.264, but fall back to software. Recordly disables
// VA-API on Linux (see electron/gpuSwitches.ts), so hardware encoding is
// frequently unavailable there even though software encoding works.
let encoderConfig = buildEncoderConfig("prefer-hardware");
try {
const support = await VideoEncoder.isConfigSupported(encoderConfig);
if (!support.supported) {
this.lastNativeExportError = `H.264 Annex B encoding is not supported at ${this.config.width}x${this.config.height}.`;
return false;
const softwareConfig = buildEncoderConfig("prefer-software");
const softwareSupport = await VideoEncoder.isConfigSupported(softwareConfig);
if (!softwareSupport.supported) {
this.lastNativeExportError = `H.264 Annex B encoding is not supported at ${this.config.width}x${this.config.height}.`;
return false;
}
encoderConfig = softwareConfig;
console.warn(
`[VideoExporter] ${NATIVE_EXPORT_ENGINE_NAME} hardware H.264 encoding is unavailable at ${this.config.width}x${this.config.height}; using software encoding instead.`,
);
}
} catch (error) {
this.lastNativeExportError = error instanceof Error ? error.message : String(error);
+21 -5
View File
@@ -686,23 +686,39 @@ export class VideoExporter {
return false;
}
const encoderConfig: VideoEncoderConfig = {
const buildEncoderConfig = (
hardwareAcceleration: VideoEncoderConfig["hardwareAcceleration"],
): VideoEncoderConfig => ({
codec: "avc1.640034",
width: this.config.width,
height: this.config.height,
bitrate: this.config.bitrate,
framerate: this.config.frameRate,
hardwareAcceleration: "prefer-hardware",
hardwareAcceleration,
avc: { format: "annexb" },
};
});
// Hardware H.264 is unavailable on many Linux builds because VA-API is
// disabled (see electron/gpuSwitches.ts); software encoding still works.
let encoderConfig = buildEncoderConfig("prefer-hardware");
try {
const support = await VideoEncoder.isConfigSupported(encoderConfig);
if (!support.supported) {
const softwareConfig = buildEncoderConfig("prefer-software");
const softwareSupport = await VideoEncoder.isConfigSupported(softwareConfig);
if (!softwareSupport.supported) {
console.warn(
`[VideoExporter] Native H.264 Annex B encoding is unsupported at ${this.config.width}x${this.config.height}`,
);
return false;
}
encoderConfig = softwareConfig;
console.warn(
`[VideoExporter] Native H.264 Annex B encoding is unsupported at ${this.config.width}x${this.config.height}`,
`[VideoExporter] Native hardware H.264 encoding is unavailable at ${this.config.width}x${this.config.height}; using software encoding instead.`,
);
return false;
}
} catch (error) {
console.warn("[VideoExporter] Native encoder support check failed:", error);