Title: [260884] trunk/Source/WebCore
Revision
260884
Author
[email protected]
Date
2020-04-29 00:57:52 -0700 (Wed, 29 Apr 2020)

Log Message

[WebXR][WPE] Implement XRTest::simulateDeviceConnection()
https://bugs.webkit.org/show_bug.cgi?id=210912

Reviewed by Dean Jackson.

This API gives tests the ability to spin up a simulated XR device which
is an XR device which from the point of view of the WebXR API behaves
like a normal XR device. These simulated XR devices can be controlled by
the associated FakeXRDevice object.

No new tests as this is machinery required to execute tests when
implementing the WebXR API.

* Modules/webxr/WebXRSystem.cpp:
(WebCore::WebXRSystem::WebXRSystem): Initialize the default inline device.
(WebCore::WebXRSystem::registerSimulatedXRDeviceForTesting): Add a newly
created simulated XR device to the list of available devices. Update
also the active immersive device and current inline device.
(WebCore::WebXRSystem::unregisterSimulatedXRDeviceForTesting): Remove
all simulated devices from the list of immersive XR devices.
* Modules/webxr/WebXRSystem.h: New DummyInlineDevice which represents
the default inline device which must not provide pose information.
* Modules/webxr/WebXRView.cpp:
(WebCore::WebXRView::WebXRView): Removed some methods that should be
really part of a fake XRView instance.
(WebCore::WebXRView::setProjectionMatrix): Add implementation.
(WebCore::WebXRView::eye const): Deleted.
(WebCore::WebXRView::projectionMatrix const): Deleted.
(WebCore::WebXRView::transform const): Deleted.
* Modules/webxr/WebXRView.h:
(WebCore::WebXRView::eye const): Implemented.
(WebCore::WebXRView::projectionMatrix const): Ditto.
(WebCore::WebXRView::transform const): Ditto.
(WebCore::WebXRView::setEye): Ditto.
(WebCore::WebXRView::setTransform): Ditto.
* Modules/webxr/XRReferenceSpaceType.h: Moved the definitions to PlatformXR.
* platform/xr/PlatformXR.cpp:
(PlatformXR::Instance::nextDeviceId): New method which returns uniquely
defined ids for XR devices.
(PlatformXR::Device::Device):
* platform/xr/PlatformXR.h:
(PlatformXR::Device::id const): New method.
(PlatformXR::Device::supports const): Ditto.
(PlatformXR::Device::setSupportedModes): Ditto.
(PlatformXR::Device::setEnabledFeatures): Ditto.
(PlatformXR::Device::operator== const): Ditto.
* testing/FakeXRViewInit.h: fieldOfView is optional.
* testing/WebFakeXRDevice.cpp:
(WebCore::FakeXRView::setFieldOfView): Implemented.
(WebCore::WebFakeXRDevice::setViews): Ditto.
(WebCore::WebFakeXRDevice::setViewerOrigin): Ditto.
(WebCore::WebFakeXRDevice::clearViewerOrigin): Ditto.
(WebCore::WebFakeXRDevice::setFloorOrigin): Ditoo.
(WebCore::WebFakeXRDevice::clearFloorOrigin): Ditto.
(WebCore::WebFakeXRDevice::parseRigidTransform): Added.
(WebCore::WebFakeXRDevice::parseView): Ditto.
* testing/WebFakeXRDevice.h: Defined FakeXRView class which wraps a
XRView adding some associated data as the field of view and viewport.
Also defined the SimulatedXRDevice which is an PlatformXR::Device with
some additional data useful for testing purpouses.
* testing/WebXRTest.cpp:
(WebCore::WebXRTest::simulateDeviceConnection): Create a new
FakeXRDevice with an associated simulated XR device with the data
provided by a FakeXRDeviceInit.
(WebCore::WebXRTest::disconnectAllDevices): Remove all simulated devices
from the list of immersive devices.
* testing/WebXRTest.h: Call simulateDeviceConnection with ScriptExecutionContext.
* testing/WebXRTest.idl: Ditto.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (260883 => 260884)


