Diff
Modified: trunk/ChangeLog (276432 => 276433)
--- trunk/ChangeLog 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/ChangeLog 2021-04-22 14:06:06 UTC (rev 276433)
@@ -1,3 +1,14 @@
+2021-04-22 Imanol Fernandez <[email protected]>
+
+ Implement WebXR Input Sources
+ https://bugs.webkit.org/show_bug.cgi?id=223257
+
+ Reviewed by Youenn Fablet.
+
+ Enable WPE Gamepad when WebXR is enabled.
+
+ * Source/cmake/OptionsWPE.cmake:
+
2021-04-22 Carlos Garcia Campos <[email protected]>
[SOUP] Add support for preconnect
Modified: trunk/LayoutTests/ChangeLog (276432 => 276433)
--- trunk/LayoutTests/ChangeLog 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/LayoutTests/ChangeLog 2021-04-22 14:06:06 UTC (rev 276433)
@@ -1,3 +1,14 @@
+2021-04-22 Imanol Fernandez <[email protected]>
+
+ Implement WebXR Input Sources
+ https://bugs.webkit.org/show_bug.cgi?id=223257
+
+ Reviewed by Youenn Fablet.
+
+ Update WebXR Input Source test expectations.
+
+ * platform/wpe/TestExpectations:
+
2021-04-22 Carlos Garcia Campos <[email protected]>
[SOUP] Add support for preconnect
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (276432 => 276433)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2021-04-22 14:06:06 UTC (rev 276433)
@@ -1,3 +1,24 @@
+2021-04-22 Imanol Fernandez <[email protected]>
+
+ Implement WebXR Input Sources
+ https://bugs.webkit.org/show_bug.cgi?id=223257
+
+ Reviewed by Youenn Fablet.
+
+ 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-21 Tim Nguyen <[email protected]>
Import css/css-will-change tests from WPT
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/events_input_source_recreation.https-expected.txt (0 => 276433)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/events_input_source_recreation.https-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/events_input_source_recreation.https-expected.txt 2021-04-22 14:06:06 UTC (rev 276433)
@@ -0,0 +1,3 @@
+
+PASS Input sources are re-created when handedness or target ray mode changes
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/events_input_sources_change.https-expected.txt (0 => 276433)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/events_input_sources_change.https-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/events_input_sources_change.https-expected.txt 2021-04-22 14:06:06 UTC (rev 276433)
@@ -0,0 +1,3 @@
+
+PASS Transient input sources fire events in the right order
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/events_session_select.https-expected.txt (0 => 276433)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/events_session_select.https-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/events_session_select.https-expected.txt 2021-04-22 14:06:06 UTC (rev 276433)
@@ -0,0 +1,3 @@
+
+PASS XRInputSources primary input presses properly fires off the right events
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/events_session_select_subframe.https-expected.txt (0 => 276433)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/events_session_select_subframe.https-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/events_session_select_subframe.https-expected.txt 2021-04-22 14:06:06 UTC (rev 276433)
@@ -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
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/events_session_squeeze.https-expected.txt (0 => 276433)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/events_session_squeeze.https-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/events_session_squeeze.https-expected.txt 2021-04-22 14:06:06 UTC (rev 276433)
@@ -0,0 +1,3 @@
+
+PASS XRInputSources primary input presses properly fires off the right events
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/getInputPose_handedness.https-expected.txt (0 => 276433)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/getInputPose_handedness.https-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/getInputPose_handedness.https-expected.txt 2021-04-22 14:06:06 UTC (rev 276433)
@@ -0,0 +1,3 @@
+
+PASS XRInputSources properly communicate their handedness
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_add_remove.https-expected.txt (0 => 276433)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_add_remove.https-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_add_remove.https-expected.txt 2021-04-22 14:06:06 UTC (rev 276433)
@@ -0,0 +1,3 @@
+
+PASS XRInputSources can be properly added and removed from the session
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_emulatedPosition.https-expected.txt (0 => 276433)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_emulatedPosition.https-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_emulatedPosition.https-expected.txt 2021-04-22 14:06:06 UTC (rev 276433)
@@ -0,0 +1,3 @@
+
+PASS Poses from XRInputSource.gripSpace have emulatedPosition set properly
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_profiles.https-expected.txt (0 => 276433)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_profiles.https-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_profiles.https-expected.txt 2021-04-22 14:06:06 UTC (rev 276433)
@@ -0,0 +1,3 @@
+
+PASS WebXR InputSource's profiles list can be set
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_sameObject.https-expected.txt (0 => 276433)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_sameObject.https-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrInputSource_sameObject.https-expected.txt 2021-04-22 14:06:06 UTC (rev 276433)
@@ -0,0 +1,3 @@
+
+PASS XRInputSource attributes meet [SameObject] requirement
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrReferenceSpace_originOffset.https-expected.txt (0 => 276433)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrReferenceSpace_originOffset.https-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webxr/xrReferenceSpace_originOffset.https-expected.txt 2021-04-22 14:06:06 UTC (rev 276433)
@@ -0,0 +1,3 @@
+
+PASS Updating XRReferenceSpace origin offset updates view and input matrices.
+
Modified: trunk/LayoutTests/platform/wpe/TestExpectations (276432 => 276433)
--- trunk/LayoutTests/platform/wpe/TestExpectations 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/LayoutTests/platform/wpe/TestExpectations 2021-04-22 14:06:06 UTC (rev 276433)
@@ -610,6 +610,11 @@
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 ]
@@ -624,10 +629,15 @@
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 ]
@@ -635,6 +645,7 @@
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 ]
Modified: trunk/Source/WebCore/ChangeLog (276432 => 276433)
--- trunk/Source/WebCore/ChangeLog 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/ChangeLog 2021-04-22 14:06:06 UTC (rev 276433)
@@ -1,3 +1,118 @@
+2021-04-22 Imanol Fernandez <[email protected]>
+
+ Implement WebXR Input Sources
+ https://bugs.webkit.org/show_bug.cgi?id=223257
+
+ Reviewed by Youenn Fablet.
+
+ 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-22 Carlos Garcia Campos <[email protected]>
[GTK][WPE] Bump libsoup3 version to 2.99.4
Modified: trunk/Source/WebCore/Modules/gamepad/Gamepad.h (276432 => 276433)
--- trunk/Source/WebCore/Modules/gamepad/Gamepad.h 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/Modules/gamepad/Gamepad.h 2021-04-22 14:06:06 UTC (rev 276433)
@@ -55,6 +55,7 @@
const Vector<Ref<GamepadButton>>& buttons() const;
void updateFromPlatformGamepad(const PlatformGamepad&);
+ void setConnected(bool connected) { m_connected = connected; }
private:
explicit Gamepad(const PlatformGamepad&);
Modified: trunk/Source/WebCore/Modules/webxr/WebXRFrame.cpp (276432 => 276433)
--- trunk/Source/WebCore/Modules/webxr/WebXRFrame.cpp 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/Modules/webxr/WebXRFrame.cpp 2021-04-22 14:06:06 UTC (rev 276433)
@@ -119,7 +119,7 @@
// 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 @@
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) {
Copied: trunk/Source/WebCore/Modules/webxr/WebXRGamepad.cpp (from rev 276432, trunk/Source/WebCore/testing/WebFakeXRInputController.h) (0 => 276433)
--- trunk/Source/WebCore/Modules/webxr/WebXRGamepad.cpp (rev 0)
+++ trunk/Source/WebCore/Modules/webxr/WebXRGamepad.cpp 2021-04-22 14:06:06 UTC (rev 276433)
@@ -0,0 +1,61 @@
+/*
+ * 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
+// Gamepad's index attribute must be -1.
+constexpr int DefaultXRGamepadId = -1;
+
+// https://immersive-web.github.io/webxr-gamepads-module/#gamepad-differences
+WebXRGamepad::WebXRGamepad(double timestamp, double connectTime, const PlatformXR::Device::FrameData::InputSource& source)
+ : PlatformGamepad(DefaultXRGamepadId)
+{
+ 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)
Copied: trunk/Source/WebCore/Modules/webxr/WebXRGamepad.h (from rev 276432, trunk/Source/WebCore/Modules/webxr/WebXRInputSourceArray.h) (0 => 276433)
--- trunk/Source/WebCore/Modules/webxr/WebXRGamepad.h (rev 0)
+++ trunk/Source/WebCore/Modules/webxr/WebXRGamepad.h 2021-04-22 14:06:06 UTC (rev 276433)
@@ -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)
Modified: trunk/Source/WebCore/Modules/webxr/WebXRInputSource.cpp (276432 => 276433)
--- trunk/Source/WebCore/Modules/webxr/WebXRInputSource.cpp 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/Modules/webxr/WebXRInputSource.cpp 2021-04-22 14:06:06 UTC (rev 276433)
@@ -28,7 +28,14 @@
#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 {
@@ -35,43 +42,114 @@
WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRInputSource);
-Ref<WebXRInputSource> WebXRInputSource::create(Ref<WebXRSpace>&& targetRaySpace)
+Ref<WebXRInputSource> WebXRInputSource::create(Document& document, Ref<WebXRSession>&& session, double timestamp, const PlatformXR::Device::FrameData::InputSource& source)
{
- return adoptRef(*new WebXRInputSource(WTFMove(targetRaySpace)));
+ return adoptRef(*new WebXRInputSource(document, WTFMove(session), timestamp, source));
}
-WebXRInputSource::WebXRInputSource(Ref<WebXRSpace>&& targetRaySpace)
- : m_handedness(XRHandedness::None)
- , m_targetRayMode(XRTargetRayMode::Gaze)
- , m_targetRaySpace(WTFMove(targetRaySpace))
+WebXRInputSource::WebXRInputSource(Document& document, Ref<WebXRSession>&& session, double timestamp, const PlatformXR::Device::FrameData::InputSource& source)
+ : m_session(WTFMove(session))
+ , m_targetRaySpace(WebXRInputSpace::create(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 if (auto* document = downcast<Document>(m_session->scriptExecutionContext()))
+ m_gripSpace = WebXRInputSpace::create(*document, 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
Modified: trunk/Source/WebCore/Modules/webxr/WebXRInputSource.h (276432 => 276433)
--- trunk/Source/WebCore/Modules/webxr/WebXRInputSource.h 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/Modules/webxr/WebXRInputSource.h 2021-04-22 14:06:06 UTC (rev 276433)
@@ -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,54 @@
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(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(); };
+ WebXRSpace* gripSpace() const { return m_gripSpace.get(); }
+ 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(Document&, Ref<WebXRSession>&&, double timestamp, const InputSource&);
- XRHandedness m_handedness;
- XRTargetRayMode m_targetRayMode;
- Ref<WebXRSpace> m_targetRaySpace;
- Vector<String> m_profiles;
+ Ref<XRInputSourceEvent> createEvent(const AtomString&);
+
+ 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
+
+ bool m_selectStarted { false };
+ bool m_squeezeStarted { false };
};
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/webxr/WebXRInputSource.idl (276432 => 276433)
--- trunk/Source/WebCore/Modules/webxr/WebXRInputSource.idl 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/Modules/webxr/WebXRInputSource.idl 2021-04-22 14:06:06 UTC (rev 276433)
@@ -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;
};
Modified: trunk/Source/WebCore/Modules/webxr/WebXRInputSourceArray.cpp (276432 => 276433)
--- trunk/Source/WebCore/Modules/webxr/WebXRInputSourceArray.cpp 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/Modules/webxr/WebXRInputSourceArray.cpp 2021-04-22 14:06:06 UTC (rev 276433)
@@ -27,7 +27,11 @@
#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 {
@@ -34,16 +38,144 @@
WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRInputSourceArray);
+Ref<WebXRInputSourceArray> WebXRInputSourceArray::create(Ref<WebXRSession>&& session)
+{
+ return adoptRef(*new WebXRInputSourceArray(WTFMove(session)));
+}
+
+WebXRInputSourceArray::WebXRInputSourceArray(Ref<WebXRSession>&& session)
+ : m_session(WTFMove(session))
+{
+}
+
+WebXRInputSourceArray::~WebXRInputSourceArray() = default;
+
unsigned WebXRInputSourceArray::length() const
{
- return 0;
+ return m_inputSources.size();
}
-WebXRInputSource* WebXRInputSourceArray::item(unsigned) const
+WebXRInputSource* WebXRInputSourceArray::item(unsigned index) const
{
- return nullptr;
+ return index >= m_inputSources.size() ? nullptr: m_inputSources[index].ptr();
}
+void WebXRInputSourceArray::clear()
+{
+ m_inputSources.clear();
+}
+
+// https://immersive-web.github.io/webxr/#list-of-active-xr-input-sources
+void WebXRInputSourceArray::update(double timestamp, const InputSourceList& inputSources)
+{
+ Vector<RefPtr<WebXRInputSource>> added;
+ Vector<RefPtr<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 = WTFMove(added);
+ init.removed = WTFMove(removed);
+
+ 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) {
+ m_session->queueTaskKeepingObjectAlive(m_session.get(), TaskSource::WebXR, [&session = m_session.get(), event = WTFMove(event)]() {
+ event->setFrameActive(true);
+ session.dispatchEvent(event.copyRef());
+ event->setFrameActive(false);
+ });
+ }
+ }
+}
+
+// https://immersive-web.github.io/webxr/#list-of-active-xr-input-sources
+void WebXRInputSourceArray::handleRemovedInputSources(const InputSourceList& inputSources, Vector<RefPtr<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 (!WTF::anyOf(inputSources, [&source](auto& item) { return item.handle == source->handle(); })) {
+ 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<RefPtr<WebXRInputSource>>& added, Vector<RefPtr<WebXRInputSource>>& removed, Vector<Ref<XRInputSourceEvent>>& inputEvents)
+{
+ auto* document = downcast<Document>(m_session->scriptExecutionContext());
+ if (!document)
+ return;
+
+ 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(*document, 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(*document, 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
#endif // ENABLE(WEBXR)
Modified: trunk/Source/WebCore/Modules/webxr/WebXRInputSourceArray.h (276432 => 276433)
--- trunk/Source/WebCore/Modules/webxr/WebXRInputSourceArray.h 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/Modules/webxr/WebXRInputSourceArray.h 2021-04-22 14:06:06 UTC (rev 276433)
@@ -27,6 +27,7 @@
#if ENABLE(WEBXR)
+#include "PlatformXR.h"
#include <wtf/IsoMalloc.h>
#include <wtf/Ref.h>
#include <wtf/RefCounted.h>
@@ -33,19 +34,32 @@
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<WebXRSession>&&);
+ ~WebXRInputSourceArray();
unsigned length() const;
WebXRInputSource* item(unsigned) const;
+ void clear();
+ void update(double timestamp, const InputSourceList&);
+
private:
- WebXRInputSourceArray() = default;
+ WebXRInputSourceArray(Ref<WebXRSession>&&);
+
+ void handleRemovedInputSources(const InputSourceList&, Vector<RefPtr<WebXRInputSource>>&, Vector<Ref<XRInputSourceEvent>>&);
+ void handleAddedOrUpdatedInputSources(double timestamp, const InputSourceList&, Vector<RefPtr<WebXRInputSource>>&, Vector<RefPtr<WebXRInputSource>>&, Vector<Ref<XRInputSourceEvent>>&);
+
+ Ref<WebXRSession> m_session;
+ Vector<Ref<WebXRInputSource>> m_inputSources;
};
} // namespace WebCore
Copied: trunk/Source/WebCore/Modules/webxr/WebXRInputSpace.cpp (from rev 276432, trunk/Source/WebCore/Modules/webxr/WebXRInputSourceArray.cpp) (0 => 276433)
--- trunk/Source/WebCore/Modules/webxr/WebXRInputSpace.cpp (rev 0)
+++ trunk/Source/WebCore/Modules/webxr/WebXRInputSpace.cpp 2021-04-22 14:06:06 UTC (rev 276433)
@@ -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)
Copied: trunk/Source/WebCore/Modules/webxr/WebXRInputSpace.h (from rev 276432, trunk/Source/WebCore/Modules/webxr/WebXRInputSource.h) (0 => 276433)
--- trunk/Source/WebCore/Modules/webxr/WebXRInputSpace.h (rev 0)
+++ trunk/Source/WebCore/Modules/webxr/WebXRInputSpace.h 2021-04-22 14:06:06 UTC (rev 276433)
@@ -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)
Modified: trunk/Source/WebCore/Modules/webxr/WebXRSession.cpp (276432 => 276433)
--- trunk/Source/WebCore/Modules/webxr/WebXRSession.cpp 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/Modules/webxr/WebXRSession.cpp 2021-04-22 14:06:06 UTC (rev 276433)
@@ -52,7 +52,7 @@
WebXRSession::WebXRSession(Document& document, WebXRSystem& system, XRSessionMode mode, PlatformXR::Device& device, FeatureList&& requestedFeatures)
: ActiveDOMObject(&document)
- , m_inputSources(WebXRInputSourceArray::create())
+ , m_inputSources(WebXRInputSourceArray::create(*this))
, m_xrSystem(system)
, m_mode(mode)
, m_device(makeWeakPtr(device))
@@ -62,8 +62,8 @@
, m_timeOrigin(MonotonicTime::now())
, m_views(device.views(mode))
{
+ m_device->setTrackingAndRenderingClient(makeWeakPtr(*this));
m_device->initializeTrackingAndRendering(mode);
- m_device->setTrackingAndRenderingClient(makeWeakPtr(*this));
// https://immersive-web.github.io/webxr/#ref-for-dom-xrreferencespacetype-viewer%E2%91%A2
// Every session MUST support viewer XRReferenceSpaces.
@@ -315,6 +315,11 @@
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 @@
// 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,26 @@
{
}
+void WebXRSession::sessionDidInitializeInputSources(Vector<PlatformXR::Device::FrameData::InputSource>&& inputSources)
+{
+ // https://immersive-web.github.io/webxr/#dom-xrsystem-requestsession
+ // 5.4.11 Queue a task to perform the following steps: NOTE: These steps ensure that initial inputsourceschange
+ // events occur after the initial session is resolved.
+ queueTaskKeepingObjectAlive(*this, TaskSource::WebXR, [this, inputSources = WTFMove(inputSources)]() mutable {
+ // 1. Set session's promise resolved flag to true.
+ m_inputInitialized = true;
+ // 2. Let sources be any existing input sources attached to session.
+ // 3. If sources is non-empty, perform the following steps:
+ if (!inputSources.isEmpty()) {
+ auto timestamp = (MonotonicTime::now() - m_timeOrigin).milliseconds();
+ // 3.1. Set session's list of active XR input sources to sources.
+ // 3.2. Fire an XRInputSourcesChangeEvent named inputsourceschange on session with added set to sources.
+ // Note: 3.1 and 3.2 steps are handled inside the update() call.
+ m_inputSources->update(timestamp, inputSources);
+ }
+ });
+}
+
void WebXRSession::sessionDidEnd()
{
// This can be called as a result of finishing the shutdown initiated
@@ -527,6 +554,9 @@
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:
Modified: trunk/Source/WebCore/Modules/webxr/WebXRSession.h (276432 => 276433)
--- trunk/Source/WebCore/Modules/webxr/WebXRSession.h 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/Modules/webxr/WebXRSession.h 2021-04-22 14:06:06 UTC (rev 276433)
@@ -84,6 +84,7 @@
IntSize nativeWebGLFramebufferResolution() const;
IntSize recommendedWebGLFramebufferResolution() const;
bool supportsViewportScaling() const;
+ bool isPositionEmulated() const;
// EventTarget.
ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); }
@@ -111,6 +112,7 @@
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 @@
// 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
Modified: trunk/Source/WebCore/Modules/webxr/WebXRSpace.cpp (276432 => 276433)
--- trunk/Source/WebCore/Modules/webxr/WebXRSpace.cpp 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/Modules/webxr/WebXRSpace.cpp 2021-04-22 14:06:06 UTC (rev 276433)
@@ -54,6 +54,11 @@
}
+bool WebXRSpace::isPositionEmulated() const
+{
+ return session().isPositionEmulated();
+}
+
WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRViewerSpace);
WebXRViewerSpace::WebXRViewerSpace(Document& document, WebXRSession& session)
Modified: trunk/Source/WebCore/Modules/webxr/WebXRSpace.h (276432 => 276433)
--- trunk/Source/WebCore/Modules/webxr/WebXRSpace.h 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/Modules/webxr/WebXRSpace.h 2021-04-22 14:06:06 UTC (rev 276433)
@@ -47,6 +47,7 @@
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; }
Modified: trunk/Source/WebCore/Modules/webxr/WebXRSystem.cpp (276432 => 276433)
--- trunk/Source/WebCore/Modules/webxr/WebXRSystem.cpp 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/Modules/webxr/WebXRSystem.cpp 2021-04-22 14:06:06 UTC (rev 276433)
@@ -446,14 +446,7 @@
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.
});
}
Modified: trunk/Source/WebCore/Modules/webxr/XRHandedness.h (276432 => 276433)
--- trunk/Source/WebCore/Modules/webxr/XRHandedness.h 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/Modules/webxr/XRHandedness.h 2021-04-22 14:06:06 UTC (rev 276433)
@@ -27,13 +27,11 @@
#if ENABLE(WEBXR)
+#include "PlatformXR.h"
+
namespace WebCore {
-enum class XRHandedness {
- None,
- Left,
- Right,
-};
+using XRHandedness = PlatformXR::XRHandedness;
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/webxr/XRInputSourceEvent.cpp (276432 => 276433)
--- trunk/Source/WebCore/Modules/webxr/XRInputSourceEvent.cpp 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/Modules/webxr/XRInputSourceEvent.cpp 2021-04-22 14:06:06 UTC (rev 276433)
@@ -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 @@
: 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 @@
return *m_inputSource;
}
-Optional<int> XRInputSourceEvent::buttonIndex() const
+void XRInputSourceEvent::setFrameActive(bool active)
{
- return m_buttonIndex;
+ m_frame->setActive(active);
}
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/webxr/XRInputSourceEvent.h (276432 => 276433)
--- trunk/Source/WebCore/Modules/webxr/XRInputSourceEvent.h 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/Modules/webxr/XRInputSourceEvent.h 2021-04-22 14:06:06 UTC (rev 276433)
@@ -37,11 +37,11 @@
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,8 +49,10 @@
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);
Modified: trunk/Source/WebCore/Modules/webxr/XRInputSourcesChangeEvent.h (276432 => 276433)
--- trunk/Source/WebCore/Modules/webxr/XRInputSourcesChangeEvent.h 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/Modules/webxr/XRInputSourcesChangeEvent.h 2021-04-22 14:06:06 UTC (rev 276433)
@@ -52,6 +52,8 @@
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);
Modified: trunk/Source/WebCore/Modules/webxr/XRInputSourcesChangeEvent.idl (276432 => 276433)
--- trunk/Source/WebCore/Modules/webxr/XRInputSourcesChangeEvent.idl 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/Modules/webxr/XRInputSourcesChangeEvent.idl 2021-04-22 14:06:06 UTC (rev 276433)
@@ -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;
};
Modified: trunk/Source/WebCore/Modules/webxr/XRTargetRayMode.h (276432 => 276433)
--- trunk/Source/WebCore/Modules/webxr/XRTargetRayMode.h 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/Modules/webxr/XRTargetRayMode.h 2021-04-22 14:06:06 UTC (rev 276433)
@@ -27,13 +27,11 @@
#if ENABLE(WEBXR)
+#include "PlatformXR.h"
+
namespace WebCore {
-enum class XRTargetRayMode {
- Gaze,
- TrackedPointer,
- Screen,
-};
+using XRTargetRayMode = PlatformXR::XRTargetRayMode;
} // namespace WebCore
Modified: trunk/Source/WebCore/Sources.txt (276432 => 276433)
--- trunk/Source/WebCore/Sources.txt 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/Sources.txt 2021-04-22 14:06:06 UTC (rev 276433)
@@ -426,8 +426,10 @@
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
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (276432 => 276433)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-04-22 14:06:06 UTC (rev 276433)
@@ -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>"; };
@@ -28992,6 +29000,8 @@
E1EE8AF02412B17000E794D6 /* WebXRFrame.cpp */,
E1EE8AE32412B17000E794D6 /* WebXRFrame.h */,
E19490882434F15900416A99 /* WebXRFrame.idl */,
+ 11E5163B261E1A1400E69F25 /* WebXRGamepad.cpp */,
+ 11E5163A261E1A1400E69F25 /* WebXRGamepad.h */,
E1EE8B0D2412B17000E794D6 /* WebXRInputSource.cpp */,
E1EE8B172412B17000E794D6 /* WebXRInputSource.h */,
E19490892434F15A00416A99 /* WebXRInputSource.idl */,
@@ -28998,6 +29008,8 @@
E1EE8AE62412B17000E794D6 /* WebXRInputSourceArray.cpp */,
E1EE8ADD2412B17000E794D6 /* WebXRInputSourceArray.h */,
E19490932434F16000416A99 /* WebXRInputSourceArray.idl */,
+ 11E51637261E1A0500E69F25 /* WebXRInputSpace.cpp */,
+ 11E51635261E1A0500E69F25 /* WebXRInputSpace.h */,
E12FDAFB24A0FD1C0070236E /* WebXRLayer.cpp */,
E12FDAFD24A0FD1E0070236E /* WebXRLayer.h */,
E12FDAFE24A0FD1F0070236E /* WebXRLayer.idl */,
@@ -35782,8 +35794,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 */,
@@ -37100,8 +37114,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 */,
Modified: trunk/Source/WebCore/platform/gamepad/GamepadConstants.cpp (276432 => 276433)
--- trunk/Source/WebCore/platform/gamepad/GamepadConstants.cpp 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/platform/gamepad/GamepadConstants.cpp 2021-04-22 14:06:06 UTC (rev 276433)
@@ -43,7 +43,16 @@
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
#endif // ENABLE(GAMEPAD)
Modified: trunk/Source/WebCore/platform/gamepad/GamepadConstants.h (276432 => 276433)
--- trunk/Source/WebCore/platform/gamepad/GamepadConstants.h 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/platform/gamepad/GamepadConstants.h 2021-04-22 14:06:06 UTC (rev 276433)
@@ -62,6 +62,9 @@
extern const GamepadButtonRole maximumGamepadButton;
const WTF::String& standardGamepadMappingString();
+#if ENABLE(WEBXR)
+const WTF::String& xrStandardGamepadMappingString();
+#endif
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/xr/PlatformXR.h (276432 => 276433)
--- trunk/Source/WebCore/platform/xr/PlatformXR.h 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/platform/xr/PlatformXR.h 2021-04-22 14:06:06 UTC (rev 276433)
@@ -56,16 +56,24 @@
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 @@
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 @@
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 @@
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();
Modified: trunk/Source/WebCore/testing/WebFakeXRDevice.cpp (276432 => 276433)
--- trunk/Source/WebCore/testing/WebFakeXRDevice.cpp 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/testing/WebFakeXRDevice.cpp 2021-04-22 14:06:06 UTC (rev 276433)
@@ -106,6 +106,19 @@
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 @@
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));
}
@@ -239,9 +257,12 @@
{
}
-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)
Modified: trunk/Source/WebCore/testing/WebFakeXRDevice.h (276432 => 276433)
--- trunk/Source/WebCore/testing/WebFakeXRDevice.h 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/testing/WebFakeXRDevice.h 2021-04-22 14:06:06 UTC (rev 276433)
@@ -80,6 +80,7 @@
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 @@
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 @@
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
Modified: trunk/Source/WebCore/testing/WebFakeXRInputController.cpp (276432 => 276433)
--- trunk/Source/WebCore/testing/WebFakeXRInputController.cpp 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/testing/WebFakeXRInputController.cpp 2021-04-22 14:06:06 UTC (rev 276433)
@@ -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 };
+
+Ref<WebFakeXRInputController> WebFakeXRInputController::create(PlatformXR::InputSourceHandle handle, const FakeXRInputSourceInit& init)
{
+ return adoptRef(*new WebFakeXRInputController(handle, init));
}
-void WebFakeXRInputController::setProfiles(Vector<String>)
+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)
{
+ setPointerOrigin(init.pointerOrigin, false);
+ setGripOrigin(init.gripOrigin, false);
+ setSupportedButtons(init.supportedButtons);
}
void WebFakeXRInputController::setGripOrigin(FakeXRRigidTransformInit gripOrigin, bool emulatedPosition)
{
- UNUSED_PARAM(gripOrigin);
- UNUSED_PARAM(emulatedPosition);
-}
+ auto transform = WebFakeXRDevice::parseRigidTransform(gripOrigin);
+ if (transform.hasException())
+ return;
+ m_gripOrigin = InputSourcePose { transform.releaseReturnValue(), emulatedPosition };
+}
-void WebFakeXRInputController::clearGripOrigin()
-{
-}
-
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::setSupportedButtons(const Vector<FakeXRButtonStateInit>& buttons)
{
+ m_buttons.clear();
+ for (auto& button : buttons)
+ m_buttons.add(button.buttonType, button);
}
-void WebFakeXRInputController::endSelection()
+void WebFakeXRInputController::updateButtonState(const FakeXRButtonStateInit& init)
{
+ auto it = m_buttons.find(init.buttonType);
+ if (it != m_buttons.end())
+ it->value = init;
}
-void WebFakeXRInputController::simulateSelect()
+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 = ""
+ 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::setSupportedButtons(Vector<FakeXRButtonStateInit>)
+WebFakeXRInputController::ButtonOrPlaceholder WebFakeXRInputController::getButtonOrPlaceholder(FakeXRButtonStateInit::Type buttonType) const
{
-}
+ ButtonOrPlaceholder result;
-void WebFakeXRInputController::updateButtonState(FakeXRButtonStateInit)
-{
+ 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
Modified: trunk/Source/WebCore/testing/WebFakeXRInputController.h (276432 => 276433)
--- trunk/Source/WebCore/testing/WebFakeXRInputController.h 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/WebCore/testing/WebFakeXRInputController.h 2021-04-22 14:06:06 UTC (rev 276433)
@@ -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 @@
class WebFakeXRInputController final : public RefCounted<WebFakeXRInputController> {
public:
- static Ref<WebFakeXRInputController> create() { return adoptRef(*new WebFakeXRInputController); }
+ static Ref<WebFakeXRInputController> create(PlatformXR::InputSourceHandle, const FakeXRInputSourceInit&);
- void setHandedness(XRHandedness);
-
- void setTargetRayMode(XRTargetRayMode);
-
- void setProfiles(Vector<String>);
-
+ 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();
+ PlatformXR::Device::FrameData::InputSource getFrameData();
- void endSelection();
+private:
+ WebFakeXRInputController(PlatformXR::InputSourceHandle, const FakeXRInputSourceInit&);
- void simulateSelect();
+ struct ButtonOrPlaceholder {
+ Optional<PlatformXR::Device::FrameData::InputSourceButton> button;
+ Optional<Vector<float>> axes;
+ };
+ ButtonOrPlaceholder getButtonOrPlaceholder(FakeXRButtonStateInit::Type) const;
- void setSupportedButtons(Vector<FakeXRButtonStateInit>);
-
- void updateButtonState(FakeXRButtonStateInit);
-
-private:
- WebFakeXRInputController() = default;
+ 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
Modified: trunk/Source/cmake/OptionsWPE.cmake (276432 => 276433)
--- trunk/Source/cmake/OptionsWPE.cmake 2021-04-22 12:18:47 UTC (rev 276432)
+++ trunk/Source/cmake/OptionsWPE.cmake 2021-04-22 14:06:06 UTC (rev 276433)
@@ -205,6 +205,7 @@
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)