Phase 0 X1: native X11 baseline + mpv mechanism probes — campaign hypothesis refuted

Native X11 in XFCE / xfwm4-no-comp on tty7 / session 510.

Q1 (mechanism: does X server route NV12 to a hardware plane?):
NEGATIVE. Across 4 mpv VO × decode combinations
(--vo=xv ± hwdec, --vo=gpu ± hwdec), Plane 39 stayed XRGB8888
with FB ID 62 throughout. mpv-xv falls back to XShm software
put-image; mpv-gpu does GL composite via DRI3 + XPresent of an
RGB framebuffer; chromium-fourier-x11 same shape. No path on
this rockchip-drm + Mesa Panfrost + modesetting Xorg stack
engages hardware-overlay scanout for an NV12 client.

Q4 (browser X11 vs Wayland on same workload): the campaign
hypothesis is OPPOSITE to the data. chromium-fourier-x11 ×3
median: drops_post_warmup=9, frames_total=1532, fps=21.8.
Compare to A1 Wayland ×3 median: drops_post_warmup=0,
frames_total=1685, fps=24.04. X11 + xfwm4-no-comp is worse
than Plasma Wayland-with-KWin on every metric.

Likely cause: KWin's vblank-aligned wp_presentation_feedback
buffer scheduling absorbs client timing jitter; X11 + no
compositor exposes that jitter directly to the page's
getVideoPlaybackQuality() drop counter.

Operator subjective note: "first mpv was perfect" for
mpv-xv-sw despite mpv stderr "X11 can't keep up". 1080p24 SW
Xv is perceptually smooth on this hardware even though
instrumentation flagged it as struggling.

