refactor(capture): migrate atlas capture to xrCaptureAtlasEXT [#396 W6]#141
Open
dfattal wants to merge 1 commit into
Open
refactor(capture): migrate atlas capture to xrCaptureAtlasEXT [#396 W6]#141dfattal wants to merge 1 commit into
dfattal wants to merge 1 commit into
Conversation
Migrate the plugin's 'I'-key screenshot from app-side GPU readback to the
runtime-owned xrCaptureAtlasEXT (XR_EXT_atlas_capture). A live OpenXR session
now hands the runtime a path prefix; the runtime reads back the compositor's
own composited atlas and writes "<prefix>_atlas.png". The plugin no longer
does an AsyncGPUReadback or a hidden-camera Kooima re-render for live sessions.
- native~/displayxr_extensions.h: vendor the XR_EXT_atlas_capture types
(XrAtlasCaptureInfoEXT/ResultEXT, XrAtlasCaptureStageEXT, PFN_xrCaptureAtlasEXT,
struct-type values, path-max).
- native~/displayxr_hooks.{cpp,h}: resolve s_pfn_capture_atlas via the existing
s_next_gipa chain (mirrors xrSetSharedTextureOutputRectEXT); add exported
displayxr_capture_atlas(prefix, stage).
- Runtime/DisplayXRNative.cs + DisplayXRFeature.cs: opt into the extension,
add CaptureAtlas(pathPrefix, projectionOnly=true) P/Invoke wrapper.
- Runtime/DisplayXRScreenshot.cs: gut BeginCapture/CaptureOnDemand/s_CaptureCam/
GetStereoMatrices/FlipViewZ for the live path; rewire Capture() to compute the
numbered "<stem>-<N>_<cols>x<rows>" prefix (mirrors the demos'
MakeCaptureAtlasPrefix) and call CaptureAtlas. Flash overlay + filename
numbering kept. The editor-preview _OnAtlasReady readback path is unchanged
(no runtime OpenXR session in pure-editor preview — out of scope).
native~/displayxr_readback.{cpp,h} untouched. The 'I'-key binding in
Samples~/DisplayXRInputController.cs is unchanged.
Native DLL builds + links clean (displayxr_capture_atlas export verified via
dumpbin). The C# was not compiled here (no headless Unity Editor) — it mirrors
the existing RequestDisplayMode C#->native flow and needs Unity Editor batchmode
verification.
Resolves #140.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Migrate the plugin's
I-key atlas/screenshot capture from app-side GPU readback to the runtime-ownedxrCaptureAtlasEXT(XR_EXT_atlas_capture). W6 of #396 (unified capture). Resolves #140.A live OpenXR session now hands the runtime a path prefix; the runtime reads back the compositor's own composited atlas and writes
<prefix>_atlas.png. The plugin no longer does anAsyncGPUReadbackor a hidden-camera Kooima re-render for live sessions — and the runtime can now capture the true post-compose atlas (window-space / quad layers) which the old swapchain readback physically couldn't see.Three layers
native~/displayxr_extensions.h— vendor theXR_EXT_atlas_capturedefs (XrAtlasCaptureInfoEXT/ResultEXT,XrAtlasCaptureStageEXT,PFN_xrCaptureAtlasEXT, struct-type values 1000999120/121, path-max 256), matching the existing in-file style. Source of truth:displayxr-runtime/.../XR_EXT_atlas_capture.h.native~/displayxr_hooks.{cpp,h}—static PFN_xrCaptureAtlasEXT s_pfn_capture_atlas, resolved via the existings_next_gipa(s_instance, "xrCaptureAtlasEXT", &fn)chain at the same call site asxrSetSharedTextureOutputRectEXT. New exportdisplayxr_capture_atlas(prefix, stage)buildsXrAtlasCaptureInfoEXT(strncpy prefix, cap 255) and calls the runtime, returning 1 onXR_SUCCEEDED.Runtime/DisplayXRFeature.cs—"XR_EXT_atlas_capture"added toExtensionStrings;CaptureAtlas(string pathPrefix, bool projectionOnly = true)guarded onm_HooksInstalledlikeRequestDisplayMode.Runtime/DisplayXRNative.cs—[DllImport] displayxr_capture_atlas([MarshalAs(LPStr)] string, int)neardisplayxr_request_display_mode.Runtime/DisplayXRScreenshot.cs— guttedBeginCapture/CaptureOnDemand/s_CaptureCam/EnsureCaptureCamera/GetStereoMatrices/FlipViewZfor the live path.Capture()now computes the numbered<stem>-<N>_<cols>x<rows>prefix (mirrors the demos'MakeCaptureAtlasPrefix; number against..._atlas.png, return prefix without extension) and callsDisplayXRFeature.CaptureAtlas(prefix, true). Flash overlay + filename numbering kept.Scope notes
_OnAtlasReady/displayxr_standalone_is_running()path left fully intact (it still encodes app-side — there is no runtime OpenXR session in pure-editor preview). The app-sideBeginCapturereadback is kept only for that path.native~/displayxr_readback.{cpp,h}untouched (unrelated macOS offscreen preview).Samples~/.../DisplayXRInputController.csI-key binding untouched (it callsDisplayXRScreenshot.Capture()).projectionOnly = true(matches the native test apps / demos).Build / verify
displayxr_capture_atlasexport confirmed viadumpbin /exports. CommittedRuntime/Plugins/Windows/x64/displayxr_unity.dllrebuilt.RequestDisplayModeC#→native flow; needs Unity Editor batchmode (BuildScript.BuildWindows64) + a liveI-press test against adisplayxr-unity-test*project.🤖 Generated with Claude Code