Commit Graph

3803 Commits

Author SHA1 Message Date
Geoffrey McRae
4999e24bb7 [common] debug: switch to libunwind instead of bfd 2026-07-29 12:39:10 +10:00
Geoffrey McRae
4f96ded6f9 [client] wayland: use multi-line debug output for hdr support info 2026-07-29 12:39:10 +10:00
Geoffrey McRae
ea7924af43 [all] debug: add multiline debug print variants 2026-07-29 12:39:10 +10:00
Geoffrey McRae
61f00ae625 [client] hdr: refactor name to clean up log output 2026-07-29 12:39:10 +10:00
Geoffrey McRae
737614bc69 [client] audio: redesign playback synchronization
Model playback latency from the device period, arrival jitter, source
packet phase, and resampler delay. Treat audio:latencyOffset as an
explicit addition to this minimum and align the first device pull to
the next packet deadline. This starts playback near its steady-state
target without unnecessary prefill or startup underruns. Use a
512-frame default period as a practical low-latency baseline.

Replace the startup clock hold with a one-sided proportional
acquisition controller, then hand off to source/device rate
feed-forward and a slow phase loop. Calibrate the logical device
timeline at handoff, discard correction that opposes the current
error, and slew-limit rate changes. This prevents startup drain,
integral wind-up, overshoot, and long convergence while preserving
clock-drift compensation.

Allow audio backends to expose a real-time resampler and use
PipeWire's adaptive resampler when version 1.4 or newer supports it.
Retain libsamplerate as the fallback and add audio:resampler to select
the implementation. Wait for PipeWire stream setup to complete and
propagate rate-control failures cleanly.

Track PipeWire input-consumption and output-equivalent clocks
separately. The input clock measures ring latency while the output
clock drives feed-forward using the ratio that governed each request.
This removes delayed self-feedback that made adaptive resampling
oscillate between the correction limits.

Reduce audio:debug output to useful latency, clock, jitter, and xrun
values, and scale the playback graph from the startup estimate. Update
the option names and documentation for the new latency model.
2026-07-29 12:39:08 +10:00
Geoffrey McRae
814f1797fe [client] audio: reduce playback startup delay 2026-07-28 23:49:45 +10:00
Geoffrey McRae
739931fca3 [client] audio: include the jitter in the target calculation 2026-07-28 23:45:11 +10:00
Geoffrey McRae
6f6816b99f [client] audio: keep PipeWire callbacks realtime safe
Avoid querying playback timing on every graph cycle. Refresh backend
latency only when audio diagnostics request it, and defer callback
errors for reporting from non-realtime contexts.

Move microphone delivery to a bounded SPSC queue drained by a sender
thread. This keeps PureSpice locking and socket writes out of the
PipeWire capture callback while bounding overload behavior.

Validate and recycle capture buffers before enqueueing their contents.
These changes improve deadline margin when using small period sizes.
2026-07-28 23:39:55 +10:00
Geoffrey McRae
76230726cc [client] audio: harden playback at small period sizes
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
Bound playback writes and synchronization slews to the physical ring
storage, preventing overwritten samples from being treated as valid PCM.
Trigger clock resynchronization when output must be dropped.

Wait for enough startup audio to cover backend demand and a complete
source packet. Generate silence if playback begins early instead of
rewinding the reader into stale ring storage.

Honor PipeWire playback frame requests and fully initialize empty chunks.
This keeps playback reliable when using small device period sizes.
2026-07-28 22:59:08 +10:00
Geoffrey McRae
d956dd8fd3 [client] audio: rework synchronization for low latency
Drive playback timing from audio sample positions instead of packet
arrival cadence. Use SPICE multimedia timestamps to anchor streams,
detect discontinuities, and estimate the long-term source rate. Ignore
their coarse phase corrections when steering the playback buffer.

Measure the device clock independently and wait for it to stabilize
before enabling a bounded, slew-limited phase controller. Align startup
buffering from logical producer and consumer positions so backend
startup reserves do not become persistent latency.

Size the buffer from the backend period, measured delivery jitter, and
resampler delay. Update PipeWire and PulseAudio to report their actual
startup requirements and presentation latency. Default to a 10 ms
device period with 4 ms of additional buffering, and make detailed
synchronization diagnostics opt-in through audio:debug.

