Skip to content

feat(win): probe_displays joins the SR runtime's display enumeration (multi-screen M0) - #314

Merged
dfattal merged 3 commits into
mainfrom
feat/win-probe-displays-sr-enum
Oct 8, 2026
Merged

dfattal merged 3 commits into
mainfrom
feat/win-probe-displays-sr-enum

Conversation

@dfattal

@dfattal dfattal commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

What / why

Windows twin of #311 (Linux M0). This is the first Windows brick of the joint multi-screen plan (runtime docs/roadmap/multi-screen.md, ADR-047).

Today the Windows arm already claims every table-known Leia panel, but every claim is VERIFIED with an empty serial and no SR identity. On the two-panel rig (AUO B194 laptop panel = SR device AL + Acer DS1, each with its own SpatialLabs camera) both monitors read VERIFIED while SR had authenticated only the AL's FPC — the DS1 is EDID-only until SR's D1 pairing fix lands.

probe_displays now joins the runtime's monitor list with srEnumerateDisplays (Windows slot 106, SDK 1.38.0+2031, ST-5481 phase B) when the installed SR runtime has it:

  • Join key: same EDID (manufacturer, product) AND, when SR marks its location desktop-global, the same desktop origin; else the pair when unique in SR's list. Identical twins with nothing to tell them apart are claimed at EDID confidence with no serial and no displayId — never someone else's identity.
  • Confidence follows SR: FPC_VERIFIED → VERIFIED + FPC serial; EDID_ONLY → EDID (still beats sim_display's FALLBACK). A monitor the frozen table does not know but SR lists is claimed anyway (SR's product-code registry is authoritative, the table drifts) — this replaces the "claim the primary monitor" deferral whenever SR can enumerate.
  • No enumeration (older SR runtime → SR_ERROR_FUNCTION_UNSUPPORTED, service down, compiled out): today's behaviour byte-identical.
  • Binding table (displayId, HMONITOR, device name) kept plug-in-private via leia_win_claims_store/lookup for the M5/M6 per-DP binding. Nothing reads it yet. HMONITORs and EDID_ONLY ids are not stable across display-config events, so nothing is persisted past the 2 s cache.

SR side (leia_sr_v2_common.cpp, DXR_LEIA_HAS_SR_DISPLAY_ENUM): one process-wide probe SrInstance, created lazily in NON_BLOCKING_CLIENT mode and never srInitialized (enumeration needs only a valid instance; initialise would start trackers — confirmed with the SR session), 2 s cache (the runtime re-runs probe_displays per registry refresh), dropped on any failure and on plug-in destroy. srGetRuntimeCapabilities with the routing + binding capability structs chained is logged once for bring-up.