x1_summary.md surfaces three legitimate next moves: honest
closure, reframe to operator-experience-driven Wayland-stutter
scenarios, or pivot to client/driver-layer mechanism work
(modesetting NV12 Xv adapter, chromium hw-overlay flags).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-03 18:46:03 +00:00
parent 298431810e
commit 3d49582ed0
155 changed files with 26547 additions and 0 deletions
@@ -0,0 +1,257 @@
# Phase 0 X1 — X11 / xfwm4-no-comp baseline + mpv mechanism probes
**Date:** 2026-05-03 ~20:1720:43 CEST.
**Session:** XFCE on tty7 / session 510, xfwm4 with
`use_compositing=false` (entry-2 pre-seed). Native X11 — Xorg
PID 45263, modesetting Xorg driver, DSI-1 1280×800
@ 59.98 Hz with `right` rotation.
**Workload:** 1080p **24 fps** H.264 (`bbb_1080p30_h264.mp4`
file is misnamed; mpv reports 24 fps content) for mpv reps;
`brave_drops_test.html` for chromium reps (matches A1 Wayland
reps exactly).
## Headline results
**Q1 (campaign mechanism — does the X server route NV12 to a
hardware plane?): NEGATIVE.**
Across 4 mpv VO × decode combinations, **Plane 39 stayed
XRGB8888 with FB ID 62 the entire time.** No path under native
X11 + modesetting Xorg + Mesa Panfrost engages
hardware-overlay scanout on this rockchip-drm RK3568 stack.
| Cell | Plane 39 pre | Plane 39 post | mpv stderr indicator |
|---|---|---|---|
| mpv `--vo=xv --hwdec=no` | XRGB8888 / fb 62 | XRGB8888 / fb 62 | "X11 can't keep up! XShm completion events" |
| mpv `--vo=xv --hwdec=v4l2request-copy` | XRGB8888 / fb 62 | XRGB8888 / fb 62 | autoconvert `nv12 → yuv420p`, A/V desync |
| mpv `--vo=gpu --gpu-context=x11 --hwdec=no` | XRGB8888 / fb 62 | XRGB8888 / fb 62 | clean exit, VO yuv420p |
| mpv `--vo=gpu --gpu-context=x11 --hwdec=v4l2request-copy` | XRGB8888 / fb 62 | XRGB8888 / fb 62 | clean exit, **VO accepted nv12 directly** |
Plane 45 stayed at FB 0 (unused) throughout.
**Q4 (browser X11 vs Wayland comparison on the same workload):
NEGATIVE for the campaign hypothesis.** chromium-fourier under
native X11 + xfwm4-no-comp produces **more** drops, **fewer**
frames, **lower** effective fps than the same browser on the
same page under Plasma Wayland 6.6.4 with KWin compositing.
| | chromium-fourier-x11 (n=3) | A1 Wayland (n=3) |
|---|---|---|
| drops_total median | **14** | 0 |
| drops_post_warmup median | **9** | 0 |
| frames_total median | **1532** | 1685 |
| effective fps median | **21.8** | 24.04 |
A 3-rep cluster doesn't have IQR vs IQR comparison meaningful
for floor-vs-non-floor, but the difference is 9 drops_post_warmup
vs 0, sustained, with the X11 cells consistently below the
Wayland baseline on every metric. **This is the opposite of the
campaign hypothesis.**
## Operator subjective observation
**"first mpv was perfect"** — operator-reported during the
mpv-xv-sw rep (the one where mpv stderr complained "X11 can't
keep up"). The visible playback was smooth even though Plane 39
stayed XRGB8888 (no hardware overlay) and mpv was using 101 % of
one CPU core for SW XShm put-image at 1080p24. **A subjective
data point that a software-Xv path can deliver perceptually
stutterless 1080p24 playback** on this hardware, regardless of
the absence of hardware-overlay scanout.
## Per-cell details
### mpv-xv-sw (`--vo=xv --hwdec=no`)
```
VO: [xv] 1920x1080 yuv420p
[vo/xv] X11 can't keep up! Waiting for XShm completion events...
GPU: 487 MHz mean (98.6% non-idle)
Workload CPU: 101% mean, 186% peak
Plane 39: XRGB8888 fb 62 throughout
```
Xv adapter on modesetting Xorg + rockchip-drm uses **XShm
software put-image**. mpv decodes H.264 → yuv420p in software
on a single core, hands the YUV image to the X server via
shared memory; the X server CPU-converts YUV → RGB and
draws into the screen pixmap (Plane 39's FB 62). No
hardware-overlay path engaged. Despite mpv's "can't keep up"
warning, **operator subjectively observed smooth playback**.
### mpv-xv-hw (`--vo=xv --hwdec=v4l2request-copy`)
libva via `libva-v4l2-request-fourier` decodes H.264 → NV12
on the hantro VPU. mpv autoconverts NV12 → yuv420p (since
Xv only accepts yuv420p) — that conversion is the bottleneck.
```
[autoconvert] Converting nv12 -> yuv420p
VO: [xv] 1920x1080 yuv420p
Audio/Video desynchronisation detected!
Consider trying `--profile=fast` and/or `--hwdec=auto` as they may help.
```
The `--hwdec=v4l2request-copy` path doesn't help under Xv
because the autoconvert eats more CPU than software decode
saved. **A/V desync is the canonical mpv stutter signal.**
### mpv-gpu-sw (`--vo=gpu --gpu-context=x11 --hwdec=no`)
```
VO: [gpu] 1920x1080 yuv420p
GPU: 800 MHz median, 774 MHz mean (96.4% non-idle)
Plane 39: XRGB8888 fb 62 throughout
```
mpv's modern GPU VO does GL composite (libplacebo shaders)
with DRI3 + XPresent. GPU runs near max (Mali-G52 at full
800 MHz). No hardware overlay; mpv presents an RGB
framebuffer that the X server scans out from Plane 39.
### mpv-gpu-hw (`--vo=gpu --gpu-context=x11 --hwdec=v4l2request-copy`)
```
VO: [gpu] 1920x1080 nv12
GPU: 800 MHz median, 777 MHz mean (98.6% non-idle)
Plane 39: XRGB8888 fb 62 throughout
```
Same as mpv-gpu-sw but with hardware decode producing NV12
that mpv's GL VO accepts directly (no CPU autoconvert). GPU
shader handles NV12 → RGB sampling. Still no
hardware-overlay scanout — mpv's RGB output goes to FB 62.
### chromium-fourier-x11 ×3
```
chromium-ohm-gl-fix-step2/chrome --enable-logging=stderr
--autoplay-policy=no-user-gesture-required
--user-data-dir=/tmp/chrome-profile-...
file:///home/mfritsche/fourier-test/brave_drops_test.html
```
Note: chromium ozone defaults to X11 backend when no
`--ozone-platform=` is specified and `WAYLAND_DISPLAY` is
unset (under XFCE/X11, it isn't). The "Failed to send
GetTerminationStatus" stderr noise is teardown-only.
Three reps. Frame-by-frame DROPS_TRAJECTORY shows drops are
NOT clumped — they trickle throughout the playback at ~0.10.4
per second, accelerating slightly toward the end. This is
qualitatively different from "stall, recover, stall" patterns;
it's persistent low-grade frame loss.
## Why is X11 worse than Wayland here?
A reasonable hypothesis: under Plasma Wayland, KWin's
**triple-buffered GL composite path is engineered with
explicit vblank-aligned commit timing** via
`wp_presentation_feedback`. The browser hands KWin a buffer
once per browser-frame; KWin schedules its own composite at
vblank. Drops require both the browser missing its compose
deadline AND KWin missing the next vblank — a more robust
double-buffer than X11's single-buffer scanout.
Under native X11 + xfwm4-no-comp:
- xfwm4 isn't compositing (use_compositing=false), so it has
zero buffer-management role
- Chromium's ozone-x11 backend presents directly via DRI3 +
XPresent
- The X server schedules the present, but **the client
(chrome) is the only buffer-flow manager** — there's no
intermediate compositor to absorb timing jitter
- Result: when chrome's GPU process misses its target, no
buffer-of-last-resort exists; the X server scans out the
previous fb again, which the page-level
`getVideoPlaybackQuality()` counts as a drop
This is **the opposite of the campaign's "no compositor =
fewer drops" reasoning**, and well-documented as a known
property of compositorless X11 + DRI3: less smoothing, more
client-visible jitter.
## What the data does NOT establish
- That this result generalizes to other workloads. Operator
reported *subjectively* perfect playback for mpv-xv-sw —
the "stutter" observation is specific to chrome on this
test page.
- That all native-X11 + non-comp WM combos behave like
xfwm4-no-comp. openbox might have different buffer-flow
characteristics; not tested in this session.
- That a Plasma Wayland session under stress (multi-window
with continuously-updating surfaces, GPU contention,
thermal throttling) wouldn't ALSO stutter. The campaign's
premise is operator's observed daily-driver experience —
my synthetic 70 s reps in a fresh Wayland session don't
cover the conditions where Wayland actually fails.
- That hardware-overlay support is *impossible* on this
stack. modesetting Xorg with `Option "PageFlip" "true"`
and a video driver explicitly requesting DRM_FORMAT_NV12
scanout might engage Plane 39 NV12 — but that path isn't
wired in any of the clients we tested. **It's a kernel /
Mesa / Xorg-driver gap, not a hardware gap.**
## Implications for the campaign
The original framing — *"stutterless playback possible with
X11? proven impossible with Wayland"* — is **partially
inverted by today's data on this specific workload**:
- Wayland is delivering stutterless playback (A1 reps: 0
drops × 3).
- X11 + non-compositing WM is **not** delivering stutterless
playback (X1 reps: 9 drops_post_warmup median).
The campaign's load-bearing mechanism — "X11 can give Plane
39 directly to NV12" — is also not realized on this stack
(mpv reps × 4 confirm Plane 39 stays XRGB8888 regardless of
client).
This is a **decisive negative outcome for the campaign as
originally framed**. Three legitimate next moves:
1. **Honest closure.** Document the negative result as the
research outcome. The campaign answers "no, X11 doesn't
help here, and no, the predicted mechanism isn't engaged
on this hardware/software stack." That is itself a useful
research finding — particularly for anyone considering
X11 as a Wayland-stutter workaround on rockchip-drm.
2. **Reframe to find the conditions under which Wayland
actually stutters.** Operator-experience driven: specific
apps/content/durations that reproduce the daily-driver
stutter, then test those same conditions under X11. Risks
data-shopping; needs operator-supplied scenarios to
anchor against.
3. **Pivot the mechanism question.** If the X server isn't
programming Plane 39 with NV12 because no client requests
it, the lever is at the client/driver layer, not the
session layer. Investigate: would patching the modesetting
Xorg DDX driver to expose an NV12-capable Xv adapter
change the result? Would `--ozone-platform=x11` with
chromium's `--enable-features=...` for hardware video
overlay change the result? These are kernel/Mesa/X-driver
patches, not user-facing-session changes.
## File map
```
01_live_session.txt — XFCE/X11 substrate snapshot
x11research_x1_mpv_xv_sw/ — mpv --vo=xv --hwdec=no
x11research_x1_mpv_xv_hw/ — mpv --vo=xv --hwdec=v4l2request (incomplete, SSH-killed)
x11research_x1_mpv_xv_hw_rep1/ — same, retried clean via systemd-run
x11research_x1_mpv_gpu_sw/ — mpv --vo=gpu --hwdec=no
x11research_x1_mpv_gpu_hw/ — mpv --vo=gpu --hwdec=v4l2request
x11research_x1_chromium_fourier_x11/ — chromium-fourier 1st rep (drops 37 — outlier)
x11research_x1_chromium_fourier_x11_rep1/ — chromium-fourier 2nd rep (drops 14)
x11research_x1_chromium_fourier_x11_rep2/ — chromium-fourier 3rd rep (drops 11)
x1_summary.md — this file
```
Each rep dir contains `drops_summary.txt` (where applicable),
`gpu_freq_summary.txt`, `drm_diff.txt`, `top_workload.txt`,
`top_full.txt`, `stderr.log`, `perf_report_top50.txt`, and the
raw devfreq trans_stat / drm_info dumps.