Diff
Modified: trunk/LayoutTests/ChangeLog (261219 => 261220)
--- trunk/LayoutTests/ChangeLog 2020-05-06 08:28:37 UTC (rev 261219)
+++ trunk/LayoutTests/ChangeLog 2020-05-06 09:30:26 UTC (rev 261220)
@@ -1,3 +1,12 @@
+2020-04-29 Sergio Villar Senin <svil...@igalia.com>
+
+ [WebXR] Implement isSessionSupported()
+ https://bugs.webkit.org/show_bug.cgi?id=211187
+
+ Reviewed by Dean Jackson.
+
+ * platform/wpe/TestExpectations: Added some skipped tests that are now passing.
+
2020-05-06 Diego Pino Garcia <dp...@igalia.com>
GTK] Gardening, update expectations and baselines after r261191
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (261219 => 261220)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2020-05-06 08:28:37 UTC (rev 261219)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2020-05-06 09:30:26 UTC (rev 261220)
@@ -1,3 +1,14 @@
+2020-04-29 Sergio Villar Senin <svil...@igalia.com>
+
+ [WebXR] Implement isSessionSupported()
+ https://bugs.webkit.org/show_bug.cgi?id=211187
+
+ Reviewed by Dean Jackson.
+
+ * web-platform-tests/webxr/xrDevice_isSessionSupported_immersive.https-expected.txt: Added.
+ * web-platform-tests/webxr/xrDevice_isSessionSupported_immersive_unsupported.https-expected.txt: Added.
+ * web-platform-tests/webxr/xrDevice_isSessionSupported_inline.https-expected.txt: Added.
+
2020-05-05 Antoine Quint <grao...@apple.com>
Fix animation ordering to make imported/w3c/web-platform-tests/css/css-animations/Element-getAnimations.tentative.html pass
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrDevice_isSessionSupported_immersive.https-expected.txt (0 => 261220)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrDevice_isSessionSupported_immersive.https-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrDevice_isSessionSupported_immersive.https-expected.txt 2020-05-06 09:30:26 UTC (rev 261220)
@@ -0,0 +1,3 @@
+
+PASS isSessionSupported resolves to true when immersive options supported
+
Property changes on: trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrDevice_isSessionSupported_immersive.https-expected.txt
___________________________________________________________________
Added: svn:eol-style
+LF
\ No newline at end of property
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrDevice_isSessionSupported_immersive_unsupported.https-expected.txt (0 => 261220)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrDevice_isSessionSupported_immersive_unsupported.https-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrDevice_isSessionSupported_immersive_unsupported.https-expected.txt 2020-05-06 09:30:26 UTC (rev 261220)
@@ -0,0 +1,3 @@
+
+PASS isSessionSupported resolves to false when options not supported
+
Property changes on: trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrDevice_isSessionSupported_immersive_unsupported.https-expected.txt
___________________________________________________________________
Added: svn:eol-style
+LF
\ No newline at end of property
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrDevice_isSessionSupported_inline.https-expected.txt (0 => 261220)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrDevice_isSessionSupported_inline.https-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrDevice_isSessionSupported_inline.https-expected.txt 2020-05-06 09:30:26 UTC (rev 261220)
@@ -0,0 +1,3 @@
+
+PASS isSessionSupported resolves to true when inline options supported
+
Property changes on: trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrDevice_isSessionSupported_inline.https-expected.txt
___________________________________________________________________
Added: svn:eol-style
+LF
\ No newline at end of property
Modified: trunk/LayoutTests/platform/wpe/TestExpectations (261219 => 261220)
--- trunk/LayoutTests/platform/wpe/TestExpectations 2020-05-06 08:28:37 UTC (rev 261219)
+++ trunk/LayoutTests/platform/wpe/TestExpectations 2020-05-06 09:30:26 UTC (rev 261220)
@@ -1082,6 +1082,9 @@
# WebXR
webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/idlharness.https.window.html [ Pass ]
+webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrDevice_isSessionSupported_inline.https.html [ Pass ]
+webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrDevice_isSessionSupported_immersive.https.html [ Pass ]
+webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrDevice_isSessionSupported_immersive_unsupported.https.html [ Pass ]
# Passing since r259006.
imported/w3c/web-platform-tests/css/css-grid/alignment/self-baseline/grid-self-baseline-changes-grid-area-size-010.html
Modified: trunk/Source/WebCore/ChangeLog (261219 => 261220)
--- trunk/Source/WebCore/ChangeLog 2020-05-06 08:28:37 UTC (rev 261219)
+++ trunk/Source/WebCore/ChangeLog 2020-05-06 09:30:26 UTC (rev 261220)
@@ -1,3 +1,51 @@
+2020-04-29 Sergio Villar Senin <svil...@igalia.com>
+
+ [WebXR] Implement isSessionSupported()
+ https://bugs.webkit.org/show_bug.cgi?id=211187
+
+ Reviewed by Dean Jackson.
+
+ The isSessionSupported() method queries if a given mode may be supported
+ by the UA and device capabilities. Apart from the needed machinery in
+ the webxr Module we're adding an OpenXR implementation of the
+ enumerateImmersiveXRDevices() method required by isSessionSupported().
+
+ The method is not completely implemented as it lacks a few action at its
+ very end, like firing events. They'll be implemented in follow up
+ patches as they require additional changes.
+
+ Some OpenXR runtimes as Monado always enumerate at least one device even
+ if none is connected. This dummy device might interfere with tests
+ execution (as there will be more devices than expected) so we're adding
+ a testMode to WebXRSystem which does not query platform for existing
+ devices.
+
+ Added expected results and unskipped some WPT that are now passing.
+
+ * Modules/webxr/WebXRSystem.cpp:
+ (WebCore::WebXRSystem::ensureImmersiveXRDeviceIsSelected): Asks platform
+ code for the list of attached XR devices and properly set the active
+ immersive device if any.
+ (WebCore::WebXRSystem::isSessionSupported): Partially implemented.
+ (WebCore::WebXRSystem::registerSimulatedXRDeviceForTesting): Set the
+ passed in mock device as either the current active immersive or inline
+ device.
+ (WebCore::WebXRSystem::unregisterSimulatedXRDeviceForTesting): Removes
+ the passed in mock device from the list of immersive devices.
+ * Modules/webxr/WebXRSystem.h:
+ * html/FeaturePolicy.cpp:
+ (WebCore::policyTypeName): Handle XRSpatialTracking.
+ (WebCore::FeaturePolicy::parse): Parse "xr-spatial-tracking".
+ (WebCore::FeaturePolicy::allows const): Handle XRSpatialTracking.
+ * html/FeaturePolicy.h: Added XRSpatialTracking.
+ * platform/xr/PlatformXR.h:
+ (PlatformXR::Instance::immersiveXRDevices const): Keep a list of immersive devices.
+ * platform/xr/openxr/PlatformXR.cpp:
+ (PlatformXR::Instance::Impl::collectSupportedSessionModes): Gather supported session
+ modes for a given device from OpenXR.
+ (PlatformXR::Instance::enumerateImmersiveXRDevices): Collect devices from OpenXR. We
+ are currently asking for HMD devices.
+
2020-05-06 Antoine Quint <grao...@apple.com>
[Web Animations] Coordinate "update animations and send events" procedure across multiple timelines
Modified: trunk/Source/WebCore/Modules/webxr/WebXRSystem.cpp (261219 => 261220)
--- trunk/Source/WebCore/Modules/webxr/WebXRSystem.cpp 2020-05-06 08:28:37 UTC (rev 261219)
+++ trunk/Source/WebCore/Modules/webxr/WebXRSystem.cpp 2020-05-06 09:30:26 UTC (rev 261220)
@@ -28,6 +28,8 @@
#if ENABLE(WEBXR)
+#include "Document.h"
+#include "FeaturePolicy.h"
#include "PlatformXR.h"
#include "RuntimeEnabledFeatures.h"
#include "WebXRSession.h"
@@ -50,15 +52,90 @@
WebXRSystem::~WebXRSystem() = default;
-void WebXRSystem::isSessionSupported(XRSessionMode, IsSessionSupportedPromise&&)
+// https://immersive-web.github.io/webxr/#ensures-an-immersive-xr-device-is-selected
+void WebXRSystem::ensureImmersiveXRDeviceIsSelected()
{
- // When the supportsSession(mode) method is invoked, it MUST return a new Promise promise and run the following steps in parallel:
- // 1. Ensure an XR device is selected.
- // 2. If the XR device is null, reject promise with a "NotSupportedError" DOMException and abort these steps.
- // 3. If the XR device's list of supported modes does not contain mode, reject promise with a "NotSupportedError" DOMException and abort these steps.
- // 4. Else resolve promise.
+ // Don't ask platform code for XR devices, we're using simulated ones.
+ // TODO: should be have a MockPlatformXR implementation instead ?
+ if (UNLIKELY(m_testingMode))
+ return;
+
+ if (m_activeImmersiveDevice)
+ return;
+
+ // https://immersive-web.github.io/webxr/#enumerate-immersive-xr-devices
+ auto& platformXR = PlatformXR::Instance::singleton();
+ bool isFirstXRDevicesEnumeration = !m_immersiveXRDevicesHaveBeenEnumerated;
+ platformXR.enumerateImmersiveXRDevices();
+ m_immersiveXRDevicesHaveBeenEnumerated = true;
+ const Vector<std::unique_ptr<PlatformXR::Device>>& immersiveXRDevices = platformXR.immersiveXRDevices();
+
+ // https://immersive-web.github.io/webxr/#select-an-immersive-xr-device
+ auto* oldDevice = m_activeImmersiveDevice.get();
+ if (immersiveXRDevices.isEmpty()) {
+ m_activeImmersiveDevice = nullptr;
+ return;
+ }
+ if (immersiveXRDevices.size() == 1) {
+ m_activeImmersiveDevice = makeWeakPtr(immersiveXRDevices.first().get());
+ return;
+ }
+
+ if (m_activeImmersiveSession && oldDevice && immersiveXRDevices.findMatching([&] (auto& entry) { return entry.get() == oldDevice; }) != notFound)
+ ASSERT(m_activeImmersiveDevice.get() == oldDevice);
+ else {
+ // TODO: implement a better UA selection mechanism if required.
+ m_activeImmersiveDevice = makeWeakPtr(immersiveXRDevices.first().get());
+ }
+
+ if (isFirstXRDevicesEnumeration || m_activeImmersiveDevice.get() == oldDevice)
+ return;
+
+ // TODO: 7. Shut down any active XRSessions.
+ // TODO: 8. Set the XR compatible boolean of all WebGLRenderingContextBase instances to false.
+ // TODO: 9. Queue a task to fire an event named devicechange on the context object.
}
+// https://immersive-web.github.io/webxr/#dom-xrsystem-issessionsupported
+void WebXRSystem::isSessionSupported(XRSessionMode mode, IsSessionSupportedPromise&& promise)
+{
+ // 1. Let promise be a new Promise.
+ // 2. If mode is "inline", resolve promise with true and return it.
+ if (mode == XRSessionMode::Inline) {
+ promise.resolve(true);
+ return;
+ }
+
+ // 3. If the requesting document’s origin is not allowed to use the "xr-spatial-tracking" feature policy,
+ // reject promise with a "SecurityError" DOMException and return it.
+ auto document = downcast<Document>(scriptExecutionContext());
+ if (!isFeaturePolicyAllowedByDocumentAndAllOwners(FeaturePolicy::Type::XRSpatialTracking, *document, LogFeaturePolicyFailure::Yes)) {
+ promise.reject(Exception { SecurityError });
+ return;
+ }
+
+ // 4. Run the following steps in parallel:
+ scriptExecutionContext()->postTask([this, promise = WTFMove(promise), mode] (ScriptExecutionContext&) mutable {
+ // 4.1 Ensure an immersive XR device is selected.
+ ensureImmersiveXRDeviceIsSelected();
+
+ // 4.2 If the immersive XR device is null, resolve promise with false and abort these steps.
+ if (!m_activeImmersiveDevice) {
+ promise.resolve(false);
+ return;
+ }
+
+ // 4.3 If the immersive XR device's list of supported modes does not contain mode, resolve promise with false and abort these steps.
+ if (!m_activeImmersiveDevice->supports(mode)) {
+ promise.resolve(false);
+ return;
+ }
+
+ // 4.4 Resolve promise with true.
+ promise.resolve(true);
+ });
+}
+
void WebXRSystem::requestSession(XRSessionMode, const XRSessionInit&, RequestSessionPromise&&)
{
PlatformXR::Instance::singleton();
@@ -94,6 +171,7 @@
{
if (!RuntimeEnabledFeatures::sharedFeatures().webXREnabled())
return;
+ m_testingMode = true;
if (device.supports(PlatformXR::SessionMode::ImmersiveVr) || device.supports(PlatformXR::SessionMode::ImmersiveAr)) {
m_immersiveDevices.append(makeWeakPtr(device));
m_activeImmersiveDevice = m_immersiveDevices.last();
@@ -108,10 +186,14 @@
return;
ASSERT(m_immersiveDevices.contains(device));
m_immersiveDevices.removeFirst(device);
+ if (m_activeImmersiveDevice == device)
+ m_activeImmersiveDevice = nullptr;
if (m_inlineXRDevice == device)
m_inlineXRDevice = makeWeakPtr(m_defaultInlineDevice);
+ m_testingMode = false;
}
+
} // namespace WebCore
#endif // ENABLE(WEBXR)
Modified: trunk/Source/WebCore/Modules/webxr/WebXRSystem.h (261219 => 261220)
--- trunk/Source/WebCore/Modules/webxr/WebXRSystem.h 2020-05-06 08:28:37 UTC (rev 261219)
+++ trunk/Source/WebCore/Modules/webxr/WebXRSystem.h 2020-05-06 09:30:26 UTC (rev 261220)
@@ -74,6 +74,8 @@
private:
WebXRSystem(ScriptExecutionContext&);
+ void ensureImmersiveXRDeviceIsSelected();
+
// https://immersive-web.github.io/webxr/#default-inline-xr-device
class DummyInlineDevice final : public PlatformXR::Device {
public:
@@ -84,6 +86,9 @@
};
DummyInlineDevice m_defaultInlineDevice;
+ bool m_immersiveXRDevicesHaveBeenEnumerated { false };
+ bool m_testingMode { false };
+
WeakPtr<WebXRSession> m_activeImmersiveSession;
WeakPtr<PlatformXR::Device> m_activeImmersiveDevice;
Modified: trunk/Source/WebCore/html/FeaturePolicy.cpp (261219 => 261220)
--- trunk/Source/WebCore/html/FeaturePolicy.cpp 2020-05-06 08:28:37 UTC (rev 261219)
+++ trunk/Source/WebCore/html/FeaturePolicy.cpp 2020-05-06 09:30:26 UTC (rev 261220)
@@ -50,6 +50,10 @@
return "SyncXHR";
case FeaturePolicy::Type::Fullscreen:
return "Fullscreen";
+#if ENABLE(WEBXR)
+ case FeaturePolicy::Type::XRSpatialTracking:
+ return "XRSpatialTracking";
+#endif
}
ASSERT_NOT_REACHED();
return "";
@@ -154,6 +158,9 @@
bool isDisplayCaptureInitialized = false;
bool isSyncXHRInitialized = false;
bool isFullscreenInitialized = false;
+#if ENABLE(WEBXR)
+ bool isXRSpatialTrackingInitialized = false;
+#endif
for (auto allowItem : allowAttributeValue.split(';')) {
auto item = allowItem.stripLeadingAndTrailingMatchedCharacters(isHTMLSpace<UChar>);
if (item.startsWith("camera")) {
@@ -181,9 +188,17 @@
updateList(document, policy.m_fullscreenRule, item.substring(11));
continue;
}
+#if ENABLE(WEBXR)
+ if (item.startsWith("xr-spatial-tracking")) {
+ isXRSpatialTrackingInitialized = true;
+ updateList(document, policy.m_xrSpatialTrackingRule, item.substring(19));
+ continue;
+ }
+#endif
}
- // By default, camera, microphone, display-capture, and fullscreen policy is 'self'
+ // By default, camera, microphone, display-capture, fullscreen and
+ // xr-spatial-tracking policy is 'self'.
if (!isCameraInitialized)
policy.m_cameraRule.allowedList.add(document.securityOrigin().data());
if (!isMicrophoneInitialized)
@@ -190,6 +205,10 @@
policy.m_microphoneRule.allowedList.add(document.securityOrigin().data());
if (!isDisplayCaptureInitialized)
policy.m_displayCaptureRule.allowedList.add(document.securityOrigin().data());
+#if ENABLE(WEBXR)
+ if (!isXRSpatialTrackingInitialized)
+ policy.m_xrSpatialTrackingRule.allowedList.add(document.securityOrigin().data());
+#endif
// https://w3c.github.io/webappsec-feature-policy/#process-feature-policy-attributes
// 9.5 Process Feature Policy Attributes
@@ -225,6 +244,10 @@
return isAllowedByFeaturePolicy(m_syncXHRRule, origin);
case Type::Fullscreen:
return isAllowedByFeaturePolicy(m_fullscreenRule, origin);
+#if ENABLE(WEBXR)
+ case Type::XRSpatialTracking:
+ return isAllowedByFeaturePolicy(m_xrSpatialTrackingRule, origin);
+#endif
}
ASSERT_NOT_REACHED();
return false;
Modified: trunk/Source/WebCore/html/FeaturePolicy.h (261219 => 261220)
--- trunk/Source/WebCore/html/FeaturePolicy.h 2020-05-06 08:28:37 UTC (rev 261219)
+++ trunk/Source/WebCore/html/FeaturePolicy.h 2020-05-06 09:30:26 UTC (rev 261220)
@@ -38,7 +38,16 @@
public:
static FeaturePolicy parse(Document&, const HTMLIFrameElement&, StringView);
- enum class Type { Camera, Microphone, DisplayCapture, SyncXHR, Fullscreen };
+ enum class Type {
+ Camera,
+ Microphone,
+ DisplayCapture,
+ SyncXHR,
+ Fullscreen,
+#if ENABLE(WEBXR)
+ XRSpatialTracking,
+#endif
+ };
bool allows(Type, const SecurityOriginData&) const;
struct AllowRule {
@@ -53,6 +62,7 @@
AllowRule m_displayCaptureRule;
AllowRule m_syncXHRRule;
AllowRule m_fullscreenRule;
+ AllowRule m_xrSpatialTrackingRule;
};
enum class LogFeaturePolicyFailure { No, Yes };
Modified: trunk/Source/WebCore/platform/xr/PlatformXR.h (261219 => 261220)
--- trunk/Source/WebCore/platform/xr/PlatformXR.h 2020-05-06 08:28:37 UTC (rev 261219)
+++ trunk/Source/WebCore/platform/xr/PlatformXR.h 2020-05-06 09:30:26 UTC (rev 261220)
@@ -19,6 +19,7 @@
#pragma once
#include <memory>
+#include <wtf/Vector.h>
#include <wtf/WeakPtr.h>
namespace PlatformXR {
@@ -70,6 +71,8 @@
static Device::DeviceId nextDeviceId();
+ void enumerateImmersiveXRDevices();
+ const Vector<std::unique_ptr<Device>>& immersiveXRDevices() const { return m_immersiveXRDevices; }
private:
Instance();
~Instance();
@@ -76,6 +79,8 @@
struct Impl;
std::unique_ptr<Impl> m_impl;
+
+ Vector<std::unique_ptr<Device>> m_immersiveXRDevices;
};
#endif // ENABLE(WEBXR)
Modified: trunk/Source/WebCore/platform/xr/openxr/PlatformXR.cpp (261219 => 261220)
--- trunk/Source/WebCore/platform/xr/openxr/PlatformXR.cpp 2020-05-06 08:28:37 UTC (rev 261219)
+++ trunk/Source/WebCore/platform/xr/openxr/PlatformXR.cpp 2020-05-06 09:30:26 UTC (rev 261220)
@@ -67,6 +67,7 @@
~Impl();
#if USE_OPENXR
+ void collectSupportedSessionModes(Device&, XrSystemId);
XrInstance m_instance { XR_NULL_HANDLE };
#endif // USE_OPENXR
};
@@ -147,6 +148,43 @@
{
}
+#if USE_OPENXR
+
+void Instance::Impl::collectSupportedSessionModes(Device& device, XrSystemId systemId)
+{
+ uint32_t viewConfigurationCount;
+ XrResult result = xrEnumerateViewConfigurations(m_instance, systemId, 0, &viewConfigurationCount, nullptr);
+ if (result != XR_SUCCESS) {
+ WTFLogAlways("xrEnumerateViewConfigurations(): error %s\n", resultToString(result, m_instance).utf8().data());
+ return;
+ }
+
+ XrViewConfigurationType viewConfigurations[viewConfigurationCount];
+ result = xrEnumerateViewConfigurations(m_instance, systemId, viewConfigurationCount, &viewConfigurationCount, viewConfigurations);
+ if (result != XR_SUCCESS) {
+ WTFLogAlways("xrEnumerateViewConfigurations(): error %s\n", resultToString(result, m_instance).utf8().data());
+ WTFLogAlways("xrEnumerateViewConfigurations(): error %s\n", resultToString(result, m_instance).utf8().data());
+ return;
+ }
+
+ Device::ListOfSupportedModes supportedModes;
+ for (uint32_t i = 0; i < viewConfigurationCount; ++i) {
+ auto viewConfigurationProperties = createStructure<XrViewConfigurationProperties, XR_TYPE_VIEW_CONFIGURATION_PROPERTIES>();
+ result = xrGetViewConfigurationProperties(m_instance, systemId, viewConfigurations[i], &viewConfigurationProperties);
+ if (result != XR_SUCCESS) {
+ WTFLogAlways("xrGetViewConfigurationProperties(): error %s\n", resultToString(result, m_instance).utf8().data());
+ return;
+ }
+ if (viewConfigurationProperties.viewConfigurationType == XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO)
+ supportedModes.append(SessionMode::ImmersiveAr);
+ else if (viewConfigurationProperties.viewConfigurationType == XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO)
+ supportedModes.append(SessionMode::ImmersiveVr);
+ }
+ device.setSupportedModes(supportedModes);
+}
+
+#endif // USE_OPENXR
+
Instance& Instance::singleton()
{
static LazyNeverDestroyed<Instance> s_instance;
@@ -161,6 +199,30 @@
Instance::Instance() = default;
Instance::~Instance() = default;
+void Instance::enumerateImmersiveXRDevices()
+{
+#if USE_OPENXR
+ if (m_impl->m_instance == XR_NULL_HANDLE) {
+ WTFLogAlways("%s Unable to enumerate XR devices. No XrInstance present\n", __FUNCTION__);
+ return;
+ }
+
+ auto systemGetInfo = createStructure<XrSystemGetInfo, XR_TYPE_SYSTEM_GET_INFO>();
+ systemGetInfo.formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
+
+ XrSystemId systemId;
+ XrResult result = xrGetSystem(m_impl->m_instance, &systemGetInfo, &systemId);
+ if (result != XR_SUCCESS) {
+ WTFLogAlways("xrGetSystem(): error %s\n", resultToString(result, m_impl->m_instance).utf8().data());
+ return;
+ }
+
+ auto device = makeUnique<Device>();
+ m_impl->collectSupportedSessionModes(*device, systemId);
+ m_immersiveXRDevices.append(WTFMove(device));
+#endif // USE_OPENXR
+}
+
} // namespace PlatformXR
#endif // ENABLE(WEBXR)