diff --git a/quest/m0/cef-headless.md b/quest/m0/cef-headless.md index 8087cb8..cfc65c8 100644 --- a/quest/m0/cef-headless.md +++ b/quest/m0/cef-headless.md @@ -12,40 +12,53 @@ GPU path cannot paint fails its source saying why instead of staying [moq-dev/studio#59](https://github.com/moq-dev/studio/pull/59) picks the display at setup: Chromium's Wayland Ozone platform when `$WAYLAND_DISPLAY` is set, X11 when only `$DISPLAY` is, and the CPU path with neither. It passes the -browser suite on the GPU path on NVIDIA (RTX 3070 Ti, GNOME on Wayland), and -on the CPU path with no display on NVIDIA and Intel. - -Mesa did not paint in its only trial, on nixos2 (Intel UHD 630, Mesa 26.2.4, -beside an RTX 2070), under a headless sway on the Intel render node, since no -desktop session was logged in: - -- Wayland: CEF's GPU process starts on Mesa's EGL, but the first shared image - fails to allocate ("Unable to allocate frame for first frame capture: - OOM?") and the page never paints. The same happens with glvnd pinned to - Mesa (`__EGL_VENDOR_LIBRARY_FILENAMES`) and with `--disable-gpu-sandbox`. - Release CEF strips the allocation's own log (a `DLOG` in - `media/gfx/renderable_mappable_shared_image_video_frame_pool.cc`). -- X11, under that sway's XWayland: shared textures import, but come back - empty (transparent pages, black WebGL). -- The same headless sway on the NVIDIA render node paints shared textures, so - the harness itself works. - -First check whether a real Mesa desktop session paints; the headless sway on -a hybrid host may be the cause. If it does not, find which allocation fails -(a debug CEF build, or `chrome://gpu` in a CEF client on the same host). - -When the capturer cannot allocate, CEF never paints and never says so. Fail -the page loudly instead, from a signal CEF or Chromium gives (no first-paint -timeout). +browser suite on the GPU path on NVIDIA (RTX 3070 Ti, GNOME on Wayland). + +Found on nixos2 (Intel UHD 630, Mesa 26.2.4, beside an RTX 2070): + +- X11 on Mesa paints since + [moq-dev/studio#73](https://github.com/moq-dev/studio/pull/73). ANGLE drew + through GLX there, which left every shared texture blank; the X11 path now + passes `--use-angle=gl-egl`. +- Wayland is still unknown on Mesa. Under a headless sway on the Intel render + node, the first shared image fails to allocate ("Unable to allocate frame + for first frame capture: OOM?") and the page never paints. That headless + sway on the NVIDIA node paints, so the harness works. +- GNOME with no monitor attached cannot run the Wayland path on any GPU. It + advertises no `wl_output`, and Chromium's `WaylandConnection::Initialize` + round-trips until one appears, so CEF's `initialize` never returns. The + helper hangs before reading a command and every page stays `Starting`. + Meanwhile `gnome-shell` uses a full core. + +Remaining: + +- Rerun `binary(browser)` on Wayland on the Intel GPU in GNOME with a display + connected, over ssh with `WAYLAND_DISPLAY=wayland-0`, + `XDG_RUNTIME_DIR=/run/user/1000`, and `VK_DRIVER_FILES` pointing at Mesa's + `intel_icd`. If it still fails to allocate, find which allocation fails (a + debug CEF build, or `chrome://gpu` in a CEF client on the same host). +- Fail a page loudly when the GPU path cannot paint, from a signal CEF or + Chromium gives (no first-paint timeout): + - On allocation failure, Chromium's frame sink video capturer logs the OOM + line and calls `Stop()`, which calls the consumer's `OnStopped()`. CEF's + `CefVideoConsumerOSR` drops `OnStopped` and `OnLog` (empty bodies in + `libcef/browser/osr/video_consumer_osr.h`), so no client callback fires. + Surfacing it likely needs a CEF change upstream. + - When `$WAYLAND_DISPLAY` has no `wl_output`, decide that at setup rather + than hang in `initialize`: for example, check for an output in `raster()` + and fall to X11 or the CPU path. Decided 2026-11-06 (maintainer, /quest-unblock): this trial runs before nixos2 switches to Windows ([windows-host](/quest/m0/windows-host.md)), which then leaves no Mesa machine on NixOS. -Since 2026-11-06 ([kixelated/nixos#31](https://github.com/kixelated/nixos/pull/31)), -GDM logs `kixelated` into GNOME at boot on nixos2. Its GNOME Shell runs on -the Intel GPU (`card1`, `renderD128`) with no monitor attached, so an agent -runs `binary(browser)` there over ssh with `WAYLAND_DISPLAY=wayland-0` and -`XDG_RUNTIME_DIR=/run/user/1000`. If a page paints only with a display -connected, say so and ask the maintainer for an HDMI dummy plug on the -motherboard's port. +## Waiting + +- Maintainer: connect an HDMI dummy plug (or a monitor) to nixos2's + motherboard HDMI port, which the Intel GPU drives, since GNOME offers + Chromium no Wayland output without one. An agent cannot plug hardware, and + a virtual monitor would test a different setup from a real desktop. Check + that `cat /sys/class/drm/card1-HDMI-A-*/status` shows `connected` and that + `wayland-info` on `wayland-0` lists a `wl_output`. Alternative: skip the + Wayland trial on Mesa and let nixos2 switch to Windows, leaving the Wayland + result unknown. Recommended: the dummy plug. diff --git a/quest/m0/cef-x11-nvidia.md b/quest/m0/cef-x11-nvidia.md index d38080d..8a89ed5 100644 --- a/quest/m0/cef-x11-nvidia.md +++ b/quest/m0/cef-x11-nvidia.md @@ -15,6 +15,11 @@ From [moq-dev/studio#59](https://github.com/moq-dev/studio/pull/59), picked - On nixos (RTX 3070 Ti, NVIDIA 580), the GPU path under X11 never paints: CEF's GPU process logs "Can't create buffer -- gbm device is missing". Wayland sessions avoid it since #59, but X11-only sessions still hit it. +- Since [moq-dev/studio#73](https://github.com/moq-dev/studio/pull/73) the X11 + path passes `--use-angle=gl-egl`, which made it paint on Mesa; rerun nixos + with it first. On nixos2 under GNOME's XWayland, with the studio on the RTX + 2070, CEF still allocated on the Intel GPU that runs the X server (Intel + X-tiled modifier) despite `--render-node-override`. - First find why. Likely suspects: the NVIDIA GBM backend (`nvidia-drm_gbm.so`) is not on CEF's search path (`GBM_BACKENDS_PATH`), or `nvidia-drm` modeset is off. Fix it if the studio can, for example by diff --git a/rs/moq-scene/src/browser/host.rs b/rs/moq-scene/src/browser/host.rs index c2c1af2..378812f 100644 --- a/rs/moq-scene/src/browser/host.rs +++ b/rs/moq-scene/src/browser/host.rs @@ -496,6 +496,11 @@ wrap_app! { Display::X11 => "x11", }; command_line.append_switch_with_value(Some(&"ozone-platform".into()), Some(&platform.into())); + // On X11, ANGLE otherwise draws through GLX, which on Mesa + // leaves shared textures blank. Wayland is always EGL. + if *display == Display::X11 { + command_line.append_switch_with_value(Some(&"use-angle".into()), Some(&"gl-egl".into())); + } // Paint on the studio's GPU, which is the only one it // imports from. if let Some(node) = render_node {