WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-223257-20210416181733.patch (text/plain), 89.33 KB, created by
Imanol Fernandez
on 2021-04-16 09:17:34 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Imanol Fernandez
Created:
2021-04-16 09:17:34 PDT
Size:
89.33 KB
patch
obsolete
>Subversion Revision: 276138 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index ced6022d9bae55fa2953a36d8ddd8440f9a5908c..f6e0ceeec4a2a80f70682c0aedf1e5dd3de46d77 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,118 @@ >+2021-03-16 Imanol Fernandez <ifernandez@igalia.com> >+ >+ Implement WebXR Input Sources >+ https://bugs.webkit.org/show_bug.cgi?id=223257 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This patch implements the platform data definition and the DOM bits required to support WebXR Input Sources, the input mechanism used in WebXR. >+ Example XR input sources include, but are not limited to, handheld controllers, optically tracked hands, and gaze-based input methods. >+ >+ More info about the API in: >+ - https://immersive-web.github.io/webxr/#input >+ - https://immersive-web.github.io/webxr-gamepads-module/#webxr-device-api-integration >+ >+ Tested by WebXR WPT. >+ >+ * Modules/gamepad/Gamepad.h: Add setConnected method. >+ >+ * Modules/webxr/WebXRGamepad.cpp: Bridge between WebXRInputSource and Gamepad >+ (WebCore::WebXRGamepad::WebXRGamepad): >+ * Modules/webxr/WebXRGamepad.h: >+ >+ * Modules/webxr/WebXRInputSpace.cpp: Instance of WebXRSpace used for WebXRInputSource spaces. >+ (WebCore::WebXRInputSpace::create): >+ (WebCore::WebXRInputSpace::WebXRInputSpace): >+ (WebCore::WebXRInputSpace::nativeOrigin const): >+ * Modules/webxr/WebXRInputSpace.h: >+ >+ * Modules/webxr/WebXRFrame.cpp: >+ (WebCore::WebXRFrame::populatePose): set emulatedPosition based on the spaces. >+ >+ * Modules/webxr/WebXRInputSource.cpp: Complete WebXRInputSource implementation. >+ (WebCore::WebXRInputSpace::create): >+ (WebCore::WebXRInputSpace::WebXRInputSpace): >+ (WebCore::WebXRInputSpace::nativeOrigin const): >+ (WebCore::WebXRInputSource::create): >+ (WebCore::WebXRInputSource::WebXRInputSource): >+ (WebCore::WebXRInputSource::update): >+ (WebCore::WebXRInputSource::requiresInputSourceChange): >+ (WebCore::WebXRInputSource::disconnect): >+ (WebCore::WebXRInputSource::pollEvents): >+ (WebCore::WebXRInputSource::createEvent): >+ * Modules/webxr/WebXRInputSource.h: >+ (WebCore::WebXRInputSource::handle const): >+ (WebCore::WebXRInputSource::handedness const): >+ (WebCore::WebXRInputSource::targetRayMode const): >+ (WebCore::WebXRInputSource::targetRaySpace const): >+ (WebCore::WebXRInputSource::gripSpace const): >+ (WebCore::WebXRInputSource::profiles const): >+ (WebCore::WebXRInputSource::gamepad const): >+ >+ * Modules/webxr/WebXRInputSource.idl: Add gamepad attribute. >+ >+ * Modules/webxr/WebXRInputSourceArray.cpp: Implement input source updates and event dispatching. >+ (WebCore::WebXRInputSourceArray::create): >+ (WebCore::WebXRInputSourceArray::WebXRInputSourceArray): >+ (WebCore::WebXRInputSourceArray::length const): >+ (WebCore::WebXRInputSourceArray::item const): >+ (WebCore::WebXRInputSourceArray::clear): >+ (WebCore::WebXRInputSourceArray::update): >+ (WebCore::WebXRInputSourceArray::handleRemovedInputSources): >+ (WebCore::WebXRInputSourceArray::handleAddedOrUpdatedInputSources): >+ * Modules/webxr/WebXRInputSourceArray.h: >+ >+ * Modules/webxr/WebXRSession.cpp: >+ (WebCore::WebXRSession::WebXRSession): Set tracking delegate before initializing tracking and rendering. >+ (WebCore::WebXRSession::isPositionEmulated const): Add helper method. >+ (WebCore::WebXRSession::shutdown): Clear WebXRInputSourceArray instance. >+ (WebCore::WebXRSession::sessionDidInitializeInputSources): Dispatch initial InputSource discovery event. >+ (WebCore::WebXRSession::onFrame): Update WebXRInputSourceArray instance. >+ * Modules/webxr/WebXRSession.h: >+ >+ * Modules/webxr/WebXRSpace.cpp: Add virtual class isPositionEmulated to be used in WebXRFrame. >+ (WebCore::WebXRSpace::isPositionEmulated const): >+ * Modules/webxr/WebXRSpace.h: >+ >+ * Modules/webxr/WebXRSystem.cpp: >+ (WebCore::WebXRSystem::requestSession): update FIXME comment. >+ >+ * Modules/webxr/XRHandedness.h: Reuse PlatformXR enum. >+ >+ * Modules/webxr/XRInputSourceEvent.cpp: >+ (WebCore::XRInputSourceEvent::XRInputSourceEvent): >+ (WebCore::XRInputSourceEvent::setFrameActive): >+ * Modules/webxr/XRInputSourceEvent.h: >+ >+ * Modules/webxr/XRInputSourcesChangeEvent.h: >+ >+ * Modules/webxr/XRTargetRayMode.h: Reuse PlatformXR enum. >+ >+ * platform/gamepad/GamepadConstants.cpp: >+ (WebCore::xrStandardGamepadMappingString): Add xr-standard gamepad mapping name. >+ * platform/gamepad/GamepadConstants.h: >+ >+ * platform/xr/PlatformXR.h: Add Input Source frame data. >+ >+ * testing/WebFakeXRDevice.cpp: Implement required changes to run and pass WebXR Input Source tests. >+ (WebCore::SimulatedXRDevice::initializeTrackingAndRendering): >+ (WebCore::SimulatedXRDevice::frameTimerFired): >+ (WebCore::WebFakeXRDevice::simulateResetPose): >+ (WebCore::WebFakeXRDevice::simulateInputSourceConnection): >+ * testing/WebFakeXRDevice.h: >+ * testing/WebFakeXRInputController.cpp: >+ (WebCore::WebFakeXRInputController::create): >+ (WebCore::WebFakeXRInputController::WebFakeXRInputController): >+ (WebCore::WebFakeXRInputController::setGripOrigin): >+ (WebCore::WebFakeXRInputController::setPointerOrigin): >+ (WebCore::WebFakeXRInputController::disconnect): >+ (WebCore::WebFakeXRInputController::reconnect): >+ (WebCore::WebFakeXRInputController::setSupportedButtons): >+ (WebCore::WebFakeXRInputController::updateButtonState): >+ (WebCore::WebFakeXRInputController::getFrameData): >+ (WebCore::WebFakeXRInputController::getButtonOrPlaceholder const): >+ * testing/WebFakeXRInputController.h: >+ > 2021-04-16 Antoine Quint <graouts@webkit.org> > > Blend using calc() when necessary >diff --git a/Source/WebCore/Modules/gamepad/Gamepad.h b/Source/WebCore/Modules/gamepad/Gamepad.h >index 8f193341605cc6010160d1e28d2679065c4c6177..43ced5457f2f4fd4a476b5d362a4a9dac50a0f32 100644 >--- a/Source/WebCore/Modules/gamepad/Gamepad.h >+++ b/Source/WebCore/Modules/gamepad/Gamepad.h >@@ -55,6 +55,7 @@ public: > const Vector<Ref<GamepadButton>>& buttons() const; > > void updateFromPlatformGamepad(const PlatformGamepad&); >+ void setConnected(bool connected) { m_connected = connected; } > > private: > explicit Gamepad(const PlatformGamepad&); >diff --git a/Source/WebCore/Modules/webxr/WebXRFrame.cpp b/Source/WebCore/Modules/webxr/WebXRFrame.cpp >index f45fb11475a2d8240f6bf47806b4009848cb087d..78f41d9b8fd96eb8c0fd15aee3d31b83eb21c920 100644 >--- a/Source/WebCore/Modules/webxr/WebXRFrame.cpp >+++ b/Source/WebCore/Modules/webxr/WebXRFrame.cpp >@@ -119,7 +119,7 @@ ExceptionOr<Optional<WebXRFrame::PopulatedPose>> WebXRFrame::populatePose(const > // 7. Let transform be poseâs transform. > // 8. Query the XR device's tracking system for spaceâs pose relative to baseSpace at the frameâs time. > >- if (!m_data.isTrackingValid) { >+ if (m_isAnimationFrame && !m_data.isTrackingValid) { > // FIXME: check if spaceâs pose relative to baseSpace has been determined in the past. > // Anyway this emulation is usually provided by the system in the pose (e.g. OpenXR) > // so we shouldn't hit this path in most XRPlatform ports. >@@ -131,7 +131,7 @@ ExceptionOr<Optional<WebXRFrame::PopulatedPose>> WebXRFrame::populatePose(const > return { WTF::nullopt }; > > auto transform = *baseTransform.inverse() * space.effectiveOrigin(); >- bool emulatedPosition = m_data.isPositionEmulated || !m_data.isPositionValid; >+ bool emulatedPosition = space.isPositionEmulated() || baseSpace.isPositionEmulated(); > > bool limit = mustPosesBeLimited(space, baseSpace); > if (limit) { >diff --git a/Source/WebCore/Modules/webxr/WebXRGamepad.cpp b/Source/WebCore/Modules/webxr/WebXRGamepad.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..47c047c0d714a9611d89f197df49105726e83560 >--- /dev/null >+++ b/Source/WebCore/Modules/webxr/WebXRGamepad.cpp >@@ -0,0 +1,57 @@ >+/* >+ * Copyright (C) 2020 Igalia S.L. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "WebXRGamepad.h" >+ >+#if ENABLE(WEBXR) && ENABLE(GAMEPAD) >+ >+#include "Gamepad.h" >+#include "GamepadConstants.h" >+#include "XRTargetRayMode.h" >+ >+namespace WebCore { >+ >+// https://immersive-web.github.io/webxr-gamepads-module/#gamepad-differences >+WebXRGamepad::WebXRGamepad(double timestamp, double connectTime, const PlatformXR::Device::FrameData::InputSource& source) >+ : PlatformGamepad(-1) >+{ >+ m_lastUpdateTime = MonotonicTime::fromRawSeconds(Seconds::fromMilliseconds(timestamp).value()); >+ m_connectTime = MonotonicTime::fromRawSeconds(Seconds::fromMilliseconds(connectTime).value()); >+ // In order to report a mapping of "xr-standard" the device MUST report a targetRayMode of "tracked-pointer" and MUST have a non-null gripSpace. >+ // It MUST have at least one primary trigger, separate from any touchpads or thumbsticks >+ if (source.targetRayMode == XRTargetRayMode::TrackedPointer && !source.buttons.isEmpty() && source.gripOrigin.hasValue()) >+ m_mapping = xrStandardGamepadMappingString(); >+ m_axes = source.axes.map([](auto value) { >+ return SharedGamepadValue(value); >+ }); >+ m_buttons = source.buttons.map([](auto& value) { >+ return SharedGamepadValue(value.pressedValue); >+ }); >+} >+ >+} // namespace WebCore >+ >+#endif // ENABLE(WEBXR) && ENABLE(GAMEPAD) >diff --git a/Source/WebCore/Modules/webxr/WebXRGamepad.h b/Source/WebCore/Modules/webxr/WebXRGamepad.h >new file mode 100644 >index 0000000000000000000000000000000000000000..a07f4c71e13b9388df180b47441ca6ba7ea4bddb >--- /dev/null >+++ b/Source/WebCore/Modules/webxr/WebXRGamepad.h >@@ -0,0 +1,50 @@ >+/* >+ * Copyright (C) 2020 Igalia S.L. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if ENABLE(WEBXR) && ENABLE(GAMEPAD) >+ >+#include "PlatformGamepad.h" >+#include "PlatformXR.h" >+#include <wtf/Vector.h> >+ >+namespace WebCore { >+ >+class WebXRGamepad: public PlatformGamepad { >+public: >+ WebXRGamepad(double timestamp, double connectTime, const PlatformXR::Device::FrameData::InputSource&); >+ >+private: >+ const Vector<SharedGamepadValue>& axisValues() const final { return m_axes; } >+ const Vector<SharedGamepadValue>& buttonValues() const final { return m_buttons; } >+ >+ Vector<SharedGamepadValue> m_axes; >+ Vector<SharedGamepadValue> m_buttons; >+}; >+ >+} // namespace WebCore >+ >+#endif // ENABLE(WEBXR) >diff --git a/Source/WebCore/Modules/webxr/WebXRInputSource.cpp b/Source/WebCore/Modules/webxr/WebXRInputSource.cpp >index f3076751198dbbc376cb9719b8a87b12c62018dd..ed9397b8159d7a0998d6be6c8aadb7cb4cceb837 100644 >--- a/Source/WebCore/Modules/webxr/WebXRInputSource.cpp >+++ b/Source/WebCore/Modules/webxr/WebXRInputSource.cpp >@@ -28,50 +28,129 @@ > > #if ENABLE(WEBXR) > >-#include "WebXRSpace.h" >+#include "EventNames.h" >+#if ENABLE(GAMEPAD) >+#include "Gamepad.h" >+#include "WebXRGamepad.h" >+#endif >+#include "WebXRFrame.h" >+#include "WebXRSession.h" >+#include "XRInputSourceEvent.h" > #include <wtf/IsoMallocInlines.h> > > namespace WebCore { > > WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRInputSource); > >-Ref<WebXRInputSource> WebXRInputSource::create(Ref<WebXRSpace>&& targetRaySpace) >+Ref<WebXRInputSource> WebXRInputSource::create(Ref<Document>&& document, Ref<WebXRSession>&& session, double timestamp, const PlatformXR::Device::FrameData::InputSource& source) > { >- return adoptRef(*new WebXRInputSource(WTFMove(targetRaySpace))); >+ return adoptRef(*new WebXRInputSource(WTFMove(document), WTFMove(session), timestamp, source)); > } > >-WebXRInputSource::WebXRInputSource(Ref<WebXRSpace>&& targetRaySpace) >- : m_handedness(XRHandedness::None) >- , m_targetRayMode(XRTargetRayMode::Gaze) >- , m_targetRaySpace(WTFMove(targetRaySpace)) >+WebXRInputSource::WebXRInputSource(Ref<Document>&& document, Ref<WebXRSession>&& session, double timestamp, const PlatformXR::Device::FrameData::InputSource& source) >+ : m_document(document.copyRef()) >+ , m_session(WTFMove(session)) >+ , m_targetRaySpace(WebXRInputSpace::create(WTFMove(document), m_session.copyRef(), source.pointerOrigin)) >+ , m_connectTime(timestamp) >+#if ENABLE(GAMEPAD) >+ , m_gamepad(Gamepad::create(WebXRGamepad(timestamp, timestamp, source))) >+#endif > { >+ update(timestamp, source); > } > > WebXRInputSource::~WebXRInputSource() = default; > >-XRHandedness WebXRInputSource::handedness() const >+void WebXRInputSource::update(double timestamp, const PlatformXR::Device::FrameData::InputSource& source) > { >- return m_handedness; >+#if !ENABLE(GAMEPAD) >+ UNUSED_PARAM(timestamp); >+#endif >+ m_source = source; >+ m_targetRaySpace->setPose(source.pointerOrigin); >+ if (auto gripOrigin = source.gripOrigin) { >+ if (m_gripSpace) >+ m_gripSpace->setPose(*gripOrigin); >+ else >+ m_gripSpace = WebXRInputSpace::create(m_document.get(), m_session.copyRef(), *gripOrigin); >+ } else >+ m_gripSpace = nullptr; >+#if ENABLE(GAMEPAD) >+ m_gamepad->updateFromPlatformGamepad(WebXRGamepad(timestamp, m_connectTime, source)); >+#endif > } > >-XRTargetRayMode WebXRInputSource::targetRayMode() const >+bool WebXRInputSource::requiresInputSourceChange(const InputSource& source) > { >- return m_targetRayMode; >+ return m_source.handeness != source.handeness >+ || m_source.targetRayMode != source.targetRayMode >+ || m_source.profiles != source.profiles >+ || static_cast<bool>(m_gripSpace) != source.gripOrigin.hasValue(); > } > >-const WebXRSpace& WebXRInputSource::targetRaySpace() const >+void WebXRInputSource::disconnect() > { >- return m_targetRaySpace; >+ m_connected = false; >+#if ENABLE(GAMEPAD) >+ m_gamepad->setConnected(false); >+#endif > } > >-RefPtr<WebXRSpace> WebXRInputSource::gripSpace() const >+void WebXRInputSource::pollEvents(Vector<Ref<XRInputSourceEvent>>& events) > { >- return { }; >+ if (!m_connected) { >+ // A user agent MUST dispatch a selectend event on an XRSession when one of its XRInputSources ends >+ // when an XRInputSource that has begun a primary select action is disconnected. >+ if (m_selectStarted) >+ events.append(createEvent(eventNames().selectendEvent)); >+ >+ // A user agent MUST dispatch a squeezeend event on an XRSession when one of its XRInputSources ends >+ // when an XRInputSource that has begun a primary squeeze action is disconnected. >+ if (m_squeezeStarted) >+ events.append(createEvent(eventNames().squeezeendEvent)); >+ >+ return; >+ } >+ >+ // https://immersive-web.github.io/webxr-gamepads-module/#xr-standard-gamepad-mapping >+ // Button indices are based on the xr-standard layout. >+ bool selectStarted = !m_source.buttons.isEmpty() && m_source.buttons.first().pressed; >+ bool squeezeStarted = m_source.buttons.size() > 1 && m_source.buttons[1].pressed; >+ >+ if (selectStarted != m_selectStarted) { >+ if (selectStarted) { >+ // A user agent MUST dispatch a selectstart event on an XRSession when one of its XRInputSources begins its primary action. >+ events.append(createEvent(eventNames().selectstartEvent)); >+ } else { >+ // A user agent MUST dispatch a selectend event on an XRSession when one of its XRInputSources ends its primary action. >+ // A user agent MUST dispatch a select event on an XRSession when one of its XRInputSources has fully completed a primary action >+ events.append(createEvent(eventNames().selectEvent)); >+ events.append(createEvent(eventNames().selectendEvent)); >+ } >+ m_selectStarted = selectStarted; >+ } >+ >+ if (squeezeStarted != m_squeezeStarted) { >+ if (squeezeStarted) { >+ // A user agent MUST dispatch a squeezestart event on an XRSession when one of its XRInputSources begins its primary squeeze action. >+ events.append(createEvent(eventNames().squeezestartEvent)); >+ } else { >+ // A user agent MUST dispatch a selectend event on an XRSession when one of its XRInputSources ends its primary squeeze action. >+ // A user agent MUST dispatch a select event on an XRSession when one of its XRInputSources has fully completed a primary squeeze action. >+ events.append(createEvent(eventNames().squeezeEvent)); >+ events.append(createEvent(eventNames().squeezeendEvent)); >+ } >+ m_squeezeStarted = squeezeStarted; >+ } > } > >-const Vector<String>& WebXRInputSource::profiles() const >+Ref<XRInputSourceEvent> WebXRInputSource::createEvent(const AtomString& name) > { >- return m_profiles; >+ XRInputSourceEvent::Init init; >+ init.frame = WebXRFrame::create(m_session.copyRef(), WebXRFrame::IsAnimationFrame::No); >+ init.inputSource = makeRefPtr(*this); >+ >+ return XRInputSourceEvent::create(name, init); > } > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/webxr/WebXRInputSource.h b/Source/WebCore/Modules/webxr/WebXRInputSource.h >index 68c29ab1cdb906dbe14bb9492ab2fd88b41d4112..cb0310fa68bb67312f54572d48b7ab12b91d8954 100644 >--- a/Source/WebCore/Modules/webxr/WebXRInputSource.h >+++ b/Source/WebCore/Modules/webxr/WebXRInputSource.h >@@ -27,6 +27,9 @@ > > #if ENABLE(WEBXR) > >+#include "PlatformXR.h" >+#include "WebXRGamepad.h" >+#include "WebXRInputSpace.h" > #include "XRHandedness.h" > #include "XRTargetRayMode.h" > #include <wtf/IsoMalloc.h> >@@ -38,27 +41,55 @@ > > namespace WebCore { > >-class WebXRSpace; >+#if ENABLE(GAMEPAD) >+class Gamepad; >+#endif >+class XRInputSourceEvent; >+class WebXRInputSpace; > > class WebXRInputSource : public RefCounted<WebXRInputSource> { > WTF_MAKE_ISO_ALLOCATED(WebXRInputSource); > public: >- static Ref<WebXRInputSource> create(Ref<WebXRSpace>&&); >+ using InputSource = PlatformXR::Device::FrameData::InputSource; >+ using InputSourceButton = PlatformXR::Device::FrameData::InputSourceButton; >+ >+ static Ref<WebXRInputSource> create(Ref<Document>&&, Ref<WebXRSession>&&, double timestamp, const InputSource&); > ~WebXRInputSource(); > >- XRHandedness handedness() const; >- XRTargetRayMode targetRayMode() const; >- const WebXRSpace& targetRaySpace() const; >- RefPtr<WebXRSpace> gripSpace() const; >- const Vector<String>& profiles() const; >+ PlatformXR::InputSourceHandle handle() const { return m_source.handle; } >+ XRHandedness handedness() const { return m_source.handeness; } >+ XRTargetRayMode targetRayMode() const { return m_source.targetRayMode; }; >+ const WebXRSpace& targetRaySpace() const {return m_targetRaySpace.get(); }; >+ RefPtr<WebXRSpace> gripSpace() const { return m_gripSpace; } >+ const Vector<String>& profiles() const { return m_source.profiles; }; >+#if ENABLE(GAMEPAD) >+ const Gamepad* gamepad() const { return m_gamepad.ptr(); } >+#endif >+ >+ void update(double timestamp, const InputSource&); >+ bool requiresInputSourceChange(const InputSource&); >+ void disconnect(); >+ >+ void pollEvents(Vector<Ref<XRInputSourceEvent>>&); > > private: >- WebXRInputSource(Ref<WebXRSpace>&&); >+ WebXRInputSource(Ref<Document>&&, Ref<WebXRSession>&&, double timestamp, const InputSource&); >+ >+ Ref<XRInputSourceEvent> createEvent(const AtomString&); >+ >+ Ref<Document> m_document; >+ Ref<WebXRSession> m_session; >+ InputSource m_source; >+ Ref<WebXRInputSpace> m_targetRaySpace; >+ RefPtr<WebXRInputSpace> m_gripSpace; >+ double m_connectTime { 0 }; >+ bool m_connected { true }; >+#if ENABLE(GAMEPAD) >+ Ref<Gamepad> m_gamepad; >+#endif > >- XRHandedness m_handedness; >- XRTargetRayMode m_targetRayMode; >- Ref<WebXRSpace> m_targetRaySpace; >- Vector<String> m_profiles; >+ bool m_selectStarted { false }; >+ bool m_squeezeStarted { false }; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/webxr/WebXRInputSource.idl b/Source/WebCore/Modules/webxr/WebXRInputSource.idl >index 0459f3fe4707521137bf53f1a344eddd98ebd369..8d219065657a2f3ee36833ed8ea5428a224a5a08 100644 >--- a/Source/WebCore/Modules/webxr/WebXRInputSource.idl >+++ b/Source/WebCore/Modules/webxr/WebXRInputSource.idl >@@ -35,5 +35,8 @@ > readonly attribute XRTargetRayMode targetRayMode ; > [SameObject] readonly attribute WebXRSpace targetRaySpace; > [SameObject] readonly attribute WebXRSpace? gripSpace ; >- [SameObject] readonly attribute FrozenArray<DOMString> profiles; >+ [CachedAttribute, SameObject] readonly attribute FrozenArray<DOMString> profiles; >+ >+ // https://immersive-web.github.io/webxr-gamepads-module/#xrinputsource-interface >+ [Conditional=GAMEPAD, SameObject] readonly attribute Gamepad? gamepad; > }; >diff --git a/Source/WebCore/Modules/webxr/WebXRInputSourceArray.cpp b/Source/WebCore/Modules/webxr/WebXRInputSourceArray.cpp >index c4c085532bcd9aac2738090bfa3fddfea43355d3..cfd51bdfd4922007d828e0afd35abdad56df63dc 100644 >--- a/Source/WebCore/Modules/webxr/WebXRInputSourceArray.cpp >+++ b/Source/WebCore/Modules/webxr/WebXRInputSourceArray.cpp >@@ -27,21 +27,155 @@ > #include "WebXRInputSourceArray.h" > > #if ENABLE(WEBXR) >- >+#include "EventNames.h" >+#include "WebXRInputSource.h" >+#include "WebXRSession.h" >+#include "XRInputSourceEvent.h" >+#include "XRInputSourcesChangeEvent.h" > #include <wtf/IsoMallocInlines.h> > > namespace WebCore { > > WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRInputSourceArray); > >+Ref<WebXRInputSourceArray> WebXRInputSourceArray::create(Ref<Document>&& document, Ref<WebXRSession>&& session) >+{ >+ return adoptRef(*new WebXRInputSourceArray(WTFMove(document), WTFMove(session))); >+} >+ >+WebXRInputSourceArray::WebXRInputSourceArray(Ref<Document>&& document, Ref<WebXRSession>&& session) >+ : m_document(WTFMove(document)) >+ , m_session(WTFMove(session)) >+{ >+} >+ >+WebXRInputSourceArray::~WebXRInputSourceArray() = default; >+ > unsigned WebXRInputSourceArray::length() const > { >- return 0; >+ return m_inputSources.size(); >+} >+ >+WebXRInputSource* WebXRInputSourceArray::item(unsigned index) const >+{ >+ if (index >= m_inputSources.size()) >+ return nullptr; >+ return m_inputSources[index].ptr(); >+} >+ >+void WebXRInputSourceArray::clear() >+{ >+ m_inputSources.clear(); > } > >-WebXRInputSource* WebXRInputSourceArray::item(unsigned) const >+// https://immersive-web.github.io/webxr/#list-of-active-xr-input-sources >+void WebXRInputSourceArray::update(double timestamp, const InputSourceList& inputSources) > { >- return nullptr; >+ Vector<Ref<WebXRInputSource>> added; >+ Vector<Ref<WebXRInputSource>> removed; >+ Vector<Ref<XRInputSourceEvent>> inputEvents; >+ >+ handleRemovedInputSources(inputSources, removed, inputEvents); >+ handleAddedOrUpdatedInputSources(timestamp, inputSources, added, removed, inputEvents); >+ >+ if (!added.isEmpty() || !removed.isEmpty()) { >+ // A user agent MUST dispatch an inputsourceschange event on an XRSession when the sessionâs list of active XR input sources has changed. >+ XRInputSourcesChangeEvent::Init init; >+ init.session = m_session.copyRef(); >+ init.added = added.map([](auto& input) { >+ return makeRefPtr(input.get()); >+ }); >+ init.removed = removed.map([](auto& input) { >+ return makeRefPtr(input.get()); >+ }); >+ >+ auto event = XRInputSourcesChangeEvent::create(eventNames().inputsourceschangeEvent, init); >+ m_session->queueTaskToDispatchEvent(m_session.get(), TaskSource::WebXR, WTFMove(event)); >+ } >+ >+ if (!inputEvents.isEmpty()) { >+ // When the user agent has to fire an input source event with name name, XRFrame frame, and XRInputSource source it MUST run the following steps: >+ // 1. Create an XRInputSourceEvent event with type name, frame frame, and inputSource source. >+ // 2. Set frameâs active boolean to true. >+ // 3. Apply frame updates for frame. >+ // 4. Dispatch event on frameâs session >+ // 5. Set frameâs active boolean to false. >+ >+ for (auto& event : inputEvents) { >+ event->setFrameActive(true); >+ m_session->queueTaskToDispatchEvent(m_session.get(), TaskSource::WebXR, event.copyRef()); >+ m_session->queueTaskKeepingObjectAlive(m_session.get(), TaskSource::WebXR, [event = WTFMove(event)]() { >+ event->setFrameActive(false); >+ }); >+ } >+ } >+} >+ >+// https://immersive-web.github.io/webxr/#list-of-active-xr-input-sources >+void WebXRInputSourceArray::handleRemovedInputSources(const InputSourceList& inputSources, Vector<Ref<WebXRInputSource>>& removed, Vector<Ref<XRInputSourceEvent>>& inputEvents) >+{ >+ // When any previously added XR input sources are no longer available for XRSession session, the user agent MUST run the following steps: >+ // 1. If session's promise resolved flag is not set, abort these steps. >+ // 2. Let removed be a new list. >+ // 3. For each XR input source that is no longer available: >+ // 3.1 Let inputSource be the XRInputSource in session's list of active XR input sources associated with the XR input source. >+ // 3.2 Add inputSource to removed. >+ m_inputSources.removeAllMatching([this, &inputSources, &removed, &inputEvents](auto& source) { >+ if (inputSources.findMatching([&source](auto& item) { return item.handle == source->handle(); }) == WTF::notFound) { >+ removed.append(source.copyRef()); >+ source->disconnect(); >+ source->pollEvents(inputEvents); >+ return true; >+ } >+ return false; >+ }); >+} >+ >+// https://immersive-web.github.io/webxr/#list-of-active-xr-input-sources >+void WebXRInputSourceArray::handleAddedOrUpdatedInputSources(double timestamp, const InputSourceList& inputSources, Vector<Ref<WebXRInputSource>>& added, Vector<Ref<WebXRInputSource>>& removed, Vector<Ref<XRInputSourceEvent>>& inputEvents) >+{ >+ for (auto& inputSource : inputSources) { >+ auto index = m_inputSources.findMatching([&inputSource](auto& item) { return item->handle() == inputSource.handle; }); >+ if (index == WTF::notFound) { >+ // When new XR input sources become available for XRSession session, the user agent MUST run the following steps: >+ // 1. If session's promise resolved flag is not set, abort these steps. >+ // 2. Let added be a new list. >+ // 3. For each new XR input source: >+ // 3.1 Let inputSource be a new XRInputSource in the relevant realm of this XRSession. >+ // 3.2 Add inputSource to added. >+ auto input = WebXRInputSource::create(m_document.copyRef(), m_session.copyRef(), timestamp, inputSource); >+ added.append(input.copyRef()); >+ input->pollEvents(inputEvents); >+ m_inputSources.append(WTFMove(input)); >+ continue; >+ } >+ >+ // When the handedness, targetRayMode, profiles, or presence of a gripSpace for any XR input sources change for XRSession session, the user agent MUST run the following steps >+ // 1. If sessionâs promise resolved flag is not set, abort these steps. >+ // 2. Let added be a new list. >+ // 3. Let removed be a new list. >+ // 4. For each changed XR input source: >+ // 4.1 Let oldInputSource be the XRInputSource in session's list of active XR input sources previously associated with the XR input source. >+ // 4.1 Let newInputSource be a new XRInputSource in the relevant realm of session. >+ // 4.1 Add oldInputSource to removed. >+ // 4.1 Add newInputSource to added. >+ auto& input = m_inputSources[index]; >+ >+ if (input->requiresInputSourceChange(inputSource)) { >+ removed.append(input.copyRef()); >+ input->disconnect(); >+ input->pollEvents(inputEvents); >+ m_inputSources.remove(index); >+ >+ auto newInputSource = WebXRInputSource::create(m_document.copyRef(), m_session.copyRef(), timestamp, inputSource); >+ added.append(newInputSource.copyRef()); >+ newInputSource->pollEvents(inputEvents); >+ m_inputSources.append(WTFMove(newInputSource)); >+ } else { >+ input->update(timestamp, inputSource); >+ input->pollEvents(inputEvents); >+ } >+ } > } > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/webxr/WebXRInputSourceArray.h b/Source/WebCore/Modules/webxr/WebXRInputSourceArray.h >index 43b9d1a0ff1ee57d594def9213c0630883836d62..b775ba96e2a1a0ea2a5d265ee1834fd75ab5804d 100644 >--- a/Source/WebCore/Modules/webxr/WebXRInputSourceArray.h >+++ b/Source/WebCore/Modules/webxr/WebXRInputSourceArray.h >@@ -27,25 +27,40 @@ > > #if ENABLE(WEBXR) > >+#include "PlatformXR.h" > #include <wtf/IsoMalloc.h> > #include <wtf/Ref.h> > #include <wtf/RefCounted.h> > > namespace WebCore { > >+class Document; > class WebXRInputSource; >+class XRInputSourceEvent; >+class WebXRSession; > > class WebXRInputSourceArray : public RefCounted<WebXRInputSourceArray> { > WTF_MAKE_ISO_ALLOCATED(WebXRInputSourceArray); > public: >- static Ref<WebXRInputSourceArray> create() { return adoptRef(*new WebXRInputSourceArray()); } >- ~WebXRInputSourceArray() = default; >+ using InputSourceList = Vector<PlatformXR::Device::FrameData::InputSource>; >+ static Ref<WebXRInputSourceArray> create(Ref<Document>&&, Ref<WebXRSession>&&); >+ ~WebXRInputSourceArray(); > > unsigned length() const; > WebXRInputSource* item(unsigned) const; > >+ void clear(); >+ void update(double timestamp, const InputSourceList&); >+ > private: >- WebXRInputSourceArray() = default; >+ WebXRInputSourceArray(Ref<Document>&&, Ref<WebXRSession>&&); >+ >+ void handleRemovedInputSources(const InputSourceList&, Vector<Ref<WebXRInputSource>>&, Vector<Ref<XRInputSourceEvent>>&); >+ void handleAddedOrUpdatedInputSources(double timestamp, const InputSourceList&, Vector<Ref<WebXRInputSource>>&, Vector<Ref<WebXRInputSource>>&, Vector<Ref<XRInputSourceEvent>>&); >+ >+ Ref<Document> m_document; >+ Ref<WebXRSession> m_session; >+ Vector<Ref<WebXRInputSource>> m_inputSources; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/webxr/WebXRInputSpace.cpp b/Source/WebCore/Modules/webxr/WebXRInputSpace.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..f77ca52372a4ecb56fe4671dd76e5451835ddde7 >--- /dev/null >+++ b/Source/WebCore/Modules/webxr/WebXRInputSpace.cpp >@@ -0,0 +1,63 @@ >+/* >+ * Copyright (C) 2020 Igalia S.L. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "WebXRInputSpace.h" >+ >+#if ENABLE(WEBXR) >+ >+#include "WebXRFrame.h" >+#include "WebXRRigidTransform.h" >+#include "WebXRSession.h" >+#include <wtf/IsoMallocInlines.h> >+ >+namespace WebCore { >+ >+WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRInputSpace); >+ >+// WebXRInputSpace >+ >+Ref<WebXRInputSpace> WebXRInputSpace::create(Document& document, Ref<WebXRSession>&& session, const PlatformXR::Device::FrameData::InputSourcePose& pose) >+{ >+ return adoptRef(*new WebXRInputSpace(document, WTFMove(session), pose)); >+} >+ >+WebXRInputSpace::WebXRInputSpace(Document& document, Ref<WebXRSession>&& session, const PlatformXR::Device::FrameData::InputSourcePose& pose) >+ : WebXRSpace(document, WebXRRigidTransform::create()) >+ , m_session(WTFMove(session)) >+ , m_pose(pose) >+{ >+} >+ >+WebXRInputSpace::~WebXRInputSpace() = default; >+ >+TransformationMatrix WebXRInputSpace::nativeOrigin() const >+{ >+ return WebXRFrame::matrixFromPose(m_pose.pose); >+} >+ >+} // namespace WebCore >+ >+#endif // ENABLE(WEBXR) >diff --git a/Source/WebCore/Modules/webxr/WebXRInputSpace.h b/Source/WebCore/Modules/webxr/WebXRInputSpace.h >new file mode 100644 >index 0000000000000000000000000000000000000000..495a8c85b09594d657c3e63cb17af031aca7ba66 >--- /dev/null >+++ b/Source/WebCore/Modules/webxr/WebXRInputSpace.h >@@ -0,0 +1,64 @@ >+/* >+ * Copyright (C) 2020 Igalia S.L. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if ENABLE(WEBXR) >+ >+#include "WebXRSpace.h" >+#include "XRHandedness.h" >+#include "XRTargetRayMode.h" >+#include <wtf/IsoMalloc.h> >+#include <wtf/RefCounted.h> >+ >+namespace WebCore { >+ >+class WebXRInputSpace : public RefCounted<WebXRInputSpace>, public WebXRSpace { >+ WTF_MAKE_ISO_ALLOCATED(WebXRInputSpace); >+public: >+ static Ref<WebXRInputSpace> create(Document&, Ref<WebXRSession>&&, const PlatformXR::Device::FrameData::InputSourcePose&); >+ virtual ~WebXRInputSpace(); >+ >+ using RefCounted<WebXRInputSpace>::ref; >+ using RefCounted<WebXRInputSpace>::deref; >+ >+ bool isPositionEmulated() const final { return m_pose.isPositionEmulated; } >+ void setPose(const PlatformXR::Device::FrameData::InputSourcePose& pose) { m_pose = pose; } >+ >+private: >+ WebXRInputSpace(Document&, Ref<WebXRSession>&&, const PlatformXR::Device::FrameData::InputSourcePose&); >+ WebXRSession& session() const final { return m_session.get(); } >+ TransformationMatrix nativeOrigin() const final; >+ >+ void refEventTarget() final { ref(); } >+ void derefEventTarget() final { deref(); } >+ >+ Ref<WebXRSession> m_session; >+ PlatformXR::Device::FrameData::InputSourcePose m_pose; >+}; >+ >+} // namespace WebCore >+ >+#endif // ENABLE(WEBXR) >diff --git a/Source/WebCore/Modules/webxr/WebXRSession.cpp b/Source/WebCore/Modules/webxr/WebXRSession.cpp >index deb4a590e79cd2b0d0f83043de704d14617e029b..a81fd5861c2efcf66090624bdd9f55dca60dab98 100644 >--- a/Source/WebCore/Modules/webxr/WebXRSession.cpp >+++ b/Source/WebCore/Modules/webxr/WebXRSession.cpp >@@ -52,7 +52,7 @@ Ref<WebXRSession> WebXRSession::create(Document& document, WebXRSystem& system, > > WebXRSession::WebXRSession(Document& document, WebXRSystem& system, XRSessionMode mode, PlatformXR::Device& device, FeatureList&& requestedFeatures) > : ActiveDOMObject(&document) >- , m_inputSources(WebXRInputSourceArray::create()) >+ , m_inputSources(WebXRInputSourceArray::create(document, *this)) > , m_xrSystem(system) > , m_mode(mode) > , m_device(makeWeakPtr(device)) >@@ -62,8 +62,8 @@ WebXRSession::WebXRSession(Document& document, WebXRSystem& system, XRSessionMod > , m_timeOrigin(MonotonicTime::now()) > , m_views(device.views(mode)) > { >- m_device->initializeTrackingAndRendering(mode); > m_device->setTrackingAndRenderingClient(makeWeakPtr(*this)); >+ m_device->initializeTrackingAndRendering(mode); > > // https://immersive-web.github.io/webxr/#ref-for-dom-xrreferencespacetype-viewer%E2%91%A2 > // Every session MUST support viewer XRReferenceSpaces. >@@ -315,6 +315,11 @@ bool WebXRSession::supportsViewportScaling() const > return m_mode == XRSessionMode::ImmersiveVr && m_device->supportsViewportScaling(); > } > >+bool WebXRSession::isPositionEmulated() const >+{ >+ return m_frameData.isPositionEmulated || !m_frameData.isPositionValid; >+} >+ > // https://immersive-web.github.io/webxr/#shut-down-the-session > void WebXRSession::shutdown(InitiatedBySystem initiatedBySystem) > { >@@ -338,6 +343,8 @@ void WebXRSession::shutdown(InitiatedBySystem initiatedBySystem) > // 4. Remove session from the list of inline sessions. > m_xrSystem.sessionEnded(*this); > >+ m_inputSources->clear(); >+ > if (initiatedBySystem == InitiatedBySystem::Yes) { > // If we get here, the session termination was triggered by the system rather than > // via XRSession.end(). Since the system has completed the session shutdown, we can >@@ -411,6 +418,25 @@ void WebXRSession::stop() > { > } > >+void WebXRSession::sessionDidInitializeInputSources(Vector<PlatformXR::Device::FrameData::InputSource>&& inputSources) >+{ >+ // https://immersive-web.github.io/webxr/#dom-xrsystem-requestsession >+ // 5.4.10 Queue a task to perform the following steps: NOTE: These steps ensure that initial inputsourceschange >+ // events occur after the initial session is resolved. >+ // 1. Set session's promise resolved flag to true. >+ // 2. Let sources be any existing input sources attached to session. >+ // 3. If sources is non-empty, perform the following steps: >+ // 1. Set session's list of active XR input sources to sources. >+ // 2. Fire an XRInputSourcesChangeEvent named inputsourceschange on session with added set to sources. >+ >+ auto timestamp = (MonotonicTime::now() - m_timeOrigin).milliseconds(); >+ >+ queueTaskKeepingObjectAlive(*this, TaskSource::WebXR, [this, timestamp, inputSources = WTFMove(inputSources)]() mutable { >+ m_inputInitialized = true; >+ m_inputSources->update(timestamp, inputSources); >+ }); >+} >+ > void WebXRSession::sessionDidEnd() > { > // This can be called as a result of finishing the shutdown initiated >@@ -527,6 +553,9 @@ void WebXRSession::onFrame(PlatformXR::Device::FrameData&& frameData) > frame->setActive(true); > > // 6.4.Apply frame updates for frame. >+ if (m_inputInitialized) >+ m_inputSources->update(now, frameData.inputSources); >+ > frame->setFrameData(WTFMove(frameData)); > > // 6.5.For each entry in sessionâs list of currently running animation frame callbacks, in order: >diff --git a/Source/WebCore/Modules/webxr/WebXRSession.h b/Source/WebCore/Modules/webxr/WebXRSession.h >index 313d8fc0e1569b829fe981e60885577cf366711e..8ed41e172c9a7daf77ca4ac68d1a4f12a5815c96 100644 >--- a/Source/WebCore/Modules/webxr/WebXRSession.h >+++ b/Source/WebCore/Modules/webxr/WebXRSession.h >@@ -84,6 +84,7 @@ public: > IntSize nativeWebGLFramebufferResolution() const; > IntSize recommendedWebGLFramebufferResolution() const; > bool supportsViewportScaling() const; >+ bool isPositionEmulated() const; > > // EventTarget. > ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); } >@@ -111,6 +112,7 @@ private: > void stop() override; > > // PlatformXR::TrackingAndRenderingClient >+ void sessionDidInitializeInputSources(Vector<PlatformXR::Device::FrameData::InputSource>&&) final; > void sessionDidEnd() final; > > enum class InitiatedBySystem : bool { No, Yes }; >@@ -152,6 +154,9 @@ private: > // In meters. > double m_minimumNearClipPlane { 0.1 }; > double m_maximumFarClipPlane { 1000.0 }; >+ >+ // https://immersive-web.github.io/webxr/#xrsession-promise-resolved >+ bool m_inputInitialized { false }; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/webxr/WebXRSpace.cpp b/Source/WebCore/Modules/webxr/WebXRSpace.cpp >index fa881d4bbb4f551bd6a328292b0229ea17d949f9..119214189fc201d851344deb0d316d39f478a593 100644 >--- a/Source/WebCore/Modules/webxr/WebXRSpace.cpp >+++ b/Source/WebCore/Modules/webxr/WebXRSpace.cpp >@@ -54,6 +54,11 @@ TransformationMatrix WebXRSpace::effectiveOrigin() const > } > > >+bool WebXRSpace::isPositionEmulated() const >+{ >+ return session().isPositionEmulated(); >+} >+ > WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRViewerSpace); > > WebXRViewerSpace::WebXRViewerSpace(Document& document, WebXRSession& session) >diff --git a/Source/WebCore/Modules/webxr/WebXRSpace.h b/Source/WebCore/Modules/webxr/WebXRSpace.h >index 4a9dbefdd3b547f8a0623d265649d6f90bb9bf4a..d8f88ea58b9584518d476540edc8dddb19679db4 100644 >--- a/Source/WebCore/Modules/webxr/WebXRSpace.h >+++ b/Source/WebCore/Modules/webxr/WebXRSpace.h >@@ -47,6 +47,7 @@ public: > virtual WebXRSession& session() const = 0; > virtual TransformationMatrix nativeOrigin() const = 0; > TransformationMatrix effectiveOrigin() const; >+ virtual bool isPositionEmulated() const; > > virtual bool isReferenceSpace() const { return false; } > virtual bool isBoundedReferenceSpace() const { return false; } >diff --git a/Source/WebCore/Modules/webxr/WebXRSystem.cpp b/Source/WebCore/Modules/webxr/WebXRSystem.cpp >index 2028a04f24276f0c7ee3ac7ce0e440ae44233828..4d185f80f3af6e1b8aa836ae10c4c1d3c7a61764 100644 >--- a/Source/WebCore/Modules/webxr/WebXRSystem.cpp >+++ b/Source/WebCore/Modules/webxr/WebXRSystem.cpp >@@ -446,14 +446,7 @@ void WebXRSystem::requestSession(Document& document, XRSessionMode mode, const X > promise.resolve(WTFMove(session)); > rejectPromiseWithNotSupportedError.release(); > >- // FIXME: >- // 5.4.10 Queue a task to perform the following steps: NOTE: These steps ensure that initial inputsourceschange >- // events occur after the initial session is resolved. >- // 1. Set session's promise resolved flag to true. >- // 2. Let sources be any existing input sources attached to session. >- // 3. If sources is non-empty, perform the following steps: >- // 1. Set session's list of active XR input sources to sources. >- // 2. Fire an XRInputSourcesChangeEvent named inputsourceschange on session with added set to sources. >+ // 5.4.10 is handled in WebXRSession::sessionDidInitializeInputSources. > }); > } > >diff --git a/Source/WebCore/Modules/webxr/XRHandedness.h b/Source/WebCore/Modules/webxr/XRHandedness.h >index 9333034d0cd49ac8dee902a081644804378cbc2c..85985ccafa6bcd456ac0b6452e704ae0bfe07876 100644 >--- a/Source/WebCore/Modules/webxr/XRHandedness.h >+++ b/Source/WebCore/Modules/webxr/XRHandedness.h >@@ -27,13 +27,11 @@ > > #if ENABLE(WEBXR) > >+#include "PlatformXR.h" >+ > namespace WebCore { > >-enum class XRHandedness { >- None, >- Left, >- Right, >-}; >+using XRHandedness = PlatformXR::XRHandedness; > > } // namespace WebCore > >diff --git a/Source/WebCore/Modules/webxr/XRInputSourceEvent.cpp b/Source/WebCore/Modules/webxr/XRInputSourceEvent.cpp >index 22631ab55297056cc063d744689d3e033ca0fa57..fc88bf7a79b698407049cf600b9717ebd362c221 100644 >--- a/Source/WebCore/Modules/webxr/XRInputSourceEvent.cpp >+++ b/Source/WebCore/Modules/webxr/XRInputSourceEvent.cpp >@@ -30,9 +30,12 @@ > > #include "WebXRFrame.h" > #include "WebXRInputSource.h" >+#include <wtf/IsoMallocInlines.h> > > namespace WebCore { > >+WTF_MAKE_ISO_ALLOCATED_IMPL(XRInputSourceEvent); >+ > Ref<XRInputSourceEvent> XRInputSourceEvent::create(const AtomString& type, const Init& initializer, IsTrusted isTrusted) > { > return adoptRef(*new XRInputSourceEvent(type, initializer, isTrusted)); >@@ -42,7 +45,6 @@ XRInputSourceEvent::XRInputSourceEvent(const AtomString& type, const Init& initi > : Event(type, initializer, isTrusted) > , m_frame(initializer.frame) > , m_inputSource(initializer.inputSource) >- , m_buttonIndex(initializer.buttonIndex) > { > ASSERT(m_frame); > ASSERT(m_inputSource); >@@ -60,9 +62,9 @@ const WebXRInputSource& XRInputSourceEvent::inputSource() const > return *m_inputSource; > } > >-Optional<int> XRInputSourceEvent::buttonIndex() const >+void XRInputSourceEvent::setFrameActive(bool active) > { >- return m_buttonIndex; >+ m_frame->setActive(active); > } > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/webxr/XRInputSourceEvent.h b/Source/WebCore/Modules/webxr/XRInputSourceEvent.h >index 8c7fc04747a2bf11ea8b2fb7b5ca9f454ac15303..e3c541134551bc275af0fc41b67eac439833f091 100644 >--- a/Source/WebCore/Modules/webxr/XRInputSourceEvent.h >+++ b/Source/WebCore/Modules/webxr/XRInputSourceEvent.h >@@ -37,11 +37,11 @@ class WebXRFrame; > class WebXRInputSource; > > class XRInputSourceEvent final : public Event { >+ WTF_MAKE_ISO_ALLOCATED(XRInputSourceEvent); > public: > struct Init : EventInit { > RefPtr<WebXRFrame> frame; > RefPtr<WebXRInputSource> inputSource; >- Optional<int> buttonIndex; > }; > > static Ref<XRInputSourceEvent> create(const AtomString&, const Init&, IsTrusted = IsTrusted::No); >@@ -49,7 +49,9 @@ public: > > const WebXRFrame& frame() const; > const WebXRInputSource& inputSource() const; >- Optional<int> buttonIndex() const; >+ void setFrameActive(bool); >+ >+ EventInterface eventInterface() const final { return XRInputSourceEventInterfaceType; } > > private: > XRInputSourceEvent(const AtomString&, const Init&, IsTrusted); >diff --git a/Source/WebCore/Modules/webxr/XRInputSourcesChangeEvent.h b/Source/WebCore/Modules/webxr/XRInputSourcesChangeEvent.h >index 03a64b7b68d4f6226d42d1f27ed23221d26e8a84..dd5478f9ffac431738afb9ea2c191984f372d5d2 100644 >--- a/Source/WebCore/Modules/webxr/XRInputSourcesChangeEvent.h >+++ b/Source/WebCore/Modules/webxr/XRInputSourcesChangeEvent.h >@@ -52,6 +52,8 @@ public: > const Vector<RefPtr<WebXRInputSource>>& added() const; > const Vector<RefPtr<WebXRInputSource>>& removed() const; > >+ EventInterface eventInterface() const final { return XRInputSourcesChangeEventInterfaceType; } >+ > private: > XRInputSourcesChangeEvent(const AtomString&, const Init&, IsTrusted); > >diff --git a/Source/WebCore/Modules/webxr/XRInputSourcesChangeEvent.idl b/Source/WebCore/Modules/webxr/XRInputSourcesChangeEvent.idl >index 522bdc1d5dabe07c852ecd413d7c374712b6836d..eb919a10fb94c0b2e8ec88b4335ff59bba751cec 100644 >--- a/Source/WebCore/Modules/webxr/XRInputSourcesChangeEvent.idl >+++ b/Source/WebCore/Modules/webxr/XRInputSourcesChangeEvent.idl >@@ -41,6 +41,6 @@ > constructor(DOMString type, XRInputSourcesChangeEventInit eventInitDict); > > [SameObject] readonly attribute WebXRSession session; >- [SameObject] readonly attribute FrozenArray<WebXRInputSource> added; >- [SameObject] readonly attribute FrozenArray<WebXRInputSource> removed; >+ [CachedAttribute, SameObject] readonly attribute FrozenArray<WebXRInputSource> added; >+ [CachedAttribute, SameObject] readonly attribute FrozenArray<WebXRInputSource> removed; > }; >diff --git a/Source/WebCore/Modules/webxr/XRTargetRayMode.h b/Source/WebCore/Modules/webxr/XRTargetRayMode.h >index 1fca44e451b97c56026e145b522331f8165bae7f..b73b4e0cd1f34b8bb1845c5d5043406d7a71cd76 100644 >--- a/Source/WebCore/Modules/webxr/XRTargetRayMode.h >+++ b/Source/WebCore/Modules/webxr/XRTargetRayMode.h >@@ -29,11 +29,9 @@ > > namespace WebCore { > >-enum class XRTargetRayMode { >- Gaze, >- TrackedPointer, >- Screen, >-}; >+#include "PlatformXR.h" >+ >+using XRTargetRayMode = PlatformXR::XRTargetRayMode; > > } // namespace WebCore > >diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt >index ecacdebc1359a9ced42fdddc5a0b5b5ecfdc295b..eeddd7937758970e167529b419d7dd8933fbb569 100644 >--- a/Source/WebCore/Sources.txt >+++ b/Source/WebCore/Sources.txt >@@ -426,8 +426,10 @@ Modules/websockets/WorkerThreadableWebSocketChannel.cpp > Modules/webxr/NavigatorWebXR.cpp @no-unify > Modules/webxr/WebXRBoundedReferenceSpace.cpp @no-unify > Modules/webxr/WebXRFrame.cpp @no-unify >+Modules/webxr/WebXRGamepad.cpp @no-unify > Modules/webxr/WebXRInputSource.cpp @no-unify > Modules/webxr/WebXRInputSourceArray.cpp @no-unify >+Modules/webxr/WebXRInputSpace.cpp @no-unify > Modules/webxr/WebXRLayer.cpp @no-unify > Modules/webxr/WebXRPose.cpp @no-unify > Modules/webxr/WebXRReferenceSpace.cpp @no-unify >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index 2d6a46109bd54cb3bc9b9ea2719410f2a3a5a4c9..ab89f0d0a2cf9b988d1c772ba1a3829c51b66d0b 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -416,6 +416,10 @@ > 119340A31FEE024000935F1E /* RenderTreeBuilderBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 119340A11FEE024000935F1E /* RenderTreeBuilderBlock.h */; }; > 1199FA46208E35A3002358CC /* LayoutContainerBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 1199FA44208E35A3002358CC /* LayoutContainerBox.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 11CB2789203BA570004A1DC9 /* RenderTreeBuilderFullScreen.h in Headers */ = {isa = PBXBuildFile; fileRef = 11CB2787203BA570004A1DC9 /* RenderTreeBuilderFullScreen.h */; }; >+ 11E51638261E1A0600E69F25 /* WebXRInputSpace.h in Headers */ = {isa = PBXBuildFile; fileRef = 11E51635261E1A0500E69F25 /* WebXRInputSpace.h */; }; >+ 11E51639261E1A0600E69F25 /* WebXRInputSpace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 11E51637261E1A0500E69F25 /* WebXRInputSpace.cpp */; }; >+ 11E5163C261E1A1500E69F25 /* WebXRGamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = 11E5163A261E1A1400E69F25 /* WebXRGamepad.h */; }; >+ 11E5163D261E1A1500E69F25 /* WebXRGamepad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 11E5163B261E1A1400E69F25 /* WebXRGamepad.cpp */; }; > 1400D7A817136EA70077CE05 /* ScriptWrappableInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 1400D7A717136EA70077CE05 /* ScriptWrappableInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 1403B99709EB13AF00797C7F /* DOMWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 1403B99509EB13AF00797C7F /* DOMWindow.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 1403BA0F09EB18F900797C7F /* JSDOMWindow.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 1403BA0E09EB18F800797C7F /* JSDOMWindow.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -6407,6 +6411,10 @@ > 11CB2786203BA570004A1DC9 /* RenderTreeBuilderFullScreen.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreeBuilderFullScreen.cpp; sourceTree = "<group>"; }; > 11CB2787203BA570004A1DC9 /* RenderTreeBuilderFullScreen.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RenderTreeBuilderFullScreen.h; sourceTree = "<group>"; }; > 11D19C2E23159BAE008F24D3 /* TableFormattingContextGeometry.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TableFormattingContextGeometry.cpp; sourceTree = "<group>"; }; >+ 11E51635261E1A0500E69F25 /* WebXRInputSpace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebXRInputSpace.h; sourceTree = "<group>"; }; >+ 11E51637261E1A0500E69F25 /* WebXRInputSpace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebXRInputSpace.cpp; sourceTree = "<group>"; }; >+ 11E5163A261E1A1400E69F25 /* WebXRGamepad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebXRGamepad.h; sourceTree = "<group>"; }; >+ 11E5163B261E1A1400E69F25 /* WebXRGamepad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebXRGamepad.cpp; sourceTree = "<group>"; }; > 11E6CF1B25F140E30013D3D5 /* JSWebXRReferenceSpaceCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWebXRReferenceSpaceCustom.cpp; sourceTree = "<group>"; }; > 11E6CF1D25F140E40013D3D5 /* JSWebXRSpaceCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWebXRSpaceCustom.cpp; sourceTree = "<group>"; }; > 11FF02D520BA3C810083F25B /* Verification.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Verification.cpp; sourceTree = "<group>"; }; >@@ -28987,12 +28995,16 @@ > E1EE8AF02412B17000E794D6 /* WebXRFrame.cpp */, > E1EE8AE32412B17000E794D6 /* WebXRFrame.h */, > E19490882434F15900416A99 /* WebXRFrame.idl */, >+ 11E5163B261E1A1400E69F25 /* WebXRGamepad.cpp */, >+ 11E5163A261E1A1400E69F25 /* WebXRGamepad.h */, > E1EE8B0D2412B17000E794D6 /* WebXRInputSource.cpp */, > E1EE8B172412B17000E794D6 /* WebXRInputSource.h */, > E19490892434F15A00416A99 /* WebXRInputSource.idl */, > E1EE8AE62412B17000E794D6 /* WebXRInputSourceArray.cpp */, > E1EE8ADD2412B17000E794D6 /* WebXRInputSourceArray.h */, > E19490932434F16000416A99 /* WebXRInputSourceArray.idl */, >+ 11E51637261E1A0500E69F25 /* WebXRInputSpace.cpp */, >+ 11E51635261E1A0500E69F25 /* WebXRInputSpace.h */, > E12FDAFB24A0FD1C0070236E /* WebXRLayer.cpp */, > E12FDAFD24A0FD1E0070236E /* WebXRLayer.h */, > E12FDAFE24A0FD1F0070236E /* WebXRLayer.idl */, >@@ -32115,6 +32127,7 @@ > 4162A451101145AE00DFF3ED /* DedicatedWorkerGlobalScope.h in Headers */, > 41A3D58F101C152D00316D07 /* DedicatedWorkerThread.h in Headers */, > FD06DFA6134A4DEF006F5D7D /* DefaultAudioDestinationNode.h in Headers */, >+ E4F38D1B2626F13B007B1064 /* DefaultResourceLoadPriority.h in Headers */, > CD83D36221122A210076E11C /* DeferrableTask.h in Headers */, > FD31602C12B0267600C1A359 /* DelayDSPKernel.h in Headers */, > FD31602E12B0267600C1A359 /* DelayNode.h in Headers */, >@@ -34614,7 +34627,6 @@ > B595FF471824CEE300FF51CD /* RenderIterator.h in Headers */, > BCEA487A097D93020094C9E4 /* RenderLayer.h in Headers */, > 0F580CFF0F12DE9B0051D689 /* RenderLayerBacking.h in Headers */, >- E4F38D1B2626F13B007B1064 /* DefaultResourceLoadPriority.h in Headers */, > 0F580CFD0F12DE9B0051D689 /* RenderLayerCompositor.h in Headers */, > 3C244FEAA375AC633F88BE6F /* RenderLayerModelObject.h in Headers */, > 0F53FB84213B7A6400C40D34 /* RenderLayerScrollableArea.h in Headers */, >@@ -35773,8 +35785,10 @@ > B10B6982140C174000BC1C26 /* WebVTTTokenizer.h in Headers */, > E1EE8B7E2413191F00E794D6 /* WebXRBoundedReferenceSpace.h in Headers */, > E1EE8B8A2413191F00E794D6 /* WebXRFrame.h in Headers */, >+ 11E5163C261E1A1500E69F25 /* WebXRGamepad.h in Headers */, > E1EE8BA82413196300E794D6 /* WebXRInputSource.h in Headers */, > E1EE8B862413191F00E794D6 /* WebXRInputSourceArray.h in Headers */, >+ 11E51638261E1A0600E69F25 /* WebXRInputSpace.h in Headers */, > E12FDB0024A0FD200070236E /* WebXRLayer.h in Headers */, > E1EE8B882413191F00E794D6 /* WebXRPose.h in Headers */, > E1EE8BA62413196300E794D6 /* WebXRReferenceSpace.h in Headers */, >@@ -37091,8 +37105,10 @@ > CECDC93C21F2972900976BD1 /* WebVideoFullscreenControllerAVKit.mm in Sources */, > E1EE8B802413191F00E794D6 /* WebXRBoundedReferenceSpace.cpp in Sources */, > E1EE8B932413195000E794D6 /* WebXRFrame.cpp in Sources */, >+ 11E5163D261E1A1500E69F25 /* WebXRGamepad.cpp in Sources */, > E1EE8BA12413196300E794D6 /* WebXRInputSource.cpp in Sources */, > E1EE8B8C2413191F00E794D6 /* WebXRInputSourceArray.cpp in Sources */, >+ 11E51639261E1A0600E69F25 /* WebXRInputSpace.cpp in Sources */, > E12FDAFF24A0FD200070236E /* WebXRLayer.cpp in Sources */, > E1EE8B8B2413191F00E794D6 /* WebXRPose.cpp in Sources */, > E1EE8B7F2413191F00E794D6 /* WebXRReferenceSpace.cpp in Sources */, >diff --git a/Source/WebCore/platform/gamepad/GamepadConstants.cpp b/Source/WebCore/platform/gamepad/GamepadConstants.cpp >index c85e26a799ddc5d5581ce123e5ffb173532cad33..fc3960f39f446e35425f144af875a5f94fb63c7b 100644 >--- a/Source/WebCore/platform/gamepad/GamepadConstants.cpp >+++ b/Source/WebCore/platform/gamepad/GamepadConstants.cpp >@@ -43,6 +43,15 @@ const WTF::String& standardGamepadMappingString() > return standardGamepadMapping; > } > >+#if ENABLE(WEBXR) >+// https://immersive-web.github.io/webxr-gamepads-module/#dom-gamepadmappingtype-xr-standard >+const WTF::String& xrStandardGamepadMappingString() >+{ >+ static NeverDestroyed<String> xrStandardGamepadMapping = "xr-standard"; >+ return xrStandardGamepadMapping; >+} >+#endif >+ > > } // namespace WebCore > >diff --git a/Source/WebCore/platform/gamepad/GamepadConstants.h b/Source/WebCore/platform/gamepad/GamepadConstants.h >index 7e169f4da8b98fe6efaa1e230e2a4e924a236733..633afd73d3747faa3a08ae756cb43215125d254f 100644 >--- a/Source/WebCore/platform/gamepad/GamepadConstants.h >+++ b/Source/WebCore/platform/gamepad/GamepadConstants.h >@@ -62,6 +62,9 @@ extern const size_t numberOfStandardGamepadButtonsWithHomeButton; > extern const GamepadButtonRole maximumGamepadButton; > > const WTF::String& standardGamepadMappingString(); >+#if ENABLE(WEBXR) >+const WTF::String& xrStandardGamepadMappingString(); >+#endif > > } // namespace WebCore > >diff --git a/Source/WebCore/platform/xr/PlatformXR.h b/Source/WebCore/platform/xr/PlatformXR.h >index 0499c76e06ea68069a818ae3153a475cf8f9d6e9..4234b4353e3baedb0b2ae1c18954975d83583d00 100644 >--- a/Source/WebCore/platform/xr/PlatformXR.h >+++ b/Source/WebCore/platform/xr/PlatformXR.h >@@ -56,16 +56,24 @@ enum class Eye { > using LayerHandle = int; > > #if ENABLE(WEBXR) >+using InputSourceHandle = int; > >-class TrackingAndRenderingClient : public CanMakeWeakPtr<TrackingAndRenderingClient> { >-public: >- virtual ~TrackingAndRenderingClient() = default; >+// https://immersive-web.github.io/webxr/#enumdef-xrhandedness >+enum class XRHandedness { >+ None, >+ Left, >+ Right, >+}; > >- virtual void sessionDidEnd() = 0; >- // FIXME: handle frame update >- // FIXME: handle visibility changes >+// https://immersive-web.github.io/webxr/#enumdef-xrtargetraymode >+enum class XRTargetRayMode { >+ Gaze, >+ TrackedPointer, >+ Screen, > }; > >+class TrackingAndRenderingClient; >+ > class Device : public ThreadSafeRefCounted<Device>, public CanMakeWeakPtr<Device> { > WTF_MAKE_FAST_ALLOCATED; > WTF_MAKE_NONCOPYABLE(Device); >@@ -163,6 +171,28 @@ public: > template<class Decoder> static Optional<LayerData> decode(Decoder&); > }; > >+ struct InputSourceButton { >+ bool touched { false }; >+ bool pressed { false }; >+ float pressedValue { 0 }; >+ }; >+ >+ struct InputSourcePose { >+ Pose pose; >+ bool isPositionEmulated { false }; >+ }; >+ >+ struct InputSource { >+ InputSourceHandle handle { 0 }; >+ XRHandedness handeness { XRHandedness::None }; >+ XRTargetRayMode targetRayMode { XRTargetRayMode::Gaze }; >+ Vector<String> profiles; >+ InputSourcePose pointerOrigin; >+ Optional<InputSourcePose> gripOrigin; >+ Vector<InputSourceButton> buttons; >+ Vector<float> axes; >+ }; >+ > bool isTrackingValid { false }; > bool isPositionValid { false }; > bool isPositionEmulated { false }; >@@ -173,6 +203,7 @@ public: > StageParameters stageParameters; > Vector<View> views; > HashMap<LayerHandle, LayerData> layers; >+ Vector<InputSource> inputSources; > > template<class Encoder> void encode(Encoder&) const; > template<class Decoder> static Optional<FrameData> decode(Decoder&); >@@ -214,6 +245,19 @@ protected: > WeakPtr<TrackingAndRenderingClient> m_trackingAndRenderingClient; > }; > >+class TrackingAndRenderingClient : public CanMakeWeakPtr<TrackingAndRenderingClient> { >+public: >+ virtual ~TrackingAndRenderingClient() = default; >+ >+ // This event is used to ensure that initial inputsourceschange events occur after the initial session is resolved. >+ // WebxR apps can wait for the input source events before calling requestAnimationFrame. >+ // Per-frame input source updates are handled via session.requestAnimationFrame which calls Device::requestFrame. >+ virtual void sessionDidInitializeInputSources(Vector<Device::FrameData::InputSource>&&) = 0; >+ virtual void sessionDidEnd() = 0; >+ // FIXME: handle frame update >+ // FIXME: handle visibility changes >+}; >+ > class Instance { > public: > WEBCORE_EXPORT static Instance& singleton(); >diff --git a/Source/WebCore/testing/WebFakeXRDevice.cpp b/Source/WebCore/testing/WebFakeXRDevice.cpp >index e0164f49ca097b51a11ad188205654dc308282b5..f8c618e28215fd091bfd8b3f77507edbf576b8c3 100644 >--- a/Source/WebCore/testing/WebFakeXRDevice.cpp >+++ b/Source/WebCore/testing/WebFakeXRDevice.cpp >@@ -106,6 +106,19 @@ void SimulatedXRDevice::initializeTrackingAndRendering(PlatformXR::SessionMode) > attributes.stencil = false; > attributes.antialias = false; > m_gl = GraphicsContextGL::create(attributes, nullptr); >+ >+ if (m_trackingAndRenderingClient) { >+ // WebXR FakeDevice waits for simulateInputConnection calls to add input sources- >+ // There is no way to know how many simulateInputConnection calls will the device receive, >+ // so notify the input sources have been initialized with an empty list. This is not a problem because >+ // WPT tests rely on requestAnimationFrame updates to test the input sources. >+ callOnMainThread([this, weakThis = makeWeakPtr(*this)]() { >+ if (!weakThis) >+ return; >+ if (m_trackingAndRenderingClient) >+ m_trackingAndRenderingClient->sessionDidInitializeInputSources({ }); >+ }); >+ } > } > > void SimulatedXRDevice::shutDownTrackingAndRendering() >@@ -134,6 +147,11 @@ void SimulatedXRDevice::frameTimerFired() > for (auto& layer : m_layers) > data.layers.add(layer.key, FrameData::LayerData { .opaqueTexture = layer.value }); > >+ for (auto& input : m_inputConnections) { >+ if (input->isConnected()) >+ data.inputSources.append(input->getFrameData()); >+ } >+ > if (m_FrameCallback) > m_FrameCallback(WTFMove(data)); > } >@@ -237,11 +255,15 @@ void WebFakeXRDevice::setFloorOrigin(FakeXRRigidTransformInit origin) > > void WebFakeXRDevice::simulateResetPose() > { >+ > } > >-Ref<WebFakeXRInputController> WebFakeXRDevice::simulateInputSourceConnection(FakeXRInputSourceInit) >+Ref<WebFakeXRInputController> WebFakeXRDevice::simulateInputSourceConnection(const FakeXRInputSourceInit& init) > { >- return WebFakeXRInputController::create(); >+ auto handle = ++mInputSourceHandleIndex; >+ auto input = WebFakeXRInputController::create(handle, init); >+ m_device.addInputConnection(input.copyRef()); >+ return input; > } > > ExceptionOr<PlatformXR::Device::FrameData::Pose> WebFakeXRDevice::parseRigidTransform(const FakeXRRigidTransformInit& init) >diff --git a/Source/WebCore/testing/WebFakeXRDevice.h b/Source/WebCore/testing/WebFakeXRDevice.h >index 761fcbc036720696eb56f8cc4d3ee585c9cca938..9f366ca11fe0499b101f665205286f627c1c6cad 100644 >--- a/Source/WebCore/testing/WebFakeXRDevice.h >+++ b/Source/WebCore/testing/WebFakeXRDevice.h >@@ -80,6 +80,7 @@ public: > void setSupportsShutdownNotification(bool supportsShutdownNotification) { m_supportsShutdownNotification = supportsShutdownNotification; } > void simulateShutdownCompleted(); > void scheduleOnNextFrame(Function<void()>&&); >+ void addInputConnection(Ref<WebFakeXRInputController>&& input) { m_inputConnections.append(WTFMove(input)); }; > private: > WebCore::IntSize recommendedResolution(PlatformXR::SessionMode) final; > void initializeTrackingAndRendering(PlatformXR::SessionMode) final; >@@ -101,6 +102,7 @@ private: > RefPtr<WebCore::GraphicsContextGL> m_gl; > HashMap<PlatformXR::LayerHandle, PlatformGLObject> m_layers; > uint32_t m_layerIndex { 0 }; >+ Vector<Ref<WebFakeXRInputController>> m_inputConnections; > }; > > class WebFakeXRDevice final : public RefCounted<WebFakeXRDevice> { >@@ -116,18 +118,19 @@ public: > void setFloorOrigin(FakeXRRigidTransformInit); > void clearFloorOrigin() { m_device.setFloorOrigin(WTF::nullopt); } > void simulateResetPose(); >- Ref<WebFakeXRInputController> simulateInputSourceConnection(FakeXRInputSourceInit); >+ Ref<WebFakeXRInputController> simulateInputSourceConnection(const FakeXRInputSourceInit&); > static ExceptionOr<Ref<FakeXRView>> parseView(const FakeXRViewInit&); > SimulatedXRDevice& simulatedXRDevice() { return m_device; } > void setSupportsShutdownNotification(); > void simulateShutdown(); > >+ static ExceptionOr<PlatformXR::Device::FrameData::Pose> parseRigidTransform(const FakeXRRigidTransformInit&); >+ > private: > WebFakeXRDevice(); > >- static ExceptionOr<PlatformXR::Device::FrameData::Pose> parseRigidTransform(const FakeXRRigidTransformInit&); >- > SimulatedXRDevice m_device; >+ PlatformXR::InputSourceHandle mInputSourceHandleIndex { 0 }; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/testing/WebFakeXRInputController.cpp b/Source/WebCore/testing/WebFakeXRInputController.cpp >index 790c9870bb48c51ce855a5ae2fb2a3671ca716b0..7c827289610dbfcd1d4985c75619a5150b8e7a02 100644 >--- a/Source/WebCore/testing/WebFakeXRInputController.cpp >+++ b/Source/WebCore/testing/WebFakeXRInputController.cpp >@@ -27,63 +27,153 @@ > #include "WebFakeXRInputController.h" > > #if ENABLE(WEBXR) >+#include "WebFakeXRDevice.h" > > namespace WebCore { > >-void WebFakeXRInputController::setHandedness(XRHandedness) >-{ >-} >+using InputSource = PlatformXR::Device::FrameData::InputSource; >+using InputSourceButton = PlatformXR::Device::FrameData::InputSourceButton; >+using InputSourcePose = PlatformXR::Device::FrameData::InputSourcePose; >+using ButtonType = FakeXRButtonStateInit::Type; > >-void WebFakeXRInputController::setTargetRayMode(XRTargetRayMode) >-{ >-} >+// https://immersive-web.github.io/webxr-gamepads-module/#xr-standard-gamepad-mapping >+constexpr std::array<ButtonType, 5> XR_STANDARD_BUTTONS = { ButtonType::Grip, ButtonType::Touchpad, ButtonType::Thumbstick, ButtonType::OptionalButton, ButtonType::OptionalThumbstick }; > >-void WebFakeXRInputController::setProfiles(Vector<String>) >+Ref<WebFakeXRInputController> WebFakeXRInputController::create(PlatformXR::InputSourceHandle handle, const FakeXRInputSourceInit& init) > { >+ return adoptRef(*new WebFakeXRInputController(handle, init)); > } > >-void WebFakeXRInputController::setGripOrigin(FakeXRRigidTransformInit gripOrigin, bool emulatedPosition) >+WebFakeXRInputController::WebFakeXRInputController(PlatformXR::InputSourceHandle handle, const FakeXRInputSourceInit& init) >+ : m_handle(handle) >+ , m_handeness(init.handedness) >+ , m_targetRayMode(init.targetRayMode) >+ , m_profiles(init.profiles) >+ , m_primarySelected(init.selectionStarted) >+ , m_simulateSelect(init.selectionClicked) > { >- UNUSED_PARAM(gripOrigin); >- UNUSED_PARAM(emulatedPosition); >+ setPointerOrigin(init.pointerOrigin, false); >+ setGripOrigin(init.gripOrigin, false); >+ setSupportedButtons(init.supportedButtons); > } > >-void WebFakeXRInputController::clearGripOrigin() >+void WebFakeXRInputController::setGripOrigin(FakeXRRigidTransformInit gripOrigin, bool emulatedPosition) > { >-} >+ auto transform = WebFakeXRDevice::parseRigidTransform(gripOrigin); >+ if (transform.hasException()) >+ return; >+ m_gripOrigin = InputSourcePose { transform.releaseReturnValue(), emulatedPosition }; >+} > > void WebFakeXRInputController::setPointerOrigin(FakeXRRigidTransformInit pointerOrigin, bool emulatedPosition) > { >- UNUSED_PARAM(pointerOrigin); >- UNUSED_PARAM(emulatedPosition); >+ auto transform = WebFakeXRDevice::parseRigidTransform(pointerOrigin); >+ if (transform.hasException()) >+ return; >+ m_pointerOrigin = { transform.releaseReturnValue(), emulatedPosition }; > } > > void WebFakeXRInputController::disconnect() > { >+ m_connected = false; > } > > void WebFakeXRInputController::reconnect() > { >+ m_connected = true; > } > >-void WebFakeXRInputController::startSelection() >-{ >-} >- >-void WebFakeXRInputController::endSelection() >+void WebFakeXRInputController::setSupportedButtons(const Vector<FakeXRButtonStateInit>& buttons) > { >+ m_buttons.clear(); >+ for (auto& button : buttons) >+ m_buttons.add(button.buttonType, button); > } > >-void WebFakeXRInputController::simulateSelect() >+void WebFakeXRInputController::updateButtonState(const FakeXRButtonStateInit& init) > { >+ auto it = m_buttons.find(init.buttonType); >+ if (it != m_buttons.end()) >+ it->value = init; > } > >-void WebFakeXRInputController::setSupportedButtons(Vector<FakeXRButtonStateInit>) >+InputSource WebFakeXRInputController::getFrameData() > { >+ InputSource state; >+ state.handle = m_handle; >+ state.handeness = m_handeness; >+ state.targetRayMode = m_targetRayMode; >+ state.profiles = m_profiles; >+ state.pointerOrigin = m_pointerOrigin; >+ state.gripOrigin = m_gripOrigin; >+ >+ if (m_simulateSelect) >+ m_primarySelected = true; >+ >+ // https://immersive-web.github.io/webxr-gamepads-module/#xr-standard-gamepad-mapping >+ // Mimic xr-standard gamepad layout >+ >+ // Primary trigger is required and must be at index 0 >+ state.buttons.append({ >+ .touched = m_primarySelected, >+ .pressed = m_primarySelected, >+ .pressedValue = m_primarySelected ? 1.0f : 0.0f >+ }); >+ >+ // Next buttons in xr-standard order >+ for (auto buttonType : XR_STANDARD_BUTTONS) { >+ auto data = getButtonOrPlaceholder(buttonType); >+ if (data.button) >+ state.buttons.append(*data.button); >+ if (data.axes) >+ state.axes.appendVector(*data.axes); >+ >+ } >+ >+ if (m_simulateSelect) { >+ m_primarySelected = false; >+ m_simulateSelect = false; >+ } >+ >+ return state; > } > >-void WebFakeXRInputController::updateButtonState(FakeXRButtonStateInit) >+WebFakeXRInputController::ButtonOrPlaceholder WebFakeXRInputController::getButtonOrPlaceholder(FakeXRButtonStateInit::Type buttonType) const > { >+ ButtonOrPlaceholder result; >+ >+ auto it = m_buttons.find(buttonType); >+ if (it != m_buttons.end()) { >+ result.button = InputSourceButton { >+ .touched = it->value.touched, >+ .pressed = it->value.pressed, >+ .pressedValue = it->value.pressedValue >+ }; >+ >+ if (buttonType == ButtonType::Touchpad || buttonType == ButtonType::Thumbstick) >+ result.axes = Vector<float> { it->value.xValue, it->value.yValue }; >+ >+ } else { >+ // Add a placeholder if needed >+ // Devices that lack one of the optional inputs listed in the tables above MUST preserve their place in the >+ // buttons or axes array, reporting a placeholder button or placeholder axis, respectively. >+ if (buttonType != ButtonType::OptionalButton || buttonType != ButtonType::OptionalThumbstick) { >+ auto priority = std::find(XR_STANDARD_BUTTONS.begin(), XR_STANDARD_BUTTONS.end(), buttonType); >+ ASSERT(priority != XR_STANDARD_BUTTONS.end()); >+ >+ for (auto it = priority + 1; it != XR_STANDARD_BUTTONS.end(); ++it) { >+ if (m_buttons.contains(*it)) { >+ result.button = InputSourceButton(); >+ break; >+ } >+ } >+ } >+ >+ if (buttonType == ButtonType::Touchpad && m_buttons.contains(ButtonType::Thumbstick)) >+ result.axes = Vector<float> { 0.0, 0.0 }; >+ } >+ >+ return result; > } > > } // namespace WebCore >diff --git a/Source/WebCore/testing/WebFakeXRInputController.h b/Source/WebCore/testing/WebFakeXRInputController.h >index d28cea4f86ea9ca4656ebdf8c5251ef4b92499cd..8b5bcf3647efcadc69bb68a610a3dc993411cbaa 100644 >--- a/Source/WebCore/testing/WebFakeXRInputController.h >+++ b/Source/WebCore/testing/WebFakeXRInputController.h >@@ -28,9 +28,12 @@ > #if ENABLE(WEBXR) > > #include "FakeXRButtonStateInit.h" >+#include "FakeXRInputSourceInit.h" > #include "FakeXRRigidTransformInit.h" >+#include "PlatformXR.h" > #include "XRHandedness.h" > #include "XRTargetRayMode.h" >+#include <wtf/HashMap.h> > #include <wtf/RefCounted.h> > #include <wtf/Vector.h> > >@@ -38,36 +41,44 @@ namespace WebCore { > > class WebFakeXRInputController final : public RefCounted<WebFakeXRInputController> { > public: >- static Ref<WebFakeXRInputController> create() { return adoptRef(*new WebFakeXRInputController); } >- >- void setHandedness(XRHandedness); >- >- void setTargetRayMode(XRTargetRayMode); >- >- void setProfiles(Vector<String>); >+ static Ref<WebFakeXRInputController> create(PlatformXR::InputSourceHandle, const FakeXRInputSourceInit&); > >+ void setHandedness(XRHandedness handeness) { m_handeness = handeness; } >+ void setTargetRayMode(XRTargetRayMode mode) { m_targetRayMode = mode; } >+ void setProfiles(Vector<String>&& profiles) { m_profiles = WTFMove(profiles); } > void setGripOrigin(FakeXRRigidTransformInit gripOrigin, bool emulatedPosition = false); >- >- void clearGripOrigin(); >- >+ void clearGripOrigin() { m_gripOrigin = WTF::nullopt; } > void setPointerOrigin(FakeXRRigidTransformInit pointerOrigin, bool emulatedPosition = false); >- > void disconnect(); >- > void reconnect(); >+ void startSelection() { m_primarySelected = true; } >+ void endSelection() { m_primarySelected = false; } >+ void simulateSelect() { m_simulateSelect = true; } >+ void setSupportedButtons(const Vector<FakeXRButtonStateInit>&); >+ void updateButtonState(const FakeXRButtonStateInit&); >+ bool isConnected() const { return m_connected; } > >- void startSelection(); >- >- void endSelection(); >- >- void simulateSelect(); >- >- void setSupportedButtons(Vector<FakeXRButtonStateInit>); >- >- void updateButtonState(FakeXRButtonStateInit); >+ PlatformXR::Device::FrameData::InputSource getFrameData(); > > private: >- WebFakeXRInputController() = default; >+ WebFakeXRInputController(PlatformXR::InputSourceHandle, const FakeXRInputSourceInit&); >+ >+ struct ButtonOrPlaceholder { >+ Optional<PlatformXR::Device::FrameData::InputSourceButton> button; >+ Optional<Vector<float>> axes; >+ }; >+ ButtonOrPlaceholder getButtonOrPlaceholder(FakeXRButtonStateInit::Type) const; >+ >+ PlatformXR::InputSourceHandle m_handle { 0 }; >+ XRHandedness m_handeness { XRHandedness::None }; >+ XRTargetRayMode m_targetRayMode { XRTargetRayMode::Gaze }; >+ Vector<String> m_profiles; >+ PlatformXR::Device::FrameData::InputSourcePose m_pointerOrigin; >+ Optional<PlatformXR::Device::FrameData::InputSourcePose> m_gripOrigin; >+ HashMap<FakeXRButtonStateInit::Type, FakeXRButtonStateInit, WTF::IntHash<FakeXRButtonStateInit::Type>, WTF::StrongEnumHashTraits<FakeXRButtonStateInit::Type>> m_buttons; >+ bool m_connected { true }; >+ bool m_primarySelected { false }; >+ bool m_simulateSelect { false }; > }; > > } // namespace WebCore >diff --git a/Source/cmake/OptionsWPE.cmake b/Source/cmake/OptionsWPE.cmake >index d8c2c251f3ea55fdce895e39c6591924c2e8cf5e..79c243d8ebb764964229d953c305542e9cef0679 100644 >--- a/Source/cmake/OptionsWPE.cmake >+++ b/Source/cmake/OptionsWPE.cmake >@@ -203,6 +203,7 @@ if (ENABLE_WEBXR) > if (NOT OPENXR_FOUND) > message(FATAL_ERROR "OpenXR is required to enable WebXR support.") > endif () >+ SET_AND_EXPOSE_TO_BUILD(ENABLE_GAMEPAD ON) > SET_AND_EXPOSE_TO_BUILD(USE_OPENXR ${OpenXR_FOUND}) > SET_AND_EXPOSE_TO_BUILD(XR_USE_PLATFORM_EGL TRUE) > SET_AND_EXPOSE_TO_BUILD(XR_USE_GRAPHICS_API_OPENGL TRUE) >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 7058511ea2f23ce53b821ed33deff04bcdd7b7f4..1528704cf15e927f42eb91e8d573c8ce203732ae 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,14 @@ >+2021-03-16 Imanol Fernandez <ifernandez@igalia.com> >+ >+ Implement WebXR Input Sources >+ https://bugs.webkit.org/show_bug.cgi?id=223257 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Update WebXR Input Source test expectations. >+ >+ * platform/wpe/TestExpectations: >+ > 2021-04-16 Zalan Bujtas <zalan@apple.com> > > [IFC] Incorrect box height when scrollbar takes padding box space >diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog >index e97274c010054e2ad5c1fafb0a633fbd05b155f5..e7eb3f31c78cbc2f0d0128bc49e77d2fadc0399f 100644 >--- a/LayoutTests/imported/w3c/ChangeLog >+++ b/LayoutTests/imported/w3c/ChangeLog >@@ -1,3 +1,24 @@ >+2021-03-16 Imanol Fernandez <ifernandez@igalia.com> >+ >+ Implement WebXR Input Sources >+ https://bugs.webkit.org/show_bug.cgi?id=223257 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Update WebXR Input Source test expectations. >+ >+ * web-platform-tests/webxr/events_input_source_recreation.https-expected.txt: Added. >+ * web-platform-tests/webxr/events_input_sources_change.https-expected.txt: Added. >+ * web-platform-tests/webxr/events_session_select.https-expected.txt: Added. >+ * web-platform-tests/webxr/events_session_select_subframe.https-expected.txt: Added. >+ * web-platform-tests/webxr/events_session_squeeze.https-expected.txt: Added. >+ * web-platform-tests/webxr/getInputPose_handedness.https-expected.txt: Added. >+ * web-platform-tests/webxr/xrInputSource_add_remove.https-expected.txt: Added. >+ * web-platform-tests/webxr/xrInputSource_emulatedPosition.https-expected.txt: Added. >+ * web-platform-tests/webxr/xrInputSource_profiles.https-expected.txt: Added. >+ * web-platform-tests/webxr/xrInputSource_sameObject.https-expected.txt: Added. >+ * web-platform-tests/webxr/xrReferenceSpace_originOffset.https-expected.txt: Added. >+ > 2021-04-16 Antoine Quint <graouts@webkit.org> > > Blend using calc() when necessary >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/events_input_source_recreation.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/events_input_source_recreation.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..d7051e9206fa4bdd89fb81b4eb0b090ba22b0472 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/events_input_source_recreation.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS Input sources are re-created when handedness or target ray mode changes >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/events_input_sources_change.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/events_input_sources_change.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..38db126062fbf26e5ae0b339589901a8ed8beedf >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/events_input_sources_change.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS Transient input sources fire events in the right order >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/events_session_select.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/events_session_select.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..92169e98002e9f0f89ef8744c73900e3ae23559b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/events_session_select.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS XRInputSources primary input presses properly fires off the right events >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/events_session_select_subframe.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/events_session_select_subframe.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..7d3dfbe31f2b50eacea285527b2292a51f5272e6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/events_session_select_subframe.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS Ensures that an XRInputSources primary input being pressed and released in the space of a single frame properly fires off the right events >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/events_session_squeeze.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/events_session_squeeze.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..92169e98002e9f0f89ef8744c73900e3ae23559b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/events_session_squeeze.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS XRInputSources primary input presses properly fires off the right events >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/getInputPose_handedness.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/getInputPose_handedness.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..089e7ae3ebebf1e614a35b4bb73b18da51542e3f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/getInputPose_handedness.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS XRInputSources properly communicate their handedness >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_add_remove.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_add_remove.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..d4b564bf857d53de7c832c3d25b40e213f9a2448 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_add_remove.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS XRInputSources can be properly added and removed from the session >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_emulatedPosition.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_emulatedPosition.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..4aa707f6ce44ef648f44f0dac695e27dc0f5656d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_emulatedPosition.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS Poses from XRInputSource.gripSpace have emulatedPosition set properly >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_profiles.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_profiles.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..8d176ed76e199cea774bd12b9f8e9f0f43b44df1 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_profiles.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS WebXR InputSource's profiles list can be set >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_sameObject.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_sameObject.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..e8b20bcf5ebd0eee3862d0c59c73009c824bf345 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_sameObject.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS XRInputSource attributes meet [SameObject] requirement >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/xrReferenceSpace_originOffset.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrReferenceSpace_originOffset.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..ec34cfc2cc7659eb4fb0a31c095848cc32bad247 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrReferenceSpace_originOffset.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS Updating XRReferenceSpace origin offset updates view and input matrices. >+ >diff --git a/LayoutTests/platform/wpe/TestExpectations b/LayoutTests/platform/wpe/TestExpectations >index 89c20e0d77ee1d6f9afe5f98179c7db26b2754e2..3a77e318989385639d0a302b5a837b10e9f81ecd 100644 >--- a/LayoutTests/platform/wpe/TestExpectations >+++ b/LayoutTests/platform/wpe/TestExpectations >@@ -636,6 +636,11 @@ webkit.org/b/213131 gamepad [ Skip ] > webkit.org/b/213131 http/tests/misc/gamepads-insecure.html [ Skip ] > > # WebXR >+imported/w3c/web-platform-tests/webxr/events_input_source_recreation.https.html [ Pass ] >+imported/w3c/web-platform-tests/webxr/events_input_sources_change.https.html [ Pass ] >+imported/w3c/web-platform-tests/webxr/events_session_select_subframe.https.html [ Pass ] >+imported/w3c/web-platform-tests/webxr/events_session_select.https.html [ Pass ] >+imported/w3c/web-platform-tests/webxr/events_session_squeeze.https.html [ Pass ] > webkit.org/b/212897 imported/w3c/web-platform-tests/webxr/idlharness.https.window.html [ Failure ] > imported/w3c/web-platform-tests/webxr/xrBoundedReferenceSpace_updates.https.html [ Pass ] > webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/webGLCanvasContext_create_xrcompatible.https.html [ Pass ] >@@ -650,10 +655,15 @@ webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrDevice_requestSessio > webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrDevice_requestSession_no_mode.https.html [ Pass ] > webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrDevice_requestSession_non_immersive_no_gesture.https.html [ Pass ] > webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrDevice_requestSession_optionalFeatures.https.html [ Pass ] >+imported/w3c/web-platform-tests/webxr/getInputPose_handedness.https.html [ Pass ] > imported/w3c/web-platform-tests/webxr/getViewerPose_emulatedPosition.https.html [ Pass ] > imported/w3c/web-platform-tests/webxr/xrFrame_getViewerPose_getPose.https.html [ Pass ] > imported/w3c/web-platform-tests/webxr/xrFrame_getPose.https.html [ Pass ] > imported/w3c/web-platform-tests/webxr/xrFrame_session_sameObject.https.html [ Pass ] >+imported/w3c/web-platform-tests/webxr/xrInputSource_add_remove.https.html [ Pass ] >+imported/w3c/web-platform-tests/webxr/xrInputSource_emulatedPosition.https.html [ Pass ] >+imported/w3c/web-platform-tests/webxr/xrInputSource_profiles.https.html [ Pass ] >+imported/w3c/web-platform-tests/webxr/xrInputSource_sameObject.https.html [ Pass ] > imported/w3c/web-platform-tests/webxr/xrSession_viewer_availability.https.html [ Pass ] > webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/ar-module/idlharness.https.window.html [ Pass ] > webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/ar-module/xrDevice_isSessionSupported_immersive-ar.https.html [ Pass ] >@@ -661,6 +671,7 @@ imported/w3c/web-platform-tests/webxr/xrView_eyes.https.html [ Pass ] > imported/w3c/web-platform-tests/webxr/xrView_match.https.html [ Pass ] > imported/w3c/web-platform-tests/webxr/xrView_oneframeupdate.https.html [ Pass ] > imported/w3c/web-platform-tests/webxr/navigator_xr_sameObject.https.html [ Pass ] >+imported/w3c/web-platform-tests/webxr/xrReferenceSpace_originOffset.https.html [ Pass ] > imported/w3c/web-platform-tests/webxr/xrReferenceSpace_originOffset_viewer.https.html [ Pass ] > imported/w3c/web-platform-tests/webxr/xrReferenceSpace_relationships.https.html [ Pass ] > imported/w3c/web-platform-tests/webxr/xrRigidTransform_constructor.https.html [ Pass ] >diff --git a/ChangeLog b/ChangeLog >index 37e8d3e4074019b6fb0d628d9cd28c31a8a87a5f..2d5d26b764bb4f9efb5c340afda5b80cde32f282 100644 >--- a/ChangeLog >+++ b/ChangeLog >@@ -1,3 +1,14 @@ >+2021-03-16 Imanol Fernandez <ifernandez@igalia.com> >+ >+ Implement WebXR Input Sources >+ https://bugs.webkit.org/show_bug.cgi?id=223257 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Enable WPE Gamepad when WebXR is enabled. >+ >+ * Source/cmake/OptionsWPE.cmake: >+ > 2021-04-16 Philippe Normand <pnormand@igalia.com> > > [CMake] UBSan build fixes
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 223257
:
423344
|
423347
|
423598
|
424375
|
425413
|
426234
|
426801