Second commit pins the SR v2 SDK to sr-sdk-v2-1.38.0.2031 (the release SDK superseding 1895: one dispatch numbering + header set for Windows and Linux; 1895's slots are an exact prefix, appends only).

Measured on the rig (runtime v2.26.0, LeiaSR 1.38.0+2029)

 WARN leia_plugin: SR multi-display caps: externalRouting=1 routingFlags=0x1 displayBinding=1 maxBoundDisplays=1
 WARN leia_plugin: SR enumerates 2 display(s):
 WARN leia_plugin:   SR display #0 id=0x0000000000000001 FPC_VERIFIED serial='QALA2137AL0011' product=AL edid=0xAF06/0xB194/0 at (0,0) 3840x2160 60.00 Hz device='\.\DISPLAY1' hmonitor=0x1007d
 WARN leia_plugin:   SR display #1 id=0xe31a65dd1e032b8e EDID_ONLY serial='' product=D1 edid=0x7204/0x0001/841936990 at (3840,0) 3840x2160 60.00 Hz device='\.\DISPLAY5' hmonitor=0x20001
 :: Per-display DP claims (resolved registry, #69)
	monitor 0x8c413a2f61152ce7  3840x2160 @ (0,0)      plug-in='leia-sr'  confidence=VERIFIED  apis=vk|d3d11|d3d12|gl  serial=QALA2137AL0011
	monitor 0xb72ea4c616544d01  3840x2160 @ (3840,0)   plug-in='leia-sr'  confidence=EDID      apis=vk|d3d11|d3d12|gl
  • displayxr-cli selftest PASSED; info DP selection unchanged (leia-sr on every path, paths agree).
  • cube_handle_d3d11_win (installed runtime, dev DLL rename-swapped in): weaver READY, weaves as before; the enumeration runs in-process too.
  • Once SR's D1 pairing fix lands, the (3840,0) claim flips EDID → VERIFIED with serial QI012321D10117 with no plug-in change.

Tests

tests/test_display_claims_win.c (pure C matcher: this rig, twins ambiguous / twins by origin, unknown monitor, table-only, legacy path, descriptor stride, binding store) — wired into the Linux ctest lane next to test_stereo_camera_parse; also passes under MSVC locally.

Not done

  • Nothing in the Windows runtime consumes the serial/displayId yet (M2–M6 are Linux-first).
  • The SR SDK's glog lines (Connected to existing mutex/memory/event) now appear on stderr whenever a headless CLI creates the probe instance — SDK-side noise, not ours.

🤖 Generated with Claude Code

dfattal and others added 3 commits October 7, 2026 19:32
…+B+C: srEnumerateDisplays, routing + binding structs)

2031 = ST-5525-linux-support-jul7 @ 114ef832d (the #440 merge into rc-q3,
identical tree 4b220a89c): one dispatch numbering and one header set for
Windows and Linux. sr_loader.h declares 108 slots on Windows; 1895's are an
exact prefix. APPENDS ONLY -- 106 pfnEnumerateDisplays, 107
pfnDisplayGetRefreshRate (sr_display.h); new SR_TYPE tags 22-26
(SrWeaverRoutingInfo, SrDisplayBindingInfo, routing/binding capabilities,
SrDisplayDescriptor). Older installed runtimes answer
SR_ERROR_FUNCTION_UNSUPPORTED for 106/107.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…(multi-screen M0)

Windows twin of #311. The frozen EDID table already claimed every Leia
panel, but every claim was VERIFIED with an empty serial and no SR identity:
on the two-panel rig (AUO B194 laptop panel = SR device AL, Acer DS1) both
monitors read VERIFIED while SR had authenticated only the AL's FPC.

probe_displays now joins the runtime's monitor list with srEnumerateDisplays
(Windows slot 106, SDK 1.38.0+2031) when the installed SR runtime has it:
  - same EDID (manufacturer, product) AND, when SR marks its location
    desktop-global, the same desktop origin; else the pair when it is unique
    in SR's list. Identical twins with nothing to tell them apart are claimed
    at EDID confidence with no serial and no displayId -- never someone
    else's identity.
  - FPC_VERIFIED -> VERIFIED + FPC serial; EDID_ONLY -> EDID (still beats
    sim_display's FALLBACK); a monitor the table does not know but SR lists
    is claimed anyway (SR's product-code registry is authoritative, the
    table drifts) -- this replaces the "claim the primary monitor" deferral
    whenever SR can enumerate.
  - no enumeration (older SR runtime, service down, compiled out): today's
    behaviour, byte-identical -- table hit + READY = VERIFIED, no serial, and
    the primary-monitor deferral on a table miss.
  - the per-monitor binding (displayId, HMONITOR, device name) is kept in a
    plug-in-private table (leia_win_claims_store/lookup) for the M5/M6
    per-DP binding. Nothing reads it yet. HMONITORs and EDID_ONLY ids are not
    stable across display-config events, so nothing is persisted past the
    cache TTL.

The SR side (leia_sr_v2_common.cpp, DXR_LEIA_HAS_SR_DISPLAY_ENUM): one
process-wide probe SrInstance, created lazily in NON_BLOCKING_CLIENT mode
and never srInitialize'd (rt_EnumerateDisplays needs only a valid instance;
initialise would start trackers), a 2 s cache because the runtime re-runs
probe_displays per registry refresh, dropped on any failure and on plug-in
destroy. srGetRuntimeCapabilities with the routing + binding capability
structs chained is logged once for bring-up. The claim set is logged at
WARN once per change, INFO otherwise.

Measured on the rig (runtime v2.26.0, LeiaSR 1.38.0+2029):
  monitor @ (0,0)    leia-sr VERIFIED serial=QALA2137AL0011 (SR id 0x1, \.\DISPLAY1)
  monitor @ (3840,0) leia-sr EDID     serial=''             (SR id hash,  \.\DISPLAY5)
displayxr-cli selftest PASSED; cube_handle_d3d11_win weaves as before.
Once SR's D1 pairing fix lands the second claim flips to VERIFIED with its
FPC serial with no plug-in change.

Matcher is platform-neutral C, host-tested by tests/test_display_claims_win.c
(wired into the Linux ctest lane next to test_stereo_camera_parse; also
passes under MSVC).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The Linux lane runs each host test by path (no ctest), so the executable
added in the previous commit was built but never executed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@dfattal
dfattal force-pushed the feat/win-probe-displays-sr-enum branch from 5bdfc38 to 982e6db Compare October 8, 2026 02:32
@dfattal
dfattal merged commit 4fc7573 into main Oct 8, 2026
16 checks passed
@dfattal
dfattal deleted the feat/win-probe-displays-sr-enum branch October 8, 2026 02:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant