24 Commits
Author SHA1 Message Date
Daniel Golle 6917907d4d plymouth-theme-openwrt-demo: suit small hi-DPI panels
The theme was laid out and drawn with a 1080p screen in mind, and on a
small panel with a device scale above one it falls short.

The backdrop holding the logo, links and nodes is now allocated in
device pixels and drawn through a canvas scaled by the device scale, so
the static scene is as sharp as what is drawn on top of it. At scale 1
the texture matrix is the identity and plutovg keeps its plain blit.

The pictograms get a floor of 12 logical pixels and shrink only as far
as needed for the row to fit the screen width. The row is reserved for
that size and the logo and graph are laid out in the height left above
it; where the floor does not apply, the layout is unchanged.

In boot-up mode the backlight that the DRM panel references through its
backlight phandle is taken to zero before the first frame and faded in
over 1.5 s to 80% of its maximum, as full brightness lifts the black
background to grey. A panel carrying the bootloader-initialized
property already shows the bootloader's picture and is left alone. On
a backlight whose scale is not perceptual the ramp follows the CIE 1931
lightness curve pwm_bl uses for its own tables.

Nothing reports how far a system upgrade has got, so the upgrade modes
keep the whole graph and turn a spinner around the router node instead
of dismantling the graph on a timer, which would read as progress.
The pictograms stand for services coming up, so only boot-up mode
shows them. A router shuts down within a few seconds, so shutdown and
reboot take the graph down one level every 250 ms, leaves first, and
only the logo is left after three steps.

paint() walked every packet and pulse once per damaged rectangle, and
every packet and pulse damaged a rectangle of its own, so the cost of a
frame grew with the square of the packet count and was spent in script
loops rather than in pixels. A splash connecting to a running bus
received one packet per existing ubus object, without the cap
flow_spawn() observes, and dropped far below its frame rate. Damage is
now collected into one box per frame, paint() draws each packet once
with colours built when the packet is created, pulse rings are filled
as annuli where a stroke cost considerably more, and FLOW_CAP, lowered
to 8 as a handful of packets conveys activity as well as two dozen,
applies to packets launched by ubus objects too.

Fixes: 6aca04f334 ("plymouth-theme-openwrt-demo: add a demo theme for the ucode engine")
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-10-11 18:23:56 +01:00
Daniel Golle 74c76563c7 plymouth-plugin-ucode: hand the display over and back
A splash shown by the plugin held the display until something told
plymouthd to let go, gave a waiting display client no way to know when
that happened, and crashed or lost its ubus link on changes of mode.

In boot-up mode, open the input event nodes present when the splash
starts and those procd announces later, and on the first key, button
or touch press send plymouthd the deactivate request over its own
socket. procd replaces /dev with a fresh tmpfs after preinit, where the
splash starts, so the nodes it creates cannot be watched for; its
hotplug.d scripts run for every input device once the node exists,
coldplugged ones included, and the one shipped here hands the node to
the plugin as a plymouth status update.

Publish a plymouth object whose status method reports whether the
splash holds the display, and hand procd a plymouth.release event
whenever it lets go, without waiting for the reply, so a service can
wait for it with a trigger; procd runs triggers for events it is
handed, not for broadcasts. Stop the frame timer on the way to idle
and start it again when plymouth redraws the splash after
reactivating, and drop the unused progress callback.

Clear the ucode VM after freeing it, as uc_vm_init() leaves
vm->registry pointing at the freed registry. Remove the object before
freeing the connection. Drop a connection whose ubusd went away from a
disconnect handler, since plymouth's event loop frees the watch
itself, keep the inotify wait on the ubus socket directory armed so a
restarted ubusd is picked up, and clear the ids libubus caches from
the previous ubusd before registering again.

Keep the splash up through sysupgrade: in stage2, copy plymouth's
files, plugins and ucode modules into the ramfs, take the display back
with plymouth-evict and switch to system-upgrade mode; in do_stage2,
start plymouthd from the ramfs. Schedule frames against a deadline
advancing by one interval, so a theme keeps its frame rate under load.

Fixes: 9ef83aa136 ("plymouth-plugin-ucode: add a scripted splash plugin for ucode")
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-10-11 18:23:56 +01:00
Daniel Golle eb8e5b3614 plymouth: hand the display over and take it back
A deactivated splash kept flushing its displays from a timer. When the
shutdown sequence reactivated the daemon waiting since boot, whatever
had taken the display over still held DRM master, so the splash never
appeared, and the last frame gave way to the console during the final
kill. libudev-zero cannot tie a frame buffer device to its DRM card, so
every fbdev emulation of a DRM driver was driven as a second display.

