[WebXR] Check device orientation support when requesting a reference space
authorsvillar@igalia.com <svillar@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jun 2020 10:49:42 +0000 (10:49 +0000)
committersvillar@igalia.com <svillar@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jun 2020 10:49:42 +0000 (10:49 +0000)
https://bugs.webkit.org/show_bug.cgi?id=213519

Reviewed by Carlos Garcia Campos.

When requesting a local reference space the specs mandate us to check whether or not the device
supports orientation tracking. This was not implemented in the OpenXR backend, so we were unconditionally
returning true.

The OpenXR devices now properly check whether or not orientation tracking is initialized. We took the chance
to refactor a bit the OpenXR backend moving all the device initialization code to the OpenXRDevice class.

The current tests already check this functionality.

* Modules/webxr/WebXRSession.cpp:
(WebCore::WebXRSession::referenceSpaceIsSupported const): Call supportsOrientationTracking() on device.
* platform/xr/PlatformXR.h:
(PlatformXR::Device::supportsOrientationTracking const): Added.
* platform/xr/openxr/PlatformXROpenXR.cpp:
(PlatformXR::Instance::enumerateImmersiveXRDevices): Just create the OpenXR device, it will automatically
initialize itself.
(PlatformXR::OpenXRDevice::OpenXRDevice): Get XrSystem and XrInstance as parametters.
(PlatformXR::OpenXRDevice::collectSupportedSessionModes): Moved from Instance::Impl.
(PlatformXR::Instance::Impl::collectSupportedSessionModes): Deleted.
* platform/xr/openxr/PlatformXROpenXR.h:
* testing/WebFakeXRDevice.h: Mark the SimulatedXRDevice as supporting orientation tracking.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@263503 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/Modules/webxr/WebXRSession.cpp
Source/WebCore/platform/xr/PlatformXR.h
Source/WebCore/platform/xr/openxr/PlatformXROpenXR.cpp
Source/WebCore/platform/xr/openxr/PlatformXROpenXR.h
Source/WebCore/testing/WebFakeXRDevice.h

index 80f99e2..c293f1c 100644 (file)
@@ -1,3 +1,32 @@
+2020-06-23  Sergio Villar Senin  <svillar@igalia.com>
+
+        [WebXR] Check device orientation support when requesting a reference space
+        https://bugs.webkit.org/show_bug.cgi?id=213519
+
+        Reviewed by Carlos Garcia Campos.
+
+        When requesting a local reference space the specs mandate us to check whether or not the device
+        supports orientation tracking. This was not implemented in the OpenXR backend, so we were unconditionally
+        returning true.
+
+        The OpenXR devices now properly check whether or not orientation tracking is initialized. We took the chance
+        to refactor a bit the OpenXR backend moving all the device initialization code to the OpenXRDevice class.
+
+        The current tests already check this functionality.
+
+        * Modules/webxr/WebXRSession.cpp:
+        (WebCore::WebXRSession::referenceSpaceIsSupported const): Call supportsOrientationTracking() on device.
+        * platform/xr/PlatformXR.h:
+        (PlatformXR::Device::supportsOrientationTracking const): Added.
+        * platform/xr/openxr/PlatformXROpenXR.cpp:
+        (PlatformXR::Instance::enumerateImmersiveXRDevices): Just create the OpenXR device, it will automatically
+        initialize itself.
+        (PlatformXR::OpenXRDevice::OpenXRDevice): Get XrSystem and XrInstance as parametters.
+        (PlatformXR::OpenXRDevice::collectSupportedSessionModes): Moved from Instance::Impl.
+        (PlatformXR::Instance::Impl::collectSupportedSessionModes): Deleted.
+        * platform/xr/openxr/PlatformXROpenXR.h:
+        * testing/WebFakeXRDevice.h: Mark the SimulatedXRDevice as supporting orientation tracking.
+
 2020-06-24  James Savage  <james.savage@apple.com>
 
         Upstream iPadOS 13.0 multi-window support
index 8c662cc..1ea5ca9 100644 (file)
@@ -108,11 +108,10 @@ bool WebXRSession::referenceSpaceIsSupported(XRReferenceSpaceType type) const
             return true;
 
         // 4. If type is local or local-floor, and the XR device supports reporting orientation data, return true.
