Add --renderer for displays with no usable GPU; gate the header reading

GTK4 defaults to Vulkan, and an X11-forwarded display has no device to make a
swapchain from; the plot is a GtkGLArea, so it then asks for a GL context that
is not there either. --renderer cairo is the software preset for that display:
it exports GSK_RENDERER=cairo and LIBGL_ALWAYS_SOFTWARE=1 in main() before
gtk_init()/adw_init(), because both are read when the renderer and the context
are created. --renderer gl is the faster choice when indirect GL works, and
--renderer vulkan makes the default explicit. Nothing is exported, and GTK's
own choice stands, when the option is absent.

The once-a-second header line is now behind UDPSCOPE_PROBE_HEADER, following
the [notrace] rule: its widths are still sampled for the exit dump, but the
line is detail behind that reading rather than output every run prints.
UDPSCOPE_PROBE_RENDERER prints the exported pair before GTK starts and the
GskRenderer GTK actually built.

README, the manual's overview and docs/claude record the two symptoms and the
cure.
This commit is contained in:
Martino Ferrari committed 2026-10-28 16:03:05 +01:00
1 parent ac054a30c9
commit fcf268d249
9 files changed
+151 -7

No files matched your search

+27 -1
View File
@@ -27,7 +27,10 @@ Options: `--server`, `--port`, `--multicast`, `--interface`, `--buffer-mb`
window the toolbar offers, default 600), `--holdoff` (default trigger hold-off),
`--recv-buffer`, `--plots` (the number of stacked plots to start with, 1..8; rows are
added and removed from the **Layout editor** afterwards), `--relative-time` (see below),
`--capture-packets N` (see "Packet capture" below).
`--capture-packets N` (see "Packet capture" below), `--renderer NAME` (GTK's renderer:
`cairo`, `gl` or `vulkan`; `cairo` is the software preset that exports both
`GSK_RENDERER` and `LIBGL_ALWAYS_SOFTWARE` before GTK initialises — see the SSH
limitation below).
**What a large `--buffer-mb` costs at startup, and what the window says while it happens.** The
buffer's rings are value-initialised, so allocating one touches every byte of `--buffer-mb` --- about
@@ -2922,6 +2925,29 @@ silence timeout and then resumes, which is the EMI case end to end.
inner popover takes the grab, the menu closes under the click, and the bubble is
left parented to a row in a hidden popover. Export is described in the
Documentation instead.
- **Over SSH with X11 forwarding the window may never paint or allocate, and the cure is
`--renderer cairo`.** There are two walls, in order.
GTK4 defaults to Vulkan and a forwarded display has no usable Vulkan device, so the
log shows `vkCreateSwapchainKHR(): Initialization of an object could not be completed
... (VK_ERROR_INITIALIZATION_FAILED)` and nothing is drawn. `GSK_RENDERER` alone gets
past that, but the plot is a `GtkGLArea` and asks GDK for a GL context of its own
whatever GSK draws with; over forwarding there is no hardware one, and the window then
stays unallocated — `header: window_button_w=0` with a zero `bar_w`, and no
`[width-probe]` line (it prints only once the plot has a viewport wider than 100 px) —
while the stream side is fine. Absence of `buffer allocated:` is *not* part of that
reading: signals arrive disabled, so a start with nothing enabled plans no buffer and
prints no line even on a healthy display, and the plot stays empty until a signal's
switch is turned on.
`--renderer cairo` is the preset for exactly this display: it exports
`GSK_RENDERER=cairo` **and** `LIBGL_ALWAYS_SOFTWARE=1` (llvmpipe answers the GL area),
the same pair `tools/make-help-shots.sh` uses. `--renderer gl` is the faster
alternative when indirect GL works. The variables are exported in `main()` **before**
`gtk_init()`/`adw_init()`, which is the whole trap: they are read when the renderer and
the GL context are created, so setting them later is a silent no-op. Without the option
nothing is set and GTK's own choice stands. No `GDK_BACKEND` companion exists on
purpose: an X11-forwarded session carries `DISPLAY` and no `WAYLAND_DISPLAY`, so GDK
already selects X11; forcing it would override a working local Wayland session for no
gain (if both are set and Wayland is broken, export `GDK_BACKEND=x11` yourself).
- **The tour card can cover its own target, and in the documented headless run it
does.** The card is placed under, over or beside the hole whenever one of those has
room; when the target covers the whole content -- which is what the plot does at the