Skip to content

Multi-screen M2: segments — per-screen DP instances for a spanning window (was: ADR-015 Phase 3b split-weave) #546

Description

@dfattal

Goal

Implement the runtime side of ADR-015 Phase 3b — let DisplayXR drive multi-monitor 3D configs end-to-end. This is the runtime lane and is not blocked on the vendor SDK (single-display correctness already works; the vendor asks for spanning/eye-tracking are tracked separately — see below).

Already done (Phase 3a + ABI)

  • probe_displays() + struct xrt_display_claim in xrt_plugin.h; registry built in target_plugin_loader.c.
  • comp_dp_factory.h routes the live single-display render through the per-monitor registry (scalar safety net).
  • All create_dp_<api>() factories accept window_handle documented "may be NULL".
  • Plugin-side EDID/SR probe + canvas-offset interlacing phase (D3D11).

Scope of this issue (Phase 3b)

  1. Real per-window monitor resolution — replace the COMP_DP_PRIMARY_MONITOR sentinel in comp_dp_factory.h call sites with the actual monitor id the window is on.
  2. Simultaneous multi-DP per compositor — a compositor holds one DP per display its window overlaps.
  3. Atlas split-weave — when a window spans displays, split the atlas at the display boundary and call each DP's process_atlas() with its sub-region (via the existing canvas_offset_x/y, canvas_width/height params); composite results back into the window output. Put the shared logic in a comp_multi_display helper rather than duplicating across the 5 API compositors.
  4. DP lifecycle on display change — create/destroy DPs as window coverage changes; hold both during a cross-boundary slide.
  5. Primary/secondary HWND model — display with the majority of window area = primary, gets the real HWND; secondaries get window_handle = NULL. Hot-swap primary on majority change.

Start with D3D11 (richest test surface; cube_zones_d3d11_win / windowspace_* apps exist), then generalize the helper.

Depends on (vendor SDK, tracked elsewhere)

Spanning across displays and multi-display eye tracking need vendor SR-SDK changes (NULL-HWND cooperative weaver, multi-FPC trackers). Those are not in scope here — see docs/specs/vendor/multi-display-vendor-requirements.md and the vendor-ask tracker (transferred to displayxr-leia-plugin). Phase 3b structural work (registry resolution, split helper, lifecycle) can land and be exercised with sim_display on multiple monitors before the vendor SDK ships R1/R2.

References

Activity

  1. dfattal commented on Jun 11, 2026

    @dfattal
    CollaboratorAuthor

    Vendor SR-SDK requirements (R1–R4) that the spanning/eye-tracking parts depend on are tracked in DisplayXR/displayxr-leia-plugin#43 (was runtime #111). Phase 3b structural work here is not blocked on them.

  2. changed the title [-]ADR-015 Phase 3b: multi-DP routing + atlas split-weave + primary/secondary HWND lifecycle[/-] [+]Multi-screen M2: segments — per-screen DP instances for a spanning window (was: ADR-015 Phase 3b split-weave)[/+] on Oct 7, 2026
  3. dfattal commented on Oct 7, 2026

    @dfattal
    CollaboratorAuthor

    Re-scoped 2026-10-07 to multi-screen M2 (segments). ADR-047 (PR #1849) supersedes the ADR-015 §3–§4 model this issue described: a spanning window is no longer one atlas split at the display boundary; it is split into per-screen segments, each with its own DP instance, present origin, canvas and (from M3) its own views.

    What stays from the original scope: real per-window monitor resolution (item 1), simultaneous multi-DP per compositor (item 2), DP lifecycle on coverage change (item 4), a shared helper instead of per-backend copies. What changes: item 3 (atlas split-weave) becomes per-segment process_atlas with canvas = segment rect and per-segment set_present_origin (ADR-033); item 5 (primary/secondary HWND) is Windows-only drag snapping, not the model. u_multi_display_compute_slices survives as the segment-rect math.

    M2 gate: a cube_handle_vk_linux window dragged across eDP↔DS1 on ds1-linux is anaglyph on both halves (sim_display DP per segment, per-instance sim state, set_present_origin on sim), no 2D band. DP factory ABI gains a screen binding (ABI bump, ADR-020 append rule). Depends on M0 (#69 task list). Plan: docs/roadmap/multi-screen.md.

  4. dfattal commented on Oct 7, 2026

    @dfattal
    CollaboratorAuthor

    Status 2026-10-07: M2 (#1853, 4a521aa) and M3 (#1854, 785396f) are on main. Delivered for Vulkan on X11/XWayland: per-screen segment DPs via the append-only create_dp_vk_for_screen slot (item 2), per-segment process_atlas with canvas = segment + viewport/scissor + set_present_origin (re-scoped item 3), DP lifecycle with hysteresis and a deferred retire list (item 4), the shared comp_segments helper, per-segment views + XrViewDisplayBindingsDXR, mixed-vendor segments, DXR_SCREEN_PLUGIN per-screen pin (#793 phase 3 mechanism). Human-verified on ds1-linux (Leia DS1 + sim eDP).

    Still open here: item 1 (COMP_DP_PRIMARY_MONITOR call sites in the D3D11 service / GL paths), the other graphics APIs and Windows (M6), native-Wayland segments (window-geometry extension must report the window's monitor — docs/specs/runtime/wayland-window-geometry.md §5), the IPC/service path (never segments), hotplug re-enumeration. Plan: docs/roadmap/multi-screen.md.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions