refactor(viewer): consolidate Qt6 boards onto cage + Wayland#2883
refactor(viewer): consolidate Qt6 boards onto cage + Wayland#2883vpetersson wants to merge 1 commit into
Conversation
Pi4-64, Pi5, x86, and arm64 now all run the viewer under `cage` (a wlroots kiosk compositor) with mpv on --vo=gpu --gpu-context=wayland and Qt on QT_QPA_PLATFORM=wayland. Previously only x86 and (per the in-flight arm64 PR) generic arm64 took this path; Pi4-64 and Pi5 ran Qt linuxfb + mpv --vo=drm directly on KMS. Folding them all onto one display stack drops a per-board branch each in image_builder, Dockerfile.viewer, start_viewer.sh, and media_player. --drm-mode=1920x1080@60 is dropped on Pi4-64/Pi5: under cage mpv doesn't hold DRM master so the flag is a no-op, and the GPU does the scaling that the CPU zimg upscale at 4K previously couldn't keep up with. --vd-lavc-threads=4 stays. cage + qt6-wayland move from the per-board apt extension into the shared is_qt6 branch in image_builder. va-driver-all stays x86-only (no VAAPI on ARM). The render-GID mirror in start_viewer.sh now applies to all four Qt6 boards because the GL context on Pi also needs /dev/dri/renderD128 access. FAQ entries that claimed "no Wayland compositor in the stack" are updated. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
There was a problem hiding this comment.
Pull request overview
This PR consolidates all Qt6-capable device types (pi4-64, pi5, x86, arm64) onto a single viewer display stack: running the viewer under cage with Qt on QT_QPA_PLATFORM=wayland, and mpv on --vo=gpu --gpu-context=wayland. This removes prior per-board branching (notably the Pi KMS --vo=drm path) and aligns runtime/build configuration, tests, and docs accordingly.
Changes:
- Move
cage+qt6-waylandinto the shared Qt6 viewer image dependencies and gateQT_QPA_PLATFORM=waylandonis_qt6. - Wrap the viewer in
cagefor all Qt6 boards instart_viewer.sh, including render-node group mirroring for GPU access. - Update mpv invocation defaults and unit tests to assert Wayland GL VO usage across all Qt6 device types; adjust FAQ entries to reflect the Wayland compositor in the stack.
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
website/data/faq.yaml |
Updates FAQ wording to reflect the new cage/Wayland-based viewer stack. |
tools/image_builder/utils.py |
Consolidates Qt6 viewer apt deps to include cage and qt6-wayland across boards. |
docker/Dockerfile.viewer.j2 |
Gates QT_QPA_PLATFORM=wayland on is_qt6 for all Qt6 images. |
bin/start_viewer.sh |
Runs viewer under cage for all Qt6 boards and mirrors host render-node GID. |
src/anthias_viewer/media_player.py |
Switches mpv VO to Wayland GL (--vo=gpu --gpu-context=wayland) and adjusts Pi tuning. |
tests/test_media_player.py |
Updates/extends assertions to cover Wayland VO on all Qt6 device types. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # straight on KMS/DRM, with mpv on --vo=drm. Qt6 boards (pi4-64, | ||
| # pi5, x86, arm64) run the viewer under `cage` (a kiosk wlroots | ||
| # compositor) with QT_QPA_PLATFORM=wayland and mpv on --vo=gpu | ||
| # --gpu-context=wayland — no X code path on either track. The | ||
| # cage + qt6-wayland pair is added to the Qt6 apt extension below. |
| # Covers x86 (balenaOS doesn't expose /dev/fb0), arm64 Armbian | ||
| # boards (Rock Pi / Orange Pi / Banana Pi, …), and the Pi4-64 / Pi5 | ||
| # (consolidated onto Wayland so all Qt6 boards share one display | ||
| # stack — see #TBD). |
| - question: How do I rotate the screen for portrait orientation? | ||
| answer: | | ||
| Rotation happens at the kernel / firmware level. The Anthias viewer renders straight to the Linux framebuffer (Qt `linuxfb`) and to KMS (mpv `--vo=drm`) — there's no Wayland compositor in the stack — so the standard Raspberry Pi config knobs apply directly. | ||
| Rotation happens at the kernel / firmware level on the Pi. The viewer renders through `cage` (a kiosk Wayland compositor that talks straight to KMS) on Pi4/Pi5/x86/arm64, and through Qt `linuxfb` directly on legacy 32-bit Pi boards (Pi2/Pi3) — neither path goes through a desktop compositor, so the standard Raspberry Pi config knobs apply directly. |
On-device validation blocked the Pi4-64/Pi5 consolidationTested the rebuilt viewer image on a real Pi4 Model B (Debian Trixie, 4K display via HDMI). Same 1080p H.264 asset, same 30-s window, frame drops via mpv
Why this regresses on Pi
Options
Leaning toward (A) — the consolidation goal hinged on Pi being able to keep up, and on this hardware + mpv combo it can't. Marking the PR draft pending direction. Side-finding worth keepingEven without cage, just switching the Pi (Tested on a 4K-connected Pi4-64 Rev 1.5; the Pi5 has roughly 2× the V3D throughput so it might just squeak through, but I'd want the same test there before assuming.) |
…4 to 1080p Folds in PR #2883: Pi 4-64 / Pi 5 now run under cage with mpv on --vo=gpu --gpu-context=wayland, joining x86 and arm64 on a single Wayland-based display stack. Drops the --vo=drm legacy path entirely from MPVMediaPlayer. Qt 5 boards (pi2 / pi3) stay on linuxfb via VLCMediaPlayer — out of scope here. Replaces the perf branch's `--vo=gpu --gpu-context=drm` standalone fix with the consolidated cage path. The previous standalone finding (3-6 vo drops / 30 s on Pi 4 at 4K) was a Pi-without-cage optimization; once Pi runs under cage like every other Qt6 board, the same trick applies via wayland but cage's composite step adds its own pass and the V3D on Pi 4 can't keep up at 4K (738 vo drops / 30 s measured at native 4K under cage). Fix: move the 1080p mode pin one layer up from app code to host config — the new ansible/.../cmdline.txt.j2 conditional appends `video=HDMI-A-1:1920x1080@60 video=HDMI-A-2:1920x1080@60` when `device_type == 'pi4-64'`. With output pinned to 1080p there's no upscale anywhere in the pipeline, matching the bandwidth profile of today's --vo=drm production setup. Pi 5 / x86 / arm64 keep the connector's preferred mode (typically 4K). Pi 5's V3D 7.1 has roughly 2× Pi 4's throughput; x86 iGPUs handle 4K via VAAPI; arm64 SBC perf varies by SoC. Other notable changes folded in from #2883: * tools/image_builder/utils.py — `cage` + `qt6-wayland` move out of the per-board branch into the shared is_qt6 block. `wlr-randr` (was x86-only) goes in the shared block too since rotation now happens via wlr-randr on every Qt6 board. `va-driver-all` stays x86-only (no VAAPI on Pi / ARM SoCs). * docker/Dockerfile.viewer.j2 — QT_QPA_PLATFORM=wayland gated on is_qt6 instead of board in ('x86', 'arm64'). * bin/start_viewer.sh — case on DEVICE_TYPE: every Qt6 board takes the cage + sudo path. Pi2 / Pi3 stay on the legacy direct-sudo path. * src/anthias_viewer/media_player.py — single --vo=gpu --gpu-context=wayland for all reachable device types. The per-board rotate_args block is gone: every Qt6 device inherits the transform from cage via wlr-randr, so mpv would double-rotate if it set --video-rotate. * tests/test_media_player.py — parametrised tests for all four Qt6 boards (x86, arm64, pi4-64, pi5) hitting the same VO path; rotation tests assert mpv *never* sets --video-rotate under cage. * website/data/faq.yaml — rotation entry points at Settings page / wlr-randr; resolution entry calls out the Pi 4 1080p pin. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Closing. Folded into #2885, which now consolidates Pi 5 / x86 / arm64 onto cage + Wayland (Pi 4 stays on linuxfb — on-device testing showed the V3D 6.0 can't keep up with cage's composite pass on top of mpv, even with a 1080p HDMI mode pin). The base of this PR ( |



