Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions bin/test_webview_cpp.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env bash
# Build and run AnthiasWebview's QtTest unit tests.
#
# Requires Qt 6 (qt6-base-dev, qt6-base-private-dev) and libmpv-dev
# on the host or in a builder container. The viewer Docker image
# already ships those for the per-board builder stage — running
# this inside that container is the canonical environment.
#
# Usage: bin/test_webview_cpp.sh
#
# The tests run against libmpv WITHOUT a real OpenGL context;
# mpv_render_context_create is exercised by real-device validation
# on the BBB test bed instead. CI integration is a follow-up.

set -euo pipefail

cd "$(dirname "$0")/.."

WEBVIEW_DIR="src/anthias_webview"
BUILD_DIR="${WEBVIEW_DIR}/tests/build"

mkdir -p "${BUILD_DIR}"
pushd "${BUILD_DIR}" >/dev/null

qmake6 ../tests.pro
make -j"$(nproc)"

# QTEST_MAIN's generated binary exits non-zero on any test failure.
# ``QT_QPA_PLATFORM=offscreen`` skips connecting to a real display
# server / framebuffer — the tests don't render, they just exercise
# the mpv_handle property contract.
QT_QPA_PLATFORM=offscreen ./AnthiasWebviewTests

popd >/dev/null
39 changes: 35 additions & 4 deletions docker/Dockerfile.viewer.j2
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,18 @@ RUN --mount=type=cache,target=/var/cache/apt,id=qt6-builder-apt-{{ artifact_boar
apt-get install -y --no-install-recommends \
build-essential \
qt6-base-dev \
qt6-multimedia-dev \
qt6-webengine-dev
# qt6-multimedia-dev: AnthiasWebview's VideoView wraps QMediaPlayer +
# QVideoWidget (issue #2904, see ``src/anthias_webview/AnthiasWebview.pro``).
# Runtime backend is gstreamer (forced via ``QT_MEDIA_BACKEND`` env
# below); plugin discovery happens at runtime against the
# ``gstreamer1.0-*`` packages added to ``viewer_extra_apt_dependencies``.
COPY src/anthias_webview/AnthiasWebview.pro /src/anthias_webview/AnthiasWebview.pro
COPY src/anthias_webview/src /src/anthias_webview/src
COPY src/anthias_webview/res /src/anthias_webview/res
WORKDIR /src/anthias_webview
# webview is 3 .cpp files (~6s on x86 native, ~30s under arm64 QEMU);
# webview is 4 .cpp files (~6s on x86 native, ~30s under arm64 QEMU);
# adding ccache would only save a couple of seconds on incremental
# rebuilds and the cache mount + apt install + PATH wiring would
# outweigh the saving.
Expand Down Expand Up @@ -76,10 +82,35 @@ ENV QT_QPA_EGLFS_FORCE888=1
# the viewer in cage; this env var tells Qt to load the qt6-wayland
# platform plugin so it renders into cage's surface.
ENV QT_QPA_PLATFORM=wayland
{% elif board == 'pi4-64' %}
# Pi 4 switched from ``linuxfb`` to ``eglfs`` for issue #2904:
# libmpv-render needs an OpenGL context to paint frames into the
# AnthiasWebview window, and ``linuxfb`` has none. ``eglfs`` (the
# Qt KMS/EGL platform) gives Qt a GL context paired with KMS
# scanout. ``QT_QPA_EGLFS_KMS_CONFIG`` pins 1080p — the V3D 6.0
# can't composite Chromium + libmpv on top of the connector's
# native 4K, and Qt's ``eglfs_kms`` integration reads this JSON
# at QPA init time. Validated on real Pi 4 hardware: under eglfs
# QWebEngineProcess still spawns its zygote + 2 renderers and
# loads pages, so the platform switch doesn't regress web /
# image rendering.
ENV QT_QPA_PLATFORM=eglfs
ENV QT_QPA_EGLFS_KMS_CONFIG=/etc/anthias/eglfs-kms.json
# bin/start_viewer.sh auto-detects QT_SCALE_FACTOR from
# /sys/class/drm/*-*/modes — but the kernel mode list still
# reports the connector's EDID-preferred mode (4K on most TVs),
# even though eglfs is rendering into a 1080p framebuffer per the
# KMS config above. Pinning scale=1 short-circuits the auto-detect
# (which respects an existing value) so a 1920-wide page lays out
# at 1920 physical px on the 1080p surface — i.e. CSS px ≡ physical
# px, the same end-state the linuxfb+4K-with-scale=2 path produced.
ENV QT_SCALE_FACTOR=1
RUN mkdir -p /etc/anthias
COPY docker/eglfs-kms-pi4.json /etc/anthias/eglfs-kms.json
{% else %}
# Pi 4 (Qt6) and Pi 2 / Pi 3 (Qt5) keep the classic linuxfb path —
# the Pi 4 V3D 6.0 can't keep up with cage's composite pass on top
# of video, so the viewer renders directly to the framebuffer.
# Pi 2 / Pi 3 (Qt5) keep the classic linuxfb path — VLC paints
# directly to the framebuffer and there's no libmpv embedding on
# those boards.
ENV QT_QPA_PLATFORM=linuxfb
{% endif %}

Expand Down
15 changes: 15 additions & 0 deletions docker/eglfs-kms-pi4.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"device": "/dev/dri/card1",
"hwcursor": false,
"pbuffers": true,
"outputs": [
{
"name": "HDMI1",
"mode": "1920x1080"
},
{
"name": "HDMI2",
"mode": "1920x1080"
}
]
}
7 changes: 7 additions & 0 deletions src/anthias_viewer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from anthias_viewer.constants import SPLASH_DELAY as SPLASH_DELAY
from anthias_viewer.constants import SPLASH_PAGE_URL as SPLASH_PAGE_URL
from anthias_viewer.constants import STANDBY_SCREEN as STANDBY_SCREEN
from anthias_viewer import media_player as _media_player_module
from anthias_viewer.media_player import MediaPlayerProxy
from anthias_viewer.playback import (
navigate_to_asset,
Expand Down Expand Up @@ -907,6 +908,12 @@ def setup() -> None:

bus = pydbus.SessionBus()
browser_bus = bus.get('anthias.webview', '/Anthias')
# MPVMediaPlayer calls AnthiasWebview's playVideo / stopVideo
# slots via this same proxy now that video lives in-process
# (issue #2904). Inject after load_browser so the proxy is
# already bound to the running AnthiasWebview; load_browser
# would otherwise race the D-Bus name registration.
_media_player_module.set_browser_bus(browser_bus)


def start_loop() -> None:
Expand Down
Loading