Skip to content

Local 2D/3D zones: per-window 3D without switching the whole screen #224

@dfattal

Description

@dfattal

Tracking issue for the local 2D/3D zones design. Full spec: docs/roadmap/local-3d-zones.md (commit 47f0dcb).

Problem

Today's switchable-lens displays are globally 2D or globally 3D. Any client requesting 3D pins the whole panel to 3D, which forces 3D apps into fullscreen or "the whole desktop looks distorted while a small 3D window is open."

Goal: an app rendering a normal Win32 window can have its window region in 3D while the rest of the desktop stays 2D — without changing how DWM composes, and without requiring any shell to mediate.

Approach

App pre-weaves into its own swap chain (unchanged). Runtime publishes a screen-space binary 3D-zone mask to the display processor each frame via new DP vtable methods. Vendor's DP translates that into whatever hardware zone mechanism it supports — including the degenerate 1×1 case that maps cleanly to today's global on/off.

Vendor-agnostic: any vendor implementing the DP vtable additions can participate. No vendor-specific SDK or service architecture is mandated.

Phasing

  • Phase 0: DP vtable additions land in xrt_display_processor (get_local_zone_caps, create/publish/clear/destroy_local_zone_mask). First-vendor DP implements with zone_grid = 1×1 (collapses to today's global on/off). Validates end-to-end plumbing on existing hardware.
  • Phase 1: Runtime ships XR_EXT_local_3d_zone with the three tiers (whole-window / rect-list / render-target). Per-frame Z-order occlusion subtraction, HWND screen-rect mapping, fallback to legacy request_display_mode when the DP doesn't implement the new methods.
  • Phase 2: First per-zone hardware lands (any vendor). Same client code now produces per-window 3D zones; runtime changes confined to capability reporting.
  • Phase 3: DisplayXR Shell adopts the same API — becomes one mask publisher among many. No shell-specific DP path required.

Open questions to resolve before Phase 1

  • Mask resolution defaults (suggested window/8 clamped [16..1024]).
  • Update cadence: runtime soft-caps via max_update_hz, or pass through and let vendor coalesce?
  • Hysteresis at zone boundaries — vendor's job, but document expectation.
  • Hardware cursor over 3D zones: accept artifact, or carve a 2D rect around GetCursorPos()?
  • Sub-pixel screen-rect to zone-grid alignment — leave loose (OR rule is conservative) or tighten?

Out of scope

  • Shell-mode generalization (covered by Phase 3 once the underlying primitives ship).
  • macOS / Android (the per-frame Z-order pass is Win32-specific; other platforms can follow once a per-zone display ships there).
  • Vendor implementation specifics — each vendor's DP is their own project.

Related

  • ADR-014 (shell owns rendering mode) — generalizes; shell becomes one mask publisher.
  • XR_EXT_display_info — candidate place to surface localZoneCapable + grid dimensions to apps that don't take the full extension.
  • docs/guides/vendor-integration.md — to be extended with the new vtable methods.

Metadata

Metadata

Assignees

No one assigned

    Labels

    architectureArchitectural design and structural changesdesign-neededNeeds design discussion before implementationenhancementNew feature or requestextensionOpenXR extension workfutureFuture work, not immediate prioritywindowsWindows platform

    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