Skip to content

DisplayXR Runtime v2.7.0

Choose a tag to compare

@github-actions github-actions released this 18 Aug 08:28
· 1067 commits to main since this release

Highlights

One compositor pipeline and Windows-native app switching. The service now runs a single always-on multi-compositor with one display processor per panel — N concurrent IPC apps no longer mean N weavers fighting over the lens — and every IPC app is a first-class window citizen: it appears in the taskbar/Alt-Tab, focusing it gives it the display, launching it shows it, and the spatial shell composes only the apps launched inside it, so you can use any other app over a running shell without closing it.

Features

One always-on pipeline (#964)

  • One compositor pipeline — always-on multi-comp, default presenter policy when no controller is attached, one DP per panel (#964) (#1003)
  • Presenter strategies: service window / app window / client texture / present-owner; the #963 standalone↔workspace seam is gone
  • The shell composes only apps launched under it (#964 Phase A)
  • Park an APP_HWND window when it loses the panel; park (minimize) the service window instead of hiding it while hosted clients live (#964 Phase A)

Windows-native app switching (#1014 / #1017)

  • Focus follows the OS foreground window (#964 Phase A)
  • Launching an app takes the panel — the new-app focus rule (#964 Phase A)
  • Foreground override — reach an IPC app without killing the shell; an outside app can take the panel while the workspace keeps running (#964 Phase A)
  • Match the foreground by process, so engine apps resolve correctly, and restore a parked presenter that takes the panel (#1017)
  • Every hosted client gets its own runtime window — Phase B (#1014)

Panel lease + queued transitions (#965 / #966)

  • Panel lease — one mode owner, deny-with-reason, no latched replay, mode events only after the DP confirms (#961, #761)
  • Mode/geometry transitions applied on the render thread via the S3 command queue (#966); present-owner submit contract (#965) (#1010)

Robustness

  • Detect a lost D3D11 device at every create/present and exit for orderly relaunch; the DP is no longer driven after device removal; sticky present tokens (#1002) (#1009)
  • Append-only display-processor vtable slot set_window — with a matching vendor plug-in the panel re-binds in place on focus changes, with no weaver recreate and no 2D blip (#1008) (#1021). Ships with the paired Leia SR plug-in release.
  • Present watchdog — name the Present call that never returns (#1000)
  • Log which D3D adapter was chosen, and why (#1000)
  • exit()/terminate tripwires — atexit stack logger + SEH guard at every thread entry (#950)
  • Plug-in loader refuses build-tree/worktree DLL paths; NULL-guard begin/end_feature (#952)
  • Runtime-owned window phase-snaps its own drags via the DP vtable (#625) (#997)
  • DXR_QTRACE — an opt-in tracer for the whole head/view pose path
  • Legacy per-client path still available for one release via DXR_LEGACY_STANDALONE=1 (motion-to-photon measured at or better than legacy on both tested app shapes)

Pacing / throughput (#1019)

  • Restore commit backpressure for pipeline clients — legacy WebXR ran unthrottled at ~300 Hz, causing judder and tearing; commits are now paced to the display (DXR_COMMIT_PACE) (#1019)
  • App-window presenters default to frame-latency 2 on cross-adapter boxes (DXR_APP_HWND_LATENCY) — 40 to 60 fps (#1019)

IPC hardening / capacity

  • Explicit client classes — declared at connect, verified by the service, per-class quotas (#960)
  • One focus authority — compositor focused slot canonical, no predict_frame promotion, server-side input focus (#962)
  • Capacity — IPC_MAX_CLIENTS 8 to 32, runtime-admitted cap, reserved controller slot (#959)
  • Server-derived client identity — stop trusting describe_client.pid (#954)
  • Authorize the controller-only workspace mutators (#955)
  • No blocking pipe I/O under global_state.lock; bound client-supplied allocs; check swapchain ids; cap the event queue (#956)
  • Resolve client id to xc off global_state.lock for the window handlers (#957)
  • Per-client [HEALTH] telemetry from the mainloop (#951)

Input

  • Presence poll off client threads; lock the qwerty integrator (#958)
  • Rank providers like display processors — presence walks the hierarchy
  • Hand-tracking source follows provider presence
  • qwerty masquerades as the top provider's profile — hot-swaps go silent
  • Ultraleap idle-disconnect watchdog — stop being a Leap client when no XR consumer polls (#941)
  • Compose-from-copy for controller producers (#925 S5) (#940)

Fixes

  • The #902 Vulkan queue-lock layer can never break vkCreateInstance; its manifest now uses a loader-resolvable path (#1025)
  • Hosted world-absolute view chain keys on the head pose, not workspace_mode — hosted view poses no longer lose standing height under an active workspace (#1014 follow-up) (#1024)
  • Per-client atlas submission atomicity — the single-frame tear window is shut (#1018) (#1020)
  • Pace commits on an absolute deadline, not a duration (#1019)
  • CLIENT_TEXTURE weaves on its own thread — the render thread must never make an unbounded driver call for one client (#1017)
  • Exactly one window feeds qwerty — the active presenter's; freezing pose integration must not bank time (#1016)
  • Every process_atlas site owns the shared DP's state (#1016)
  • Parked windows restore, and a restored presenter keeps presenting (#1014)
  • An UNPLACED slot is not a workspace tile — canvas is its presenter's rect (#1014)
  • Workspace empty state keys on placed slots, not slot count (#964 Phase A)
  • Present-owner transparency on the shared DP; the direct path resets viewport and scissor (#964 follow-ups) (#1013)
  • One DP per HWND, ever — removes an SR WndProc-subclass crash class; late-weave governor samples only while the service window presents (#1012)
  • Truthful comp_multi banners; MULTI_MAX_CLIENTS exhaustion fails the create loudly (#1004) (#1011)
  • Close the runtime-owned window gracefully — ESC ends the session instead of losing it (#999)
  • Restore the app's pipeline state after compositing; drop the pointless CPU fence wait (#996)
  • Standalone/workspace transition dead ends + mainloop shm-push crash (#963)
  • Monkey-test F1/F2 — no visibility demotion of standalone clients, controller policy only once the workspace is active, throttled layer errors, quiet plug-in refresh
  • Monkey-test F3/F4/F5 — workspace enumerate lists only APP/PRESENT_OWNER, one-write log lines, standalone client names
  • cube_hosted_legacy_d3d12_win wrote sRGB into a UNORM-read atlas (#988)
  • WebXR bridge exits on XR_ERROR_INSTANCE_LOST/SESSION_LOST instead of spinning on :9014 (#953)
  • Trampoline thread owns its :9014 listener; startup singleton (#975)
  • u_crash_guard: keep the stack-buffer length local to the Windows branch
  • Atlas capture dropped the bottom half of legacy frames
  • WebXR got a world-absolute camera 1.6 m above its own poses
  • Hosted apps over IPC lost the rig height — cube floated 1.5 m overhead
  • Session end must not install 2D as the service-wide default mode (#762)
  • An exception in the window proc must not kill the service
  • Standalone present strobe — never clear an atlas slot a skipped blit will reuse
  • Input: reconnect after a service drop; coalesce profile-change events
  • Input: arbitrate the hand roles against provider presence, not registration
  • Input: tracked hands ignored navigation and were stranded at the desk
  • Ultraleap: a Leap unplugged while idle never handed the roles back

Docs

  • Service architecture map (as built) + ADR-035 target architecture; Phase-1/2/3 update banners (#954-#959, #960/#961/#962, #963, #964, #966/#965, #1002, #967)
  • comp_multi one-pipeline design note (#967) + docs index entries
  • D-9 focus follows the OS foreground; D-10 scoped, non-exclusive workspace (#964/#1014)
  • One-pipeline design note — motion-to-photon A/B first pass (pipeline vs DXR_LEGACY_STANDALONE=1)
  • ADR-035: record the confirmed decisions — DP stays in-process, wait on #943
  • Corrected stale service/IPC claims found by the architecture review
  • Chrome hot-swap freeze root-caused — three.js XRControllerModelFactory stale cached model; three.js #34264 fixed upstream in r186 (masquerade still load-bearing)

CI / Build

  • Opt CI into sim-input explicitly (DXR_SIM_INPUT=1)

Other

  • chore(versions): bump runtime to v2.6.3

Known issues

  • Present-owner (browser) 4K windows can hitch on cross-adapter machines (#1019).
  • Focused-presenter frame rate degrades with 4-5 concurrent clients (#1022).
  • Under a foreground override the workspace controller receives no frame ticks (its cursor/UI pauses).
  • Transparent/zones apps in forced-IPC mode without a workspace can present a blank window (fix in progress).