Carry a patch that stops the frame timer while the splash is
deactivated. Add plymouth-evict, which stops every process holding a
KMS device other than plymouthd and waits until they are gone. A
process that belongs to a procd service is stopped through procd,
which applies the service's own term_timeout and does not respawn it,
and the wait ends on procd's instance.stop notifications; anything
else, and everything once ubus is gone as in sysupgrade's stage2, gets
SIGTERM directly. The shutdown action runs it, ignores rcS cancelling
the K script, and switches to shutdown mode before reactivating, so
the first frame back is already the shutdown splash.

Install plymouthd-fd-escrow, which keeps the last frame on the display
through the final kill, and install the DRM renderer alone, as the
splash is meant for devices with a KMS driver.

Fixes: 1a39b47dbd ("plymouth: add boot splash for KMS devices")
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-10-11 18:23:56 +01:00
Daniel Golle 8d4551ceb2 kmscon: wait for the splash, add unifont, depend on evdev
Started while plymouth holds DRM master, kmscon retries taking it from
a timer and logs a failure on every attempt. Its built-in 8x16 font
covers the first 256 code points only, held in CP437 order while
kmscon looks glyphs up by Unicode code point, so box drawing, block and
braille characters come out wrong. The input event nodes it reads only
exist with the evdev handler, which nothing pulled in.

Do not start the instance while plymouth reports that it holds the
display, and start it on the plymouth.release event the splash hands
procd when it lets go. Build the GNU Unifont engine into a
kmscon-mod-unifont package; its generator genunifont is packaged as a
host build, and a patch lets meson use that one. The init script
passes --font-engine only when one is configured, so kmscon falls
through to unifont when the module is installed. GNU Unifont is
dual-licensed under GPL-2.0-or-later with a font embedding exception
and OFL-1.1; kmscon takes the font under OFL-1.1, so the module
package carries that licence besides MIT. Depend on kmod-input-evdev.

Fixes: 3c8ebee9b4 ("kmscon: depend on input-support for the evdev nodes")
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-10-07 08:23:38 +01:00
Daniel Golle afb0a7453e kmscon: drop the enabled option
Whether a service runs at boot is already expressed by its rc.d symlink,
which service enable and service disable maintain. A UCI option saying
the same thing is a second source of truth that disagrees with the first
as soon as either is touched on its own.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-10-03 16:57:13 +01:00
Daniel Golle 42627cc499 kmscon: make the libseat backend activate its seat
The seat is enabled while libseat_open_seat() is still running, before
uterm_vt_allocate() has installed the callbacks an activation needs, and
whatever libseat has buffered is never dispatched because watching its fd
for readability yields nothing. kmscon therefore stayed asleep with
--libseat: no video device was initialised and the display stayed dark.

Carry patches that dispatch libseat once from an idle callback and replay
an enable that arrived too early, and that mark an unopened tty as -1 so
the backend stops issuing VT ioctls on file descriptor 0.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-10-03 16:57:13 +01:00
Daniel Golle 816fa8fe0c plymouth-theme-openwrt-demo: fix the theme descriptor name
plymouth resolves a configured theme as themes/<name>/<name>.plymouth,
so the descriptor has to carry the name of its directory. Named
openwrt.plymouth it is never found, and plymouth walks its fallback
chain down to the built-in text splash, which draws nothing at all on a
board that has no text console.

Name the descriptor after the theme so the configured theme loads.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-10-02 08:56:57 +01:00
Daniel Golle cf4452f67a plymouth-plugin-ucode: start the splash without a console
The preinit hook asked for a splash by appending "splash" to a faked
kernel command line and told plymouth to ignore serial consoles, which
left it free to take the system console as its terminal anyway.

--graphical-boot covers both and keeps plymouth on KMS only.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-10-02 08:56:57 +01:00
Daniel Golle fd188acfb6 plymouth-plugin-ucode: honour the display device scale
ply_pixel_buffer_get_size() reports the logical area while
ply_pixel_buffer_get_argb32_data() points at the device pixel buffer.
Where the device scale is above one, the plutovg surface then describes
the buffer as too narrow and with too short a stride, so each odd
logical row lands in the right half of the panel and the image collapses
into a fraction of it. The damaged area is handed over in logical
coordinates as well, while ply_renderer_head_flush_area() reads it as
device pixels.