-        // TODO: add API to PlatformXR::Device
-        return true;
+        if (m_device->supportsOrientationTracking())
+            return true;
     }
 
-
     // 5. If type is bounded-floor and session is an immersive session, return the result of whether bounded
     //    reference spaces are supported by the XR device.
     // https://immersive-web.github.io/webxr/#bounded-reference-spaces-are-supported
index 6bce362..371023c 100644 (file)
@@ -53,6 +53,8 @@ public:
     void setEnabledFeatures(SessionMode mode, const ListOfEnabledFeatures& features) { m_enabledFeaturesMap.set(mode, features); }
     ListOfEnabledFeatures enabledFeatures(SessionMode mode) const { return m_enabledFeaturesMap.get(mode); }
 
+    bool supportsOrientationTracking() const { return m_supportsOrientationTracking; }
+
 protected:
     Device() = default;
 
@@ -61,6 +63,8 @@ protected:
     // which is a list of feature descriptors which MUST be initially an empty list.
     using EnabledFeaturesPerModeMap = WTF::HashMap<SessionMode, ListOfEnabledFeatures, WTF::IntHash<SessionMode>, WTF::StrongEnumHashTraits<SessionMode>>;
     EnabledFeaturesPerModeMap m_enabledFeaturesMap;
+
+    bool m_supportsOrientationTracking { false };
 };
 
 class Instance {
index dbfd3cd..8e7894f 100644 (file)
@@ -168,44 +168,6 @@ Instance::Impl::~Impl()
 
 #if USE_OPENXR
 
-Optional<Vector<SessionMode>> Instance::Impl::collectSupportedSessionModes(OpenXRDevice& device)
-{
-    uint32_t viewConfigurationCount;
-    auto result = xrEnumerateViewConfigurations(m_instance, device.xrSystemId(), 0, &viewConfigurationCount, nullptr);
-    if (result != XR_SUCCESS) {
-        LOG(XR, "xrEnumerateViewConfigurations(): error %s\n", resultToString(result, m_instance).utf8().data());
-        return WTF::nullopt;
-    }
-
-    XrViewConfigurationType viewConfigurations[viewConfigurationCount];
-    result = xrEnumerateViewConfigurations(m_instance, device.xrSystemId(), viewConfigurationCount, &viewConfigurationCount, viewConfigurations);
-    if (result != XR_SUCCESS) {
-        LOG(XR, "xrEnumerateViewConfigurations(): error %s\n", resultToString(result, m_instance).utf8().data());
-        return WTF::nullopt;
-    }
-
-    Vector<SessionMode> supportedModes;
-    for (uint32_t i = 0; i < viewConfigurationCount; ++i) {
-        auto viewConfigurationProperties = createStructure<XrViewConfigurationProperties, XR_TYPE_VIEW_CONFIGURATION_PROPERTIES>();
-        result = xrGetViewConfigurationProperties(m_instance, device.xrSystemId(), viewConfigurations[i], &viewConfigurationProperties);
-        if (result != XR_SUCCESS) {
-            LOG(XR, "xrGetViewConfigurationProperties(): error %s\n", resultToString(result, m_instance).utf8().data());
-            return WTF::nullopt;
-        }
-        switch (viewConfigurationProperties.viewConfigurationType) {
-            case XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO:
-                supportedModes.append(SessionMode::ImmersiveAr);
-                break;
-            case XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO:
-                supportedModes.append(SessionMode::ImmersiveVr);
-                break;
-            default:
-                break;
-        };
-    }
-    return supportedModes;
-}
-
 #endif // USE_OPENXR
 
 Instance& Instance::singleton()
@@ -237,23 +199,54 @@ void Instance::enumerateImmersiveXRDevices()
 
     XrSystemId systemId;
     XrResult result = xrGetSystem(m_impl->xrInstance(), &systemGetInfo, &systemId);
-    if (result != XR_SUCCESS) {
-        LOG(XR, "xrGetSystem(): error %s\n", resultToString(result, m_impl->xrInstance()).utf8().data());
-        return;
-    }
+    RETURN_IF_FAILED(result, "xrGetSystem", m_impl->xrInstance());
+
+    m_immersiveXRDevices.append(makeUnique<OpenXRDevice>(systemId, m_impl->xrInstance()));
+#endif // USE_OPENXR
+}
+
+OpenXRDevice::OpenXRDevice(XrSystemId id, XrInstance instance)
+    : m_systemId(id)
+    , m_instance(instance)
+{
+    auto systemProperties = createStructure<XrSystemProperties, XR_TYPE_SYSTEM_PROPERTIES>();
+    XrResult result = xrGetSystemProperties(instance, m_systemId, &systemProperties);
+    if (result == XR_SUCCESS)
+        m_supportsOrientationTracking = systemProperties.trackingProperties.orientationTracking == XR_TRUE;
+    else
+        LOG(XR, "xrGetSystemProperties(): error %s\n", resultToString(result, m_impl->xrInstance()).utf8().data());
+
+    collectSupportedSessionModes();
+}
+
+void OpenXRDevice::collectSupportedSessionModes()
+{
+    uint32_t viewConfigurationCount;
+    auto result = xrEnumerateViewConfigurations(m_instance, m_systemId, 0, &viewConfigurationCount, nullptr);
+    RETURN_IF_FAILED(result, "xrEnumerateViewConfigurations", m_instance);
 
-    auto device = makeUnique<OpenXRDevice>();
-    device->setXrSystemId(systemId);
-    auto sessionModes = m_impl->collectSupportedSessionModes(*device);
-    if (sessionModes) {
-        for (auto& mode : sessionModes.value()) {
-            // TODO: fill in features
-            device->setEnabledFeatures(mode, { });
+    XrViewConfigurationType viewConfigurations[viewConfigurationCount];
+    result = xrEnumerateViewConfigurations(m_instance, m_systemId, viewConfigurationCount, &viewConfigurationCount, viewConfigurations);
+    RETURN_IF_FAILED(result, "xrEnumerateViewConfigurations", m_instance);
+
+    for (uint32_t i = 0; i < viewConfigurationCount; ++i) {
+        auto viewConfigurationProperties = createStructure<XrViewConfigurationProperties, XR_TYPE_VIEW_CONFIGURATION_PROPERTIES>();
+        result = xrGetViewConfigurationProperties(m_instance, m_systemId, viewConfigurations[i], &viewConfigurationProperties);
+        if (result != XR_SUCCESS) {
+            LOG(XR, "xrGetViewConfigurationProperties(): error %s\n", resultToString(result, m_instance).utf8().data());
+            continue;
         }
+        switch (viewConfigurationProperties.viewConfigurationType) {
+        case XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO:
+            setEnabledFeatures(SessionMode::ImmersiveAr, { });
+            break;
+        case XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO:
+            setEnabledFeatures(SessionMode::ImmersiveVr, { });
+            break;
+        default:
+            break;
+        };
     }
-
-    m_immersiveXRDevices.append(WTFMove(device));
-#endif // USE_OPENXR
 }
 
 } // namespace PlatformXR
index d970883..5a96d63 100644 (file)
@@ -41,10 +41,13 @@ namespace PlatformXR {
 // the XRSystem is basically the entry point for the WebXR API available via the Navigator object.
 class OpenXRDevice final : public Device {
 public:
-    void setXrSystemId(XrSystemId id) { m_systemId = id; }
+    OpenXRDevice(XrSystemId, XrInstance);
     XrSystemId xrSystemId() const { return m_systemId; }
 private:
+    void collectSupportedSessionModes();
+
     XrSystemId m_systemId;
+    XrInstance m_instance;
 };
 
 } // namespace PlatformXR
index b4c584d..7d46161 100644 (file)
@@ -63,6 +63,7 @@ private:
 class SimulatedXRDevice final : public PlatformXR::Device {
     WTF_MAKE_FAST_ALLOCATED;
 public:
+    SimulatedXRDevice() { m_supportsOrientationTracking = true; }
     void setNativeBoundsGeometry(Vector<FakeXRBoundsPoint> geometry) { m_nativeBoundsGeometry = geometry; }
     void setViewerOrigin(RefPtr<WebXRRigidTransform>&& origin) { m_viewerOrigin = WTFMove(origin); }
     void setFloorOrigin(RefPtr<WebXRRigidTransform>&& origin) { m_floorOrigin = WTFMove(origin); }