block / block/buzz

[Bug][Linux] AppImage build force-sets WEBKIT_DISABLE_DMABUF_RENDERER (broken per #3654); .deb build does not

Open
#4,920 2 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Rust
Stars
32.7k
Forks
4.3k
Avg merge
1d 13h
Merged PRs (30d)
253

Description

buzz-desktop hardcodes `WEBKIT_DISABLE_DMABUF_RENDERER`, which #3654 identifies as broken — and it costs ~15% of a CPU core

## Summary

`buzz-desktop` sets `WEBKIT_DISABLE_DMABUF_RENDERER=1` for its WebKit child process from inside the binary. #3654 reports that this variable no longer falls back to shared memory on current WebKitGTK and instead leaves the transport mode empty, causing a null-pointer dereference (SIGSEGV) when content needs a compositing layer — and recommends `WEBKIT_DMABUF_RENDERER_FORCE_SHM=1` instead.

So Buzz ships with the broken lever enabled by default. On top of the crash exposure described in #3654, I can measure a CPU cost: setting `WEBKIT_DMABUF_RENDERER_FORCE_SHM=1` externally reduces the renderer's idle CPU from ~63% to ~48% of a core.

## Evidence that Buzz sets it

The string is present in the shipped binaries — both packages:

```
$ strings -n 8 /usr/bin/buzz-desktop.bin | grep -oE 'WEBKIT_[A-Z_]+'
WEBKIT_DISABLE_DMABUF_RENDERER
WEBKIT_DISABLE_COMPOSITING_MODE

$ strings -n 8 /usr/bin/buzz-desktop | grep -oE 'WEBKIT_[A-Z_]+' # .deb build
WEBKIT_DISABLE_DMABUF_RENDERER
WEBKIT_DISABLE_COMPOSITING_MODE
```

And it appears in the running renderer's environment:

```
$ tr '\0' '\n' < /proc//environ | grep '^WEBKIT'
WEBKIT_DISABLE_DMABUF_RENDERER=1
```

It is **not** set by my shell, by any shell rc file, by `~/.config/environment.d/`, or by the AppImage's `AppRun` / `apprun-hooks/linuxdeploy-plugin-gtk.sh` — I checked each. The only remaining source is `buzz-desktop` itself.

## Measured cost

Idle, visible window, no user interaction. `utime+stime` deltas from `/proc//stat` over 60s windows, run from a detached script after a settle period. Phases interleaved A/B/A/B, with Buzz-closed reference phases at both ends to prove the desktop was quiet and did not drift:

| Phase | `kwin_x11` | `Xorg` | `WebKitWebProcess` |
|---|---|---|---|
| 0. closed (reference) | 2.9 % | 4.8 % | — |
| A1 stock | 93.3 % | 32.8 % | **61.2 %** |
| B1 + `FORCE_SHM` | 97.0 % | 34.0 % | **48.5 %** |
| A2 stock | 94.4 % | 33.2 % | **65.8 %** |
| B2 + `FORCE_SHM` | 92.2 % | 31.2 % | **48.1 %** |
| Z. closed (drift check) | 0.7 % | 3.4 % | — |

The two stock values (61.2, 65.8) and the two `FORCE_SHM` values (48.5, 48.1) do not overlap, and the `FORCE_SHM` pair is notably more stable. The compositor and X server are unaffected, as expected — this changes buffer transport, not how much gets composited.

**Important limitation:** because the variable is set inside the binary, I cannot unset it from outside. So what I measured is *adding* `WEBKIT_DMABUF_RENDERER_FORCE_SHM=1` on top of Buzz's own `WEBKIT_DISABLE_DMABUF_RENDERER=1`, not replacing it. A build with the flag removed or swapped would likely show the same or better, but I could not test that.

## Environment

| | |
|---|---|
| Buzz | 0.5.4 AppImage (`md5 66409eb79953315f5a7cb0e10d91af34`); same string also in 0.5.2 `.deb` |
| Toolkit | WebKitGTK 4.1 + GTK3 |
| OS | Kubuntu, kernel 7.0.0-28-generic, KDE Plasma 6.6.5 / kwin 6.6.4, X11 |
| Machine | KVM/QEMU guest, 22 vCPU, 30 GB RAM |
| CPU | Xeon E5-2680 @ 2.70 GHz — AVX yes, AVX2 no |
| GPU | virtio-gpu, kernel reports `features: -virgl` → Mesa 26.0.3 llvmpipe, `Accelerated: no` |

No GPU acceleration at all here, which is exactly the configuration the dmabuf path cannot help with — and where #3654's recommended `FORCE_SHM` is the correct transport.

## Suggested fix

- Replace the hardcoded `WEBKIT_DISABLE_DMABUF_RENDERER=1` with `WEBKIT_DMABUF_RENDERER_FORCE_SHM=1`, per #3654.
- Or, at minimum, stop forcing it unconditionally and let it be overridden — currently a user can only add variables alongside it, not remove it.
- If the original intent was to work around blank windows on some drivers, `FORCE_SHM` addresses that case without the null-transport crash path.

Related: #3654 (the variable's broken fallback), #3677 (idle renderer/compositor load — a separate and much larger cost on this setup, which this change does not address).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.