--- trunk/Source/WebCore/ChangeLog	2020-04-29 07:36:27 UTC (rev 260883)
+++ trunk/Source/WebCore/ChangeLog	2020-04-29 07:57:52 UTC (rev 260884)
@@ -1,3 +1,74 @@
+2020-04-23  Sergio Villar Senin  <[email protected]>
+
+        [WebXR][WPE] Implement XRTest::simulateDeviceConnection()
+        https://bugs.webkit.org/show_bug.cgi?id=210912
+
+        Reviewed by Dean Jackson.
+
+        This API gives tests the ability to spin up a simulated XR device which
+        is an XR device which from the point of view of the WebXR API behaves
+        like a normal XR device. These simulated XR devices can be controlled by
+        the associated FakeXRDevice object.
+
+        No new tests as this is machinery required to execute tests when
+        implementing the WebXR API.
+
+        * Modules/webxr/WebXRSystem.cpp:
+        (WebCore::WebXRSystem::WebXRSystem): Initialize the default inline device.
+        (WebCore::WebXRSystem::registerSimulatedXRDeviceForTesting): Add a newly
+        created simulated XR device to the list of available devices. Update
+        also the active immersive device and current inline device.
+        (WebCore::WebXRSystem::unregisterSimulatedXRDeviceForTesting): Remove
+        all simulated devices from the list of immersive XR devices.
+        * Modules/webxr/WebXRSystem.h: New DummyInlineDevice which represents
+        the default inline device which must not provide pose information.
+        * Modules/webxr/WebXRView.cpp:
+        (WebCore::WebXRView::WebXRView): Removed some methods that should be
+        really part of a fake XRView instance.
+        (WebCore::WebXRView::setProjectionMatrix): Add implementation.
+        (WebCore::WebXRView::eye const): Deleted.
+        (WebCore::WebXRView::projectionMatrix const): Deleted.
+        (WebCore::WebXRView::transform const): Deleted.
+        * Modules/webxr/WebXRView.h:
+        (WebCore::WebXRView::eye const): Implemented.
+        (WebCore::WebXRView::projectionMatrix const): Ditto.
+        (WebCore::WebXRView::transform const): Ditto.
+        (WebCore::WebXRView::setEye): Ditto.
+        (WebCore::WebXRView::setTransform): Ditto.
+        * Modules/webxr/XRReferenceSpaceType.h: Moved the definitions to PlatformXR.
+        * platform/xr/PlatformXR.cpp:
+        (PlatformXR::Instance::nextDeviceId): New method which returns uniquely
+        defined ids for XR devices.
+        (PlatformXR::Device::Device):
+        * platform/xr/PlatformXR.h:
+        (PlatformXR::Device::id const): New method.
+        (PlatformXR::Device::supports const): Ditto.
+        (PlatformXR::Device::setSupportedModes): Ditto.
+        (PlatformXR::Device::setEnabledFeatures): Ditto.
+        (PlatformXR::Device::operator== const): Ditto.
+        * testing/FakeXRViewInit.h: fieldOfView is optional.
+        * testing/WebFakeXRDevice.cpp:
+        (WebCore::FakeXRView::setFieldOfView): Implemented.
+        (WebCore::WebFakeXRDevice::setViews): Ditto.
+        (WebCore::WebFakeXRDevice::setViewerOrigin): Ditto.
+        (WebCore::WebFakeXRDevice::clearViewerOrigin): Ditto.
+        (WebCore::WebFakeXRDevice::setFloorOrigin): Ditoo.
+        (WebCore::WebFakeXRDevice::clearFloorOrigin): Ditto.
+        (WebCore::WebFakeXRDevice::parseRigidTransform): Added.
+        (WebCore::WebFakeXRDevice::parseView): Ditto.
+        * testing/WebFakeXRDevice.h: Defined FakeXRView class which wraps a
+        XRView adding some associated data as the field of view and viewport.
+        Also defined the SimulatedXRDevice which is an PlatformXR::Device with
+        some additional data useful for testing purpouses.
+        * testing/WebXRTest.cpp:
+        (WebCore::WebXRTest::simulateDeviceConnection): Create a new
+        FakeXRDevice with an associated simulated XR device with the data
+        provided by a FakeXRDeviceInit.
+        (WebCore::WebXRTest::disconnectAllDevices): Remove all simulated devices
+        from the list of immersive devices.
+        * testing/WebXRTest.h: Call simulateDeviceConnection with ScriptExecutionContext.
+        * testing/WebXRTest.idl: Ditto.
+
 2020-04-29  Saam Barati  <[email protected]>
 
         U_STRING_NOT_TERMINATED_WARNING ICU must be handled when using the output buffer as a C string

