From 9e7305b885803a2c7b104eadfee37c9ba333f90a Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Sat, 3 Oct 2026 01:34:25 -0400 Subject: [PATCH] [Docs] (Anland): plan and device scripts for X11 apps on the GPU --- .../skills/anland-mobilegl-plasma/SKILL.md | 6 +- .../scripts/device/x11-measure.sh | 47 +++++++ .../scripts/x11-verify.sh | 132 ++++++++++++++++++ .../notes/anland/plan-x11-gpu.md | 132 ++++++++++++++++++ 4 files changed, 315 insertions(+), 2 deletions(-) create mode 100644 .claude/skills/anland-mobilegl-plasma/scripts/device/x11-measure.sh create mode 100644 .claude/skills/anland-mobilegl-plasma/scripts/x11-verify.sh create mode 100644 docs/Disaggregated/notes/anland/plan-x11-gpu.md diff --git a/.claude/skills/anland-mobilegl-plasma/SKILL.md b/.claude/skills/anland-mobilegl-plasma/SKILL.md index 947c5d8b..d8e59ad9 100644 --- a/.claude/skills/anland-mobilegl-plasma/SKILL.md +++ b/.claude/skills/anland-mobilegl-plasma/SKILL.md @@ -26,7 +26,7 @@ nobody else is mid-test. Use your own `ct.sh` channel names (others use c, c2, 7. KWin 6.7.4 with anland's `anland` backend renders straight into the anland Android Surface through the server. While the window is not on screen (consumer disconnected) the backend powers its output down (DPMS Off + RenderLoop inhibited: no compositing, no frame callbacks) and back up when the window returns. Every other GL process is `MOBILEGL_IPC_SURFACE=offscreen` and presents through KWin. 8. Client = `/opt/mobilegl/lib/libMobileGL.so` (glibc aarch64), the container's **system-wide** GL vendor (section below): glvnd EGL vendor `/usr/share/glvnd/egl_vendor.d/10_mobilegl.json` (sorts before the distribution's `50_*.json`, which serves whenever MobileGL declines), GLX vendor `/usr/lib/libGLX_mobilegl.so.0`, settings from `/etc/mobilegl/client.conf` (`MOBILEGL_TRANSPORT=spawn MOBILEGL_IPC_DATA=shm MOBILEGL_IPC_CONTROL=unix:@anland-mobilegl`) + `/etc/mobilegl/backend`. No per-process environment is needed. 9. Zero-copy windows: client `wl_egl_window` frames are server-allocated AHardwareBuffer "shared images" exported as dma-buf fds over `zwp_linux_dmabuf_v1`; KWin imports them with EGL and the server recognises its own buffer by inode. KWin gets a DRM device via `GBM_BACKEND=mobilegl` -> `/usr/lib/gbm/mobilegl_gbm.so` (node is only an identity, never ioctl'd). Without linux-dmabuf the client falls back to wl_shm readback. -10. X11 apps (Xwayland) use the MobileGL GLX vendor with per-frame readback + `xcb_put_image`. Chrome runs ANGLE-GLES over MobileGL EGL with the GPU in-process (`mobilegl-startup.sh chrome`). +10. X11 (`docs/Disaggregated/notes/anland/plan-x11-gpu.md`): Xwayland draws with **glamor on MobileGL** (an offscreen session; `GBM_BACKEND=mobilegl` on KWin's render node; window pixmaps are shared images handed to KWin as linux-dmabuf buffers; its `glFlush` publishes them through the server, `/tmp/mgl-xwayland.client.log`); `ANLAND_XWAYLAND_GLAMOR=0` in KWin's drop-in brings back the software `-shm` Xwayland. GLX windows present their frames as shared images through **DRI3 + Present** (log `presented through DRI3+Present shared images`), falling back to readback + MIT-SHM / `xcb_put_image` when the X server has no DRI3 (`MOBILEGL_GLX_PRESENT=readback` forces it per app). Chrome runs ANGLE-GLES over MobileGL EGL with the GPU in-process (`mobilegl-startup.sh chrome`). ## First-time prerequisites (Windows host) @@ -108,7 +108,7 @@ Installed by `xdeploy.sh` (and anland's `anland-build-client.sh`), so any proces Precedence is environment > `/etc/mobilegl/backend` (backend only) > client.conf > built-in; `MOBILEGL_CONFIG_FILE` / `MOBILEGL_BACKEND_FILE` name other files (empty = off); a server process never reads them. -**Fallback.** Before bringing anything up the client probes the configured endpoint (one non-blocking connect, `MOBILEGL_IPC_PROBE_TIMEOUT_MS`, default 250, 0 = off; a refused abstract socket answers in ~0.2 ms). With no server: the EGL vendor returns `EGL_NO_DISPLAY` and no devices (glvnd moves on to the other vendor), the GLX vendor fails `__glx_Main` (libGLX falls back to the vendor Xwayland names), and `mobilegl_gbm` fails `create_device` (libgbm falls back to the device's own backend). Client queries (`eglQueryString(EGL_NO_DISPLAY)`, `eglGetProcAddress`) never bring a session up. MobileGL also steps aside for a GBM device another backend created and for `LIBGL_ALWAYS_SOFTWARE=1` - that is how Xwayland (KWin's patch sets it) keeps the software stack. Show it without stopping the real server: +**Fallback.** Before bringing anything up the client probes the configured endpoint (one non-blocking connect, `MOBILEGL_IPC_PROBE_TIMEOUT_MS`, default 250, 0 = off; a refused abstract socket answers in ~0.2 ms). With no server: the EGL vendor returns `EGL_NO_DISPLAY` and no devices (glvnd moves on to the other vendor), the GLX vendor fails `__glx_Main` (libGLX falls back to the vendor Xwayland names), and `mobilegl_gbm` fails `create_device` (libgbm falls back to the device's own backend). Client queries (`eglQueryString(EGL_NO_DISPLAY)`, `eglGetProcAddress`) never bring a session up. MobileGL also steps aside for a GBM device another backend created and for `LIBGL_ALWAYS_SOFTWARE=1` - that is how a software Xwayland (`ANLAND_XWAYLAND_GLAMOR=0`, KWin's patch sets it then) keeps the software stack. MobileGL never opens an X connection to a display its own process serves (`MG_Util/X11/DisplayGuard.h`; `MOBILEGL_X11_DIAL=0` forbids all), which is what made a glamor Xwayland deadlock on itself before. Show it without stopping the real server: ```sh sed 's|^MOBILEGL_IPC_CONTROL=.*|MOBILEGL_IPC_CONTROL=unix:@nobody|' /etc/mobilegl/client.conf > /tmp/down.conf sudo -u swung0x48 env -i HOME=/home/swung0x48 PATH=/usr/bin XDG_RUNTIME_DIR=/run/user/1000 WAYLAND_DISPLAY=wayland-0 \ @@ -117,6 +117,8 @@ sudo -u swung0x48 env -i HOME=/home/swung0x48 PATH=/usr/bin XDG_RUNTIME_DIR=/run ## Test clients and how to verify +X11 on the GPU has its own driver, `scripts/x11-verify.sh` (preflight, measure before/after with glxgears at `vblank_mode=0` on both GLX paths, deploy-client/-kwin/-server, check, apps, stop); `scripts/device/x11-measure.sh` refuses to load the phone below 40% battery. + Inside the container as root (`printf '...' | bash scripts/ct.sh `), `mgrun offscreen ` runs a client as swung0x48 in the live session through a login shell, with nothing but the surface mode and the log path set (log `/tmp/mgl-run.client.log`, override base with `MGLOG=/tmp/x.log`); a plain `env -i ... bash -l -c ''` as swung0x48 gets MobileGL the same way: ```sh mgrun offscreen eglinfo -B ; mgrun offscreen glxinfo -B diff --git a/.claude/skills/anland-mobilegl-plasma/scripts/device/x11-measure.sh b/.claude/skills/anland-mobilegl-plasma/scripts/device/x11-measure.sh new file mode 100644 index 00000000..b5c45e0d --- /dev/null +++ b/.claude/skills/anland-mobilegl-plasma/scripts/device/x11-measure.sh @@ -0,0 +1,47 @@ +# x11-measure.sh