Description
Pi4-64, Pi5, x86, and arm64 now all run the viewer under
cage(a wlroots kiosk compositor) with Qt onQT_QPA_PLATFORM=waylandand mpv on--vo=gpu --gpu-context=wayland. Previously only x86 and (per #2879) generic arm64 took this path; Pi4-64 and Pi5 ran Qt linuxfb + mpv--vo=drmdirectly on KMS. Folding all four onto one display stack drops a per-board branch each inimage_builder,Dockerfile.viewer,start_viewer.sh, andmedia_player.py.Notable per-file changes:
tools/image_builder/utils.py—cage+qt6-waylandmove out of the per-board branch into the sharedis_qt6block (now in every Qt6 image, not just x86/arm64).va-driver-allstays x86-only (no VAAPI on ARM SoCs — Pi uses v4l2-request/m2m, Rockchip/Allwinner/Amlogic use V4L2 M2M too).docker/Dockerfile.viewer.j2—ENV QT_QPA_PLATFORM=waylandgated onis_qt6instead ofboard in ('x86', 'arm64').bin/start_viewer.sh—case "$DEVICE_TYPE" in x86|arm64|pi4-64|pi5)now wraps the viewer incageon all four boards. The render-GID mirror that previously only mattered on x86 (VAAPI //dev/dri/renderD128) also applies on Pi — the GL context (V3D render node) needs the same access for--vo=gpu --gpu-context=wayland.src/anthias_viewer/media_player.py—--vo=gpu --gpu-context=waylandfor every Qt6 board; the previous--drm-mode=1920x1080@60pin is dropped on Pi4-64/Pi5 (no-op under cage anyway, and GPU scaling handles 4K without the A72/A76 CPU zimg upscale that the pin was working around).--vd-lavc-threads=4stays.tests/test_media_player.py— assertions updated; new parametrised test covers all four Qt6 device types getting--vo=gpu --gpu-context=wayland.website/data/faq.yaml— two entries that claimed "no Wayland compositor in the stack" are corrected.Validation
On-device frame-drop comparison on a Pi4 Model B (Debian Trixie, DEVICE_TYPE=pi4-64), 30 s of 1080p H.264 over
mpv --hwdec=auto-safefrom inside the viewer container:--vo=drm --drm-mode=1920x1080@60(current)--vo=gpu --gpu-context=drm(no cage)--vo=gpu --gpu-context=waylandunder cage measured separately on the rebuilt viewer image (results in the PR comments). decoder-frame-drop-count was 0 in every run — the drops are all on the VO side, which is exactly the path the move from CPU zimg upscale to GPU scaling improves.Checklist