Repository navigation
feat(test_apps): macOS cube apps ease 2D/3D through dxr::ModeSwitch::step(); linter INV-2.9 - #1904
Merged
Merged
Conversation
… dxr::ModeSwitch::step()
The runtime switches a rendering mode in one frame (ADR-028) and never ramps
the stereo disparity, so the smooth Windows V-key transition is app-side:
displayxr-common's dxr::ModeSwitch, driven by the Windows-only
XrSessionUpdateModeSwitch. The macOS cube_handle apps carried hand-copied
40-line versions of that glue, and the four macOS zones apps (and the Windows
zones apps and cube_handle_vk_linux) never wired it, so they snapped.
- cube_handle_{metal,vk,gl}_macos: the inline copies become one call to the
new platform-neutral ModeSwitch::step() (displayxr-common#73).
- cube_zones_{metal,vk}_macos, cube_zones_texture_{metal,gl}_macos: adopt it.
Zones carry per-zone ipdFactor (1.0 / 0.6), so the sequencer runs as a 0..1
scale (steadyIpd = 1) that multiplies every rig's ipdFactor.
- test_apps/common/mode_switch_test_knob.h: DXR_TEST_MODE_TOGGLE_S=<s> makes
those apps toggle 3D<->2D through the sequencer every <s> seconds and log
each ramp frame ("ModeSwitch trace:"), so the ramp can be verified without
synthesizing key presses.
- displayxr-common pinned to the #73 commit (GIT_SHALLOW FALSE: a SHA cannot be
fetched shallow). DRAFT: re-pin to the release tag that carries #73 before
merging.
- check_displayxr_app.py INV-2.9 (advisory, per leg): an app that requests
rendering modes but never references ModeSwitch is flagged. Hermetic unit
tests in scripts/tests/test_check_displayxr_app_mode_switch.py, run by
lint.yml. Still flagged after this change: the six Windows zones apps and
cube_handle_vk_linux (not touched here).
- docs: INV-2.9 in displayxr-app-rules.md; XR_DXR_display_info.md
"Smooth transitions are the application's job".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dfattal
force-pushed
the
feat/macos-mode-switch-ease
branch
from
October 12, 2026 03:29
9080639 to
c7fb3b1
Compare
dfattal
marked this pull request as ready for review
October 12, 2026 03:52
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ask
David: "ease 2D<->3D transitions (mode switching) the same way we do on Windows; that's valid for all apps and should be clear in displayxr-common."
What Windows actually does (researched)
The easing is entirely app-side:
oxr_session.c, which is platform-neutral. The runtime-owned V key (qwerty, used by hosted/legacy apps) toggles instantly on every OS.request_display_modeflips the lens on the frame the mode lands (WindowsSwitchableLensHint, macOS/LinuxsrLensEnable/Disable).cube_handle_*apps call displayxr-common'sXrSessionUpdateModeSwitch(), which drivesdxr::ModeSwitch: rampipdFactorto 0, then request 2D; request 3D, then ramp up over 0.18 s.The macOS gap
The macOS
cube_handle_{metal,vk,gl}apps (and the modelviewer demo) already eased, through hand-copied 40-line versions of that glue.XrSessionUpdateModeSwitchtakes the Windows-onlyXrSessionManager, so they could not call it. I measured the copies on sim-display and they work. The real gaps:cube_handle_vk_linux(not touched here, now flagged by the linter).Changes
dxr::ModeSwitch::step()(feat(mode_switch): one-call ModeSwitch::step() for every platform; document the 2D/3D transition contract displayxr-common#73).ipdFactor(1.0 / 0.6), so the sequencer runs as a 0..1 scale (steadyIpd = 1) that multiplies every rig'sipdFactor.test_apps/common/mode_switch_test_knob.h: withDXR_TEST_MODE_TOGGLE_S=<s>, those apps toggle 3D<->2D through the sequencer every<s>seconds and log each ramp frame (ModeSwitch trace:), so the ramp can be checked without synthesizing key presses.ModeSwitchis flagged. Hermetic tests are inscripts/tests/test_check_displayxr_app_mode_switch.py, run bylint.yml.displayxr-app-rules.md; a new section inXR_DXR_display_info.md, "Smooth transitions are the application's job".Merge order (DRAFT)
displayxr-common is pinned to the #73 commit (
5d71fdb,GIT_SHALLOW FALSE, because a SHA cannot be fetched shallow) intest_apps/commonand the 7 touched apps. Merge and tag common #73 first, then re-pin these 8GIT_TAGs to that tag (GIT_SHALLOW TRUE), then merge this PR.Overlap with open drafts:
GIT_TAGlines, so it conflicts trivially. Keep this PR's pin (or the new tag). Itsmain.mmanddisplayxr-app-rules.mdhunks are in other regions.cube_handle_vk_macos/main.mmandcube_zones_vk_macos/main.mmmore than 10 lines away from these hunks; I expect a clean rebase.No
src/changes here, so there is no overlap withoxr_session*orcomp_metal.Evidence (sim-display, anaglyph, built-in display; Apple M1 Pro)
Toggles were scripted with
DXR_TEST_MODE_TOGGLE_Sagainst this branch's runtime and apps.cube_handle_metal_macostrace (every 4th frame):The fresh fetch of the pinned SHA builds (aggregate configure, no local override). Linter: the 7 macOS apps are clean; all 6 tests in the new linter suite pass, and the INV-4.6 suite still passes.
Not run: Windows, Linux, the Leia panel. VK-via-Metal (#1900) is not exercised here:
cube_handle_vk_macosran onvk_native.Eyeball on the Leia panel (David)
Run this branch's built runtime and app with no
XRT_PLUGIN_SEARCH_PATHoverride, so the installed Leia plug-in is discovered. Then drag the window onto the Odyssey and press V, or let the knob toggle every 3 s:Expected: 3D->2D, the depth flattens over about 0.2 s, then the lens drops. 2D->3D, the lens rises on a flat image, then the depth grows in. For an A/B,
cube_hosted_metal_macosuses the runtime-owned V and still switches instantly by design.🤖 Generated with Claude Code