Modified: trunk/Source/WebCore/Modules/webxr/WebXRSystem.cpp (260883 => 260884)


--- trunk/Source/WebCore/Modules/webxr/WebXRSystem.cpp	2020-04-29 07:36:27 UTC (rev 260883)
+++ trunk/Source/WebCore/Modules/webxr/WebXRSystem.cpp	2020-04-29 07:57:52 UTC (rev 260884)
@@ -29,6 +29,8 @@
 #if ENABLE(WEBXR)
 
 #include "PlatformXR.h"
+#include "RuntimeEnabledFeatures.h"
+#include "WebXRSession.h"
 #include <wtf/IsoMallocInlines.h>
 
 namespace WebCore {
@@ -43,6 +45,7 @@
 WebXRSystem::WebXRSystem(ScriptExecutionContext& scriptExecutionContext)
     : ActiveDOMObject(&scriptExecutionContext)
 {
+    m_inlineXRDevice = makeWeakPtr(m_defaultInlineDevice);
 }
 
 WebXRSystem::~WebXRSystem() = default;
@@ -87,6 +90,28 @@
 {
 }
 
+void WebXRSystem::registerSimulatedXRDeviceForTesting(const PlatformXR::Device& device)
+{
+    if (!RuntimeEnabledFeatures::sharedFeatures().webXREnabled())
+        return;
+    if (device.supports(PlatformXR::SessionMode::ImmersiveVr) || device.supports(PlatformXR::SessionMode::ImmersiveAr)) {
+        m_immersiveDevices.append(makeWeakPtr(device));
+        m_activeImmersiveDevice = m_immersiveDevices.last();
+    }
+    if (device.supports(PlatformXR::SessionMode::Inline))
+        m_inlineXRDevice = makeWeakPtr(device);
+}
+
+void WebXRSystem::unregisterSimulatedXRDeviceForTesting(PlatformXR::Device* device)
+{
+    if (!RuntimeEnabledFeatures::sharedFeatures().webXREnabled())
+        return;
+    ASSERT(m_immersiveDevices.contains(device));
+    m_immersiveDevices.removeFirst(device);
+    if (m_inlineXRDevice == device)
+        m_inlineXRDevice = makeWeakPtr(m_defaultInlineDevice);
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(WEBXR)

Modified: trunk/Source/WebCore/Modules/webxr/WebXRSystem.h (260883 => 260884)


--- trunk/Source/WebCore/Modules/webxr/WebXRSystem.h	2020-04-29 07:36:27 UTC (rev 260883)
+++ trunk/Source/WebCore/Modules/webxr/WebXRSystem.h	2020-04-29 07:57:52 UTC (rev 260884)
@@ -56,6 +56,10 @@
     void isSessionSupported(XRSessionMode, IsSessionSupportedPromise&&);
     void requestSession(XRSessionMode, const XRSessionInit&, RequestSessionPromise&&);
 
+    // For testing purpouses only.
+    void registerSimulatedXRDeviceForTesting(const PlatformXR::Device&);
+    void unregisterSimulatedXRDeviceForTesting(PlatformXR::Device*);
+
 protected:
     // EventTarget
     EventTargetInterface eventTargetInterface() const override { return WebXRSystemEventTargetInterfaceType; }
@@ -69,6 +73,22 @@
 
 private:
     WebXRSystem(ScriptExecutionContext&);
+
+    // https://immersive-web.github.io/webxr/#default-inline-xr-device
+    class DummyInlineDevice final : public PlatformXR::Device {
+    public:
+        DummyInlineDevice()
+        {
+            m_supportedModes.append(XRSessionMode::Inline);
+        }
+    };
+    DummyInlineDevice m_defaultInlineDevice;
+
+    WeakPtr<WebXRSession> m_activeImmersiveSession;
+
+    WeakPtr<PlatformXR::Device> m_activeImmersiveDevice;
+    Vector<WeakPtr<PlatformXR::Device>> m_immersiveDevices;
+    WeakPtr<PlatformXR::Device> m_inlineXRDevice;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/webxr/WebXRView.cpp (260883 => 260884)


--- trunk/Source/WebCore/Modules/webxr/WebXRView.cpp	2020-04-29 07:36:27 UTC (rev 260883)
+++ trunk/Source/WebCore/Modules/webxr/WebXRView.cpp	2020-04-29 07:57:52 UTC (rev 260884)
@@ -42,29 +42,17 @@
 }
 
 WebXRView::WebXRView()
-    : m_eye(XREye::Left)
-    , m_projectionMatrix(Float32Array::create(0))
-    , m_transform(WebXRRigidTransform::create())
+    : m_eye(XREye::None)
 {
 }
 
 WebXRView::~WebXRView() = default;
 
-XREye WebXRView::eye() const
+void WebXRView::setProjectionMatrix(const Vector<float>& matrix)
 {
-    return m_eye;
+    m_projectionMatrix = Float32Array::create(matrix.data(), matrix.size());
 }
 
-const Float32Array& WebXRView::projectionMatrix() const
-{
-    return m_projectionMatrix;
-}
-
-const WebXRRigidTransform& WebXRView::transform() const
-{
-    return m_transform;
-}
-
 } // namespace WebCore
 
 #endif // ENABLE(WEBXR)

