Skip to content

feat(multi-screen): per-part zone views for present-owners + painted-partition weave crop (XR_DXR_weave v20) - #2018

Draft
dfattal wants to merge 1 commit into
feat/zone-locate-per-screenfrom
feat/zone-parts-present-owner
Draft

dfattal wants to merge 1 commit into
feat/zone-locate-per-screenfrom
feat/zone-parts-present-owner

Conversation

@dfattal

@dfattal dfattal commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #2011 (base feat/zone-locate-per-screen). It adds XrDisplayZonePartsDXR for XR_DXR_weave present-owners (the DisplayXR Browser) and the painted-partition weave crop. Runtime side of DisplayXR/displayxr-browser-pvt#272. Design: docs/roadmap/multi-screen.md § 8; ADR-047 Amendment 10.

Why a second PR

A present-owner's element locates are framed by the service (ipc_try_get_sr_view_poses), because its bound window's per-screen table lives there and the browser locates in one process and weaves in another. Its parts therefore need the IPC wire and the service. #2011's client-side path cannot reach them.

IPC (append-only; versioned by the u_git_tag client↔service gate)

  • ipc_view_rig_info::zone_part: 0 asks for the zone's one set; k + 1 asks for part k.
  • ipc_info_locate_views_rig gains zone_part_count, zone_parts_generation, zone_part_display_id[], zone_part_rect[] (zone-relative) and zone_part_framed.
  • ipc_arg_weave_submit::painted_generation (u64; 848 B, so the dma-buf call is 988 of 1024).
  • The session_locate_views_rig reply and message are static_asserted ≤ IPC_BUF_SIZE, and the tests pin the append order.

Flow: the zone's own locate returns the one set plus the parts list. The client then makes one more session_locate_views_rig call per part. Those extra calls happen only for a straddling zone and stay within the same DXR_ZONE_PARTS_MAX budget.

Service

  • comp_d3d11_service_get_zone_weave_table replaces get_zone_weave_screen. It returns the present-owner's table and which segment frames this locate: part k's screen, or the element's majority screen. Fresh eyes are fetched only for a non-primary framing segment, as before.
  • A part is framed in its screen's own space: u_weave_segment_window_metrics rebased to the part, with that screen's eyes (the session's own on the primary) and its nominal viewer. The display rig's share and offset come from u_segment_layout over the parts. The test asserts that this gives the same eye-relative canvas and rig scale as the client path in feat(multi-screen): per-part views for a straddling zone (XrDisplayZonePartsDXR, display_zones v4) + one majority rule #2011.
  • The per-segment placement math moved to aux (util/u_segment_layout.h) so the server can share it; oxr_segment_* keep their names.

Weave: crop where it was painted (XR_DXR_weave v20)

XrWeaveSubmitPaintedPartitionDXR { uint64_t zonePartsGeneration; } (type 1004999293, registry updated, spec § 5h + history row) is chained on the submit. The service keeps the partitions of the last tables it published, keyed by generation (comp_segments_content_from_metrics + a content ring). weave_seg_record crops each screen's input at the painted seam and places the output at the live one: the #1883 rule on the weave path. A value of 0, or an unknown generation, keeps the live seam, so pre-v20 behaviour is unchanged.

Tests

tests/tests_weave_segments.cpp adds three cases:

  • the service's per-part canvas equals the client's, in two layouts (equal pitch and half pitch);
  • the wire fields are appended and fit;
  • a weave painted against an older table is cropped at the painted seam (520 px), not at the live one (514 px).

I built it standalone with MSVC and ran it: 27 cases, 2679 assertions, all pass. oxr_session.c, oxr_weave.c, ipc_client_compositor.c, ipc_server_handler.c and comp_d3d11_service.cpp compile locally with MSVC. There was no hardware run, because the panels were in use on the shared box. This path needs a browser build before it can be seen on a panel.

What the browser (browser-pvt#272) needs

  1. Chain XrDisplayZonePartsDXR on each element's zone-scoped xrLocateViews (gate on XR_DXR_display_zones ≥ 4).
  2. When partCountOutput ≥ 2, expose each part as an extra view pair with a sub-viewport. Render part p's views into p.rect of each eye's half of the element's side-by-side submission.
  3. Chain XrWeaveSubmitPaintedPartitionDXR{generation} on the weave submit (XR_DXR_weave ≥ 20). No gate is needed to send it.

🤖 Generated with Claude Code

…partition weave crop (XR_DXR_weave v20)

Stacked on #2011. A present-owner's element locates are framed by the
service (ipc_try_get_sr_view_poses), so XrDisplayZonePartsDXR needs the
service for them:

- Wire (append-only, u_git_tag gate): ipc_view_rig_info::zone_part
  (k + 1 = locate part k); ipc_info_locate_views_rig gains the zone's
  parts (count, table generation, screen ids, zone-relative rects) and
  zone_part_framed. Reply/message sizes static_asserted <= IPC_BUF_SIZE.
- Service: comp_d3d11_service_get_zone_weave_table (replaces
  get_zone_weave_screen) returns the present-owner's table and the
  segment framing this locate: part k's screen, or the element's majority
  screen. The server frames a part in its screen's own space
  (u_weave_segment_window_metrics rebased to the part, that screen's
  eyes; the session's own on the primary) with the rig share and offset
  from u_segment_layout over the parts.
- Client: the zone's locate stashes the parts; locate_zone_parts_ipc asks
  for each part with a server-framed override (cseg = NULL), side
  effects off, under the same DXR_ZONE_PARTS_MAX budget.
- The per-segment placement math moves to aux (util/u_segment_layout.h)
  so the server shares it; oxr_segment_* keep their names.
- XR_DXR_weave v20: XrWeaveSubmitPaintedPartitionDXR (type 1004999293)
  carries the table generation a submit's views were painted with; the
  service keeps the last tables' partitions by generation
  (comp_segments_content_from_metrics + a content ring) and
  weave_seg_record crops each screen's input there (#1883 on the weave
  path). 0 / unknown = the live seam.

Tests: the service's per-part canvas equals the client's, the wire
fields are appended, and a weave painted against an older table is
cropped at the painted seam.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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