This reduces startup and steady-state latency while compensating for
physical and virtual device clock drift without reacting to transport
jitter or SPICE timestamp quantization.
2026-07-28 21:07:02 +10:00
Geoffrey McRae
4ef6672e64 [client] egl: uninitialized value release build failure
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
2026-07-28 13:45:57 +10:00
Geoffrey McRae
dc20ac05ab [client] main: fix release build uninitalized value warning 2026-07-28 13:42:38 +10:00
Geoffrey McRae
b9b2521bb7 [client] audio: synchronize callback and microphone lifetimes 2026-07-28 13:33:19 +10:00
Geoffrey McRae
532305d263 [client] pipewire: make it possible to stop from the process callback 2026-07-28 13:32:41 +10:00
Geoffrey McRae
a421be5e54 [client] audio: restore microphone volume and mute state 2026-07-28 13:17:58 +10:00
Geoffrey McRae
d384591e05 [client] audio: fix microphone restart bookkeeping 2026-07-28 13:17:02 +10:00
Geoffrey McRae
a5571f0e9e [client] spice: separate clipboard state by direction 2026-07-28 13:10:38 +10:00
Geoffrey McRae
e4658b4263 [client] spice: validate clipboard responses 2026-07-28 13:08:16 +10:00
Geoffrey McRae
e73a3dec60 [client] spice: handle clipboard request failures 2026-07-28 13:05:40 +10:00
Geoffrey McRae
67e2675afa [client] spice: fix clipboard transfer accounting 2026-07-28 13:00:38 +10:00
Geoffrey McRae
49b7f50c6b [client] spice: start for display-only configurations 2026-07-28 12:50:27 +10:00
Geoffrey McRae
44a28d52c9 [client] spice: complete startup when server info retrieval fails 2026-07-28 12:43:18 +10:00
Geoffrey McRae
f4ee349880 [client] app: make shared application state access thread-safe 2026-07-28 12:41:35 +10:00
Geoffrey McRae
f980248221 [client] spice: fix missing scancode translation for key up 2026-07-28 12:28:02 +10:00
Geoffrey McRae
e4888c362a [client] spice: make display switching atomic and failure-aware 2026-07-28 12:24:51 +10:00
Geoffrey McRae
5c7431dfd6 [client] spice: validate bitmap fills and prevent potental VLA crash 2026-07-28 12:12:38 +10:00
Geoffrey McRae
b7a1637cb0 [client] spice: validate bitmap format and check for failures 2026-07-28 12:04:32 +10:00
Geoffrey McRae
2f88063d77 [client] spice: check and track the primary surface format & validity 2026-07-28 12:01:08 +10:00
Geoffrey McRae
e09a3f7715 [repos] purespice: update submodule
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
2026-07-28 07:17:02 +10:00
Quantum
6a0526fc1e [idd] driver: report IVSHMEM size
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
2026-07-26 22:17:28 +10:00
Quantum
d3d1d48e97 [idd] installer: make multiline strings more readable
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
2026-07-23 10:01:17 +10:00
Quantum
4fa697e165 [host] installer: add new page suggesting IDD usage 2026-07-23 10:01:17 +10:00
Quantum
a3d7e3806b [host] installer: make multiline strings more readable 2026-07-23 10:01:17 +10:00
Quantum
71ba0bf8f6 [host] installer: offer the option of uninstalling IDD if detected 2026-07-23 10:01:17 +10:00
Geoffrey McRae
fe4088797c [github] workflow: fix random clang build errors due to runner issue
Ref: https://github.com/actions/runner-images/issues/14296
2026-07-23 09:44:00 +10:00
Geoffrey McRae
0e113d9d83 [client] wayland: use the locally configured white level for SDR 2026-07-23 09:44:00 +10:00
Geoffrey McRae
34af6e6f8f [idd] hdr: correct virtual monitor capabilities 2026-07-23 09:44:00 +10:00
Geoffrey McRae
9376ac10b6 [client] wayland: separate mastering metadata validation
Validate mastering primaries and luminance independently so one
unsupported component does not discard the other.

Trust content chromaticities when extended target volumes are supported,
and report the exact values and reason when metadata must be omitted.
2026-07-23 09:44:00 +10:00
Geoffrey McRae
e716435617 [idd] edid: advertise the full PQ luminance range
The virtual display transports HDR pixels rather than emitting light.
Advertise approximately 10,000 nits for both peak and frame-average
luminance, and leave the physical black level unspecified.