Modified: trunk/Source/WebCore/Modules/webxr/WebXRView.h (260883 => 260884)


--- trunk/Source/WebCore/Modules/webxr/WebXRView.h	2020-04-29 07:36:27 UTC (rev 260883)
+++ trunk/Source/WebCore/Modules/webxr/WebXRView.h	2020-04-29 07:57:52 UTC (rev 260884)
@@ -27,11 +27,13 @@
 
 #if ENABLE(WEBXR)
 
+#include "WebXRRigidTransform.h"
 #include "XREye.h"
 #include <_javascript_Core/Float32Array.h>
 #include <wtf/IsoMalloc.h>
 #include <wtf/Ref.h>
 #include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
 
 namespace WebCore {
 
@@ -43,16 +45,20 @@
     static Ref<WebXRView> create();
     ~WebXRView();
 
-    XREye eye() const;
-    const Float32Array& projectionMatrix() const;
-    const WebXRRigidTransform& transform() const;
+    XREye eye() const { return m_eye; }
+    const Float32Array& projectionMatrix() const { return *m_projectionMatrix; }
+    const WebXRRigidTransform& transform() const { return *m_transform; }
 
+    void setEye(XREye eye) { m_eye = eye; }
+    void setProjectionMatrix(const Vector<float>&);
+    void setTransform(RefPtr<WebXRRigidTransform>&& viewOffset) { m_transform = WTFMove(viewOffset); }
+
 private:
     WebXRView();
 
     XREye m_eye;
-    Ref<Float32Array> m_projectionMatrix;
-    Ref<WebXRRigidTransform> m_transform;
+    RefPtr<Float32Array> m_projectionMatrix;
+    RefPtr<WebXRRigidTransform> m_transform;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/Modules/webxr/XRReferenceSpaceType.h (260883 => 260884)


--- trunk/Source/WebCore/Modules/webxr/XRReferenceSpaceType.h	2020-04-29 07:36:27 UTC (rev 260883)
+++ trunk/Source/WebCore/Modules/webxr/XRReferenceSpaceType.h	2020-04-29 07:57:52 UTC (rev 260884)
@@ -27,15 +27,11 @@
 
 #if ENABLE(WEBXR)
 
+#include "PlatformXR.h"
+
 namespace WebCore {
 
-enum class XRReferenceSpaceType {
-    Viewer,
-    Local,
-    LocalFloor,
-    BoundedFloor,
-    Unbounded
-};
+using XRReferenceSpaceType = PlatformXR::ReferenceSpaceType;
 
 } // namespace WebCore
 

Modified: trunk/Source/WebCore/platform/xr/PlatformXR.cpp (260883 => 260884)


--- trunk/Source/WebCore/platform/xr/PlatformXR.cpp	2020-04-29 07:36:27 UTC (rev 260883)
+++ trunk/Source/WebCore/platform/xr/PlatformXR.cpp	2020-04-29 07:57:52 UTC (rev 260884)
@@ -19,3 +19,22 @@
 
 #include "config.h"
 #include "PlatformXR.h"
+
+namespace PlatformXR {
+
+#if ENABLE(WEBXR)
+
+Device::DeviceId Instance::nextDeviceId()
+{
+    static Device::DeviceId s_nextDeviceId { 0 };
+    return s_nextDeviceId++;
+}
+
+Device::Device()
+    : m_id(Instance::nextDeviceId())
+{
+}
+
+#endif // ENABLE(WEBXR)
+
+} // namespace PlatformXR

Modified: trunk/Source/WebCore/platform/xr/PlatformXR.h (260883 => 260884)


--- trunk/Source/WebCore/platform/xr/PlatformXR.h	2020-04-29 07:36:27 UTC (rev 260883)
+++ trunk/Source/WebCore/platform/xr/PlatformXR.h	2020-04-29 07:57:52 UTC (rev 260884)
@@ -29,10 +29,39 @@
     ImmersiveAr,
 };
 
