Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: a216b77387a6559dc0d785b487bc3ba7a196049c
https://github.com/WebKit/WebKit/commit/a216b77387a6559dc0d785b487bc3ba7a196049c
Author: Yoel Hawa <[email protected]>
Date: 2026-09-30 (Wed, 30 Sep 2026)
Changed paths:
A LayoutTests/model-element/volumetric/resources/volumetric-utils.js
A
LayoutTests/model-element/volumetric/volumetric-scene-api-disabled-expected.txt
A LayoutTests/model-element/volumetric/volumetric-scene-api-disabled.html
A LayoutTests/model-element/volumetric/volumetric-scene-api-expected.txt
A LayoutTests/model-element/volumetric/volumetric-scene-api.html
A
LayoutTests/model-element/volumetric/volumetric-scene-page-hidden-expected.txt
A LayoutTests/model-element/volumetric/volumetric-scene-page-hidden.html
A LayoutTests/model-element/volumetric/volumetric-scene-portal-expected.txt
A LayoutTests/model-element/volumetric/volumetric-scene-portal.html
A LayoutTests/model-element/volumetric/volumetric-scene-request-expected.txt
A LayoutTests/model-element/volumetric/volumetric-scene-request.html
M LayoutTests/platform/visionos/TestExpectations
M Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml
M Source/WTF/wtf/PlatformEnable.h
M Source/WTF/wtf/PlatformEnableCocoa.h
M Source/WebCore/CMakeLists.txt
M Source/WebCore/DerivedSources-input.xcfilelist
M Source/WebCore/DerivedSources-output.xcfilelist
M Source/WebCore/DerivedSources.make
M Source/WebCore/Headers.cmake
M Source/WebCore/Modules/model-element/HTMLModelElement.cpp
M Source/WebCore/Modules/model-element/HTMLModelElement.h
M Source/WebCore/Modules/model-element/ModelPlayer.cpp
M Source/WebCore/Modules/model-element/ModelPlayer.h
M
Source/WebCore/Modules/model-element/ModelPlayerGraphicsLayerConfiguration.h
A Source/WebCore/Modules/model-element/ModelPresentationMode.h
M Source/WebCore/Modules/model-element/SpatialPortalController.cpp
M Source/WebCore/Modules/model-element/SpatialPortalController.h
M Source/WebCore/Sources.txt
M Source/WebCore/WebCore.xcodeproj/project.pbxproj
A Source/WebCore/dom/Element+VolumetricScene.idl
A Source/WebCore/dom/ElementVolumetricScene.cpp
A Source/WebCore/dom/ElementVolumetricScene.h
M Source/WebCore/page/ChromeClient.h
M Source/WebCore/testing/Internals.cpp
M Source/WebCore/testing/Internals.h
M Source/WebCore/testing/Internals.idl
M Source/WebKit/CMakeLists.txt
M Source/WebKit/Configurations/AllowedSPI.toml
M Source/WebKit/DerivedSources-input.xcfilelist
M Source/WebKit/DerivedSources.make
M Source/WebKit/ModelProcess/cocoa/ModelProcessModelPlayerProxy.h
M Source/WebKit/ModelProcess/cocoa/ModelProcessModelPlayerProxy.messages.in
M Source/WebKit/ModelProcess/cocoa/ModelProcessModelPlayerProxy.mm
M Source/WebKit/Platform/spi/ios/UIKitSPI.h
A Source/WebKit/Shared/VolumetricSceneContentContext.h
A Source/WebKit/Shared/VolumetricSceneContentContext.serialization.in
M Source/WebKit/SourcesCocoa.txt
M Source/WebKit/UIProcess/Model/PortalPresentationManagerProxy.h
M Source/WebKit/UIProcess/Model/PortalPresentationManagerProxy.mm
M Source/WebKit/UIProcess/WebPageProxy.h
M Source/WebKit/UIProcess/WebPageProxy.messages.in
A Source/WebKit/UIProcess/ios/WKPortalVolumetricSceneController.h
A Source/WebKit/UIProcess/ios/WKPortalVolumetricSceneController.mm
M Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm
M Source/WebKit/WebKit.xcodeproj/project.pbxproj
M Source/WebKit/WebKitSwift/RealityKit/WKRKEntity.h
M Source/WebKit/WebKitSwift/RealityKit/WKRKEntity.swift
M Source/WebKit/WebProcess/Model/ModelProcessModelPlayer.cpp
M Source/WebKit/WebProcess/Model/ModelProcessModelPlayer.h
M Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
M Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h
M Source/WebKit/WebProcess/WebPage/WebPage.cpp
M Source/WebKit/WebProcess/WebPage/WebPage.h
M Source/WebKit/WebProcess/WebPage/WebPage.messages.in
M Source/cmake/WebKitFeatures.cmake
Log Message:
-----------
[visionOS] Introduce Connected Volumetric Scenes
https://bugs.webkit.org/show_bug.cgi?id=324527
<rdar://182292336>
Reviewed by Etienne Segonzac.
Introduce connected volumetric scenes for model portals on visionOS,
behind an experimental feature flag and off-by-default.
An element with the `spatial: portal` CSS property, or a bare <model>,
can now present its content in a separate volumetric visionOS window
while the page it came from stays live. ElementVolumetricScene holds the
logic for both element kinds and dispatches to SpatialPortalController
or HTMLModelElement. ModelPresentationMode moves to its own header so
inline, immersive and volumetric presentation are one concept rather
than separate flags.
Entering releases the page's claim on the model's layer hosting context
so the new scene can take it. The UI process activates a volumetric
scene, hosts the model process's layer in it, and reports the volume's
size back to WebCore. Each request carries a token in its user activity
so the connecting scene finds the presentation that asked for it. WebKit
owns the window and also closes it.
* Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml:
* Source/WTF/wtf/PlatformEnable.h:
* Source/WTF/wtf/PlatformEnableCocoa.h:
* Source/cmake/WebKitFeatures.cmake:
* Source/WebCore/CMakeLists.txt:
* Source/WebCore/DerivedSources-input.xcfilelist:
* Source/WebCore/DerivedSources-output.xcfilelist:
* Source/WebCore/DerivedSources.make:
* Source/WebCore/Headers.cmake:
* Source/WebCore/Sources.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebKit/CMakeLists.txt:
* Source/WebKit/DerivedSources-input.xcfilelist:
* Source/WebKit/DerivedSources.make:
* Source/WebKit/SourcesCocoa.txt:
* Source/WebKit/WebKit.xcodeproj/project.pbxproj:
Add the CONNECTED_VOLUMETRIC_SCENE build flag, which requires
SPATIAL_PORTAL and is off by default, and a mock scene preference for
tests.
* Source/WebCore/dom/Element+VolumetricScene.idl: Added.
* Source/WebCore/dom/ElementVolumetricScene.cpp: Added.
(WebCore::eligibleModelElement):
(WebCore::ElementVolumetricScene::presentationMode):
(WebCore::ElementVolumetricScene::setPresentationMode):
(WebCore::ElementVolumetricScene::playerForElement):
(WebCore::ElementVolumetricScene::isPresentedInVolumetricScene):
(WebCore::ElementVolumetricScene::requestVolumetricScene):
(WebCore::ElementVolumetricScene::exitVolumetricScene):
(WebCore::ElementVolumetricScene::volumetricSceneDidClose):
(WebCore::ElementVolumetricScene::documentVisibilityDidChange):
(WebCore::ElementVolumetricScene::presentationModeForTesting):
* Source/WebCore/dom/ElementVolumetricScene.h: Added.
* Source/WebCore/page/ChromeClient.h:
(WebCore::ChromeClient::enterVolumetricSceneForElement):
(WebCore::ChromeClient::exitVolumetricSceneForElement):
(WebCore::ChromeClient::reconnectVolumetricSceneForElement):
The DOM API. requestVolumetricScene() is limited to fully active
top-level documents, as immersive already is, and consumes transient
activation before asking the client to open the scene.
ElementVolumetricScene routes each operation to whichever element kind
owns the player.
* Source/WebCore/Modules/model-element/ModelPresentationMode.h: Added.
* Source/WebCore/Modules/model-element/ModelPlayerGraphicsLayerConfiguration.h:
* Source/WebCore/Modules/model-element/HTMLModelElement.cpp:
(WebCore::HTMLModelElement::visibilityStateChanged):
(WebCore::HTMLModelElement::updatePlayerVisibility):
(WebCore::HTMLModelElement::didFinishLoading):
(WebCore::HTMLModelElement::isVisible const):
(WebCore::HTMLModelElement::modelDidChange):
(WebCore::HTMLModelElement::createModelPlayer):
(WebCore::HTMLModelElement::deleteModelPlayer):
(WebCore::HTMLModelElement::configureGraphicsLayer):
(WebCore::HTMLModelElement::supportsStageModeInteraction const):
(WebCore::HTMLModelElement::ensureImmersivePresentation):
(WebCore::HTMLModelElement::exitImmersivePresentation):
(WebCore::HTMLModelElement::setPresentationMode):
(WebCore::HTMLModelElement::stop):
(WebCore::HTMLModelElement::modelContainerSizeIsEmpty const):
(WebCore::HTMLModelElement::removingSteps):
(WebCore::HTMLModelElement::liveModelPlayer const):
(WebCore::HTMLModelElement::setDetachedForImmersive): Deleted.
* Source/WebCore/Modules/model-element/HTMLModelElement.h:
* Source/WebCore/Modules/model-element/SpatialPortalController.cpp:
(WebCore::SpatialPortalController::prepareForRemoval):
(WebCore::SpatialPortalController::unregisterChildModel):
(WebCore::SpatialPortalController::viewportIntersectionChanged):
(WebCore::SpatialPortalController::portalVisibilityChanged):
(WebCore::SpatialPortalController::documentVisibilityChanged):
(WebCore::SpatialPortalController::liveModelPlayer const):
(WebCore::SpatialPortalController::ensureModelPlayer):
(WebCore::SpatialPortalController::configureGraphicsLayer):
(WebCore::SpatialPortalController::isPortalVisible const):
(WebCore::SpatialPortalController::setPresentationMode):
* Source/WebCore/Modules/model-element/SpatialPortalController.h:
(WebCore::SpatialPortalController::presentationMode const):
Replace the immersive detach flag with a presentation mode, so inline,
immersive and volumetric are one concept. Both element kinds keep their
content loaded while it is presented outside the page, and expose the
live (non-placeholder) player driving it.
* Source/WebCore/Modules/model-element/ModelPlayer.cpp:
(WebCore::ModelPlayer::enterVolumetricPresentation):
(WebCore::ModelPlayer::exitVolumetricPresentation):
(WebCore::ModelPlayer::updateVolumetricPresentationSize):
* Source/WebCore/Modules/model-element/ModelPlayer.h:
* Source/WebKit/WebProcess/Model/ModelProcessModelPlayer.cpp:
(WebKit::ModelProcessModelPlayer::configureGraphicsLayer):
(WebKit::ModelProcessModelPlayer::enterVolumetricPresentation):
(WebKit::ModelProcessModelPlayer::exitVolumetricPresentation):
(WebKit::ModelProcessModelPlayer::updateVolumetricPresentationSize):
* Source/WebKit/WebProcess/Model/ModelProcessModelPlayer.h:
* Source/WebKit/ModelProcess/cocoa/ModelProcessModelPlayerProxy.messages.in:
Carry enter, exit and volume resize down to the player.
* Source/WebKit/ModelProcess/cocoa/ModelProcessModelPlayerProxy.h:
* Source/WebKit/ModelProcess/cocoa/ModelProcessModelPlayerProxy.mm:
(WebKit::ModelProcessModelPlayerProxy::reloadModel):
(WebKit::ModelProcessModelPlayerProxy::modelStandardizedTransformSRT const):
(WebKit::ModelProcessModelPlayerProxy::modelLocalizedTransformSRT const):
(WebKit::ModelProcessModelPlayerProxy::computeTransform):
(WebKit::ModelProcessModelPlayerProxy::didFinishLoading):
(WebKit::ModelProcessModelPlayerProxy::sizeDidChange):
(WebKit::ModelProcessModelPlayerProxy::setEntityTransform):
(WebKit::ModelProcessModelPlayerProxy::updateForCurrentStageMode):
(WebKit::ModelProcessModelPlayerProxy::updateLightingForPresentationMode):
(WebKit::ModelProcessModelPlayerProxy::setPresentationMode):
(WebKit::ModelProcessModelPlayerProxy::applyPresentationTransform):
(WebKit::ModelProcessModelPlayerProxy::applyVolumetricPresentationTransform):
(WebKit::ModelProcessModelPlayerProxy::setGroundingShadowsEnabled):
(WebKit::ModelProcessModelPlayerProxy::enterVolumetricPresentation):
(WebKit::ModelProcessModelPlayerProxy::exitVolumetricPresentation):
(WebKit::ModelProcessModelPlayerProxy::updateVolumetricPresentationSize):
(WebKit::ModelProcessModelPlayerProxy::ensureImmersivePresentation):
(WebKit::ModelProcessModelPlayerProxy::exitImmersivePresentation):
(WebKit::ModelProcessModelPlayerProxy::setImmersivePresentation): Deleted.
* Source/WebKit/WebKitSwift/RealityKit/WKRKEntity.h:
* Source/WebKit/WebKitSwift/RealityKit/WKRKEntity.swift:
(WKRKEntity.receivesImageBasedLight):
(WKRKEntity.providesEnvironmentLighting):
(WKRKEntity.applyIBL(_:)):
(WKRKEntity.removeIBL):
(WKRKEntity.detachImageBasedLight):
(WKRKEntity.setIBLReceiverEnabled(_:)):
(WKRKEntity.setProvidesEnvironmentLighting(_:)):
(WKRKEntity.updateEnvironmentProbe):
(WKRKEntity.setGroundingShadowsEnabled(_:)):
(WKRKEntity.applyGroundingShadows(to:castsShadow:)):
Place and light the entity for a volume rather than an inline box. A
volume takes its lighting from its surroundings rather than the page's
environment map, and an immersive model also provides its map as a probe
so the volumes around it are lit by it. Also refuse immersive for a
portal hosting a single model.
* Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::enterVolumetricSceneForElement):
(WebKit::WebChromeClient::exitVolumetricSceneForElement):
(WebKit::WebChromeClient::reconnectVolumetricSceneForElement):
* Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h:
* Source/WebKit/WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::sharedPreferencesForWebProcess const):
(WebKit::WebPage::didCommitLoad):
(WebKit::WebPage::enterVolumetricSceneForElement):
(WebKit::WebPage::exitVolumetricSceneForElement):
(WebKit::WebPage::reconnectVolumetricSceneForElement):
(WebKit::WebPage::dismissVolumetricScenesForDetachedElements):
(WebKit::WebPage::volumetricSceneDidClose):
(WebKit::WebPage::updateVolumetricSceneSize):
* Source/WebKit/WebProcess/WebPage/WebPage.h:
* Source/WebKit/WebProcess/WebPage/WebPage.messages.in:
Track which element owns a volume, and close it on navigation or detach
rather than waiting for a request that will never come. Refuse a request
past the scene limit before the model process starts presenting it.
* Source/WebKit/Shared/VolumetricSceneContentContext.h: Added.
* Source/WebKit/Shared/VolumetricSceneContentContext.serialization.in: Added.
* Source/WebKit/UIProcess/WebPageProxy.h:
* Source/WebKit/UIProcess/WebPageProxy.messages.in:
* Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::presentVolumetricScene):
(WebKit::WebPageProxy::reconnectVolumetricSceneToContentContext):
(WebKit::WebPageProxy::dismissVolumetricScene):
(WebKit::WebPageProxy::volumetricSceneDidClose):
(WebKit::WebPageProxy::updateVolumetricSceneSize):
* Source/WebKit/UIProcess/Model/PortalPresentationManagerProxy.h:
* Source/WebKit/UIProcess/Model/PortalPresentationManagerProxy.mm:
(WebKit::PortalPresentationManagerProxy::invalidateAllModels):
(WebKit::PortalPresentationManagerProxy::showVolumetricScene):
(WebKit::PortalPresentationManagerProxy::reconnectVolumetricSceneToContentContext):
(WebKit::PortalPresentationManagerProxy::hideVolumetricScene):
(WebKit::PortalPresentationManagerProxy::hideAllVolumetricScenes):
* Source/WebKit/Platform/spi/ios/UIKitSPI.h:
* Source/WebKit/UIProcess/ios/WKPortalVolumetricSceneController.h: Added.
* Source/WebKit/UIProcess/ios/WKPortalVolumetricSceneController.mm: Added.
(pendingSceneControllers):
(volumetricSceneTokenFromActivities):
(-[WKPortalVolumetricSceneDelegate scene:willConnectToSession:options:]):
(-[WKPortalVolumetricSceneDelegate windowScene:shouldCloseForReason:]):
(-[WKPortalVolumetricViewController
viewWillTransitionToSize:withTransitionCoordinator:]):
(-[WKPortalVolumetricViewController viewDidLayoutSubviews]):
(-[WKPortalVolumetricSceneController initWithCloseHandler:]):
(-[WKPortalVolumetricSceneController dealloc]):
(-[WKPortalVolumetricSceneController setVolumeSizeChangedHandler:]):
(-[WKPortalVolumetricSceneController _containerView]):
(-[WKPortalVolumetricSceneController _pointsPerMeter]):
(-[WKPortalVolumetricSceneController _currentVolumeSizeInMeters]):
(-[WKPortalVolumetricSceneController _applyContentPlacement]):
(-[WKPortalVolumetricSceneController updateLayoutForVolumeSize]):
(-[WKPortalVolumetricSceneController hostContentWithContext:pid:]):
(-[WKPortalVolumetricSceneController presentWithCompletion:]):
(-[WKPortalVolumetricSceneController _failPresentation]):
(-[WKPortalVolumetricSceneController _configureWithScene:]):
(-[WKPortalVolumetricSceneController _stopWaitingForScene]):
(-[WKPortalVolumetricSceneController dismissWithCompletion:]):
(-[WKPortalVolumetricSceneController _handleCloseRequest]):
Activate the volumetric scene, host the model process's layer in it, and
report the volume's size back. Each request carries a token in its user
activity so the connecting scene finds the presentation that asked for
it. A page presents at most one volumetric scene at a time.
* LayoutTests/model-element/volumetric/resources/volumetric-utils.js: Added.
(const.requestVolumetricScene.element.internals.withUserGesture):
(const.appendModel):
(const.createPortalWithReadyModel.async test):
*
LayoutTests/model-element/volumetric/volumetric-scene-api-disabled-expected.txt:
Added.
* LayoutTests/model-element/volumetric/volumetric-scene-api-disabled.html:
Added.
* LayoutTests/model-element/volumetric/volumetric-scene-api-expected.txt: Added.
* LayoutTests/model-element/volumetric/volumetric-scene-api.html: Added.
*
LayoutTests/model-element/volumetric/volumetric-scene-page-hidden-expected.txt:
Added.
* LayoutTests/model-element/volumetric/volumetric-scene-page-hidden.html: Added.
* LayoutTests/model-element/volumetric/volumetric-scene-portal-expected.txt:
Added.
* LayoutTests/model-element/volumetric/volumetric-scene-portal.html: Added.
* LayoutTests/model-element/volumetric/volumetric-scene-request-expected.txt:
Added.
* LayoutTests/model-element/volumetric/volumetric-scene-request.html: Added.
* LayoutTests/platform/visionos/TestExpectations:
* Source/WebCore/testing/Internals.cpp:
(WebCore::Internals::volumetricScenePresentationMode):
* Source/WebCore/testing/Internals.h:
* Source/WebCore/testing/Internals.idl:
Enable and add tests.
Canonical link: https://commits.webkit.org/322358@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications