From 7a5b0755b35245a3d6a974daeab6b8e7242de425 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Fri, 2 Oct 2026 20:13:33 -0400 Subject: [PATCH] [Docs] (Anland): install MobileGL as the container's system-wide vendor and document the fallback --- .../skills/anland-mobilegl-plasma/SKILL.md | 32 ++++++++++++++++--- .../scripts/chrome-launch.sh | 5 +-- .../scripts/container/mgrun | 12 +++---- .../anland-mobilegl-plasma/scripts/xdeploy.sh | 29 +++++++++++++++-- .../notes/anland/runbook-plasma.md | 30 +++++++++++++++-- 5 files changed, 91 insertions(+), 17 deletions(-) diff --git a/.claude/skills/anland-mobilegl-plasma/SKILL.md b/.claude/skills/anland-mobilegl-plasma/SKILL.md index 3585e6b8..9e36c38a 100644 --- a/.claude/skills/anland-mobilegl-plasma/SKILL.md +++ b/.claude/skills/anland-mobilegl-plasma/SKILL.md @@ -23,7 +23,7 @@ nobody else is mid-test. Use your own `ct.sh` channel names (others use c, c2, 5. Container `arch-kde-mgl` (Droidspaces 6.4.5, Arch Linux ARM aarch64 glibc, host net, `rootfs.img` mounted at `/mnt/Droidspaces/arch-kde-mgl` on the Android side). Bind mounts: `/data/local/tmp/anland-mobilegl` -> `/run/anland-mobilegl`, `/data/local/tmp/display_daemon.sock` -> `/run/display.sock`. 6. `desktop-session.service` (User=swung0x48) has drop-in `ExecStart=/opt/mobilegl/bin/mobilegl-startup.sh plasma`, which writes a user drop-in for `plasma-kwin_wayland.service` (kwin_wayland_wrapper -> `/opt/mobilegl/kwin/bin/kwin_wayland` + `/opt/mobilegl/kwin/lib/libkwin.so.6.7.4`, `ANLAND_MOBILEGL=1`, `MOBILEGL_IPC_SURFACE=server`) and runs `startplasma-wayland`. 7. KWin 6.7.4 with anland's `anland` backend renders straight into the anland Android Surface through the server. Every other GL process is `MOBILEGL_IPC_SURFACE=offscreen` and presents through KWin. -8. Client = `/opt/mobilegl/lib/libMobileGL.so` (glibc aarch64): glvnd EGL vendor (`/opt/mobilegl/share/glvnd/egl_vendor.d/50_mobilegl.json`), GLX vendor (`/usr/lib/libGLX_mobilegl.so.0`, `__GLX_VENDOR_LIBRARY_NAME=mobilegl`), env `MOBILEGL_TRANSPORT=spawn MOBILEGL_IPC_DATA=shm MOBILEGL_IPC_CONTROL=unix:@anland-mobilegl`. +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`). @@ -69,7 +69,7 @@ bash scripts/cyc.sh s1 # clear sticky SW-renderer key, push, swa **Client + GBM backend (container glibc) via WSL cross-build** ```sh bash scripts/xbuild.sh [--reconfigure] # WSL ~/mgl-xbuild-a64; ~150 s full, seconds incremental -bash scripts/xdeploy.sh # rename-into-place install of libMobileGL.so + mobilegl_gbm.so, aliases, vendor JSON +bash scripts/xdeploy.sh # rename-into-place install of libMobileGL.so + mobilegl_gbm.so, aliases, vendor JSONs, client.conf, GLX/GBM env drop-ins ``` Running clients keep the old inode; restart the client, or `run-plasma.sh` for KWin/plasmashell. Build server and client from the **same commit** (both stamp `git rev-parse HEAD`), else the logs WARN "compatible wire with different build". Fallback in-container build (slow): `scripts/sync-src.sh` + anland `mobilegl-tools/anland-build-client.sh`. @@ -92,9 +92,31 @@ MSYS2_ARG_CONV_EXCL='*' wsl -d archlinux -- bash -lc 'cd ~/mgl-anl-bld && ctest `adb shell 'su -c "sh /data/local/tmp/anl/switch.sh DirectGLES"'` (sets the prop, writes `/etc/mobilegl/backend`, restarts the app), then `run-plasma.sh` - the running session's clients are pinned to the old backend. `cyc.sh` keeps whatever is set. +## System-wide vendor and fallback + +Installed by `xdeploy.sh` (and anland's `anland-build-client.sh`), so any process in the container gets MobileGL through the stock libglvnd/libgbm: + +| File | Does | +|---|---| +| `/usr/share/glvnd/egl_vendor.d/10_mobilegl.json` | EGL vendor, asked before the system's `50_*.json` | +| `/opt/mobilegl/share/glvnd/egl_vendor.d/50_mobilegl.json` | same JSON, for per-process forcing with `__EGL_VENDOR_LIBRARY_FILENAMES` | +| `/etc/mobilegl/client.conf` | `KEY=value` defaults for every client (transport, data, endpoint); rewritten on deploy | +| `/etc/mobilegl/backend` | the backend (`switch.sh` writes it); wins over a `MOBILEGL_BACKEND_TYPE` line in client.conf | +| `/etc/environment.d/10-mobilegl.conf` | `__GLX_VENDOR_LIBRARY_NAME=mobilegl`, `GBM_BACKEND=mobilegl` for the systemd user manager (all Plasma services and what they start, terminals included) | +| `/etc/profile.d/mobilegl.sh` | the same two for login shells (`bash -l`, `su -l`, ssh, `droidspaces run bash -l`) | + +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: +```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 \ + MOBILEGL_CONFIG_FILE=/tmp/down.conf eglinfo -B -p wayland # vendor = the other one, ~0.1 s +``` + ## Test clients and how to verify -Inside the container as root (`printf '...' | bash scripts/ct.sh `), `mgrun offscreen ` runs a client as swung0x48 in the live session (log `/tmp/mgl-run.client.log`, override base with `MGLOG=/tmp/x.log`): +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 timeout 25 mgrun offscreen glmark2-es2-wayland -s 1280x720 --run-forever > /tmp/gm.out 2>&1 & @@ -138,7 +160,9 @@ Reference (glmark2-es2-wayland 1280x720, zero-copy vs wl_shm): Espryt 187 vs 49, - **Input**: plain `adb shell input` is blocked - use `su -c input`; anland grabs the touchscreen, so if `input tap` does nothing use `input mouse tap x y`. Never `debuggerd -b` a container process (signal 35 kills glibc processes). - **linux-dmabuf**: the client must use `create` + roundtrip, never `create_immed` (KWin answers a failed immediate import with a protocol error that kills the client). - **Cross-session bugs**: noise / another window's pixels after some client starts or exits = process-global state in the multi-session server (handles are per client, FBO/VAO per context). Repro with `kscreenlocker_greet --testing`. -- `/etc/environment` leaks Mesa/KGSL variables through pam_env; `mobilegl-startup.sh` unsets them - keep that when editing it. +- `/etc/environment` leaks the baseline session's driver variables through pam_env (and, via `/usr/lib/environment.d/99-environment.conf`, into the user manager); `mobilegl-startup.sh` unsets them - keep that when editing it. +- **Shared log path**: Xwayland inherits KWin's `MOBILEGL_LOG_FILE_PATH`; any line a process logs opens (truncates) that file. MobileGL stays silent in processes it does not serve, but give any extra client its own `MOBILEGL_LOG_FILE_PATH`. +- **Stale per-process overrides**: an `__EGL_VENDOR_LIBRARY_FILENAMES` / `MOBILEGL_*` left in a unit drop-in or the user manager's environment (`systemctl --user show-environment`) still wins over the system files; `run-plasma.sh` (terminate-user) clears the manager's. - `handoff` mentions a `kwin_wayland` logging shim and `/tmp/mgl-kwin-.log`: stale - `/opt/mobilegl/kwin/bin/kwin_wayland` is now the real binary and logs to `/tmp/mobilegl-compositor.client.log`. ## House rules diff --git a/.claude/skills/anland-mobilegl-plasma/scripts/chrome-launch.sh b/.claude/skills/anland-mobilegl-plasma/scripts/chrome-launch.sh index 05da59f4..0be8d77b 100644 --- a/.claude/skills/anland-mobilegl-plasma/scripts/chrome-launch.sh +++ b/.claude/skills/anland-mobilegl-plasma/scripts/chrome-launch.sh @@ -2,7 +2,8 @@ # chrome-launch.sh [extra chrome flags...] - (re)start Chrome inside the running Plasma session # through mobilegl-startup.sh's `chrome` mode (ANGLE GLES over MobileGL EGL, in-process GPU), client # log /tmp/mgl-chrome-.client.log, then print its "presented through" line and save a screenshot -# to $ANL_DIR/ch-.png. Kills the running chrome first (pkill -x, never -f). +# to $ANL_DIR/ch-.png. Kills the running chrome first (pkill -x, never -f). MobileGL is the +# container's system-wide vendor (10_mobilegl.json + /etc/mobilegl/client.conf), so only the log is set here. # Env: WAIT (s before checking, default 20), CHANNEL (ct.sh channel, default chrome). set -euo pipefail here=$(cd "$(dirname "$0")" && pwd) @@ -11,7 +12,7 @@ TAG=${1:?usage: chrome-launch.sh [chrome flags...]}; shift bash "$here/ct.sh" "${CHANNEL:-chrome}" < /tmp/chrome-$TAG-out.log 2>&1 &' +sudo -u $MGL_DESKTOP_USER env XDG_RUNTIME_DIR=/run/user/\$U WAYLAND_DISPLAY=wayland-0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/\$U/bus MOBILEGL_LOG_FILE_PATH=/tmp/mgl-chrome-$TAG.log bash -c 'nohup /opt/mobilegl/bin/mobilegl-startup.sh chrome --restore-last-session $* > /tmp/chrome-$TAG-out.log 2>&1 &' sleep ${WAIT:-20} grep -ah 'presented through' /tmp/mgl-chrome-$TAG.client.log | head -3 IN diff --git a/.claude/skills/anland-mobilegl-plasma/scripts/container/mgrun b/.claude/skills/anland-mobilegl-plasma/scripts/container/mgrun index 62f084c0..e76ec453 100644 --- a/.claude/skills/anland-mobilegl-plasma/scripts/container/mgrun +++ b/.claude/skills/anland-mobilegl-plasma/scripts/container/mgrun @@ -4,7 +4,10 @@ # mgrun offscreen glmark2-es2-wayland -s 1280x720 # Wayland client, presents through KWin # mgrun offscreen eglinfo -B ; mgrun offscreen glxinfo -B # glxinfo goes through Xwayland + GLX vendor # "server" is only for a client that owns the Android Surface itself (KWin does); everything else is -# offscreen. Backend = /etc/mobilegl/backend (must match the server). Client log: +# offscreen. MobileGL is the container's system-wide vendor, so nothing selects it here: EGL comes from +# /usr/share/glvnd/egl_vendor.d/10_mobilegl.json, transport/endpoint from /etc/mobilegl/client.conf, +# the backend from /etc/mobilegl/backend (must match the server), and the GLX vendor name / GBM backend +# from /etc/profile.d/mobilegl.sh (sourced by the login shell below). Client log: # ${MGLOG:-/tmp/mgl-run.log} -> the library writes /tmp/mgl-run.client.log (truncated per run; give # concurrent clients different MGLOG values). Env: MGLOG, DESKTOP_USER (swung0x48). S=$1; shift @@ -14,8 +17,5 @@ cd /tmp exec sudo -u "$DU" env XDG_RUNTIME_DIR=/run/user/$U WAYLAND_DISPLAY=wayland-0 DISPLAY=:0 \ XAUTHORITY=$(ls /run/user/$U/xauth_* 2>/dev/null | head -1) \ DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$U/bus QT_QPA_PLATFORM=wayland \ - __EGL_VENDOR_LIBRARY_FILENAMES=/opt/mobilegl/share/glvnd/egl_vendor.d/50_mobilegl.json \ - __GLX_VENDOR_LIBRARY_NAME=mobilegl \ - MOBILEGL_TRANSPORT=spawn MOBILEGL_IPC_DATA=shm MOBILEGL_IPC_CONTROL=unix:@anland-mobilegl \ - MOBILEGL_IPC_SURFACE=$S MOBILEGL_BACKEND_TYPE=$(cat /etc/mobilegl/backend 2>/dev/null || echo DirectGLES) \ - MOBILEGL_LOG_FILE_PATH=${MGLOG:-/tmp/mgl-run.log} "$@" + MOBILEGL_IPC_SURFACE=$S MOBILEGL_LOG_FILE_PATH=${MGLOG:-/tmp/mgl-run.log} \ + bash -lc 'exec "$@"' mgrun "$@" diff --git a/.claude/skills/anland-mobilegl-plasma/scripts/xdeploy.sh b/.claude/skills/anland-mobilegl-plasma/scripts/xdeploy.sh index 0a888fa3..7ab2f4b6 100644 --- a/.claude/skills/anland-mobilegl-plasma/scripts/xdeploy.sh +++ b/.claude/skills/anland-mobilegl-plasma/scripts/xdeploy.sh @@ -2,7 +2,8 @@ # xdeploy.sh - install the WSL cross-built libMobileGL.so + mobilegl_gbm.so into the container, exactly # like anland's anland-build-client.sh: copy to a NEW inode and rename into place (overwriting a mapped # .so in place crashes every running client, KWin included), refresh the libEGL/libGL aliases, the -# glvnd GLX vendor link and the EGL vendor JSON. Does not restart anything: already-running clients +# glvnd GLX vendor link, the EGL vendor JSON (system-wide 10_mobilegl.json + the /opt copy), the client +# config /etc/mobilegl/client.conf and the GLX/GBM selection drop-ins. Does not restart anything: already-running clients # keep the old inode; restart the client (or the session) to pick up the new library. # Env: MGL_XBUILD_DIR (WSL build dir), CHANNEL (ct.sh channel, default xd), WSL_DISTRO. set -euo pipefail @@ -30,11 +31,35 @@ cp "$in/libMobileGL.so" /opt/mobilegl/lib/libMobileGL.so.new mv -f /opt/mobilegl/lib/libMobileGL.so.new /opt/mobilegl/lib/libMobileGL.so for lib in libEGL.so libEGL.so.1 libGL.so libGL.so.1; do ln -sf libMobileGL.so "/opt/mobilegl/lib/$lib"; done ln -sf /opt/mobilegl/lib/libMobileGL.so /usr/lib/libGLX_mobilegl.so.0 -printf '%s\n' '{"file_format_version":"1.0.0","ICD":{"library_path":"/opt/mobilegl/lib/libMobileGL.so"}}' >/opt/mobilegl/share/glvnd/egl_vendor.d/50_mobilegl.json +vendor='{"file_format_version":"1.0.0","ICD":{"library_path":"/opt/mobilegl/lib/libMobileGL.so"}}' +# Per-process forcing (__EGL_VENDOR_LIBRARY_FILENAMES=) keeps working off the /opt copy. +printf '%s\n' "$vendor" >/opt/mobilegl/share/glvnd/egl_vendor.d/50_mobilegl.json +# System-wide vendor: 10_ sorts ahead of the system's 50_mesa.json, so stock libglvnd asks MobileGL +# first and moves on to the other vendor whenever MobileGL declines (no server reachable). +mkdir -p /usr/share/glvnd/egl_vendor.d +printf '%s\n' "$vendor" >/usr/share/glvnd/egl_vendor.d/10_mobilegl.json.new +mv -f /usr/share/glvnd/egl_vendor.d/10_mobilegl.json.new /usr/share/glvnd/egl_vendor.d/10_mobilegl.json +# Client settings every process reads when its environment does not say otherwise (the backend +# comes from /etc/mobilegl/backend, which switch.sh rewrites). +mkdir -p /etc/mobilegl +cat >/etc/mobilegl/client.conf <<'CONF' +# MobileGL client configuration, read by every process that loads libMobileGL.so. +# KEY=value lines; a MOBILEGL_* variable in a process's environment overrides the line here. +# The backend is /etc/mobilegl/backend. Written by xdeploy.sh / anland-build-client.sh. +MOBILEGL_TRANSPORT=spawn +MOBILEGL_IPC_DATA=shm +MOBILEGL_IPC_CONTROL=unix:@anland-mobilegl +CONF +# What glvnd's libGLX and libgbm cannot infer: environment.d reaches the systemd user manager (every +# Plasma service and what it launches, terminals included), profile.d reaches login shells. +mkdir -p /etc/environment.d /etc/profile.d +printf '%s\n' '__GLX_VENDOR_LIBRARY_NAME=mobilegl' 'GBM_BACKEND=mobilegl' >/etc/environment.d/10-mobilegl.conf +printf '%s\n' 'export __GLX_VENDOR_LIBRARY_NAME=mobilegl' 'export GBM_BACKEND=mobilegl' >/etc/profile.d/mobilegl.sh mkdir -p /usr/lib/gbm cp "$in/mobilegl_gbm.so" /usr/lib/gbm/mobilegl_gbm.so.new mv -f /usr/lib/gbm/mobilegl_gbm.so.new /usr/lib/gbm/mobilegl_gbm.so rm -f "$in/libMobileGL.so" "$in/mobilegl_gbm.so" sha256sum /opt/mobilegl/lib/libMobileGL.so /usr/lib/gbm/mobilegl_gbm.so +ls /usr/share/glvnd/egl_vendor.d/ /etc/mobilegl/ /etc/environment.d/ echo DEPLOYED IN diff --git a/docs/Disaggregated/notes/anland/runbook-plasma.md b/docs/Disaggregated/notes/anland/runbook-plasma.md index c703db3e..644b9644 100644 --- a/docs/Disaggregated/notes/anland/runbook-plasma.md +++ b/docs/Disaggregated/notes/anland/runbook-plasma.md @@ -13,7 +13,7 @@ - **容器** `arch-kde-mgl`:Droidspaces 6.4.5,Arch Linux ARM(aarch64 glibc),host 网络;Android 侧 `rootfs.img` 挂在 `/mnt/Droidspaces/arch-kde-mgl`。bind mount:`/data/local/tmp/anland-mobilegl` → `/run/anland-mobilegl`,`/data/local/tmp/display_daemon.sock` → `/run/display.sock`。 - **会话**:`desktop-session.service`(User=swung0x48)的 drop-in 把 ExecStart 换成 `/opt/mobilegl/bin/mobilegl-startup.sh plasma`;它每次写 `plasma-kwin_wayland.service` 的用户 drop-in(经 `kwin_wayland_wrapper` 起 `/opt/mobilegl/kwin/bin/kwin_wayland` + `/opt/mobilegl/kwin/lib/libkwin.so.6.7.4`,`ANLAND_MOBILEGL=1`、`MOBILEGL_IPC_SURFACE=server`),然后 `startplasma-wayland`。 - **KWin 6.7.4** 带 anland 的 `anland` 后端,经 server 直接画进 anland 的 Android Surface。其余 GL 进程都是 `MOBILEGL_IPC_SURFACE=offscreen`,经 KWin 合成上屏。 -- **client 库** `/opt/mobilegl/lib/libMobileGL.so`(glibc aarch64):glvnd 的 EGL vendor(`/opt/mobilegl/share/glvnd/egl_vendor.d/50_mobilegl.json`)+ GLX vendor(`/usr/lib/libGLX_mobilegl.so.0`,`__GLX_VENDOR_LIBRARY_NAME=mobilegl`);环境 `MOBILEGL_TRANSPORT=spawn MOBILEGL_IPC_DATA=shm MOBILEGL_IPC_CONTROL=unix:@anland-mobilegl`。 +- **client 库** `/opt/mobilegl/lib/libMobileGL.so`(glibc aarch64),是容器里**全系统**的 GL vendor(见下节):EGL vendor `/usr/share/glvnd/egl_vendor.d/10_mobilegl.json`(排在发行版的 `50_*.json` 前面,MobileGL 拒绝时由它接手)、GLX vendor `/usr/lib/libGLX_mobilegl.so.0`,配置来自 `/etc/mobilegl/client.conf`(`MOBILEGL_TRANSPORT=spawn MOBILEGL_IPC_DATA=shm MOBILEGL_IPC_CONTROL=unix:@anland-mobilegl`)+ `/etc/mobilegl/backend`。进程不需要任何专门的环境变量。 - **零拷贝窗口**:client 的 `wl_egl_window` 帧是 server 分配的 AHardwareBuffer(shared image),以 dma-buf fd 经 `zwp_linux_dmabuf_v1` 交给 KWin;KWin 用 EGL 导入,server 按 inode 认出是自己发出的那块。KWin 的 DRM 设备来自 `GBM_BACKEND=mobilegl` → `/usr/lib/gbm/mobilegl_gbm.so`(节点只当身份,从不 ioctl)。没有 linux-dmabuf 时退回 wl_shm 回读。 - **X11**(Xwayland)走 MobileGL 的 GLX vendor,每帧回读 + `xcb_put_image`。Chrome 用 `mobilegl-startup.sh chrome`:ANGLE GLES 跑在 MobileGL EGL 上,GPU 在浏览器进程内。 @@ -61,7 +61,7 @@ bash scripts/cyc.sh s1 # 删粘滞软件渲染键 → 推库 → 换 ```sh bash scripts/xbuild.sh [--reconfigure] # WSL ~/mgl-xbuild-a64;全量约 150 秒,增量几秒 -bash scripts/xdeploy.sh # 新 inode 改名就位安装 libMobileGL.so + mobilegl_gbm.so,刷新别名、GLX 链接、vendor JSON +bash scripts/xdeploy.sh # 新 inode 改名就位安装 libMobileGL.so + mobilegl_gbm.so,刷新别名、GLX 链接、vendor JSON、client.conf 和 GLX/GBM 环境 drop-in ``` 已经在跑的 client 继续映射旧 inode:重启那个 client,KWin / plasmashell 就 `run-plasma.sh`。server 与 client **同一个 commit** 构建(两边 stamp 都取 `git rev-parse HEAD`),否则日志里 WARN "compatible wire with different build"。容器内构建是备用路径(慢):`scripts/sync-src.sh` 同步改动的文件,再在容器里跑 anland 的 `mobilegl-tools/anland-build-client.sh`。 @@ -91,6 +91,28 @@ MSYS2_ARG_CONV_EXCL='*' wsl -d archlinux -- bash -lc 'cd ~/mgl-anl-bld && ctest `adb shell 'su -c "sh /data/local/tmp/anl/switch.sh DirectGLES"'`(设属性、写 `/etc/mobilegl/backend`、重启 app),然后 `run-plasma.sh`——正在跑的会话里各 client 还钉在旧后端上。`cyc.sh` 不改后端。 +## 全系统 vendor 与回退 + +`xdeploy.sh`(以及 anland 的 `anland-build-client.sh`)安装下面这些,容器里任何进程经原版 libglvnd / libgbm 就用上 MobileGL: + +| 文件 | 作用 | +|---|---| +| `/usr/share/glvnd/egl_vendor.d/10_mobilegl.json` | EGL vendor,先于系统的 `50_*.json` 被问 | +| `/opt/mobilegl/share/glvnd/egl_vendor.d/50_mobilegl.json` | 同一份 JSON,留给 `__EGL_VENDOR_LIBRARY_FILENAMES` 单进程强制 | +| `/etc/mobilegl/client.conf` | 所有 client 的 `KEY=value` 默认值(transport、data、endpoint),每次部署重写 | +| `/etc/mobilegl/backend` | 后端(`switch.sh` 写);比 client.conf 里的 `MOBILEGL_BACKEND_TYPE` 优先 | +| `/etc/environment.d/10-mobilegl.conf` | `__GLX_VENDOR_LIBRARY_NAME=mobilegl`、`GBM_BACKEND=mobilegl`,给 systemd 用户管理器(所有 Plasma 服务及其子进程,包括终端) | +| `/etc/profile.d/mobilegl.sh` | 同样两项,给登录 shell(`bash -l`、`su -l`、ssh、`droidspaces run bash -l`) | + +优先级:环境变量 > `/etc/mobilegl/backend`(只管后端)> client.conf > 内置默认;`MOBILEGL_CONFIG_FILE` / `MOBILEGL_BACKEND_FILE` 可指向别的文件(设为空即关闭);server 进程不读这些文件。 + +**回退**:真正拉起之前 client 先探一次配置的 endpoint(一次非阻塞 connect,`MOBILEGL_IPC_PROBE_TIMEOUT_MS` 默认 250,0 关闭;被拒的抽象 socket 约 0.2 ms 就有结果)。没有 server 时:EGL vendor 返回 `EGL_NO_DISPLAY`、设备数 0(glvnd 换下一个 vendor),GLX vendor 的 `__glx_Main` 失败(libGLX 回退到 Xwayland 报的 vendor),`mobilegl_gbm` 的 `create_device` 失败(libgbm 回退到设备自己的后端)。客户端查询(`eglQueryString(EGL_NO_DISPLAY)`、`eglGetProcAddress`)从不拉起会话。对别的后端创建的 GBM 设备和 `LIBGL_ALWAYS_SOFTWARE=1` 的进程,MobileGL 同样让开——Xwayland(KWin 补丁给它设了这个)因此继续走软件栈。不停真 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 \ + MOBILEGL_CONFIG_FILE=/tmp/down.conf eglinfo -B -p wayland # vendor 变成另一个,约 0.1 s +``` + ## 跑测试 client 与验证 在容器里以 root 执行(`printf '...' | bash scripts/ct.sh <通道>`),`mgrun offscreen <命令>` 以 swung0x48 身份在当前会话里起一个 client(日志 `/tmp/mgl-run.client.log`,`MGLOG=/tmp/x.log` 可换): @@ -140,7 +162,9 @@ Chrome:`bash scripts/chrome-launch.sh [参数]`(日志 `/tmp/mgl-chrom - **输入注入**:普通 `adb shell input` 被拦,要 `su -c input`;anland 抓了触摸屏,`input tap` 无效时用 `input mouse tap x y`。不要对容器进程用 `debuggerd -b`(信号 35 会直接杀掉 glibc 进程)。 - **linux-dmabuf**:client 必须 `create` + roundtrip,不能 `create_immed`(KWin 对失败的立即导入回协议错误,直接断开 client)。 - **跨会话 bug**:某个 client 起来或退出后出现噪点 / 别的窗口的残影,先怀疑多会话 server 里的进程级状态(handle 是每 client 各自的,FBO / VAO 是每 context 的)。复现用 `kscreenlocker_greet --testing`。 -- `/etc/environment` 经 pam_env 带进 Mesa / KGSL 变量,`mobilegl-startup.sh` 里把它们 unset 了,改脚本时保留。 +- `/etc/environment` 经 pam_env(以及 `/usr/lib/environment.d/99-environment.conf` 进用户管理器)带进基线会话的驱动变量,`mobilegl-startup.sh` 里把它们 unset 了,改脚本时保留。 +- **共用日志路径**:Xwayland 继承 KWin 的 `MOBILEGL_LOG_FILE_PATH`,进程写第一行日志就会打开(截断)那个文件。MobileGL 在不服务的进程里不写日志,但额外起的 client 要给自己的 `MOBILEGL_LOG_FILE_PATH`。 +- **残留的单进程覆盖**:unit drop-in 或用户管理器环境(`systemctl --user show-environment`)里遗留的 `__EGL_VENDOR_LIBRARY_FILENAMES` / `MOBILEGL_*` 仍比系统文件优先;`run-plasma.sh`(terminate-user)会清掉管理器里的。 - handoff 里提到的 `kwin_wayland` 日志 shim 与 `/tmp/mgl-kwin-.log` 已过时:`/opt/mobilegl/kwin/bin/kwin_wayland` 现在就是真二进制,KWin 的 client 日志在 `/tmp/mobilegl-compositor.client.log`。 ## 规矩