Commit Graph

3764 Commits

Author SHA1 Message Date
Geoffrey McRae
ad7d869aa1 [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-19 20:41:36 +10:00
Geoffrey McRae
e18925f436 [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-19 20:13:42 +10:00
Geoffrey McRae
0333bf0261 [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-19 19:57:23 +10:00
Geoffrey McRae
e12d1dc9a8 [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-19 19:41:40 +10:00
Geoffrey McRae
e9695f5084 [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-19 19:41:36 +10:00
Geoffrey McRae
c190aaf579 [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-19 19:41:32 +10:00
Geoffrey McRae
4abbf33e9f [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-19 17:49:18 +10:00
Geoffrey McRae
79b031f061 [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-19 17:49:18 +10:00
Geoffrey McRae
29cfa58e3b [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-19 17:49:18 +10:00
Quantum
57d39bdd78 [idd] helper: use common/array.h instead of custom macros
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-19 06:48:17 +10:00
Quantum
58d24da7f3 [host] delete redundant / sizeof(char)
`sizeof(char) == 1` always per standard, so this is redundant.
2026-07-19 06:47:42 +10:00
Quantum
e9967660b7 [client] clean up manual versions of ARRAY_LENGTH macro 2026-07-19 06:47:20 +10:00
Geoffrey McRae
02751b10df [client] egl: fix SPICE video rendering to a HDR surface
If the last state had HDR enabled, the spice video surface was being
rendered as HDR even though the SPICE video content is SDR. This
corrects this.
2026-07-19 06:33:59 +10:00
Quantum
f8d9574709 [idd] helper: clean up exclusive monitor timer and respect setting 2026-07-19 06:19:30 +10:00
Quantum
f3d5c7e185 [idd] helper: hook up exclusive monitor toggle to registry 2026-07-19 06:19:30 +10:00
Quantum
1eb88b3d1e [idd] helper: add UI to toggle exclusive monitor setting 2026-07-19 06:19:30 +10:00
Quantum
6c623afc91 [idd] helper: add setting for exclusive monitor (default: yes) 2026-07-19 06:19:30 +10:00
Geoffrey McRae
7114d6f049 [idd] fix failure to detect GPU acceleration is available 2026-07-19 06:13:24 +10:00
Geoffrey McRae
653cecadeb [idd] disable HDR and post-processing when in software mode 2026-07-19 05:52:40 +10:00
Geoffrey McRae
bea35a030b [obs] hdr: apply the complete HDR cursor transform
Keep transform-only cursor messages independent from visibility and use
the cursor-specific SDR white level reported by IddCx.

Apply the Windows XYZ matrix, scalar, and transfer-domain LUT before
compositing colour and masked-colour cursors into OBS scRGB. Preserve
premultiplied alpha and leave monochrome logical masks unchanged.
2026-07-19 05:13:03 +10:00
Geoffrey McRae
99ab6448f9 [client] wayland: harden native HDR colour state
Serialize asynchronous image-description state and publish compositor
capabilities safely across the Wayland and render threads.

Use the predefined Windows-scRGB description, query each output image
description for its configured reference white, and reapply HDR when the
surface moves to an output with different colour settings.
2026-07-19 05:13:03 +10:00
Geoffrey McRae
70b795c5ba [client] egl: make native HDR encoding-safe
Request true floating-point EGL configs for scRGB and expose the native
encodings supported by the selected surface. Fall back to software HDR
mapping when the surface cannot represent the incoming wire format.

Resample PQ in linear light, keep SDR-only effects out of native PQ
chains, and consume the cursor-specific white level without changing
binary monochrome cursor mask operations.
2026-07-19 05:13:03 +10:00
Geoffrey McRae
20225f05d1 [idd] hdr: complete HDR display and cursor metadata
Publish BT.2020 chromaticities in the virtual monitor EDID so
Windows receives a valid HDR colour volume.

Extend cursor messages with their IddCx SDR white level and an
explicit visibility-valid flag. Consumers can then calibrate cursors
without treating colour-transform-only messages as cursor hides.
2026-07-19 05:12:59 +10:00
Geoffrey McRae
e9d0c88764 egl: follow active native HDR state
Keep software HDR mapping enabled until the display server activates the
requested image description. Re-evaluate the state while rendering so
asynchronous readiness or failure updates the desktop, cursor, and overlay
together with a full redraw.
2026-07-19 03:48:17 +10:00
Geoffrey McRae
94a805ab4b wayland: make HDR descriptions asynchronous
Publish HDR metadata through a locked request snapshot and wait for
image-description readiness before using it. Commit encoding changes with
matching content, preserve the active description during same-format
metadata replacements, and handle creation failures without protocol
errors.
2026-07-19 03:47:21 +10:00
Geoffrey McRae
fcd66a5172 [all] fix copyright headers 2026-07-19 03:31:44 +10:00
Geoffrey McRae
26ca90893a [idd/client] apply the Windows display color transform
Honor the IddCx 3x4 XYZ matrix and post-transfer LUT in the IDD
conversion pipeline. Carry transform changes to the client so EGL applies
the same calibration to hardware cursors, and invalidate the full frame
whenever calibration changes.
2026-07-19 03:25:30 +10:00
Geoffrey McRae
ad5d7753e8 [client] wayland: forward HDR mastering metadata
Propagate valid ST 2086 mastering primaries and luminance data, MaxCLL,
and MaxFALL to the Wayland compositor using the protocol's expected
units.
2026-07-19 02:16:19 +10:00
Geoffrey McRae
1f6dbb0dae [idd] hdr: propagate per-frame HDR metadata
Handle DEFAULT, NEW, and UNCHANGED IDDCX HDR10 metadata states and
publish valid mastering metadata through KVMFR. Preserve the metadata
across post-processing without reallocating resources for
metadata-only changes.
2026-07-19 02:13:57 +10:00
Geoffrey McRae
624fa9f8bc [client] egl: correct surface damage reporting
Apply the same sampling margin to swap damage as buffer-age repair and
clip reported rectangles to the EGL surface. This ensures compositors
update every pixel affected by scaling or filtering.
2026-07-19 01:08:26 +10:00
Geoffrey McRae
45114c75c8 [client] main: validate damage metadata 2026-07-19 01:08:26 +10:00
Geoffrey McRae
d8dee8806b [idd] rgb24: fix packed-texel damage endpoints 2026-07-19 01:02:08 +10:00
Geoffrey McRae
86824a0010 [idd] accumulate damage from dropped frames 2026-07-19 01:00:22 +10:00
Geoffrey McRae
84e0a1b956 [idd] cancel stale swap chain assignments
Invalidate in-progress swap chain setup when IddCx unassigns the
monitor, and serialize replacement assignments so workers are
never started on abandoned handles.

Also initialize all worker dependencies before starting the processing
thread and treat teardown during SetDevice as normal cancellation.
2026-07-19 00:28:56 +10:00
Geoffrey McRae
e0d3794c1d [idd] helper: fix dependency cycle issue on windows 10 2026-07-19 00:14:40 +10:00
Geoffrey McRae
a700db51a0 [idd] debug: add additional logging 2026-07-19 00:13:58 +10:00
Geoffrey McRae
ab96c7ea81 [idd] ensure the only active monitor is the IDD
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-18 22:21:18 +10:00
Quantum
83209fd3a9 [idd] helper: implement deferred mode save and revert 2026-07-18 17:45:18 +10:00
Quantum
064fef1f62 [idd] helper: add buttons for deferred mode save and revert 2026-07-18 17:45:18 +10:00
Quantum
0e05ff9742 [idd] helper: rearrange UI in preparation for deferred saves 2026-07-18 17:45:18 +10:00
Geoffrey McRae
e3e0cfd43a [client] egl: fix messy white level default definition 2026-07-18 16:39:55 +10:00
Geoffrey McRae
85d0dbf83c [client] glsl: fix failure to build on clang
Clang with -ffast-math doesnt have `isfinite`, instead implement it
locally.
2026-07-18 16:24:47 +10:00
Quantum
47aebcda0c [client] resources: clean up icon handling
This commit turns the icon handling into using a macro so we don't need to do
weird conversions from unsigned long (needed by X11) to uint32_t (needed by
Wayland).

Also simplified the error handling path on Wayland.
2026-07-18 15:44:22 +10:00
Geoffrey McRae
6a9957650c [client] add a MPV glsl style effect loader
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-18 08:42:38 +10:00
Quantum
d206e788af [host] windows: report Windows 11 OS name correctly
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
This commit brings bc96319b9486798edc6599841dd67476feea5e43's improved logic
in the IDD to the host application.
2026-07-18 04:51:41 +10:00
Quantum
dcb84451f0 [idd] helper: make WS_CHILD | WS_VISIBLE the default in widgets
This avoids literally every widget we load having to declare
`WS_CHILD | WS_VISIBLE` and then just break if you forget.
2026-07-18 04:51:22 +10:00
Geoffrey McRae
b48f8d6fec [idd] remove debounce logic now the lifecycle is properly protected 2026-07-18 04:41:38 +10:00
Geoffrey McRae
87db473122 [idd] apply resolution after the final replug
Preserve the requested display mode across intermediate swap chains when
rapid resolution changes cause replugs to be coalesced. Apply and clear
the mode only once the final replacement swap chain is ready.
2026-07-18 04:36:42 +10:00
Geoffrey McRae
791da3387a [idd] serialize monitor replugs with swap chain teardown
Keep the replug lifecycle gated until the old swap chain has drained and
released its pending frame, and the replacement swap chain is fully
initialized. Coalesce additional requests into a follow-up replug to
prevent overlapping topology changes and IddCx release-frame timeout
bugchecks.
2026-07-18 04:30:21 +10:00
Geoffrey McRae
9676b30299 [idd] stop flooding the log with parsed modes 2026-07-18 04:22:14 +10:00