[visionOS] Introduce Connected Volumetric Scenes
Component: WebKit visionOS model element / Spatial Portal | a216b77
LayoutTests/model-element/volumetric/resources/volumetric-utils.js
LayoutTests/model-element/volumetric/volumetric-scene-api-disabled.html
On visionOS, <model> content is rendered by a separate ModelProcess (RealityKit). WebContent holds only a player proxy and a layer hosting context, which the UI process composites into the page. A spatial: portal element groups child models behind a SpatialPortalController. Presenting in a separate volumetric window means the layer hosting context, normally claimed by the page, is handed to a new UIScene the UI process creates, and that scene must be matched back to the request that asked for it.
This commit adds experimental, off-by-default Connected Volumetric Scenes. requestVolumetricScene() and exitVolumetricScene() are exposed on Element for spatial: portal elements and bare <model> elements, and the model's content is presented in a separate volumetric window while the page stays live. A new ElementVolumetricScene dispatches to SpatialPortalController or HTMLModelElement. The immersive detach flag is replaced by a unified ModelPresentationMode (inline, immersive, volumetric). New messages carry enter, exit and resize through WebPage, WebPageProxy, ModelProcessModelPlayer and ModelProcessModelPlayerProxy, and the UI process hosts the model process's layer in a new WKPortalVolumetricSceneController.
WebContent UIProcess ModelProcess
│ │ │
│ requestVolumetricScene() │ │
│ (transient activation │ │
│ consumed) │ │
├─ enterVolumetricScene… ─────►│ presentVolumetricScene │
│ (scene-limit check first) │ ├─ create token + pending ctrl │
│ │ ├─ activate UIScene(token) │
│ │ │ └─ scene:willConnect… │
│ │ │ match token → ctrl │
│ │ └─ hostContent(ctx, pid) ──────►│ layer hosted in
│ │ │ volume
│◄─ updateVolumetricSceneSize ─┤ volume size change │
│ │ │
│◄─ volumetricSceneDidClose ───┤ window closed / dismissed │
│ (also on navigation/detach │ │
│ → dismissVolumetricScenes…) │ │
Significance
This is a new web-reachable API that moves a layer hosting context from the page to a UI-process-owned window, adding IPC across WebContent, ModelProcess and UIProcess plus a token-based scene activation flow.
Audit directions
The new surface runs from the DOM API to WebPage, WebPageProxy IPC, PortalPresentationManagerProxy and WKPortalVolumetricSceneController, with parallel messages to ModelProcessModelPlayerProxy.
- Context ownership. Entering releases the page's claim so the new scene can take the layer hosting context. Check that the page, the model process and the UI process cannot hold or use it at the same time, or after release.
- Lifecycle races. Look at element removal, navigation (
dismissVolumetricScenesForDetachedElements,didCommitLoad), document visibility changes,volumetricSceneDidCloseand in-flight enter/reconnect requests for stale element or player references, double-close and state desynchronization across the three processes. - Token matching. Check the activation token in the scene's user activity and the pending-controller registry (
pendingSceneControllers,volumetricSceneTokenFromActivities) for forgery, replay or collision, and whether a scene connecting without a matching request is handled safely. - UI-process validation. A compromised WebContent process could send arbitrary
presentVolumetricScene,reconnectordismissmessages, so the scene limit (at most one per page) and per-page ownership must be enforced in the UI process, along with the context IDs, pid and sizes inVolumetricSceneContentContext. - Size and transform math. Volume-size updates (
updateVolumetricPresentationSize,applyVolumetricPresentationTransform) should be checked for zero, NaN, huge or negative values flowing into the entity transform. - Presentation-mode refactor. Replacing
setDetachedForImmersive/setImmersivePresentationwithModelPresentationModetouches the immersive path too, so look at transitions such as immersive to volumetric, or a portal with a single model, for broken invariants.