Commit Graph

199 Commits

Author SHA1 Message Date
Geoffrey McRae
5b90384123 [client/idd] input: report endpoint status 2026-08-09 01:36:54 +10:00
Geoffrey McRae
ced2fb531e [idd] input: preserve reports under backpressure
Move named pipe writes off the LGMP input worker so a stalled LGInput
endpoint cannot block queue draining or lease maintenance.

Coalesce motion only under queue pressure while preserving mode, button,
wheel, and keyboard transitions. Reset HID state after discontinuities
and carry all 32 mouse button bits through the pipe and HID reports.
2026-08-08 23:42:27 +10:00
Geoffrey McRae
83c552fb9d [idd] input: receive LGMP input reports
Add an optional input transport and a dedicated LGMP receiver that
validates source ownership, generations, ordered sequences, and leases.

Poll input outside the 10 ms control timer. Forward mouse and keyboard
state through the LGInput pipe, and neutralize the endpoint before
ownership changes or transport failures can leave input held.
2026-08-08 22:56:02 +10:00
Geoffrey McRae
04fd31219c [idd] input: add mouse and keyboard IPC messages
Replace raw HID report forwarding with typed absolute mouse, relative
mouse, and keyboard messages.

Expose absolute and relative modes as separate Mouse collections because
Windows MouHID requires one X/Y motion mode per mouse device.
2026-08-08 20:18:05 +10:00
Geoffrey McRae
241ab3fad2 [idd] ipc: connect LGInput to LGIdd
Move the reusable named-pipe endpoint and shared support code into
the LGCommon static library.

Run a dedicated server in LGIdd and a reconnecting client in
LGInput, with device-lifecycle handling and report framing.

Refactor the helper pipe to use the same endpoint implementation.
2026-08-08 20:18:05 +10:00
Geoffrey McRae
214665bedd [idd] input: add virtual HID driver
Build LGInput as an independent UMDF driver with its own entry point,
service, tracing, and binary.

Expose absolute pointer, relative mouse, and keyboard collections with a
guarded report queue.

Keep LGIdd as the startup and deployment project. Give it a non-linking
build/package dependency on LGInput so F5 stages both driver stacks and
installs them together through LGIddInstall, while the two UMDF binaries
remain independent for future IPC.

Stage both DLLs for the NSIS installer, retain the WDK UMDF remote-debug
startup attachment, and move CSRWLock into LGCommon for the input
driver's report queue.
2026-08-08 20:17:32 +10:00
Geoffrey McRae
e470f9d8ae [idd] capture: preserve software copy row pitch
Use an explicit placed buffer for software frame copies so the D3D copy
uses the same row pitch published through KVMFR.

GetCopyableFootprints describes buffer copies and cannot be used to infer
the physical layout of a placed row-major texture. This caused padded
resolutions to use the wrong row starts in every consumer.

Keep the copy direct to IVSHMEM without a staging or CPU copy.
2026-08-07 21:10:37 +10:00
Geoffrey McRae
1de52f6e8a [idd] project: organize source layout
Move cadence and pipeline declarations under capture, and move local
named-pipe handling under ipc.

Flatten display contexts and rename files after their contained classes.
Keep transport headers limited to transport contracts and capabilities.

Consolidate CSwapChainProcessor definitions so each source file matches
the class it implements.
2026-08-07 18:16:18 +10:00
Geoffrey McRae
6725133375 [idd] transport: abstract LGMP implementation
Introduce transport, frame, and control interfaces with an LGMP factory
backend.

Move LGMP and IVSHMEM implementation details under transport/lgmp and
expose direct frame-buffer memory through a neutral capability.
2026-08-07 17:53:00 +10:00
Geoffrey McRae
30a1383d5e [idd] project: organize driver sources by responsibility
Group the IDD sources and Visual Studio filters by subsystem.

Split the device and swap-chain implementations into focused units,
rename the context classes, and reduce header coupling.
2026-08-07 15:49:18 +10:00
Geoffrey McRae
3ddc199bec [idd] capture: split software and hardware frame processors
Move cadence-aware hardware capture and immediate software capture
behind a common frame processor interface.

