Skip to content

[Leia SR SDK] Add EXTERNAL_ROUTING mode for multi-display integration #111

@dfattal

Description

@dfattal

Background

DisplayXR is implementing multi-display vendor DP routing (ADR-015). In a multi-display setup, DisplayXR needs to control which display processor is instantiated for which monitor. The Leia SR SDK currently handles multi-monitor detection internally, which conflicts with DisplayXR's routing.

Problem: When a machine has Monitor A (Leia 3D) and Monitor B (another vendor or sim_display), DisplayXR must route the correct DP to each monitor. The Leia SDK's internal monitor detection (getDrawRegions(), canWeave(), polling threads, installCustomWindowProc()) interferes because:

  • The SDK's WndProc hook conflicts with DisplayXR's window management
  • Background polling threads create race conditions with DisplayXR's routing decisions
  • canWeave() may return false when DisplayXR has already guaranteed the window is on a Leia display
  • Developers cannot force sim_display on a Leia-connected monitor for testing

What We Need

A new initialization mode (EXTERNAL_ROUTING or SR_WEAVER_FLAG_EXTERNAL_ROUTING) that, when set at weaver creation time:

1. Disable monitor polling threads

The two background threads (pollingLoopMonitors, pollingLoopFPCs) must not be spawned. DisplayXR will notify the SDK of relevant display changes via existing APIs or a new callback.

2. Skip installCustomWindowProc()

The SDK must NOT subclass the application's window procedure to intercept WM_WINDOWPOSCHANGING for phase snapping. DisplayXR handles window positioning.

3. Always weave (skip canWeave checks)

canWeave() / canWeaveInternal() should always return true (or the equivalent). DisplayXR guarantees it will only create a Leia DP instance for windows that are actually on a Leia display.

4. Skip getDrawRegions() splitting

Treat the full window client area as a single 3D region. DisplayXR provides the correct canvas region via the process_atlas() parameters (canvas_offset_x/y, canvas_width/height).

5. Backward compatible

No flag = current behavior. Existing integrations are unaffected.

Why This Is Needed

  • DisplayXR may need Leia weaving on monitor A and sim_display passthrough on monitor B. The SDK cannot detect or know about non-Leia monitors; only DisplayXR has the full picture.
  • When a window moves from a Leia display to a non-Leia display, DisplayXR destroys the Leia DP and creates a sim_display DP. If the SDK is also tracking window position, there will be race conditions.
  • For development, developers need to force sim_display on a Leia-connected monitor without the SDK auto-detecting and weaving.

Suggested API

// Option 1: Flag at weaver creation
WeaverErrorCode CreateDX11Weaver(SRContext* context,
                                 ID3D11DeviceContext* d3d11Context,
                                 HWND window,
                                 DWORD flags,          // NEW: SR_WEAVER_FLAG_EXTERNAL_ROUTING
                                 IDX11Weaver1** weaver);

// Option 2: Flag on context
sr::SRContext context(sr::SRContext::Params()
    .setFlag(SR_FLAG_EXTERNAL_DISPLAY_ROUTING));

Acceptance Criteria

  • When EXTERNAL_ROUTING is set, no background threads are spawned for monitor polling
  • When EXTERNAL_ROUTING is set, installCustomWindowProc() is not called
  • When EXTERNAL_ROUTING is set, the weaver always produces interlaced output (no canWeave check)
  • When EXTERNAL_ROUTING is set, getDrawRegions() returns a single region covering the full window
  • Existing behavior (no flag) is unchanged for backward compatibility
  • Unit test demonstrating the flag works

Key SDK Files

File What needs to change
modules/DimencoWeaving/sr/weaver/WeaverBaseImpl.h Add flag field, conditional thread/WndProc setup
modules/DimencoWeaving/sr/weaver/WeaverBaseImpl.ipp Guard pollingLoopMonitors, pollingLoopFPCs, installCustomWindowProc, canWeaveInternal, getDrawRegions
modules/srDirectX/dxweaver/sr/weaver/dx11weaver.h Expose flag in constructor/factory
modules/srDirectX/dxweaver/sr/weaver/dx12weaver.h Expose flag in constructor/factory

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions