Skip to content

feat(weave): a present-owner's element on screen 2 gets screen 2's views; cheap split signal - #1927

Merged
dfattal merged 1 commit into
mainfrom
feat/present-owner-per-screen-views
Oct 11, 2026
Merged

dfattal merged 1 commit into
mainfrom
feat/present-owner-per-screen-views

Conversation

@dfattal

@dfattal dfattal commented Oct 11, 2026

Copy link
Copy Markdown
Collaborator

Refs DisplayXR/displayxr-browser-pvt#272

What

This is the runtime follow-up to #1913 for the browser's multi-screen look-around (ADR-047 Amendment 4 addendum).

1. An element on one screen gets that screen's views. The browser renders no 3D itself. Each inline-3D element's views come from a zone-scoped xrLocateViews with XR_DXR_view_rig (browser patch 0036). The service frames that locate in ipc_try_get_sr_view_poses. Until now it always used the session DP's eyes and the window relative to the primary screen.

Now, before the zone rebase, the server asks comp_d3d11_service_get_zone_weave_screen whether the element lies wholly on a non-primary screen of a window woven per screen. If it does:

  • the window metrics become the whole window relative to that screen (u_weave_segment_window_metrics);
  • the eyes, for both the render pair and the XrViewDisplayRawDXR raw channel, become that screen's eyes, predicted at the locate from its segment DP;
  • the nominal viewer becomes that screen's.

The usual zone rebase then places the element on that screen's physical rectangle. The Kooima and rig math are unchanged.

What keeps the primary's views, as before:

  • A straddling element. One pixel across the seam is enough. Its parts are still woven per screen; per-part views need the web API in browser-pvt#272.
  • An element on the primary screen.
  • Any window on one screen. No per-screen table exists, so the lookup returns before anything changes.

The table follows the window, not the session. The browser locates from its browser-process session and weaves from its GPU-process session, and both are bound to its top-level window. The lookup takes the locating client's own fresh weave table (published within the last 250 ms). If there is none, it takes the table of any present-owner whose weave_hwnd is the same window. The first pass holds clients_mutex only. render_mutex is taken only for an element that is actually re-framed, to read that screen's fresh eyes. A one-screen window never waits on the render thread.

2. Cheap split signal. weave_submit's reply gains a trailing segment_count: the count of the table that submit published, read with comp_d3d11_service_weave_segment_count. It is appended the way the v12 weave_submit_dmabuf fields were, since the git-tag gate refuses a skewed client/service pair. oxr_weave.c fetches weave_get_segments for a chained XrWeaveOutputRectPartsDXR only when that count is non-zero (u_weave_segments_fetch_needed). A v19 caller therefore pays no extra round trip for a window on one screen, which includes every window on a single-screen box. weave_submit_dmabuf is untouched; desktop Linux is never segmented.

3. Pure helpers in u_weave_rect_parts.h:

  • u_weave_rect_single_segment
  • u_weave_zone_screen_segment
  • u_weave_segment_window_metrics: the same arithmetic as oxr_segment_views_whole_window_metrics, cross-checked by a test. It lives in aux because the IPC server cannot link the state tracker.
  • u_weave_segments_fetch_needed

Docs:

  • ADR-047: an Amendment 4 addendum subsection.
  • XR_DXR_weave.md §5g: new Cost and Runtime-built views (XR_DXR_view_rig) paragraphs.
  • XR_DXR_display_zones.md §3.3: a multi-screen note on zone-scoped locates.
  • comp-segments.md § Present-owners.
  • The stale "never a service session" doc comment on oxr_segment_views_set_capacity is refreshed.

There is no extension revision: the locate API is unchanged and the reply field is internal to the wire.

Why

On a box with two 3D panels, an inline-3D element sitting wholly on the second panel was rendered from the primary panel's viewer and framed against the primary panel's rectangle. #1913 already wove it with the right lattice; this fixes the wrong camera. The second part removes the per-submit synchronous weave_get_segments round trip that browser PR #273 flagged on Viz's present thread for one-screen windows.