This prevents Windows from mapping HDR into an arbitrary virtual
display limit before the frame reaches the real host display.
2026-07-23 09:44:00 +10:00
Geoffrey McRae
21a0fc08fb [idd] hdr: publish only per-content metadata
Monitor-default HDR metadata describes the virtual display rather than
the captured content. Do not expose it through KVMFR or use it to select
downstream processing limits.

Only publish explicit NEW frame metadata and otherwise use the complete
PQ range internally.
2026-07-23 09:44:00 +10:00
Geoffrey McRae
1b0e1cf74b [client] egl: correct CAS processing for HDR
Convert HDR scRGB input to normalized linear Rec.2020 before CAS, then
convert the filtered result back to scRGB. Use the content metadata to
select an appropriate normalization peak while leaving SDR unchanged.

This follows AMD's documented recommendation for applying CAS to HDR
content and prevents HDR highlights from being clamped and dimmed.
2026-07-23 09:44:00 +10:00
Geoffrey McRae
697bbc6601 [client] egl: restore effects for PQ frames
PQ sources excluded every external filter from the post-process chain.
Decode PQ/BT.2020 into FP16 linear scRGB before active effects and pass
the resulting transfer state to the desktop shader.

Keep the raw PQ path when no effect is active. This avoids adding a
conversion pass or per-frame latency to the common case.
2026-07-23 09:44:00 +10:00
Geoffrey McRae
719ffeaa60 [client] wayland: separate PQ and mastering volumes
Describe PQ pixels with the protocol-defined primary luminance range and
keep mastering luminance in the target volume. Track extended target-volume
support and omit unsupported metadata instead of creating an invalid image
description.
2026-07-23 09:44:00 +10:00
Geoffrey McRae
dbc5ca104e [client] wayland: retain coherent HDR state on failure
Keep the reference white associated with the active PQ description until
a replacement is ready. If asynchronous description creation fails, the
renderer now retains the complete previous HDR state instead of combining
new white-level values with stale compositor metadata.
2026-07-23 09:44:00 +10:00
Geoffrey McRae
068362b816 [host] hdr: encode legacy captures as HDR10
Convert FP16 scRGB captures to BT.2020 PQ before storing them in the
10-bit wire format. Preserve linear-light downsampling, publish the real
SDR white level and display metadata, and advance the format version when
those properties change.
2026-07-23 09:44:00 +10:00
Geoffrey McRae
b7e56244c1 [obs] hdr: correct logical and color cursor composition
Keep masked-color XOR operands on the untransformed logical path rather
than applying the color cursor shader. Preserve the white level delivered
with cursor updates instead of replacing it with frame SDR white during
format changes.

This keeps inverse-destination blending intact and ensures HDR cursor
brightness follows QueryHardwareCursor3.
2026-07-23 09:44:00 +10:00
Geoffrey McRae
0b9603d398 [client] egl: compose native PQ output in linear light
Decode PQ/BT.2020 desktop pixels into an FP16 linear scRGB target before
compositing the color cursor, ImGui, damage overlay, and letterboxing.
Encode the damaged result to PQ once at the surface boundary. Keep logical
AND/XOR cursor masks in the encoded domain.

This preserves premultiplied cursor edges, prevents encoded-domain
blending, uses the Wayland output reference white for local overlays, and
keeps guest cursor white and display calibration independent from frame
SDR white. It also corrects HDR-to-SDR absolute luminance scaling, gamut
matrices, black handling, and buffer-age repair for the extra pass.

Suppress overlays when their conversion framebuffer is unavailable rather
than allowing unconverted sRGB draws into an HDR target.

Use named transfer constants for cursor shader state. Convert clipped
surface rectangles explicitly before using the frame-damage merge helper,
which avoids mixing its unsigned type with the EGL surface rectangle type.

Only advertise native PQ when the FP16 composition target is available.
SDR and native scRGB retain their direct single-pass paths.
2026-07-23 09:44:00 +10:00
Geoffrey McRae
672b6c0d8a [client] hdr: serialize surface format transitions
Queue the display-server surface format while the renderer lock still
serializes the matching onFrameFormat update. This prevents the render
thread from presenting a frame in a new HDR encoding before the Wayland
image description transition has been queued.
2026-07-23 09:44:00 +10:00
Quantum
28f18188c4 [idd] helper: use common/array.h instead of custom macros 2026-07-23 09:44:00 +10:00
Quantum
0da56a67bb [host] delete redundant / sizeof(char)
`sizeof(char) == 1` always per standard, so this is redundant.
2026-07-23 09:44:00 +10:00