Size the surface in device pixels, scale the canvas by the device scale
so a theme keeps drawing in logical coordinates, and report the damaged
area in device pixels.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-10-02 08:56:57 +01:00
Daniel Golle 389a52b148 plymouth: keep the daemon off the system console
OpenWrt builds the kernel without CONFIG_VT, so BOOT_TTY never exists
and plymouth falls back to the first serial device it finds, which is
the system console. It opens that console, watches it for input, puts it
in raw mode and locks every termios bit, so a shell sharing it loses its
cursor keys, its interrupt character and a share of everything typed.
Forcing details mode along the way also costs the splash its renderer.

Carry a patch that makes --graphical-boot keep plymouth away from a
console altogether and pass it from both entry points. The faked
"splash" kernel argument and --ignore-serial-consoles go with it, both
implied now, as does --attach-to-session, which redirected the console
into plymouth's pty with TIOCCONS and stopped kernel messages reaching
the serial port.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-10-02 08:56:57 +01:00
Daniel Golle 3c8ebee9b4 kmscon: depend on input-support for the evdev nodes
kmscon reads its keyboard from /dev/input directly through libudev, so
it needs the input group and the hotplug rule that input-support ships.
It has no libevdev or libinput dependency to inherit that from, unlike
the compositors in this feed.

The DRM side already comes from libdrm.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-09-30 12:28:18 +01:00
Daniel Golle 7dd5eba75d kmscon: split the OpenGL ES path into kmscon-mod-gl
kmscon depends on a libmesa provider, so every system with a KMS
console pulls in Mesa, but the main binary links none of it: the GL
code lives entirely in mod-drm3d.so and mod-gltex.so, which are
dlopened from a directory scan of the module directory. The software
renderer bbulk is built into the binary, the drm2d backend needs only
libdrm, and hwaccel is off by default, so Mesa is unused on a default
install and the modules are absent-tolerant by construction.

Ship those two modules as kmscon-mod-gl and build them only when it
is selected. A system that carries Mesa for other reasons installs
the package and starts kmscon with --hwaccel; everything else gets a
console with no Mesa in the build at all.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-09-29 00:17:38 +01:00
Daniel Golle 605d768782 kmscon: add terminal emulator for KMS devices
A system without a framebuffer console has no text console at all.
kmscon draws a terminal straight onto a DRM device, through OpenGL ES
where the GPU allows and in software on the same device otherwise.

Device access goes through libseat, so the seat owns the drm device and
the vt rather than kmscon reaching for both itself. That needs seatd,
which is a small daemon and already starts before this service. Built
without the fbdev backend and with the built-in PC screen font, so it
needs neither pango nor freetype. The service is off until enabled, so
it does not take the display from whatever else is using it.

Two patches are carried. The first keeps the unifont generator, a
native helper linked against zlib for the build machine, out of a build
that has the unifont backend disabled, which otherwise breaks cross
compilation. The second stops an error loop: a render-only drm node
answers NULL to drmModeGetResources, which the hotplug path treated as
an error and returned from the poll handler, so kmscon wrote 776 error
lines in eighty seconds on a board where the GPU enumerates before the
display controller.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-09-26 12:41:58 +01:00
Daniel Golle 6aca04f334 plymouth-theme-openwrt-demo: add a demo theme for the ucode engine
A worked example of what the ucode splash plugin can do, and the
default theme once it is installed: nothing here is meant to be the
last word on how an OpenWrt boot should look.

The scene is a network graph, laid out afresh on every boot, drawn from
one ucode program and one SVG with no rendered frames anywhere. It has
two phases because the splash does. Before ubusd exists there is
nothing true to report, so the graph simply grows, a node every second
or so, for however long preinit takes. Once the bus is up the rest of
the graph completes at once, the row of pictograms is built from
/etc/rc.d/S*, and the packets that move afterwards are driven by real
ubus activity rather than a timer.

A stage is shown only for a service that is actually enabled and has a
pictogram, dark until the service's own ubus object appears, so a box
without blockd never shows storage. sysntpd has no object and reports
its sync through /etc/hotplug.d/ntp instead, which is the general way
for a service with a hook but no object to light its stage. Shutdown,
reboot and sysupgrade take the graph apart rather than building it.