Tests

  • scripts\build_windows.bat build: clean.
  • ctest -C Release: 111/114 pass. The 3 failures are the known-environmental tests_oxr_view_space_mode_floor, _pinned and _floor_off.
  • tests_weave_segments: 15 cases, 197 assertions (8 new, prefixed element views:). The new cases cover:
    • An element wholly on screen 2 gets screen 2's eyes and nominal viewer. Its rebased canvas is the element's on-screen rect on screen 2 (it matches u_weave_rect_parts' screenRect) at screen 2's pitch. The primary framing was one panel off.
    • A straddling element keeps the primary's framing (-1), including a 1 px sliver, while an element flush against the seam is on the primary.
    • An element on the primary of a split window keeps the session framing.
    • A window on one screen: count 0, no re-frame, and u_weave_segments_fetch_needed is false (also false for a legacy single-rect submit and a corrupt count).
    • A window wholly on screen 2 (count 1) frames every element from screen 2.
    • A resize in flight, or a screen of unknown size, keeps the session framing.
    • u_weave_segment_window_metrics is byte-equal to oxr_segment_views_whole_window_metrics for every segment of two layouts, including a screen at negative desktop x.
    • The ipc_weave_submit_reply.segment_count field trails eyes and fits IPC_BUF_SIZE.
  • tests_ipc_proto.py: 15 tests OK. A new case pins weave_submit's out args as [..., "eyes", "segment_count"] and weave_submit_dmabuf as unchanged.
  • Not run on panels. No service, no Program Files, no registry were touched.

Rig recipe (two 3D panels side by side, primary on the left)

The browser is the one from browser-pvt #273 (patch 0400, which chains XrWeaveOutputRectPartsDXR).

  1. Push this build with scripts/push-runtime-pf.sh (it restarts the service non-elevated). Register the dev Leia plug-in if needed.
  2. Launch the DisplayXR Browser from fix(#265): drop hardcoded Leia EDID lookup from comp_d3d11_window.cpp #273 with --log-file, and open a page with two inline-3D elements, for example two scene cards side by side.
  3. Size and place the window so that it straddles the seam, with element A wholly on the primary panel and element B wholly on the second.
    • Browser log: [DisplayXR][multi-screen] segments=2 parts=2, one part per element.
    • Service log, once: multi-screen: element (x,y wxh) wholly on screen 0x… — views from that screen's eyes and geometry (ADR-047 Amendment 4 addendum).
  4. By eye, on the second panel: B looks around from your position in front of the second panel. Move your head in front of panel 2 and B's parallax follows. Before this PR, B's parallax followed panel 1's tracker and was skewed by one panel width. A on panel 1 is unchanged.
  5. Drag B's page content (or the window) so that B straddles the seam. B now renders from the primary's views on both halves (expected; browser-pvt#272) while staying woven per screen. Drag it fully onto panel 2 and its own views come back.
  6. Single-screen check: drag the whole window onto the primary panel. The browser log goes to segments=0. From then on the submit reply's segment_count is 0 and the state tracker skips weave_get_segments; nothing logs this per frame, and it is covered by the unit test. On a one-screen box the call is never sent.

Open questions

🤖 Generated with Claude Code

@dfattal
dfattal requested a review from a team as a code owner October 11, 2026 02:21
…ews; cheap split signal

ADR-047 Amendment 4 addendum, the runtime half of displayxr-browser-pvt#272.

- A zone-scoped xrLocateViews (XR_DXR_view_rig + XrDisplayZoneDXR) of a
  present-owner whose window is woven per screen is framed server-side
  from the screen holding the WHOLE element when that is a non-primary
  screen: its eyes (predicted at the locate from its segment DP), its
  nominal viewer, and the element placed on its physical rectangle.
  A straddling element keeps the primary's views (per-part views need
  a web API, browser-pvt#272); an element on the primary and every
  window on one screen are framed exactly as before.
- The table follows the window, not the session: the browser locates
  from its browser process and weaves from its GPU process, so the
  lookup (comp_d3d11_service_get_zone_weave_screen) takes the locating
  client's own fresh weave table, else that of any present-owner weaving
  the same HWND. clients_mutex only; render_mutex just for a re-framed
  element.
- weave_submit's reply gains a trailing segment_count; the state tracker
  fetches weave_get_segments for a chained XrWeaveOutputRectPartsDXR only
  when it is non-zero, so a window on one screen costs a v19 caller no
  extra round trip.
- Pure helpers in u_weave_rect_parts.h (u_weave_zone_screen_segment,
  u_weave_segment_window_metrics, u_weave_segments_fetch_needed), unit-
  tested in tests_weave_segments; proto test pins the trailing field.

Refs DisplayXR/displayxr-browser-pvt#272

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dfattal
dfattal force-pushed the feat/present-owner-per-screen-views branch from 8ccd33d to 8d78c76 Compare October 11, 2026 06:24
@dfattal
dfattal merged commit f0b5960 into main Oct 11, 2026
42 checks passed
@dfattal
dfattal deleted the feat/present-owner-per-screen-views branch October 11, 2026 06:40
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