fix(cef): route Windows OPENHUMAN_DISABLE_GPU through SwiftShader software GL (#4385) (#4643)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mega Mind
2026-07-07 13:57:39 -07:00
committed by GitHub
co-authored by Claude Opus 4.8
parent 52598b47e7
commit 4dd20a31f9
4 changed files with 84 additions and 17 deletions
+5 -3
View File
@@ -139,9 +139,11 @@ OPENHUMAN_REASONING_ENABLED=
OPENHUMAN_SHELL_HIDE_WINDOW=
# [optional] Desktop CEF startup escape hatch. Set to 1/true/yes/on only when
# CEF fails before the app can render, for example on a GPU/driver stack where
# startup logs show `cef::initialize returned 0`. Adds --disable-gpu and
# --disable-gpu-compositing to the embedded CEF runtime. Leave unset otherwise;
# this disables GPU acceleration and can break WebGL-heavy surfaces.
# startup logs show `cef::initialize returned 0`. On Windows this pins CEF to the
# pure-software ANGLE/SwiftShader GL backend (needed on NVIDIA Blackwell /
# RTX 50-series, where bare --disable-gpu is insufficient — #4385); on other
# platforms it adds --disable-gpu and --disable-gpu-compositing. Leave unset
# otherwise; this disables hardware GPU acceleration and slows WebGL-heavy surfaces.
# OPENHUMAN_DISABLE_GPU=
# ---------------------------------------------------------------------------
+39 -9
View File
@@ -2030,6 +2030,23 @@ fn cef_disable_gpu_enabled(env_override: Option<&str>) -> bool {
}
}
/// Pin CEF to ANGLE's pure-software SwiftShader GL backend.
///
/// SwiftShader is a software rasteriser that needs no hardware EGL/driver, so it
/// gives both WebGL surfaces and GPU-process init a working (software) context
/// on stacks where the hardware GPU path aborts. `--enable-unsafe-swiftshader`
/// is required because Chromium gates SwiftShader-backed WebGL behind it (the
/// "unsafe" label is about software perf, not security). `--disable-gpu-compositing`
/// keeps page compositing on the CPU. Crucially this does **not** pass
/// `--disable-gpu`, which would shut the GPU process down entirely — and with it
/// the SwiftShader context that lets CEF start.
fn push_swiftshader_software_gl(args: &mut Vec<CefCommandLineArg>) {
args.push(("--use-gl", Some("angle")));
args.push(("--use-angle", Some("swiftshader")));
args.push(("--enable-unsafe-swiftshader", None));
args.push(("--disable-gpu-compositing", None));
}
fn append_platform_cef_gpu_workarounds(
args: &mut Vec<CefCommandLineArg>,
os: &str,
@@ -2044,11 +2061,27 @@ fn append_platform_cef_gpu_workarounds(
// do not reach the vendored CEF runtime. Provide a narrow, release-safe
// env escape hatch instead of forwarding arbitrary Chromium flags.
if disable_gpu {
args.push(("--disable-gpu", None));
args.push(("--disable-gpu-compositing", None));
log::info!(
"[cef-startup] OPENHUMAN_DISABLE_GPU set: adding --disable-gpu and --disable-gpu-compositing for CEF startup compatibility (issue #4294)"
);
if os == "windows" {
// Issue #4385: on NVIDIA Blackwell / RTX 50-series Windows stacks the
// bundled CEF's GPU process fails to initialise and bare
// `--disable-gpu` is not enough — `cef::initialize` still returns 0
// before any UI renders (#4294, #4385). `--disable-gpu` removes the
// GPU process without giving CEF a working software GL path, so init
// still aborts. Pin CEF to the pure-software ANGLE/SwiftShader backend
// instead — the same fallback the Linux #1697/#4193 path relies on —
// which needs no hardware driver and lets CEF start on GPUs the
// bundled Chromium doesn't yet support.
push_swiftshader_software_gl(args);
log::info!(
"[cef-startup] OPENHUMAN_DISABLE_GPU set on Windows: forcing ANGLE/SwiftShader software GL for CEF startup compatibility (issues #4294/#4385)"
);
} else {
args.push(("--disable-gpu", None));
args.push(("--disable-gpu-compositing", None));
log::info!(
"[cef-startup] OPENHUMAN_DISABLE_GPU set: adding --disable-gpu and --disable-gpu-compositing for CEF startup compatibility (issue #4294)"
);
}
}
// Issue #1697: on Arch/Manjaro-family Linux systems, the AppImage can
@@ -2078,10 +2111,7 @@ fn append_platform_cef_gpu_workarounds(
"[cef-startup] OPENHUMAN_FORCE_GPU set — skipping SwiftShader software-GL fallback (issue #1697). If the app fails to launch with a GPU process abort, unset the env var."
);
} else {
args.push(("--use-gl", Some("angle")));
args.push(("--use-angle", Some("swiftshader")));
args.push(("--enable-unsafe-swiftshader", None));
args.push(("--disable-gpu-compositing", None));
push_swiftshader_software_gl(args);
log::info!(
"[cef-startup] Linux detected: forcing ANGLE/SwiftShader software GL so WebGL surfaces (Tiny Place world renderer, Rive mascot) render without the crash-prone hardware GPU process (issues #1697/#4193); set OPENHUMAN_FORCE_GPU=1 for hardware acceleration"
);
+29 -1
View File
@@ -414,9 +414,37 @@ fn platform_cef_gpu_workarounds_disable_windows_gpu_when_requested() {
let mut args = Vec::new();
append_platform_cef_gpu_workarounds(&mut args, "windows", "x86_64", None, Some("1"));
// #4385: on Windows the escape hatch pins CEF to the pure-software
// ANGLE/SwiftShader backend instead of bare `--disable-gpu`, which is
// insufficient on NVIDIA Blackwell / RTX 50-series stacks (cef::initialize
// still returns 0). This mirrors the proven Linux #1697/#4193 fallback.
assert_eq!(
args,
vec![("--disable-gpu", None), ("--disable-gpu-compositing", None)]
vec![
("--use-gl", Some("angle")),
("--use-angle", Some("swiftshader")),
("--enable-unsafe-swiftshader", None),
("--disable-gpu-compositing", None),
]
);
}
#[test]
fn platform_cef_gpu_workarounds_windows_disable_gpu_avoids_bare_disable_gpu() {
// Regression guard for #4385: `--disable-gpu` alone leaves CEF without a
// working software GL path on unsupported (Blackwell) GPUs and init keeps
// failing. The Windows escape hatch must route through SwiftShader and must
// NOT emit the lethal `--disable-gpu` switch.
let mut args = Vec::new();
append_platform_cef_gpu_workarounds(&mut args, "windows", "x86_64", None, Some("1"));
assert!(
!args.contains(&("--disable-gpu", None)),
"Windows OPENHUMAN_DISABLE_GPU must not emit bare --disable-gpu (#4385), got: {args:?}"
);
assert!(
args.contains(&("--use-angle", Some("swiftshader"))),
"Windows OPENHUMAN_DISABLE_GPU must force SwiftShader software GL (#4385), got: {args:?}"
);
}
+11 -4
View File
@@ -119,10 +119,17 @@ the current stable Windows release. That separates a profile/cache problem from
an OS/runtime compatibility regression in CEF startup.
If the logs point to a GPU-process startup failure rather than a stale CEF
profile lock, set `OPENHUMAN_DISABLE_GPU=1` before launching OpenHuman. This
passes `--disable-gpu` and `--disable-gpu-compositing` to the embedded CEF
runtime without forwarding arbitrary Chromium flags. Leave it unset for normal
use because disabling the GPU path can break WebGL-heavy surfaces.
profile lock, set `OPENHUMAN_DISABLE_GPU=1` before launching OpenHuman. On
Windows this pins CEF to the pure-software ANGLE/SwiftShader GL backend
(`--use-gl=angle --use-angle=swiftshader --enable-unsafe-swiftshader
--disable-gpu-compositing`) rather than bare `--disable-gpu`: on NVIDIA Blackwell
/ RTX 50-series stacks the GPU process fails to initialise and `--disable-gpu`
alone leaves CEF with no working software GL path, so `cef::initialize` still
returns 0 (#4294, #4385). SwiftShader needs no hardware driver, so it lets CEF
start on GPUs the bundled Chromium (currently CEF 146.4.1) doesn't yet support.
On other platforms the same env var passes `--disable-gpu` and
`--disable-gpu-compositing` without forwarding arbitrary Chromium flags. Leave it
unset for normal use because forcing software rendering slows WebGL-heavy surfaces.
## Linux shell fallback for CEF startup crashes