Keep shared damage tracking and frame-buffer ownership in the base
processor, and move stateless format, resource, and rectangle helpers
into CFrameProcessorUtil.

Decouple frame-buffer resources from CSwapChainProcessor by passing the
device dependencies they use directly.
2026-08-07 13:34:40 +10:00
Geoffrey McRae
d7c90e4693 [idd] capture: copy software frames directly to IVSHMEM
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
build / client-tests (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client-tests (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client-tests (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client-tests (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client-tests (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client-tests (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client-tests (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client-tests (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
Bypass cadence retention when the software render adapter is active.
Publish each available source frame immediately with one damage-aware
D3D copy into its final IVSHMEM resource.

Keep only one software copy in flight so newer frames are dropped
instead of queued behind stale work. Retain accumulated damage for the
next frame and skip static re-encodes when no image update is pending.

Use a row-major IVSHMEM texture when the shared heap supports it and
fall back to a direct IVSHMEM buffer copy otherwise. In indirect mode,
copy only damaged rows from readback memory into IVSHMEM.
2026-08-07 12:43:48 +10:00
Geoffrey McRae
ce47758ebd [idd] config: support fractional refresh rates
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
build / client-tests (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client-tests (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client-tests (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client-tests (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client-tests (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client-tests (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client-tests (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client-tests (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
Store refresh rates in millihertz and preserve three decimal places.

Advertise exact rational rates while accepting legacy integer values.

Accept rates from 23.900 through 1000.000 Hz.
2026-08-06 23:40:08 +10:00
Geoffrey McRae
a279a87bdb [idd] config: reload persisted display modes
Rebuild the driver's cached mode list before replugging the monitor so
Windows enumerates the settings saved by the helper.

Keep saved mode refresh rates intact and update only ExtraMode to the
configured default refresh.
2026-08-06 23:06:40 +10:00
Geoffrey McRae
ee9d958626 [idd] scheduler: avoid secondary subscription replays 2026-08-06 18:04:10 +10:00
Geoffrey McRae
b50dd41909 [idd] scheduler: account queue maintenance work 2026-08-06 18:04:10 +10:00
Geoffrey McRae
807ea52b02 [idd] scheduler: reject isolated work timing stalls 2026-08-06 18:04:10 +10:00
Geoffrey McRae
5e7d944607 [idd] pipeline: overlap independent frame copies 2026-08-06 18:04:10 +10:00
Geoffrey McRae
d3ee46f376 [idd] scheduler: prioritize deadline publication 2026-08-06 18:04:10 +10:00
Geoffrey McRae
fac417c6b3 [idd] scheduler: avoid stale deadline waits 2026-08-06 18:04:10 +10:00
Geoffrey McRae
0b744d2286 [common] kvmfr: report cadence hold and lead timing 2026-08-06 18:04:10 +10:00
Geoffrey McRae
fb1fb8447e [idd] scheduler: unblock ownership transitions
Permit retained-buffer reuse when both private queues are occupied by a
previous timing owner, even if the new owner has no pending deliveries.

Use the shared fallback when possible. Otherwise retain the fresh frame
locally and republish it instead of waiting for stale private deliveries.
2026-08-06 18:02:08 +10:00
Geoffrey McRae
3e9dadf340 [idd] scheduler: reserve slots for frame subscribers
Replace the oldest provisional schedule entry when the bounded client
table has no empty slot. Never evict a client whose frame subscription has
already been observed.

This prevents rapid failed reconnects from filling every scheduler slot
before a real frame subscriber can be registered.
2026-08-06 18:02:08 +10:00
Geoffrey McRae
ece6afd74e [idd] scheduler: retain frames behind stalled owners
Keep preparing the newest frame when both private owner lanes remain
referenced by a non-consuming timing client. Reuse only an unreferenced
completed buffer and continue serving eligible shared subscribers.

Track owner delivery separately from local retention so cadence advances
without acknowledging owner delivery or accepting phase feedback. Republish
the newest completed frame as soon as an owner lane becomes available.
2026-08-06 18:02:08 +10:00
Geoffrey McRae
05fe4f1dd8 [idd] scheduler: account partial shared delivery
Record every requested recipient after LGMP posts to at least one live
subscriber. Targets that disappeared during the post are harmless, while
surviving targets must advance instead of remaining perpetually due.
2026-08-06 18:02:08 +10:00
Geoffrey McRae
eaf8de5e1d [idd] scheduler: republish after owner subscription
Consume subscription notifications from the private owner queues. When
any lane gains a subscriber, request a retained-frame publication for
the current timing owner so a static desktop cannot leave it waiting.
2026-08-06 18:02:08 +10:00
Geoffrey McRae
515f4ba06f [client/host/idd/obs] scheduler: validate phase feedback
Bump KVMFR to version 28 and attach generation, epoch, and deadline
identities to cadence deliveries and their timing records.

Accept phase corrections only for the exact completed publication. Keep
VM and client clocks independent by exchanging relative phase errors.

Make submission, completion, and work-estimate accounting best effort
so scheduler state cannot delay GPU submission or frame publication.
2026-08-06 18:02:08 +10:00
Geoffrey McRae
983cf588e3 [idd] scheduler: skip expired publication slots
Advance past cadence deadlines whose publication targets have already
expired after a completed periodic frame.

Use the same slack, work, and safety lead as target selection so the next
publisher wait cannot immediately expire again.
2026-08-06 18:02:08 +10:00
Geoffrey McRae
f65ecdaf5d [idd] capture: recover final desktop updates
Request one static-desktop re-encode and inspect repeated presentation
numbers for its empty dirty-rectangle marker.

Prepare every marker in a free candidate without superseding retained
damage, so the last desktop update survives a late copy failure.
2026-08-06 18:02:08 +10:00
Geoffrey McRae
909271bfe1 [idd] scheduler: preserve concurrent force requests
Replace the shared force and republish booleans with request tickets.
A completed publication now acknowledges only requests captured when it
began, so a concurrent immediate or cadence-break request survives.
2026-08-06 18:02:08 +10:00
Geoffrey McRae
f6c72b0bc5 [idd] capture: replay only completed frames
Track the newest submitted and completed frame independently. Only
retain or replay a frame after its copy callback succeeds.

Keep the prior completed frame when a newer copy fails, and compare
publication sequences so out-of-order callbacks cannot move backward.
2026-08-06 18:02:08 +10:00
Geoffrey McRae
160c5fd1fa [idd] scheduler: fold late forces into cadence
Treat a forced publication as periodic once the normal pre-deadline
send point is due. This prevents an immediate forced copy from being
followed by another copy for the same cadence slot.
2026-08-06 18:02:08 +10:00
Geoffrey McRae
babfe9b1e2 [idd] d3d12: harvest completed command slots
Check a busy slot fence before waiting for its thread-pool callback.
This lets the caller complete finished GPU work inline and avoids a
scheduler delay before the allocator and command list can be reused.
2026-08-06 18:02:08 +10:00
Geoffrey McRae
6bb5c039cd [idd] capture: keep preparing during publication
Do not freeze the spare retained candidate while a frame is copied to
IVSHMEM. Allow newer source frames to replace that candidate and retain
any frame prepared after the published sequence for the next deadline.

Take the pipeline lock before selecting the publication candidate so its
transport copy is submitted before any newly admitted preparation.
2026-08-06 18:02:08 +10:00
Geoffrey McRae
f04775823d [idd] capture: retire damage before copy submission
Retire candidate damage before submitting its publication copy. A fast
completion callback can otherwise release and reuse the candidate while
the publisher is still reading its fields and damage tail.
2026-08-06 18:02:08 +10:00
Geoffrey McRae
c56b10b194 [idd] scheduler: detect high-rate cadence breaks
Keep the client schedule floor at 2 ms while accepting shorter guest
frame intervals for cadence tracking. This lets sources above 500 Hz
trigger immediate final-frame delivery when their cadence breaks.
2026-08-06 18:02:08 +10:00
Geoffrey McRae
da7d6b4011 [idd] capture: defer interop synchronization
Signal the shared D3D11 source only after a retained candidate and its
command slots have been acquired. Superseded source frames no longer queue
a fence that no Direct3D 12 work will consume.
2026-08-06 18:02:07 +10:00
Geoffrey McRae
0a04dc4964 [idd] d3d12: signal reusable command slots
Signal a per-slot event after callbacks finish and the command slot has
returned to the free state. This removes the one millisecond polling delay
when candidate state becomes visible just before its slot is reusable.
2026-08-06 18:02:07 +10:00
Geoffrey McRae
3e6c9197f1 [idd] capture: never wait on superseded frames
Drop an acquired frame immediately when both retained candidate slots are
unavailable. Waiting for up to 2 ms held the IddCx surface and
backpressured sources whose frame period was shorter than the wait.
2026-08-06 18:02:07 +10:00
Geoffrey McRae
4c1722feac [idd] scheduler: report actual acquired frame rate
Derive the source rate from unique frames observed over the actual log
interval. The old EWMA discarded intervals below 2 ms, capping the
reported rate at 500 Hz and understating high-rate sources.
2026-08-06 18:02:07 +10:00
Geoffrey McRae
49341a240d [idd] scheduler: pipeline timing owner deliveries
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
build / client-tests (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client-tests (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client-tests (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client-tests (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client-tests (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client-tests (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client-tests (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client-tests (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
Allow the timing owner to keep one delivery pending on each independent
owner queue instead of waiting for the client to release every frame.

Count shared fallback deliveries against the same two-frame limit and
match republished frames across all active lanes. This hides the client
release round trip without allowing a third delivery for the owner.
2026-08-06 10:18:14 +10:00
Geoffrey McRae
3add7d066f [idd] logging: remove misleading swapchain noise 2026-08-06 05:58:28 +10:00
Geoffrey McRae
057fb4d40a [idd] swapchain: bind device before pipeline setup 2026-08-06 05:43:29 +10:00
Geoffrey McRae
770bce4ec0 [idd] adapter: defer render selection until initialization
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
build / client-tests (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client-tests (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client-tests (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client-tests (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client-tests (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client-tests (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client-tests (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client-tests (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
2026-08-06 05:04:22 +10:00
Geoffrey McRae
650636ccee [idd] capture: retain frames in linear buffers
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
build / client-tests (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client-tests (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client-tests (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client-tests (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client-tests (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client-tests (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client-tests (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client-tests (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
Store retained frame candidates in the final linear transport layout.
Prepare texture output in local DEFAULT buffers before cadence holding.
Then publish full frames with a single buffer copy.

Keep partial damage on matching pitched layouts and leave effect-owned
buffer copies unchanged. This moves detiling out of the
deadline-critical IVSHMEM or readback transfer.
2026-08-05 22:08:38 +10:00
Geoffrey McRae
ab25601a61 [idd] rgb24: compare stable candidate timings
Ignore allocation alignment when matching retained candidate resources.
D3D12 may resolve automatic alignment requests in GetDesc.
Comparing that value recreated the candidate for every benchmark sample.

Measure native and packed over matching wall-clock intervals.
Use preparation and publication intervals, excluding the cadence hold.
This avoids mixing GPU timestamps with fallback timing. The CPU IVSHMEM
copy is included only on indirect systems.
2026-08-05 21:45:45 +10:00
Geoffrey McRae
f073099950 [idd] capture: retire published pending damage
Track damage received after each retained candidate snapshot. When a
candidate is submitted successfully, replace the global pending set
with its trailing damage instead of requiring the source generation
to remain unchanged.

This lets published full-frame damage retire while preserving newer
partial or full updates.
2026-08-05 20:58:02 +10:00
Geoffrey McRae
ff5b43173a [idd] rgb24: isolate benchmark samples from cadence
Run effect timing samples only when the retained candidate pipeline is idle
and force each completed sample to publish immediately. This prevents work
from superseded candidates from being charged to a surviving sample.

Include the indirect CPU copy to IVSHMEM in the measured copy stage while
preserving the wall-clock fallback when GPU timestamps are unavailable.
2026-08-05 20:48:50 +10:00
Geoffrey McRae
f95c8f0660 [idd] scheduler: pace secondary frame delivery 2026-08-05 17:10:35 +10:00
Geoffrey McRae
c7ed04412e [client/idd/obs] scheduler: isolate timing owner delivery 2026-08-05 15:45:30 +10:00