android: build the Xwayland glamor stack from upstream Mesa 26.2.6
Moves the Xwayland glamor Mesa stack off the old fork base (Mesa 25.0.0-devel, build-xwayland @ 81f599c0d7) onto upstream mesa-26.2.6, the newest 26.x stable tag. The base branch upstream-26.2.6 is the plain upstream tag, so the diff here is only our commits. The idea is that this replaces build-xwayland as the source of the glamor stage in the gamescope payload.
Why
Under gamescope on kernels older than 6.0 (Retroid Flip 2 / SD865 on 4.19, Thor / 8 Gen 2 on 5.15), Xwayland leaks one dma-buf fd per image barrier. The 25.0-devel zink_screen_export_dmabuf_semaphore() returns without close(fd) when DMA_BUF_IOCTL_EXPORT_SYNC_FILE fails with ENOTTY. After roughly 50 s Xwayland hits EMFILE: logcat fills with MESA: Unable to get a valid memory fd, then zink: couldn't allocate memory and Error getting buffer, and the picture freezes while the game keeps running. Upstream fixed this in de4224a57cc. 26.2.6 has it: the fd is closed right after the ioctl, so no cherry-pick is needed.
What moved
android: minimal LLVM-free glamor Mesa stack with gndrm support(Joshua's commit, re-ported):android/build recipe, overlays and README: unchanged.- gbm.c:
gbm_create_device()accepts the gndrm socket fd when DRM_IOCTL_VERSION says "gamenative". Unchanged. - loader.c: the gndrm fd counts as render capable and defaults to zink. Unchanged.
- backend.c: the GBM backend dir is resolved at runtime as the
gbm/sibling of libgbm. Unchanged. src/meson.build: dril is built for GBM-only builds. Re-applied on 26.2's condition, which no longer haswith_platform_xcb.- pipe-loader part: dropped. Upstream removed the dynamic pipe-loader (
PIPE_SEARCH_DIRandgallium-pipeno longer exist), so there was nothing left to apply it to.
android: build the glamor Mesa stack with ELF TLS: clean cherry-pick.android: build the glamor stack on 26.2 from Linux or macOS:- Drops the meson options 26.2 removed (
gallium-vdpau,gallium-xa,gallium-opencl,gallium-nine,osmesa,install-intel-clc). - Picks the NDK prebuilt dir from
uname -sand takes bison/flex from PATH (macOS/usr/bin/bisonis 2.3). - Uses
wc -cinstead of GNUdu -b.
- Drops the meson options 26.2 removed (
zink: name command buffers only when tracing or capturing: new, a workaround.- Since 82656de0297b, zink labels its batch command buffers with
vkSetDebugUtilsObjectNameEXT. - Under gamescope, Xwayland reaches the container's adrenotools Turnip through gn-vkshim's proxy. The proxy returns its own wrapper objects as
VkCommandBufferhandles and passesvkSetDebugUtilsObjectNameEXTstraight through. Turnip then reads the wrapper as avk_object_base. - Tombstone on the Tab S7: SEGV at 0x58 in
Turnip v26.2.0 R4/libvulkan_freedreno.so, reached viacreate_batch_state→zink_start_batch→zink_context_create→eglCreateContext. Xwayland never comes up. - The commit sets the names only when
zink_tracingor RenderDoc is active, the same conditions zink already uses for its other debug labels. - It can be dropped once the shim unwraps the handle in
vkSetDebugUtilsObjectNameEXT.
- Since 82656de0297b, zink labels its batch command buffers with
Stage
Built on macOS with NDK r27d against the termux-on-gha build-20260218 prefix (only include/, libdrm and the glvnd libs are needed). Output:
lib/libgallium-26.2.6.solib/libEGL_mesa.so.0lib/libgbm.so.1lib/gbm/dri_gbm.solib/dri/libdril_dri.soshare/glvnd/egl_vendor.d/50_mesa.json
Notes on the output:
- No emulated TLS, 16 KB LOAD alignment, no libandroid, no build-host paths.
- There is no
libglapi.so.0any more: glapi has lived in libgallium since 25.1, and the TLS symbol is now_mesa_glapi_tls_Context. - libgallium now links the system
libz.soinstead of termuxlibz.so.1. - When this ships,
package-gamescope.shneedsMESA_STAGE_SONAMESupdated:libgallium-26.2.6.so, and nolibglapi.so.0.
Testing
Galaxy Tab S7 (Adreno 650, Android 11, kernel 4.19) on BrowserStack App Live, Legacy testbed build, wrappertest gl/ with WT_GL_HOLD_SEC=300 under gamescope. The test payloads are the shipped gamescope-gamenative-20261028.4 with only the glamor Mesa files swapped.
| payload | workload | result | Unable to get a valid memory fd / couldn't allocate memory / Error getting buffer |
|---|---|---|---|
| shipped 20261028.4 | gl/ hold 300 s | PASS 12/0, about 27 fps | 0 / 0 / 0 |
| shipped 20261028.4 | TestD3D (DXVK) 300 s | rendered, 59.7 fps, exit 0 | 0 / 0 / 0 |
browserstack/gamescope-glamor-upstream-4afc4a1-base20261028.4.tzst (without the zink commit) | gl/ | Xwayland SEGV at start-up | n/a |
browserstack/gamescope-glamor-upstream-af7b88f-base20261028.4.tzst | gl/ hold 300 s | PASS 12/0, 27.5 fps, window visible and still updating at the end | 0 / 0 / 0 |
| same | TestD3D (DXVK) 300 s | rendered, 59.8 fps, exit 0 | 0 / 0 / 0 |
On the Tab S7 the leak does not reproduce with these workloads, even on the shipped payload. So this run shows the 26.2.6 stack works there with no regression; it does not prove the leak is gone. That still needs a run on an affected device (Flip 2 or Thor with a GL/sprite game, where the freeze showed after about 50 s). The fd count could not be read on App Live, because its shell does not allow ps or /proc.
Test payload: https://downloads.gamenative.app/browserstack/gamescope-glamor-upstream-af7b88f-base20261028.4.tzst, 14371338 bytes, sha256 c505e63cd1b714c07964a10d4ccea111e6030252c966096fb4a05b78d762c0d2.