About 5 ms a frame at any resolution from 640x480 to 3840x2160 on a
Rock 5B, against 33 ms at the default frame rate.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-09-26 10:21:06 +01:00
Daniel Golle 9ef83aa136 plymouth-plugin-ucode: add a scripted splash plugin for ucode
Plymouth's own script plugin has its own little language and draws by
compositing prepared images, which means a theme arrives as a few
hundred PNGs. This plugin makes a theme one ucode program instead, with
a plutovg canvas over plymouth's pixel buffer, so a theme is source and
its artwork is SVG.

A theme returns setup, frame, paint and event. frame advances state and
declares what changed, paint draws one damaged rectangle, and nothing
reaches the screen that the theme did not ask for, which keeps a busy
scene at a couple of milliseconds a frame rather than repainting
everything. Themes are written against the contract in files/README.md
and can be measured offscreen, on any target, with the included
plymouth-theme-bench, which reports the package version it was built
from.

The plugin connects to ubus and passes events through, along with the
objects that already existed when it connected, so a theme can show
what the system is actually doing rather than animating a guess. It
starts the splash from a preinit hook, before the overlay is mounted,
and keeps it up through sysupgrade.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-09-26 10:21:06 +01:00
Daniel Golle 1a39b47dbd plymouth: add boot splash for KMS devices
Plymouth draws a boot splash straight onto a DRM device and holds the
display until whatever follows it takes over, so nothing of the boot is
visible between reset and the user interface. On a board with no
framebuffer console that is the only way to put anything on screen
early.

Built without the framebuffer backend, without systemd and upstart
integration, and without gtk, pango and freetype, so the runtime needs
only libpng and libdrm. msgfmt is needed at build time, for the themes
that are built and then not installed. Neither binary answers to
--version, so the CI version probe is answered by test-version.sh
instead. No theme is installed and none is named in
the daemon configuration: a theme is a package of its own and selects
itself when it is installed.

Four patches are carried. Two are build fixes for musl, which has
neither rpmatch() nor execinfo.h. The other two are bugs, both
submitted upstream. The drm renderer drops master immediately after
opening the device, so every connector probe runs as a client that is
not drm master; the kernel declines it a forced probe and returns a
cached status of "unknown", and the renderer gives up with "Could not
initialize heads", which leaves the splash able to light only a display
something else has already probed. The escape key tears the splash down
for a text view, guarded only on a VT existing, so on a kernel with
CONFIG_VT but no framebuffer console the dummy driver is bound, the
text goes nowhere and the screen turns black.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-09-26 10:21:06 +01:00
Daniel Golle 1eea39be15 vkmark: update to latest git HEAD
Update to upstream commit 83a128d (2025-09-08).

https://github.com/vkmark/vkmark
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-06-10 21:23:36 +01:00
Daniel Golle 5a17838a67 xa: add package
Package the xa65 6502/65816 cross-assembler with both a target build
and a host build. The host tool is required to assemble psiddrv during
the vice build.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-06-09 13:57:05 +01:00
Daniel Golle d47edc891a vkmark: fix build if Vulkan is present on host
Make sure to not pick up host headers and libraries by setting
CMAKE_PREFIX_PATH.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-05-31 14:21:07 +01:00
Daniel Golle 4fed050411 kmscube: update to GIT HEAD of 2025-10-24
Update PKG_SOURCE_VERSION to f60e50e887d3c49e91ac9b06d8199b36152632fa
to pick up upstream fixes accumulated since the 2024-11-06 snapshot.

Add libgst1gl to runtime DEPENDS - upstream now uses GstGL helpers.

kmscube has no tagged releases; track upstream master.

Link: https://gitlab.freedesktop.org/mesa/kmscube/-/commits/master
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2026-05-19 14:37:17 +01:00
Daniel Golle 97e80207b2 kmscube: update to git HEAD of 2024-11-06
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2025-07-17 23:53:34 +01:00
Daniel Golle 7289eed07b vkmark: update to git HEAD of 2025-06-25
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2025-07-16 12:35:16 +01:00
Daniel Golle 986f15f668 vkmark: move to utils folder
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2024-12-05 01:24:11 +00:00
Daniel Golle 7a212373f1 kmscube: update to git HEAD of 2024-09-26
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2024-12-05 01:15:41 +00:00