fix(linux): avoid forcing EGL on Wayland

This commit is contained in:
wiiiii123
2026-04-21 02:49:08 +07:00
parent 7494c90863
commit be8c5ef821
3 changed files with 130 additions and 16 deletions
+57
View File
@@ -0,0 +1,57 @@
import { describe, expect, it } from "vitest";
import { getGpuSwitches, shouldForceLinuxEgl } from "./gpuSwitches";
describe("shouldForceLinuxEgl", () => {
it("does not force EGL in a Wayland session", () => {
expect(
shouldForceLinuxEgl({
XDG_SESSION_TYPE: "wayland",
WAYLAND_DISPLAY: "wayland-0",
}),
).toBe(false);
});
it("does not force EGL when Wayland is explicitly requested via Ozone", () => {
expect(
shouldForceLinuxEgl({
OZONE_PLATFORM: "wayland",
XDG_SESSION_TYPE: "x11",
}),
).toBe(false);
});
it("forces EGL in an X11 session", () => {
expect(shouldForceLinuxEgl({ XDG_SESSION_TYPE: "x11" })).toBe(true);
});
it("forces EGL when x11 is explicitly requested via Electron's ozone hint", () => {
expect(
shouldForceLinuxEgl({
ELECTRON_OZONE_PLATFORM_HINT: "x11",
WAYLAND_DISPLAY: "wayland-0",
}),
).toBe(true);
});
});
describe("getGpuSwitches", () => {
it("returns the Linux VAAPI workaround without forcing EGL on Wayland", () => {
expect(
getGpuSwitches("linux", {
XDG_SESSION_TYPE: "wayland",
WAYLAND_DISPLAY: "wayland-0",
}),
).toEqual({
useGl: undefined,
disableFeatures: ["VaapiVideoDecoder", "VaapiVideoEncoder"],
});
});
it("returns the X11 EGL workaround on Linux X11", () => {
expect(getGpuSwitches("linux", { XDG_SESSION_TYPE: "x11" })).toEqual({
useGl: "egl",
disableFeatures: ["VaapiVideoDecoder", "VaapiVideoEncoder"],
});
});
});
+63
View File
@@ -0,0 +1,63 @@
export interface GpuSwitches {
useAngle?: string;
useGl?: string;
disableFeatures?: string[];
}
function getForcedLinuxWindowSystem(env: NodeJS.ProcessEnv): "wayland" | "x11" | null {
const ozonePlatform =
env.OZONE_PLATFORM?.toLowerCase() ??
env.ELECTRON_OZONE_PLATFORM_HINT?.toLowerCase() ??
null;
if (ozonePlatform === "wayland" || ozonePlatform === "x11") {
return ozonePlatform;
}
return null;
}
export function shouldForceLinuxEgl(env: NodeJS.ProcessEnv): boolean {
const forcedWindowSystem = getForcedLinuxWindowSystem(env);
if (forcedWindowSystem === "wayland") {
return false;
}
if (forcedWindowSystem === "x11") {
return true;
}
const sessionType = env.XDG_SESSION_TYPE?.toLowerCase();
if (sessionType === "wayland") {
return false;
}
if (sessionType === "x11") {
return true;
}
return !env.WAYLAND_DISPLAY;
}
export function getGpuSwitches(
platform: NodeJS.Platform,
env: NodeJS.ProcessEnv = process.env,
): GpuSwitches {
if (platform === "darwin") {
return {
useAngle: "metal",
disableFeatures: ["MacCatapLoopbackAudioForScreenShare"],
};
}
if (platform === "win32") {
return { useAngle: "d3d11" };
}
if (platform === "linux") {
return {
useGl: shouldForceLinuxEgl(env) ? "egl" : undefined,
disableFeatures: ["VaapiVideoDecoder", "VaapiVideoEncoder"],
};
}
return {};
}
+10 -16
View File
@@ -17,6 +17,7 @@ import {
import { RECORDINGS_DIR } from "./appPaths";
import { showCursor } from "./cursorHider";
import { registerExtensionIpcHandlers } from "./extensions/extensionIpc";
import { getGpuSwitches } from "./gpuSwitches";
import {
cleanupNativeVideoExportSessions,
getSelectedSourceId,
@@ -58,22 +59,16 @@ app.commandLine.appendSwitch("enable-unsafe-webgpu");
app.commandLine.appendSwitch("enable-gpu-rasterization");
function configureGpuAccelerationSwitches() {
if (process.platform === "darwin") {
app.commandLine.appendSwitch("use-angle", "metal");
app.commandLine.appendSwitch("disable-features", "MacCatapLoopbackAudioForScreenShare");
return;
const { useAngle, useGl, disableFeatures } = getGpuSwitches(process.platform, process.env);
if (useAngle) {
app.commandLine.appendSwitch("use-angle", useAngle);
}
if (process.platform === "win32") {
app.commandLine.appendSwitch("use-angle", "d3d11");
return;
if (useGl) {
app.commandLine.appendSwitch("use-gl", useGl);
}
if (disableFeatures && disableFeatures.length > 0) {
app.commandLine.appendSwitch("disable-features", disableFeatures.join(","));
}
// Linux (and other Unix): prefer EGL over GLX for better Wayland compatibility.
// Disable VAAPI — many distros ship broken drivers that cause
// "vaInitialize failed" and prevent the renderer from loading.
app.commandLine.appendSwitch("use-gl", "egl");
app.commandLine.appendSwitch("disable-features", "VaapiVideoDecoder,VaapiVideoEncoder");
}
async function logSmokeExportGpuDiagnostics() {
@@ -905,8 +900,7 @@ app.whenReady().then(async () => {
// source picker entirely). This avoids calling getSources() which
// would itself trigger an extra portal dialog.
const isLinuxPortalSentinel =
process.platform === "linux" &&
(sourceId === "screen:linux-portal" || !sourceId);
process.platform === "linux" && (sourceId === "screen:linux-portal" || !sourceId);
if (isLinuxPortalSentinel) {
callback({ video: { id: "screen:0:0", name: "Entire screen" } });
return;