+enum class ReferenceSpaceType {
+    Viewer,
+    Local,
+    LocalFloor,
+    BoundedFloor,
+    Unbounded
+};
+
 #if ENABLE(WEBXR)
 
 class Device : public CanMakeWeakPtr<Device> {
+    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_NONCOPYABLE(Device);
 public:
+    using DeviceId = uint32_t;
+    Device();
+    DeviceId id() const { return m_id; }
+
+    using ListOfSupportedModes = Vector<SessionMode>;
+    using ListOfEnabledFeatures = Vector<ReferenceSpaceType>;
+
+    bool supports(SessionMode mode) const { return m_supportedModes.contains(mode); }
+    void setSupportedModes(const ListOfSupportedModes& modes) { m_supportedModes = modes; }
+    void setEnabledFeatures(const ListOfEnabledFeatures& features) { m_enabledFeatures = features; }
+
+    inline bool operator==(const Device& other) const { return m_id == other.m_id; }
+
+protected:
+    ListOfSupportedModes m_supportedModes;
+    ListOfEnabledFeatures m_enabledFeatures;
+
+private:
+    DeviceId m_id;
 };
 
 class Instance {
@@ -39,6 +68,8 @@
 public:
     static Instance& singleton();
 
+    static Device::DeviceId nextDeviceId();
+
 private:
     Instance();
     ~Instance();

Modified: trunk/Source/WebCore/testing/FakeXRViewInit.h (260883 => 260884)


--- trunk/Source/WebCore/testing/FakeXRViewInit.h	2020-04-29 07:36:27 UTC (rev 260883)
+++ trunk/Source/WebCore/testing/FakeXRViewInit.h	2020-04-29 07:57:52 UTC (rev 260884)
@@ -29,6 +29,7 @@
 
 #include "FakeXRRigidTransformInit.h"
 #include "XREye.h"
+#include <wtf/Optional.h>
 #include <wtf/Vector.h>
 
 namespace WebCore {
@@ -49,7 +50,7 @@
     Vector<float> projectionMatrix;
     DeviceResolution resolution;
     FakeXRRigidTransformInit viewOffset;
-    FieldOfViewInit fieldOfView;
+    Optional<FieldOfViewInit> fieldOfView;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/testing/WebFakeXRDevice.cpp (260883 => 260884)


--- trunk/Source/WebCore/testing/WebFakeXRDevice.cpp	2020-04-29 07:36:27 UTC (rev 260883)
+++ trunk/Source/WebCore/testing/WebFakeXRDevice.cpp	2020-04-29 07:57:52 UTC (rev 260884)
@@ -28,15 +28,32 @@
 
 #if ENABLE(WEBXR)
 
+#include "DOMPointReadOnly.h"
 #include "JSDOMPromiseDeferred.h"
 #include "WebFakeXRInputController.h"
 
 namespace WebCore {
 
-void WebFakeXRDevice::setViews(Vector<FakeXRViewInit>)
+void FakeXRView::setFieldOfView(FakeXRViewInit::FieldOfViewInit fov)
 {
+    m_fov = fov;
 }
 
+WebFakeXRDevice::WebFakeXRDevice() = default;
+
+void WebFakeXRDevice::setViews(const Vector<FakeXRViewInit>& views)
+{
+    Vector<Ref<FakeXRView>>& deviceViews = m_device.views();
+    deviceViews.clear();
+
+    // TODO: do in next animation frame.
+    for (auto& viewInit : views) {
+        auto view = parseView(viewInit);
+        if (!view.hasException())
+            deviceViews.append(view.releaseReturnValue());
+    }
+}
+
 void WebFakeXRDevice::disconnect(DOMPromiseDeferred<void>&& promise)
 {
     promise.resolve();
@@ -44,12 +61,19 @@
 
 void WebFakeXRDevice::setViewerOrigin(FakeXRRigidTransformInit origin, bool emulatedPosition)
 {
-    UNUSED_PARAM(origin);
-    UNUSED_PARAM(emulatedPosition);
+    auto rigidTransform = parseRigidTransform(origin);
+    if (rigidTransform.hasException())
+        return;
+
+    // TODO: do in next animation frame.
+    m_device.setViewerOrigin(rigidTransform.releaseReturnValue());
+    m_device.setEmulatedPosition(emulatedPosition);
 }
 
 void WebFakeXRDevice::clearViewerOrigin()
 {
+    // TODO: do in next animation frame.
+    m_device.setViewerOrigin(nullptr);
 }
 
 void WebFakeXRDevice::simulateVisibilityChange(XRVisibilityState)
@@ -60,12 +84,20 @@
 {
 }
 
-void WebFakeXRDevice::setFloorOrigin(FakeXRRigidTransformInit)
+void WebFakeXRDevice::setFloorOrigin(FakeXRRigidTransformInit origin)
 {
+    auto rigidTransform = parseRigidTransform(origin);
+    if (rigidTransform.hasException())
+        return;
+
+    // TODO: do in next animation frame.
+    m_device.setFloorOrigin(rigidTransform.releaseReturnValue());
 }
 
 void WebFakeXRDevice::clearFloorOrigin()
 {
+    // TODO: do in next animation frame.
+    m_device.setFloorOrigin(nullptr);
 }
 
 void WebFakeXRDevice::simulateResetPose()
@@ -77,6 +109,53 @@
     return WebFakeXRInputController();
 }
 
+ExceptionOr<Ref<WebXRRigidTransform>> WebFakeXRDevice::parseRigidTransform(const FakeXRRigidTransformInit& init)
+{
+    if (init.position.size() != 3 || init.orientation.size() != 4)
+        return Exception { TypeError };
+
+    DOMPointInit position;
+    position.x = init.position[0];
+    position.y = init.position[1];
+    position.z = init.position[2];
+
+    DOMPointInit orientation;
+    orientation.x = init.orientation[0];
+    orientation.y = init.orientation[1];
+    orientation.z = init.orientation[2];
+    orientation.w = init.orientation[3];
+
+    return WebXRRigidTransform::create(position, orientation);
+}
+
+ExceptionOr<Ref<FakeXRView>> WebFakeXRDevice::parseView(const FakeXRViewInit& init)
+{
+    // https://immersive-web.github.io/webxr-test-api/#parse-a-view
+    auto fakeView = FakeXRView::create(init.eye);
+
+    if (init.projectionMatrix.size() != 16)
+        return Exception { TypeError };
+    fakeView->view()->setProjectionMatrix(init.projectionMatrix);
+
+    auto viewOffset = parseRigidTransform(init.viewOffset);
+    if (viewOffset.hasException())
+        return viewOffset.releaseException();
+    fakeView->view()->setTransform(viewOffset.releaseReturnValue());
+
+    fakeView->setResolution(init.resolution);
+
+    if (init.fieldOfView) {
+        fakeView->setFieldOfView(init.fieldOfView.value());
+        // TODO: Set view’s projection matrix to the projection matrix
+        // corresponding to this field of view, and depth values equal to
+        // depthNear and depthFar of any XRSession associated with the device.
+        // If there currently is none, use the default values of near=0.1,
+        // far=1000.0.
+    }
+
+    return fakeView;
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(WEBXR)

Modified: trunk/Source/WebCore/testing/WebFakeXRDevice.h (260883 => 260884)


--- trunk/Source/WebCore/testing/WebFakeXRDevice.h	2020-04-29 07:36:27 UTC (rev 260883)
+++ trunk/Source/WebCore/testing/WebFakeXRDevice.h	2020-04-29 07:57:52 UTC (rev 260884)
@@ -31,17 +31,58 @@
 #include "FakeXRInputSourceInit.h"
 #include "FakeXRViewInit.h"
 #include "JSDOMPromiseDeferred.h"
+#include "PlatformXR.h"
 #include "WebFakeXRInputController.h"
+#include "WebXRRigidTransform.h"
+#include "WebXRView.h"
 #include "XRVisibilityState.h"
 #include <wtf/RefCounted.h>
 #include <wtf/Vector.h>
 
 namespace WebCore {
+class FakeXRView final : public RefCounted<FakeXRView> {
+public:
+    static Ref<FakeXRView> create(XREye eye) { return adoptRef(*new FakeXRView(eye)); }
 
+    RefPtr<WebXRView> view() { return m_view; }
+    void setResolution(FakeXRViewInit::DeviceResolution resolution) { m_resolution = resolution; }
+    void setFieldOfView(FakeXRViewInit::FieldOfViewInit);
+
+private:
+    FakeXRView(XREye eye)
+    {
+        m_view = WebXRView::create();
+        m_view->setEye(eye);
+    }
+
+    RefPtr<WebXRView> m_view;
+    FakeXRViewInit::DeviceResolution m_resolution;
+    FakeXRViewInit::FieldOfViewInit m_fov;
+};
+
+class SimulatedXRDevice final : public PlatformXR::Device {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    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); }
+    void setEmulatedPosition(bool emulated) { m_emulatedPosition = emulated; }
+    Vector<Ref<FakeXRView>>& views() { return m_views; }
+private:
+    Optional<Vector<FakeXRBoundsPoint>> m_nativeBoundsGeometry;
+    RefPtr<WebXRRigidTransform> m_viewerOrigin;
+    RefPtr<WebXRRigidTransform> m_floorOrigin;
+    bool m_emulatedPosition { false };
+    XRVisibilityState m_visibilityState { XRVisibilityState::Visible };
+    Vector<Ref<FakeXRView>> m_views;
+};
+
 class WebFakeXRDevice final : public RefCounted<WebFakeXRDevice> {
 public:
-    void setViews(Vector<FakeXRViewInit>);
+    static Ref<WebFakeXRDevice> create() { return adoptRef(*new WebFakeXRDevice()); }
 
+    void setViews(const Vector<FakeXRViewInit>&);
+
     void disconnect(DOMPromiseDeferred<void>&&);
 
     void setViewerOrigin(FakeXRRigidTransformInit origin, bool emulatedPosition = false);
@@ -59,6 +100,17 @@
     void simulateResetPose();
 
     WebFakeXRInputController simulateInputSourceConnection(FakeXRInputSourceInit);
+
+    static ExceptionOr<Ref<FakeXRView>> parseView(const FakeXRViewInit&);
+
+    SimulatedXRDevice& simulatedXRDevice() { return m_device; }
+
+private:
+    WebFakeXRDevice();
+
+    static ExceptionOr<Ref<WebXRRigidTransform>> parseRigidTransform(const FakeXRRigidTransformInit&);
+
+    SimulatedXRDevice m_device;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/testing/WebXRTest.cpp (260883 => 260884)


--- trunk/Source/WebCore/testing/WebXRTest.cpp	2020-04-29 07:36:27 UTC (rev 260883)
+++ trunk/Source/WebCore/testing/WebXRTest.cpp	2020-04-29 07:57:52 UTC (rev 260884)
@@ -28,10 +28,71 @@
 
 #if ENABLE(WEBXR)
 
+#include "JSWebFakeXRDevice.h"
+#include "JSXRReferenceSpaceType.h"
+#include "WebXRSystem.h"
+#include "XRSessionMode.h"
+
 namespace WebCore {
 
-void WebXRTest::simulateDeviceConnection(FakeXRDeviceInit, WebFakeXRDevicePromise&&) const
+WebXRTest::~WebXRTest() = default;
+
+void WebXRTest::simulateDeviceConnection(ScriptExecutionContext& context, const FakeXRDeviceInit& init, WebFakeXRDevicePromise&& promise)
 {
+    // https://immersive-web.github.io/webxr-test-api/#dom-xrtest-simulatedeviceconnection
+    context.postTask([this, init, promise = WTFMove(promise)] (ScriptExecutionContext& context) mutable {
+        auto device = WebFakeXRDevice::create();
+        auto& simulatedDevice = device->simulatedXRDevice();
+
+        for (auto& viewInit : init.views) {
+            auto view = WebFakeXRDevice::parseView(viewInit);
+            if (view.hasException()) {
+                promise.reject(view.releaseException());
+                return;
+            }
+            simulatedDevice.views().append(view.releaseReturnValue());
+        }
+
+        if (init.supportedFeatures) {
+            Vector<XRReferenceSpaceType> features;
+            for (auto& feature : init.supportedFeatures.value()) {
+                if (auto referenceSpaceType = parseEnumeration<XRReferenceSpaceType>(*context.execState(), feature))
+                    features.append(referenceSpaceType.value());
+            }
+            simulatedDevice.setEnabledFeatures(features);
+        }
+
+        if (init.boundsCoordinates) {
+            if (init.boundsCoordinates->size() < 3) {
+                promise.reject(Exception { TypeError });
+                return;
+            }
+            simulatedDevice.setNativeBoundsGeometry(init.boundsCoordinates.value());
+        }
+
+        if (init.viewerOrigin)
+            device->setViewerOrigin(init.viewerOrigin.value());
+
+        if (init.floorOrigin)
+            device->setFloorOrigin(init.floorOrigin.value());
+
+        Vector<XRSessionMode> supportedModes;
+        if (init.supportedModes) {
+            supportedModes = init.supportedModes.value();
+            if (supportedModes.isEmpty())
+                supportedModes.append(XRSessionMode::Inline);
+        } else {
+            supportedModes.append(XRSessionMode::Inline);
+            if (init.supportsImmersive)
+                supportedModes.append(XRSessionMode::ImmersiveVr);
+        }
+        simulatedDevice.setSupportedModes(supportedModes);
+
+        m_context->registerSimulatedXRDeviceForTesting(simulatedDevice);
+
+        promise.resolve(device.get());
+        m_devices.append(WTFMove(device));
+    });
 }
 
 void WebXRTest::simulateUserActivation(XRSimulateUserActivationFunction&)
@@ -38,8 +99,11 @@
 {
 }
 
-void WebXRTest::disconnectAllDevices(DOMPromiseDeferred<void>&&)
+void WebXRTest::disconnectAllDevices(DOMPromiseDeferred<void>&& promise)
 {
+    for (auto& device : m_devices)
+        m_context->unregisterSimulatedXRDeviceForTesting(&device->simulatedXRDevice());
+    promise.resolve();
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/testing/WebXRTest.h (260883 => 260884)


--- trunk/Source/WebCore/testing/WebXRTest.h	2020-04-29 07:36:27 UTC (rev 260883)
+++ trunk/Source/WebCore/testing/WebXRTest.h	2020-04-29 07:57:52 UTC (rev 260884)
@@ -55,9 +55,10 @@
     };
 
     static Ref<WebXRTest> create(WeakPtr<WebXRSystem>&& system) { return adoptRef(*new WebXRTest(WTFMove(system))); }
+    virtual ~WebXRTest();
 
     using WebFakeXRDevicePromise = DOMPromiseDeferred<IDLInterface<WebFakeXRDevice>>;
-    void simulateDeviceConnection(FakeXRDeviceInit, WebFakeXRDevicePromise&&) const;
+    void simulateDeviceConnection(ScriptExecutionContext& state, const FakeXRDeviceInit&, WebFakeXRDevicePromise&&);
 
     // Simulates a user activation (aka user gesture) for the current scope.
     // The activation is only guaranteed to be valid in the provided function and only applies to WebXR
@@ -72,6 +73,7 @@
         : m_context(WTFMove(system)) { }
 
     WeakPtr<WebXRSystem> m_context;
+    Vector<Ref<WebFakeXRDevice>> m_devices;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/testing/WebXRTest.idl (260883 => 260884)


--- trunk/Source/WebCore/testing/WebXRTest.idl	2020-04-29 07:36:27 UTC (rev 260883)
+++ trunk/Source/WebCore/testing/WebXRTest.idl	2020-04-29 07:57:52 UTC (rev 260884)
@@ -28,12 +28,11 @@
     Conditional=WEBXR,
     Exposed=Window,
     InterfaceName=XRTest,
-    ImplementationLacksVTable,
     NoInterfaceObject
 ] interface WebXRTest {
     // Simulates connecting a device to the system.
     // Used to instantiate a fake device for use in tests.
-    Promise<WebFakeXRDevice> simulateDeviceConnection(FakeXRDeviceInit init);
+    [CallWith=ScriptExecutionContext] Promise<WebFakeXRDevice> simulateDeviceConnection(FakeXRDeviceInit init);
 
     // Simulates a user activation (aka user gesture) for the current scope.
     // The activation is only guaranteed to be valid in the provided function and only applies to WebXR
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to