Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ADR-0026: SDL picks the video driver, and says which

  • Status: Its decision is superseded by ADR-0027 — Goldberry now prefers Wayland. The findings below, and the logging, stand
  • Date: 2026-08-15
  • Relates to: docs/ARCHITECTURE.md §4, ADR-0003, ADR-0024

Context

After the frame path was made prompt and the redundant copy removed (ADR-0024), resizing still felt worse than a native window. The frame numbers said it should not: about 5 ms of work per frame at 1080p, most of it inside SDL’s upload.

The numbers were measuring the wrong thing. Binding SDL_GetCurrentVideoDriver and logging it at start-up answered it in one line:

sdl3 backend started on SDL 3.2.0, video driver x11

On a Wayland session. Every Wayland library was installed, libdecor included, and SDL was compiled with both drivers — SDL had simply chosen X11, which means the window was going through XWayland. XWayland resize is not synchronised with the compositor the way a native Wayland surface is, and looking worse than a native window while resizing is precisely what it does.

SDL’s choice turns out to be deliberate. From SDL_video.c, the Wayland driver is tried before X11 only through Wayland_preferred_bootstrap, and Wayland_IsPreferred returns true only if the compositor advertises wp_fifo_manager_v1. Without that protocol SDL judges its own Wayland presentation to have no reliable frame pacing and prefers X11. GNOME’s Mutter does not advertise it at the time of writing, so on the most common Linux desktop, SDL deliberately chooses XWayland.

Forcing Wayland works and reports higher per-frame numbers — present rises from 3.2–5.8 ms to 4.3–17.6 ms. That is not the backend being slower; it is the compositor pacing the client, which is what a native window experiences too.

Decision

SDL’s judgement stands. Goldberry does not override the video driver by default. SDL knows more about its own backends than this project does, the check exists for a real reason, and forcing Wayland on every machine would trade one platform’s stutter for another’s.

But the choice is visible and available. The chosen driver is logged at start-up at info level, so it appears in any bug report, and -Dgoldberry.backend.videoDriver=wayland sets SDL_VIDEO_DRIVER before initialization for anyone who wants to make the trade the other way. Both paths log what happened.

Alternatives considered

Prefer Wayland whenever WAYLAND_DISPLAY is set. It would very likely make resizing look better on GNOME today, which is the reported complaint. It also overrules an upstream check written by people who measured the failure mode it guards against, on every user’s machine, for a symptom observed on one. If Goldberry is going to disagree with SDL about SDL’s backends, it should be with evidence across several compositors rather than one.

Ship our own Wayland backend. ADR-0003 closed that door on purpose: SDL3 is the permanent desktop windowing layer, and the SPI exists to serve headless and to keep the platform boundary in one place, not to grow hand-written platform backends. Resize smoothness on one compositor is not the thing that reopens it.

Use SDL_Renderer with a streaming texture instead of the window surface. This is the real technical alternative and it is not dismissed — it would move the upload to the GPU and let SDL manage multiple buffers, which is roughly what native toolkits do. It also creates a GPU context for plain UI, which ADR-0002 specifically avoids for start-up time, so it is a decision about §5’s rendering pipeline rather than a fix to reach for while chasing a resize glitch. When there is a real renderer behind it, this deserves measuring properly.

Consequences

The driver is in the log, so the next time windowing behaves oddly the first question is answered before it is asked. That is worth more than it looks: nothing else in the process reveals that a Wayland session is running an X11 window.

Anyone can try the other driver with one property, and the frame path is instrumented (-Dgoldberry.log.level=TRACE) well enough to compare them.

Goldberry now has a property that changes platform behaviour, which is a category that grows. It is deliberately named as a backend detail rather than a general setting.

The reported problem is not fully fixed, and this record should not be read as if it were. What has been established is where the remaining cost lives: not in the toolkit’s frame path, which is a few milliseconds of memory writes and one SDL call, but in the presentation path SDL chose. The next real improvement is a renderer-backed present, not another round of micro-optimisation above it.