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-221225-20210216134201.patch (text/plain), 93.83 KB, created by
Imanol Fernandez
on 2021-02-16 04:42:03 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Imanol Fernandez
Created:
2021-02-16 04:42:03 PST
Size:
93.83 KB
patch
obsolete
>Subversion Revision: 272843 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index ccb54b75ffaf77c7d23ac4d13a8b41e962cd6b2c..82f59a9b53aa77f6a190a2d2afd1642c279f5cd2 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,131 @@ >+2021-02-15 Imanol Fernandez <ifernandez@igalia.com> and Sergio Villar Senin <svillar@igalia.com> >+ >+ Implement WebXR getViewerPose and getPose >+ https://bugs.webkit.org/show_bug.cgi?id=221225 >+ <rdar://problem/74112910> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ - Improve PlatformXR::FrameData struct. >+ - Implement WebXRFrame getViewerPose and getPose. >+ - Implement WebXRReferenceSpace offset, origin and effective tranforms. >+ - Implement WebXRBoundedReferenceSpace nativeOrigin. >+ - Apply frame updates in WebXRSession. >+ - Implement views for OpenXR and DummyInlineDevice inline sessions. >+ - Query and complete all the new FrameData in the OpenXR port. >+ - Complete the WebFakeXRDevice implementation for WebXR WPT tests. >+ >+ Tested by the WebXR WPT tests >+ >+ * Modules/webxr/WebXRBoundedReferenceSpace.cpp: Implement nativeOrigina and getOffsetReferenceSpace. >+ (WebCore::WebXRBoundedReferenceSpace::create): >+ (WebCore::WebXRBoundedReferenceSpace::WebXRBoundedReferenceSpace): >+ (WebCore::WebXRBoundedReferenceSpace::nativeOrigin const): >+ (WebCore::WebXRBoundedReferenceSpace::boundsGeometry const): >+ (WebCore::WebXRBoundedReferenceSpace::getOffsetReferenceSpace): >+ * Modules/webxr/WebXRBoundedReferenceSpace.h: >+ >+ * Modules/webxr/WebXRFrame.cpp: Implement WebXR getViewerPose and getPose. >+ (WebCore::WebXRFrame::create): >+ (WebCore::WebXRFrame::WebXRFrame): >+ (WebCore::WebXRFrame::mustPosesBeLimited): >+ (WebCore::WebXRFrame::populatePose): >+ (WebCore::WebXRFrame::getViewerPose): >+ (WebCore::WebXRFrame::getPose): >+ (WebCore::WebXRFrame::matrixFromPose): add helper function. >+ * Modules/webxr/WebXRFrame.h: >+ (WebCore::WebXRFrame::setFrameData): >+ * Modules/webxr/WebXRFrame.idl: add MayThrowException. >+ >+ * Modules/webxr/WebXRPose.cpp: Add WebXRRigidTransform constructor parameter. Add specialize type traits. >+ (WebCore::WebXRPose::create): >+ (WebCore::WebXRPose::WebXRPose): >+ * Modules/webxr/WebXRPose.h: >+ (WebCore::WebXRPose::isViewerPose const): >+ * Modules/webxr/WebXRPose.idl: Remove ImplementationLacksVTable >+ >+ * Modules/webxr/WebXRReferenceSpace.cpp: Implement offset, origin and effective tranforms. >+ (WebCore::WebXRReferenceSpace::create): >+ (WebCore::WebXRReferenceSpace::WebXRReferenceSpace): >+ (WebCore::WebXRReferenceSpace::nativeOrigin const): >+ (WebCore::WebXRReferenceSpace::getOffsetReferenceSpace): >+ (WebCore::WebXRReferenceSpace::floorOriginTransform const): >+ (WebCore:: const): >+ * Modules/webxr/WebXRReferenceSpace.h: >+ (WebCore::WebXRReferenceSpace::type const): >+ * Modules/webxr/WebXRReferenceSpace.idl: Add SkipVTableValidation. >+ >+ * Modules/webxr/WebXRSession.cpp: Apply frame updates for frame. Add active views data. >+ (WebCore::WebXRSession::WebXRSession): >+ (WebCore::WebXRSession::requestReferenceSpace): Use WeakPtr instead Ref for WebXRSession. >+ (WebCore::WebXRSession::onFrame): >+ (WebCore::WebXRSession::posesCanBeReported const): add >+ * Modules/webxr/WebXRSession.h: >+ >+ * Modules/webxr/WebXRSpace.cpp: Add nativeOrigin and effectiveOrigin member functions. Add specialize type traits. >+ (WebCore::WebXRSpace::WebXRSpace): >+ (WebCore::WebXRSpace::effectiveOrigin const): >+ * Modules/webxr/WebXRSpace.h: >+ (WebCore::WebXRSpace::session const): >+ (WebCore::WebXRSpace::isReferenceSpace const): >+ (WebCore::WebXRSpace::isBoundedReferenceSpace const): >+ >+ * Modules/webxr/WebXRSystem.cpp: Implement views for DummyInlineDevice. >+ (WebCore::WebXRSystem::DummyInlineDevice::requestFrame): >+ (WebCore::WebXRSystem::DummyInlineDevice::views const): >+ * Modules/webxr/WebXRSystem.h: >+ >+ * Modules/webxr/WebXRView.cpp: Pass WebXRRigidTransform in the constructor. >+ (WebCore::WebXRView::create): >+ (WebCore::WebXRView::WebXRView): >+ (WebCore::WebXRView::setProjectionMatrix): Use std::array to match device data. >+ * Modules/webxr/WebXRView.h: >+ (WebCore::WebXRView::projectionMatrix const): >+ (WebCore::WebXRView::transform const): >+ >+ * Modules/webxr/WebXRViewerPose.cpp: Add views setter. Add specialize type traits. >+ (WebCore::WebXRViewerPose::create): >+ (WebCore::WebXRViewerPose::WebXRViewerPose): >+ (WebCore::WebXRViewerPose::setViews): >+ * Modules/webxr/WebXRViewerPose.h: >+ * Modules/webxr/WebXRViewerPose.idl: Remove ImplementationLacksVTable. Add JSGenerateToNativeObject. >+ >+ * Modules/webxr/XREye.h: Reuse PlatformXR enum. >+ >+ * platform/graphics/transforms/TransformationMatrix.cpp: Add projection matrix utility functions. >+ (WebCore::TransformationMatrix::fromProjection): >+ * platform/graphics/transforms/TransformationMatrix.h: >+ >+ * platform/xr/PlatformXR.h: Improve FrameData. >+ >+ * platform/xr/openxr/PlatformXROpenXR.cpp: Query and complete all the new FrameData. >+ (PlatformXR::OpenXRDevice::createReferenceSpace): add helper function. >+ (PlatformXR::OpenXRDevice::recommendedResolution): Query resolution data from OpenXR. >+ (PlatformXR::OpenXRDevice::initializeTrackingAndRendering): Initialize local and view XrSpaces. >+ (PlatformXR::OpenXRDevice::initializeReferenceSpace): Lazily initialize stage XrSpace. >+ (PlatformXR::XrPosefToPose): add helper function. >+ (PlatformXR::xrViewToPose): add helper function. >+ (PlatformXR::OpenXRDevice::requestFrame): Complete all the new frame Data >+ (PlatformXR::OpenXRDevice::views const): Implement view data for OpenXR >+ * platform/xr/openxr/PlatformXROpenXR.h: >+ >+ * testing/WebFakeXRDevice.cpp: Complete the required implementation for WebXR WPT tests. >+ (WebCore::FakeXRView::setProjection): >+ (WebCore::FakeXRView::setFieldOfView): >+ (WebCore::SimulatedXRDevice::frameTimerFired): >+ (WebCore::SimulatedXRDevice::requestFrame): >+ (WebCore::SimulatedXRDevice::views const): >+ (WebCore::SimulatedXRDevice::scheduleOnNextFrame): >+ (WebCore::WebFakeXRDevice::setViews): >+ (WebCore::WebFakeXRDevice::setViewerOrigin): >+ (WebCore::WebFakeXRDevice::clearViewerOrigin): >+ (WebCore::WebFakeXRDevice::setBoundsGeometry): >+ (WebCore::WebFakeXRDevice::setFloorOrigin): >+ (WebCore::WebFakeXRDevice::clearFloorOrigin): >+ (WebCore::WebFakeXRDevice::parseRigidTransform): >+ (WebCore::WebFakeXRDevice::parseView): >+ * testing/WebFakeXRDevice.h: >+ > 2021-02-12 Sergio Villar Senin <svillar@igalia.com> > > Don't update form control elements validity status if they are detached from the document. >diff --git a/Source/WebCore/Modules/webxr/WebXRBoundedReferenceSpace.cpp b/Source/WebCore/Modules/webxr/WebXRBoundedReferenceSpace.cpp >index d44ed62bdcd56fbe8279401e3060388d73f491fd..947cb179a8e53a6a4c2339d1e88f2396adfcedfd 100644 >--- a/Source/WebCore/Modules/webxr/WebXRBoundedReferenceSpace.cpp >+++ b/Source/WebCore/Modules/webxr/WebXRBoundedReferenceSpace.cpp >@@ -29,29 +29,63 @@ > #if ENABLE(WEBXR) > > #include "DOMPointReadOnly.h" >+#include "Document.h" >+#include "WebXRRigidTransform.h" >+#include "WebXRSession.h" > #include <wtf/IsoMallocInlines.h> > > namespace WebCore { > > WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRBoundedReferenceSpace); > >-Ref<WebXRBoundedReferenceSpace> WebXRBoundedReferenceSpace::create(Document& document, Ref<WebXRSession>&& session, XRReferenceSpaceType type) >+Ref<WebXRBoundedReferenceSpace> WebXRBoundedReferenceSpace::create(Document& document, WebXRSession& session, XRReferenceSpaceType type) > { >- return adoptRef(*new WebXRBoundedReferenceSpace(document, WTFMove(session), type)); >+ return adoptRef(*new WebXRBoundedReferenceSpace(document, session, WebXRRigidTransform::create(), type)); > } > >-WebXRBoundedReferenceSpace::WebXRBoundedReferenceSpace(Document& document, Ref<WebXRSession>&& session, XRReferenceSpaceType type) >- : WebXRReferenceSpace(document, WTFMove(session), type) >+ >+Ref<WebXRBoundedReferenceSpace> WebXRBoundedReferenceSpace::create(Document& document, WebXRSession& session, Ref<WebXRRigidTransform>&& offset, XRReferenceSpaceType type) >+{ >+ return adoptRef(*new WebXRBoundedReferenceSpace(document, session, WTFMove(offset), type)); >+} >+ >+ >+WebXRBoundedReferenceSpace::WebXRBoundedReferenceSpace(Document& document, WebXRSession& session, Ref<WebXRRigidTransform>&& offset, XRReferenceSpaceType type) >+ : WebXRReferenceSpace(document, session, WTFMove(offset), type) > { > } > > WebXRBoundedReferenceSpace::~WebXRBoundedReferenceSpace() = default; > >+TransformationMatrix WebXRBoundedReferenceSpace::nativeOrigin() const >+{ >+ // https://immersive-web.github.io/webxr/#dom-xrreferencespacetype-bounded-floor. >+ // Bounded floor space should be at the same height as local floor space. >+ return floorOriginTransform(); >+} >+ > const Vector<Ref<DOMPointReadOnly>>& WebXRBoundedReferenceSpace::boundsGeometry() const > { >+ // FIXME: get data from device > return m_boundsGeometry; > } > >+ >+RefPtr<WebXRReferenceSpace> WebXRBoundedReferenceSpace::getOffsetReferenceSpace(const WebXRRigidTransform& offsetTransform) >+{ >+ if (!scriptExecutionContext()) >+ return nullptr; >+ ASSERT(is<Document>(scriptExecutionContext())); >+ >+ // https://immersive-web.github.io/webxr/#dom-xrreferencespace-getoffsetreferencespace >+ // Set offsetSpaceâs origin offset to the result of multiplying baseâs origin offset by originOffset in the relevant realm of base. >+ auto offset = WebXRRigidTransform::create(m_originOffset->rawTransform() * offsetTransform.rawTransform()); >+ >+ // FIXME: set offsetSpaceâs boundsGeometry to baseâs boundsGeometry, with each point multiplied by the inverse of originOffset. >+ return create(downcast<Document>(*scriptExecutionContext()), m_session, WTFMove(offset), m_type); >+} >+ >+ > } // namespace WebCore > > #endif // ENABLE(WEBXR) >diff --git a/Source/WebCore/Modules/webxr/WebXRBoundedReferenceSpace.h b/Source/WebCore/Modules/webxr/WebXRBoundedReferenceSpace.h >index 71a9f970a7301bd4f04e4c0bbee81eaeea3f44d7..75287fb75b0344b77b752b5204c2570bceba0e55 100644 >--- a/Source/WebCore/Modules/webxr/WebXRBoundedReferenceSpace.h >+++ b/Source/WebCore/Modules/webxr/WebXRBoundedReferenceSpace.h >@@ -25,13 +25,13 @@ > > #pragma once > >+#if ENABLE(WEBXR) >+ > #include "WebXRReferenceSpace.h" > #include <wtf/IsoMalloc.h> > #include <wtf/Ref.h> > #include <wtf/Vector.h> > >-#if ENABLE(WEBXR) >- > namespace WebCore { > > class DOMPointReadOnly; >@@ -39,18 +39,25 @@ class DOMPointReadOnly; > class WebXRBoundedReferenceSpace : public WebXRReferenceSpace { > WTF_MAKE_ISO_ALLOCATED(WebXRBoundedReferenceSpace); > public: >- static Ref<WebXRBoundedReferenceSpace> create(Document&, Ref<WebXRSession>&&, XRReferenceSpaceType); >+ static Ref<WebXRBoundedReferenceSpace> create(Document&, WebXRSession&, XRReferenceSpaceType); >+ static Ref<WebXRBoundedReferenceSpace> create(Document&, WebXRSession&, Ref<WebXRRigidTransform>&&, XRReferenceSpaceType); > > virtual ~WebXRBoundedReferenceSpace(); > >+ TransformationMatrix nativeOrigin() const final; > const Vector<Ref<DOMPointReadOnly>>& boundsGeometry() const; >+ RefPtr<WebXRReferenceSpace> getOffsetReferenceSpace(const WebXRRigidTransform&) final; > > private: >- WebXRBoundedReferenceSpace(Document&, Ref<WebXRSession>&&, XRReferenceSpaceType); >+ WebXRBoundedReferenceSpace(Document&, WebXRSession&, Ref<WebXRRigidTransform>&&, XRReferenceSpaceType); >+ >+ bool isBoundedReferenceSpace() const final { return true; } > > Vector<Ref<DOMPointReadOnly>> m_boundsGeometry; > }; > > } // namespace WebCore > >+SPECIALIZE_TYPE_TRAITS_WEBXRSPACE(WebXRBoundedReferenceSpace, isBoundedReferenceSpace()) >+ > #endif // ENABLE(WEBXR) >diff --git a/Source/WebCore/Modules/webxr/WebXRFrame.cpp b/Source/WebCore/Modules/webxr/WebXRFrame.cpp >index f278761b0a7b7d29d179422350a2aa198a23bdec..5f89a3b8830a05da9479502adeedfe9f7c1224d2 100644 >--- a/Source/WebCore/Modules/webxr/WebXRFrame.cpp >+++ b/Source/WebCore/Modules/webxr/WebXRFrame.cpp >@@ -28,35 +28,221 @@ > > #if ENABLE(WEBXR) > >+#include "WebXRBoundedReferenceSpace.h" >+#include "WebXRReferenceSpace.h" > #include "WebXRSession.h" > #include "WebXRViewerPose.h" > #include <wtf/IsoMallocInlines.h> > > namespace WebCore { > >+ > WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRFrame); > >-Ref<WebXRFrame> WebXRFrame::create(Ref<WebXRSession>&& session) >+Ref<WebXRFrame> WebXRFrame::create(Ref<WebXRSession>&& session, IsAnimationFrame isAnimationFrame) > { >- return adoptRef(*new WebXRFrame(WTFMove(session))); >+ return adoptRef(*new WebXRFrame(WTFMove(session), isAnimationFrame)); > } > >-WebXRFrame::WebXRFrame(Ref<WebXRSession>&& session) >- : m_session(WTFMove(session)) >+WebXRFrame::WebXRFrame(Ref<WebXRSession>&& session, IsAnimationFrame isAnimationFrame) >+ : m_isAnimationFrame(isAnimationFrame == IsAnimationFrame::Yes) >+ , m_session(WTFMove(session)) > { > } > > WebXRFrame::~WebXRFrame() = default; > > >-RefPtr<WebXRViewerPose> WebXRFrame::getViewerPose(const WebXRReferenceSpace&) >+ >+bool WebXRFrame::isOutsideNativeBoundsOfBoundedReferenceSpace(const WebXRSpace& space, const WebXRSpace&) const >+{ >+ if (!is<WebXRBoundedReferenceSpace>(space)) >+ return false; >+ >+ // FIXME: return true whenever the distance from the bounded geometry of >+ // |space| to the native origin of |other| space is greater than 1m >+ // (suggested by specs). >+ >+ return false; >+} >+ >+bool WebXRFrame::isLocalReferenceSpace(const WebXRSpace& space) const >+{ >+ if (!is<WebXRReferenceSpace>(space)) >+ return false; >+ >+ auto type = downcast<WebXRReferenceSpace>(space).type(); >+ if (type == XRReferenceSpaceType::Local || type == XRReferenceSpaceType::LocalFloor) >+ return true; >+ >+ return false; >+} >+ >+// https://immersive-web.github.io/webxr/#poses-must-be-limited >+bool WebXRFrame::mustPosesBeLimited(const WebXRSpace& space, const WebXRSpace& baseSpace) const >+{ >+ if (isOutsideNativeBoundsOfBoundedReferenceSpace(space, baseSpace) >+ || isOutsideNativeBoundsOfBoundedReferenceSpace(baseSpace, space)) >+ return true; >+ >+ if (isLocalReferenceSpace(space) || isLocalReferenceSpace(baseSpace)) { >+ // FIXME: If the distance between native origins of spaces is greater >+ // than 15m (suggested by specs) return true. >+ } >+ >+ return false; >+} >+ >+ >+struct WebXRFrame::PopulatedPose { >+ TransformationMatrix transform; >+ bool emulatedPosition { false }; >+}; >+ >+// https://immersive-web.github.io/webxr/#populate-the-pose >+ExceptionOr<Optional<WebXRFrame::PopulatedPose>> WebXRFrame::populatePose(const Document& document, const WebXRSpace& space, const WebXRSpace& baseSpace) >+{ >+ // 1. If frameâs active boolean is false, throw an InvalidStateError and abort these steps. >+ if (!m_active) >+ return Exception { InvalidStateError }; >+ >+ // 2. Let session be frameâs session object. >+ // 3. If spaceâs session does not equal session, throw an InvalidStateError and abort these steps. >+ if (&space.session() != m_session.ptr()) >+ return Exception { InvalidStateError }; >+ >+ // 4. If baseSpaceâs session does not equal session, throw an InvalidStateError and abort these steps. >+ if (&baseSpace.session() != m_session.ptr()) >+ return Exception { InvalidStateError }; >+ >+ // 5. Check if poses may be reported and, if not, throw a SecurityError and abort these steps. >+ if (!m_session->posesCanBeReported(document)) >+ return Exception { SecurityError }; >+ >+ // 6. Let limit be the result of whether poses must be limited between space and baseSpace. >+ bool limit = mustPosesBeLimited(space, baseSpace); >+ >+ // 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) { >+ // 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. >+ return { WTF::nullopt }; >+ } >+ >+ auto baseTransform = baseSpace.effectiveOrigin(); >+ if (!baseTransform.isInvertible()) >+ return { WTF::nullopt }; >+ >+ auto transform = *baseTransform.inverse() * space.effectiveOrigin(); >+ const bool emulatedPosition = m_data.isPositionEmulated || !m_data.isPositionValid; >+ >+ if (limit) { >+ // FIXME: apply pose limits logic >+ // https://immersive-web.github.io/webxr/#poses-must-be-limited >+ } >+ >+ return { PopulatedPose { transform, emulatedPosition } }; >+} >+ >+// https://immersive-web.github.io/webxr/#dom-xrframe-getviewerpose >+ExceptionOr<RefPtr<WebXRViewerPose>> WebXRFrame::getViewerPose(const Document& document, const WebXRReferenceSpace& referenceSpace) >+{ >+ // 1. Let frame be this. >+ // 2. Let session be frameâs session object. >+ // 3. If frameâs animationFrame boolean is false, throw an InvalidStateError and abort these steps. >+ if (!m_isAnimationFrame) >+ return Exception { InvalidStateError }; >+ >+ // 4. Let pose be a new XRViewerPose object in the relevant realm of session. >+ // 5. Populate the pose of sessionâs viewer reference space in referenceSpace at the time represented by frame into pose. >+ auto populatePoseResult = populatePose(document, m_session->viewerReferenceSpace(), referenceSpace); >+ if (populatePoseResult.hasException()) >+ return populatePoseResult.releaseException(); >+ >+ // 6. If pose is null return null. >+ auto populateValue = populatePoseResult.releaseReturnValue(); >+ if (!populateValue.hasValue()) >+ return nullptr; >+ >+ RefPtr<WebXRViewerPose> pose = WebXRViewerPose::create(WebXRRigidTransform::create(populateValue->transform), populateValue->emulatedPosition); >+ >+ // 7. Let xrviews be an empty list. >+ Vector<Ref<WebXRView>> xrViews; >+ // 8. For each active view view in the list of views on session, perform the following steps: >+ for (auto& view : m_session->views()) { >+ auto index = xrViews.size(); >+ if (!view.active || m_data.views.size() <= index) >+ continue; >+ >+ // 8.1 Let xrview be a new XRView object in the relevant realm of session. >+ // 8.2 Initialize xrviewâs underlying view to view. >+ // 8.3 Initialize xrviewâs eye to viewâs eye. >+ // 8.4 Initialize xrviewâs frame time to frameâs time. >+ // 8.5 Initialize xrviewâs session to session. >+ // 8.6. Let offset be an new XRRigidTransform object equal to the view offset of view in the relevant realm of session. >+ // 8.7. Set xrviewâs transform property to the result of multiplying the XRViewerPose's transform by the offset transform in the relevant realm of session >+ auto offset = matrixFromPose(m_data.views[index].offset); >+ auto transform = WebXRRigidTransform::create(pose->transform().rawTransform() * offset); >+ >+ // Set projection matrix for each view >+ std::array<float, 16> projection = switchOn(m_data.views[index].projection, [&](const PlatformXR::Device::FrameData::Fov& fov) { >+ double near = m_session->renderState().depthNear(); >+ double far = m_session->renderState().depthFar(); >+ return TransformationMatrix::fromProjection(fov.up, fov.down, fov.left, fov.right, near, far).toColumnMajorFloatArray(); >+ }, [&](const std::array<float, 16>& matrix) { >+ return matrix; >+ }, [&](std::nullptr_t&) { >+ // Use aspect projection for inline sessions >+ double fov = m_session->renderState().inlineVerticalFieldOfView().valueOr(piOverTwoDouble); >+ float aspect = 1; >+ auto layer = m_session->renderState().baseLayer(); >+ if (layer) >+ aspect = static_cast<double>(layer->framebufferWidth()) / static_cast<double>(layer->framebufferHeight()); >+ double near = m_session->renderState().depthNear(); >+ double far = m_session->renderState().depthFar(); >+ return TransformationMatrix::fromProjection(fov, aspect, near, far).toColumnMajorFloatArray(); >+ }); >+ >+ auto xrView = WebXRView::create(view.eye, WTFMove(transform), Float32Array::create(projection.data(), projection.size())); >+ >+ // 8.8. Append xrview to xrviews >+ xrViews.append(WTFMove(xrView)); >+ } >+ >+ // 9. Set poseâs views to xrviews >+ pose->setViews(WTFMove(xrViews)); >+ >+ // 10. Return pose. >+ return pose; >+} >+ >+ExceptionOr<RefPtr<WebXRPose>> WebXRFrame::getPose(const Document& document, const WebXRSpace& space, const WebXRSpace& baseSpace) > { >- return { }; >+ // 1. Let frame be this. >+ // 2. Let pose be a new XRPose object in the relevant realm of frame. >+ // 3. Populate the pose of space in baseSpace at the time represented by frame into pose. >+ >+ auto populatePoseResult = populatePose(document, space, baseSpace); >+ if (populatePoseResult.hasException()) >+ return populatePoseResult.releaseException(); >+ >+ auto populateValue = populatePoseResult.releaseReturnValue(); >+ if (!populateValue.hasValue()) >+ return nullptr; >+ >+ // 4. Return pose. >+ return RefPtr<WebXRPose>(WebXRPose::create(WebXRRigidTransform::create(populateValue->transform), populateValue->emulatedPosition)); > } > >-RefPtr<WebXRPose> WebXRFrame::getPose(const WebXRSpace&, const WebXRSpace&) >+TransformationMatrix WebXRFrame::matrixFromPose(const PlatformXR::Device::FrameData::Pose& pose) > { >- return { }; >+ TransformationMatrix matrix; >+ matrix.translate3d(pose.position.x(), pose.position.y(), pose.position.z()); >+ matrix.multiply(TransformationMatrix::fromQuaternion(pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w)); >+ return matrix; > } > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/webxr/WebXRFrame.h b/Source/WebCore/Modules/webxr/WebXRFrame.h >index 2a26ad86a2c30da8c23dfb6c7bbb90382d12e05d..71964c1c4c219d586182d6a46ec1f05b41573060 100644 >--- a/Source/WebCore/Modules/webxr/WebXRFrame.h >+++ b/Source/WebCore/Modules/webxr/WebXRFrame.h >@@ -28,6 +28,8 @@ > #if ENABLE(WEBXR) > > #include "DOMHighResTimeStamp.h" >+#include "ExceptionOr.h" >+#include "PlatformXR.h" > #include <wtf/IsoMalloc.h> > #include <wtf/Ref.h> > #include <wtf/RefCounted.h> >@@ -35,6 +37,7 @@ > > namespace WebCore { > >+class Document; > class WebXRPose; > class WebXRReferenceSpace; > class WebXRSession; >@@ -44,23 +47,38 @@ class WebXRViewerPose; > class WebXRFrame : public RefCounted<WebXRFrame> { > WTF_MAKE_ISO_ALLOCATED(WebXRFrame); > public: >- static Ref<WebXRFrame> create(Ref<WebXRSession>&&); >+ enum class IsAnimationFrame : bool { No, Yes }; >+ static Ref<WebXRFrame> create(Ref<WebXRSession>&&, IsAnimationFrame); > ~WebXRFrame(); > > const WebXRSession& session() const { return m_session.get(); } > >- RefPtr<WebXRViewerPose> getViewerPose(const WebXRReferenceSpace&); >- RefPtr<WebXRPose> getPose(const WebXRSpace&, const WebXRSpace&); >+ ExceptionOr<RefPtr<WebXRViewerPose>> getViewerPose(const Document&, const WebXRReferenceSpace&); >+ ExceptionOr<RefPtr<WebXRPose>> getPose(const Document&, const WebXRSpace&, const WebXRSpace&); > > void setTime(DOMHighResTimeStamp time) { m_time = time; } >+ void setFrameData(PlatformXR::Device::FrameData&& data) { m_data = WTFMove(data); } >+ > void setActive(bool active) { m_active = active; } > bool isActive() const { return m_active; } > >+ static TransformationMatrix matrixFromPose(const PlatformXR::Device::FrameData::Pose&); >+ > private: >- explicit WebXRFrame(Ref<WebXRSession>&&); >+ explicit WebXRFrame(Ref<WebXRSession>&&, IsAnimationFrame); >+ WebXRFrame(WebXRSession&, bool isAnimationFrame); >+ >+ bool isOutsideNativeBoundsOfBoundedReferenceSpace(const WebXRSpace&, const WebXRSpace&) const; >+ bool isLocalReferenceSpace(const WebXRSpace&) const; >+ bool mustPosesBeLimited(const WebXRSpace&, const WebXRSpace&) const; >+ >+ struct PopulatedPose; >+ ExceptionOr<Optional<PopulatedPose>> populatePose(const Document&, const WebXRSpace&, const WebXRSpace&); > > bool m_active { false }; >- DOMHighResTimeStamp m_time; >+ bool m_isAnimationFrame { false }; >+ DOMHighResTimeStamp m_time { 0 }; >+ PlatformXR::Device::FrameData m_data; > Ref<WebXRSession> m_session; > }; > >diff --git a/Source/WebCore/Modules/webxr/WebXRFrame.idl b/Source/WebCore/Modules/webxr/WebXRFrame.idl >index 21fcf3cfe4d9c75fd7f468e497db8e8007b8adf2..d340265b22d88923ee2dc25a77ddb8379da540f5 100644 >--- a/Source/WebCore/Modules/webxr/WebXRFrame.idl >+++ b/Source/WebCore/Modules/webxr/WebXRFrame.idl >@@ -33,6 +33,6 @@ > ] interface WebXRFrame { > [SameObject] readonly attribute WebXRSession session; > >- WebXRViewerPose? getViewerPose(WebXRReferenceSpace referenceSpace); >- WebXRPose? getPose(WebXRSpace space, WebXRSpace baseSpace); >+ [MayThrowException, CallWith=Document] WebXRViewerPose? getViewerPose(WebXRReferenceSpace referenceSpace); >+ [MayThrowException, CallWith=Document] WebXRPose? getPose(WebXRSpace space, WebXRSpace baseSpace); > }; >diff --git a/Source/WebCore/Modules/webxr/WebXRPose.cpp b/Source/WebCore/Modules/webxr/WebXRPose.cpp >index 1c5f80a54455cbe8fcb072d547b3196a98878658..3399d8ae5003e2ae43c01e46bd033b0913b28650 100644 >--- a/Source/WebCore/Modules/webxr/WebXRPose.cpp >+++ b/Source/WebCore/Modules/webxr/WebXRPose.cpp >@@ -35,13 +35,13 @@ namespace WebCore { > > WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRPose); > >-Ref<WebXRPose> WebXRPose::create() >+Ref<WebXRPose> WebXRPose::create(Ref<WebXRRigidTransform>&& transform, bool emulatedPosition) > { >- return adoptRef(*new WebXRPose); >+ return adoptRef(*new WebXRPose(WTFMove(transform), emulatedPosition)); > } > >-WebXRPose::WebXRPose() >- : m_transform(WebXRRigidTransform::create()) >+WebXRPose::WebXRPose(Ref<WebXRRigidTransform>&& transform, bool emulatedPosition) >+ : m_transform(WTFMove(transform)), m_emulatedPosition(emulatedPosition) > { > } > >diff --git a/Source/WebCore/Modules/webxr/WebXRPose.h b/Source/WebCore/Modules/webxr/WebXRPose.h >index 29919d24c3953aa39a2c4894bc7cce5c29c17e6a..ec579068316425d8e98233197b6990b418cba1bd 100644 >--- a/Source/WebCore/Modules/webxr/WebXRPose.h >+++ b/Source/WebCore/Modules/webxr/WebXRPose.h >@@ -26,7 +26,6 @@ > #pragma once > > #if ENABLE(WEBXR) >- > #include <wtf/IsoMalloc.h> > #include <wtf/Ref.h> > #include <wtf/RefCounted.h> >@@ -38,14 +37,16 @@ class WebXRRigidTransform; > class WebXRPose : public RefCounted<WebXRPose> { > WTF_MAKE_ISO_ALLOCATED(WebXRPose); > public: >- static Ref<WebXRPose> create(); >- ~WebXRPose(); >+ static Ref<WebXRPose> create(Ref<WebXRRigidTransform>&&, bool emulatedPosition); >+ virtual ~WebXRPose(); > > const WebXRRigidTransform& transform() const; > bool emulatedPosition() const; > >+ virtual bool isViewerPose() const { return false; } >+ > protected: >- WebXRPose(); >+ WebXRPose(Ref<WebXRRigidTransform>&&, bool emulatedPosition); > > Ref<WebXRRigidTransform> m_transform; > bool m_emulatedPosition { false }; >@@ -53,4 +54,9 @@ protected: > > } // namespace WebCore > >+#define SPECIALIZE_TYPE_TRAITS_WEBXRPOSE(ToValueTypeName, predicate) \ >+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \ >+ static bool isType(const WebCore::WebXRPose& context) { return context.predicate; } \ >+SPECIALIZE_TYPE_TRAITS_END() >+ > #endif // ENABLE(WEBXR) >diff --git a/Source/WebCore/Modules/webxr/WebXRPose.idl b/Source/WebCore/Modules/webxr/WebXRPose.idl >index 4c4e9dadc8ea0af31518694193b9249644788026..2e5b3864e5982782a795ceb9bd7c4e18d6de267b 100644 >--- a/Source/WebCore/Modules/webxr/WebXRPose.idl >+++ b/Source/WebCore/Modules/webxr/WebXRPose.idl >@@ -28,7 +28,6 @@ > Conditional=WEBXR, > SecureContext, > Exposed=Window, >- ImplementationLacksVTable, > InterfaceName=XRPose > ] interface WebXRPose { > [SameObject] readonly attribute WebXRRigidTransform transform; >diff --git a/Source/WebCore/Modules/webxr/WebXRReferenceSpace.cpp b/Source/WebCore/Modules/webxr/WebXRReferenceSpace.cpp >index d5bb0e81f92c589ac7fc6b757136525af02ca796..701e9c74a09fb399b50230c255f6fbd2423d89d2 100644 >--- a/Source/WebCore/Modules/webxr/WebXRReferenceSpace.cpp >+++ b/Source/WebCore/Modules/webxr/WebXRReferenceSpace.cpp >@@ -29,34 +29,100 @@ > #if ENABLE(WEBXR) > > #include "Document.h" >+#include "WebXRFrame.h" >+#include "WebXRRigidTransform.h" > #include "WebXRSession.h" > #include <wtf/IsoMallocInlines.h> > > namespace WebCore { > >+static constexpr double DefaultUserHeightInMeters = 1.65; >+ > WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRReferenceSpace); > >-Ref<WebXRReferenceSpace> WebXRReferenceSpace::create(Document& document, Ref<WebXRSession>&& session, XRReferenceSpaceType type) >+Ref<WebXRReferenceSpace> WebXRReferenceSpace::create(Document& document, WebXRSession& session, XRReferenceSpaceType type) > { >- return adoptRef(*new WebXRReferenceSpace(document, WTFMove(session), type)); >+ // https://immersive-web.github.io/webxr/#xrspace-native-origin >+ // The transform from the effective space to the native origin's space is >+ // defined by an origin offset, which is an XRRigidTransform initially set >+ // to an identity transform. >+ return adoptRef(*new WebXRReferenceSpace(document, session, WebXRRigidTransform::create(), type)); > } > >-WebXRReferenceSpace::WebXRReferenceSpace(Document& document, Ref<WebXRSession>&& session, XRReferenceSpaceType type) >- : WebXRSpace(document, WTFMove(session)) >+Ref<WebXRReferenceSpace> WebXRReferenceSpace::create(Document& document, WebXRSession& session, Ref<WebXRRigidTransform>&& offset, XRReferenceSpaceType type) >+{ >+ return adoptRef(*new WebXRReferenceSpace(document, session, WTFMove(offset), type)); >+} >+ >+WebXRReferenceSpace::WebXRReferenceSpace(Document& document, WebXRSession& session, Ref<WebXRRigidTransform>&& offset, XRReferenceSpaceType type) >+ : WebXRSpace(document, session, WTFMove(offset)) > , m_type(type) > { > } > > WebXRReferenceSpace::~WebXRReferenceSpace() = default; > >-RefPtr<WebXRReferenceSpace> WebXRReferenceSpace::getOffsetReferenceSpace(const WebXRRigidTransform&) >+ >+TransformationMatrix WebXRReferenceSpace::nativeOrigin() const >+{ >+ TransformationMatrix identity; >+ >+ // We assume that poses got from the devices are in local space. >+ // This will require more complex logic if we add ports with different default coordinates. >+ switch (m_type) { >+ case XRReferenceSpaceType::Viewer: { >+ // Return the current pose. Content rendered in viewer pose will stay in fixed point on HMDs. >+ auto& data = m_session.frameData(); >+ return WebXRFrame::matrixFromPose(data.origin); >+ } >+ case XRReferenceSpaceType::Local: >+ // Data from the device is already in local, use the identity matrix. >+ return identity; >+ case XRReferenceSpaceType::Unbounded: >+ // Local and unbounded use the same device space, use the identity matrix. >+ return identity; >+ case XRReferenceSpaceType::LocalFloor: { >+ // Use the floor transform provided by the device or fallback to a default height. >+ return floorOriginTransform(); >+ } >+ case XRReferenceSpaceType::BoundedFloor: >+ default: >+ // BoundedFloor is handled by WebXRBoundedReferenceSpace subclass >+ RELEASE_ASSERT_NOT_REACHED(); >+ } >+ >+ return identity; >+} >+ >+RefPtr<WebXRReferenceSpace> WebXRReferenceSpace::getOffsetReferenceSpace(const WebXRRigidTransform& offsetTransform) > { > if (!scriptExecutionContext()) > return nullptr; > ASSERT(is<Document>(scriptExecutionContext())); >- return create(downcast<Document>(*scriptExecutionContext()), m_session.copyRef(), m_type); >+ >+ // https://immersive-web.github.io/webxr/#dom-xrreferencespace-getoffsetreferencespace >+ // Set offsetSpaceâs origin offset to the result of multiplying baseâs origin offset by originOffset in the relevant realm of base. >+ auto offset = WebXRRigidTransform::create(m_originOffset->rawTransform() * offsetTransform.rawTransform()); >+ >+ return create(downcast<Document>(*scriptExecutionContext()), m_session, WTFMove(offset), m_type); >+} >+ >+TransformationMatrix WebXRReferenceSpace::floorOriginTransform() const >+{ >+ auto& data = m_session.frameData(); >+ if (!data.floorTransform) { >+ TransformationMatrix defautTransform; >+ defautTransform.translate3d(0.0, -DefaultUserHeightInMeters, 0.0); >+ return defautTransform; >+ } >+ >+ // https://immersive-web.github.io/webxr/#dom-xrreferencespacetype-local-floor >+ // Get floor estimation from the device >+ // FIXME: Round to nearest 1cm to prevent fingerprinting >+ return WebXRFrame::matrixFromPose(*data.floorTransform); > } > >+ > } // namespace WebCore > > #endif // ENABLE(WEBXR) >diff --git a/Source/WebCore/Modules/webxr/WebXRReferenceSpace.h b/Source/WebCore/Modules/webxr/WebXRReferenceSpace.h >index a2c8051f59c227d877795c2bb8f6e7363de8f3e3..281ad533266be7308b44fe914142763e9224bf42 100644 >--- a/Source/WebCore/Modules/webxr/WebXRReferenceSpace.h >+++ b/Source/WebCore/Modules/webxr/WebXRReferenceSpace.h >@@ -40,18 +40,27 @@ class WebXRSession; > class WebXRReferenceSpace : public WebXRSpace { > WTF_MAKE_ISO_ALLOCATED(WebXRReferenceSpace); > public: >- static Ref<WebXRReferenceSpace> create(Document&, Ref<WebXRSession>&&, XRReferenceSpaceType); >+ static Ref<WebXRReferenceSpace> create(Document&, WebXRSession&, XRReferenceSpaceType); >+ static Ref<WebXRReferenceSpace> create(Document&, WebXRSession&, Ref<WebXRRigidTransform>&&, XRReferenceSpaceType); > > virtual ~WebXRReferenceSpace(); > >- RefPtr<WebXRReferenceSpace> getOffsetReferenceSpace(const WebXRRigidTransform&); >+ TransformationMatrix nativeOrigin() const override; >+ virtual RefPtr<WebXRReferenceSpace> getOffsetReferenceSpace(const WebXRRigidTransform&); >+ XRReferenceSpaceType type() const { return m_type; } >+ >+ WebXRReferenceSpace(Document&, WebXRSession&, Ref<WebXRRigidTransform>&&, XRReferenceSpaceType); > > protected: >- WebXRReferenceSpace(Document&, Ref<WebXRSession>&&, XRReferenceSpaceType); >+ bool isReferenceSpace() const final { return true; } >+ >+ TransformationMatrix floorOriginTransform() const; > > XRReferenceSpaceType m_type; > }; > > } // namespace WebCore > >+SPECIALIZE_TYPE_TRAITS_WEBXRSPACE(WebXRReferenceSpace, isReferenceSpace()) >+ > #endif // ENABLE(WEBXR) >diff --git a/Source/WebCore/Modules/webxr/WebXRReferenceSpace.idl b/Source/WebCore/Modules/webxr/WebXRReferenceSpace.idl >index 283507f445a52fe2e171966f5073bc13b49fc53b..81e44d34da167b8fe6db234c240c93856352590d 100644 >--- a/Source/WebCore/Modules/webxr/WebXRReferenceSpace.idl >+++ b/Source/WebCore/Modules/webxr/WebXRReferenceSpace.idl >@@ -30,6 +30,7 @@ > Exposed=Window, > JSGenerateToJSObject, > JSGenerateToNativeObject, >+ SkipVTableValidation, > InterfaceName=XRReferenceSpace > ] interface WebXRReferenceSpace : WebXRSpace { > [NewObject] WebXRReferenceSpace getOffsetReferenceSpace(WebXRRigidTransform originOffset); >diff --git a/Source/WebCore/Modules/webxr/WebXRSession.cpp b/Source/WebCore/Modules/webxr/WebXRSession.cpp >index bd6c501cb7ec5a71cb7a707b1999fd9ba9288b2c..97ea360104cdb415aa8be8e358871559e8475ddd 100644 >--- a/Source/WebCore/Modules/webxr/WebXRSession.cpp >+++ b/Source/WebCore/Modules/webxr/WebXRSession.cpp >@@ -28,11 +28,13 @@ > > #if ENABLE(WEBXR) > >+#include "Document.h" > #include "EventNames.h" > #include "JSWebXRReferenceSpace.h" > #include "WebXRBoundedReferenceSpace.h" > #include "WebXRFrame.h" > #include "WebXRSystem.h" >+#include "WebXRView.h" > #include "XRFrameRequestCallback.h" > #include "XRRenderStateInit.h" > #include "XRSessionEvent.h" >@@ -55,7 +57,9 @@ WebXRSession::WebXRSession(Document& document, WebXRSystem& system, XRSessionMod > , m_mode(mode) > , m_device(makeWeakPtr(device)) > , m_activeRenderState(WebXRRenderState::create(mode)) >+ , m_viewerReferenceSpace(document, *this, WebXRRigidTransform::create(), XRReferenceSpaceType::Viewer) > , m_timeOrigin(MonotonicTime::now()) >+ , m_views(device.views(mode)) > { > m_device->initializeTrackingAndRendering(mode); > m_device->setTrackingAndRenderingClient(makeWeakPtr(*this)); >@@ -230,9 +234,9 @@ void WebXRSession::requestReferenceSpace(XRReferenceSpaceType type, RequestRefer > // https://immersive-web.github.io/webxr/#create-a-reference-space > RefPtr<WebXRReferenceSpace> referenceSpace; > if (type == XRReferenceSpaceType::BoundedFloor) >- referenceSpace = WebXRBoundedReferenceSpace::create(document, makeRef(*this), type); >+ referenceSpace = WebXRBoundedReferenceSpace::create(document, *this, type); > else >- referenceSpace = WebXRReferenceSpace::create(document, makeRef(*this), type); >+ referenceSpace = WebXRReferenceSpace::create(document, *this, type); > > // 2.5. Resolve promise with referenceSpace. > promise.resolve(referenceSpace.releaseNonNull()); >@@ -478,13 +482,15 @@ void WebXRSession::onFrame(PlatformXR::Device::FrameData&& frameData) > return; > > // Queue a task to perform the following steps. >- queueTaskKeepingObjectAlive(*this, TaskSource::WebXR, [this, frameData = WTFMove(frameData)]() { >+ queueTaskKeepingObjectAlive(*this, TaskSource::WebXR, [this, frameData = WTFMove(frameData)]() mutable { > if (m_ended) > return; >+ >+ m_frameData = frameData; > // 1.Let now be the current high resolution time. > auto now = (MonotonicTime::now() - m_timeOrigin).milliseconds(); > >- auto frame = WebXRFrame::create(makeRef(*this)); >+ auto frame = WebXRFrame::create(makeRef(*this), WebXRFrame::IsAnimationFrame::Yes); > // 2.Let frame be sessionâs animation frame. > // 3.Set frameâs time to frameTime. > frame->setTime(static_cast<DOMHighResTimeStamp>(frameData.predictedDisplayTime)); >@@ -508,7 +514,7 @@ void WebXRSession::onFrame(PlatformXR::Device::FrameData&& frameData) > frame->setActive(true); > > // 6.4.Apply frame updates for frame. >- // FIXME: implement. >+ frame->setFrameData(WTFMove(frameData)); > > // 6.5.For each entry in sessionâs list of currently running animation frame callbacks, in order: > for (auto& callback : callbacks) { >@@ -537,6 +543,25 @@ void WebXRSession::onFrame(PlatformXR::Device::FrameData&& frameData) > }); > } > >+// https://immersive-web.github.io/webxr/#poses-may-be-reported >+bool WebXRSession::posesCanBeReported(const Document& document) const >+{ >+ // 1. If sessionâs relevant global object is not the current global object, return false. >+ auto* sessionDocument = downcast<Document>(scriptExecutionContext()); >+ if (!sessionDocument || sessionDocument->domWindow() != document.domWindow()) >+ return false; >+ >+ // 2. If session's visibilityState in not "visible", return false. >+ if (m_visibilityState != XRVisibilityState::Visible) >+ return false; >+ >+ // 5. Determine if the pose data can be returned as follows: >+ // The procedure in the specs tries to ensure that we apply measures to >+ // prevent fingerprintint in pose data and return false in case we don't. >+ // We're going to apply them so let's just return true. >+ return true; >+} >+ > } // namespace WebCore > > #endif // ENABLE(WEBXR) >diff --git a/Source/WebCore/Modules/webxr/WebXRSession.h b/Source/WebCore/Modules/webxr/WebXRSession.h >index d8363a5c931cf50f7b6e319aeedb3e8a2334fee5..f3788dccab8274f81d1e7f1de1fb0c805865cc98 100644 >--- a/Source/WebCore/Modules/webxr/WebXRSession.h >+++ b/Source/WebCore/Modules/webxr/WebXRSession.h >@@ -32,11 +32,11 @@ > #include "JSDOMPromiseDeferred.h" > #include "WebXRFrame.h" > #include "WebXRInputSourceArray.h" >+#include "WebXRReferenceSpace.h" > #include "WebXRRenderState.h" > #include "WebXRSpace.h" > #include "XREnvironmentBlendMode.h" > #include "XRInteractionMode.h" >-#include "XRReferenceSpaceType.h" > #include "XRSessionMode.h" > #include "XRVisibilityState.h" > #include <wtf/MonotonicTime.h> >@@ -48,8 +48,8 @@ > namespace WebCore { > > class XRFrameRequestCallback; >-class WebXRReferenceSpace; > class WebXRSystem; >+class WebXRView; > struct XRRenderStateInit; > > class WebXRSession final : public RefCounted<WebXRSession>, public EventTargetWithInlineData, public ActiveDOMObject, public PlatformXR::TrackingAndRenderingClient { >@@ -90,6 +90,11 @@ public: > > XRSessionMode mode() const { return m_mode; } > >+ const WebXRReferenceSpace& viewerReferenceSpace() const { return m_viewerReferenceSpace; } >+ const Vector<PlatformXR::Device::ViewData>& views() const { return m_views; } >+ const PlatformXR::Device::FrameData& frameData() const { return m_frameData; } >+ bool posesCanBeReported(const Document&) const; >+ > private: > WebXRSession(Document&, WebXRSystem&, XRSessionMode, PlatformXR::Device&); > >@@ -128,11 +133,15 @@ private: > WeakPtr<PlatformXR::Device> m_device; > RefPtr<WebXRRenderState> m_activeRenderState; > RefPtr<WebXRRenderState> m_pendingRenderState; >+ WebXRReferenceSpace m_viewerReferenceSpace; > MonotonicTime m_timeOrigin; > > unsigned m_nextCallbackId { 1 }; > Vector<Ref<XRFrameRequestCallback>> m_callbacks; > >+ Vector<PlatformXR::Device::ViewData> m_views; >+ PlatformXR::Device::FrameData m_frameData; >+ > double m_minimumInlineFOV { 0.0 }; > double m_maximumInlineFOV { piFloat }; > >diff --git a/Source/WebCore/Modules/webxr/WebXRSpace.cpp b/Source/WebCore/Modules/webxr/WebXRSpace.cpp >index 524254fa4677b8db1523550628d3a79e69226914..a03a882b9bd87541c56ad68479512f1116e20073 100644 >--- a/Source/WebCore/Modules/webxr/WebXRSpace.cpp >+++ b/Source/WebCore/Modules/webxr/WebXRSpace.cpp >@@ -28,7 +28,9 @@ > > #if ENABLE(WEBXR) > >+#include "DOMPointReadOnly.h" > #include "Document.h" >+#include "WebXRRigidTransform.h" > #include "WebXRSession.h" > #include <wtf/IsoMallocInlines.h> > >@@ -36,14 +38,33 @@ namespace WebCore { > > WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRSpace); > >-WebXRSpace::WebXRSpace(Document& document, Ref<WebXRSession>&& session) >+WebXRSpace::WebXRSpace(Document& document, WebXRSession& session, Ref<WebXRRigidTransform>&& offset) > : ContextDestructionObserver(&document) >- , m_session(WTFMove(session)) >+ , m_session(session) >+ , m_originOffset(WTFMove(offset)) > { >+ m_session.ref(); > } > > WebXRSpace::~WebXRSpace() = default; > >+void WebXRSpace::ref() >+{ >+ m_session.ref(); >+} >+ >+void WebXRSpace::deref() >+{ >+ m_session.deref(); >+} >+ >+TransformationMatrix WebXRSpace::effectiveOrigin() const >+{ >+ // https://immersive-web.github.io/webxr/#xrspace-effective-origin >+ // The effective origin can be obtained by multiplying origin offset and the native origin. >+ return m_originOffset->rawTransform() * nativeOrigin(); >+} >+ > } // namespace WebCore > > #endif // ENABLE(WEBXR) >diff --git a/Source/WebCore/Modules/webxr/WebXRSpace.h b/Source/WebCore/Modules/webxr/WebXRSpace.h >index 7f1c4e974739a70cc4b0c0b1cebf18e5fb84990d..c62fded0c16ee9266b364e3334a6f68176a4d01f 100644 >--- a/Source/WebCore/Modules/webxr/WebXRSpace.h >+++ b/Source/WebCore/Modules/webxr/WebXRSpace.h >@@ -29,37 +29,52 @@ > > #include "ContextDestructionObserver.h" > #include "EventTarget.h" >+#include "TransformationMatrix.h" > #include <wtf/RefCounted.h> > > namespace WebCore { > > class Document; > class ScriptExecutionContext; >+class WebXRRigidTransform; > class WebXRSession; > >-class WebXRSpace : public RefCounted<WebXRSpace>, public EventTargetWithInlineData, public ContextDestructionObserver { >+class WebXRSpace : public EventTargetWithInlineData, public ContextDestructionObserver { > WTF_MAKE_ISO_ALLOCATED(WebXRSpace); > public: > virtual ~WebXRSpace(); > >- using RefCounted<WebXRSpace>::ref; >- using RefCounted<WebXRSpace>::deref; >+ const WebXRSession& session() const { return m_session; } >+ virtual TransformationMatrix nativeOrigin() const = 0; >+ TransformationMatrix effectiveOrigin() const; >+ >+ virtual bool isReferenceSpace() const { return false; } >+ virtual bool isBoundedReferenceSpace() const { return false; } >+ >+ void ref(); >+ void deref(); > > protected: >- WebXRSpace(Document&, Ref<WebXRSession>&&); >+ WebXRSpace(Document&, WebXRSession&, Ref<WebXRRigidTransform>&&); > > // EventTarget > ScriptExecutionContext* scriptExecutionContext() const override { return ContextDestructionObserver::scriptExecutionContext(); } > >- Ref<WebXRSession> m_session; >+ WebXRSession& m_session; >+ Ref<WebXRRigidTransform> m_originOffset; > > private: > // EventTarget > EventTargetInterface eventTargetInterface() const override { return WebXRSpaceEventTargetInterfaceType; } >- void refEventTarget() override { ref(); } >- void derefEventTarget() override { deref(); } >+ void refEventTarget() final { ref(); } >+ void derefEventTarget() final { deref(); } > }; > > } // namespace WebCore > >+#define SPECIALIZE_TYPE_TRAITS_WEBXRSPACE(ToValueTypeName, predicate) \ >+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \ >+ static bool isType(const WebCore::WebXRSpace& context) { return context.predicate; } \ >+SPECIALIZE_TYPE_TRAITS_END() >+ > #endif // ENABLE(WEBXR) >diff --git a/Source/WebCore/Modules/webxr/WebXRSystem.cpp b/Source/WebCore/Modules/webxr/WebXRSystem.cpp >index 85062fd53d6f0d2ad895ef8d3bd1e099aa0b3d8c..a26c62658c075a61a6cc8fbfb729acb15e899ac8 100644 >--- a/Source/WebCore/Modules/webxr/WebXRSystem.cpp >+++ b/Source/WebCore/Modules/webxr/WebXRSystem.cpp >@@ -521,12 +521,21 @@ void WebXRSystem::DummyInlineDevice::requestFrame(PlatformXR::Device::RequestFra > return; > > auto raf = InlineRequestAnimationFrameCallback::create(*m_scriptExecutionContext, [callback = WTFMove(callback)]() mutable { >- callback({ }); >+ PlatformXR::Device::FrameData data; >+ data.isTrackingValid = true; >+ data.isPositionValid = true; >+ data.views.append({ }); >+ callback(WTFMove(data)); > }); > > document->requestAnimationFrame(raf); > } > >+Vector<PlatformXR::Device::ViewData> WebXRSystem::DummyInlineDevice::views(XRSessionMode) const >+{ >+ return { { .active = true, PlatformXR::Eye::None } }; >+} >+ > > } // namespace WebCore > >diff --git a/Source/WebCore/Modules/webxr/WebXRSystem.h b/Source/WebCore/Modules/webxr/WebXRSystem.h >index 1de8b75b795067f31a09bcc67070cdb18c6f2ae7..1024d0f5a4f3c1f6b41adf7f96bd83cc384ad081 100644 >--- a/Source/WebCore/Modules/webxr/WebXRSystem.h >+++ b/Source/WebCore/Modules/webxr/WebXRSystem.h >@@ -111,9 +111,10 @@ private: > private: > void initializeTrackingAndRendering(PlatformXR::SessionMode) final { } > void shutDownTrackingAndRendering() final { } >- void initializeReferenceSpace(PlatformXR::ReferenceSpaceType) final { }; >+ void initializeReferenceSpace(PlatformXR::ReferenceSpaceType) final { } > > void requestFrame(PlatformXR::Device::RequestFrameCallback&&) final; >+ Vector<Device::ViewData> views(XRSessionMode) const final; > }; > DummyInlineDevice m_defaultInlineDevice; > >diff --git a/Source/WebCore/Modules/webxr/WebXRView.cpp b/Source/WebCore/Modules/webxr/WebXRView.cpp >index 1a98cb1450459ff265638f58df48bb4fccff30be..43d10b87ff6ccbb75010015931cb0fcf7a4b0b59 100644 >--- a/Source/WebCore/Modules/webxr/WebXRView.cpp >+++ b/Source/WebCore/Modules/webxr/WebXRView.cpp >@@ -36,23 +36,20 @@ namespace WebCore { > > WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRView); > >-Ref<WebXRView> WebXRView::create() >+Ref<WebXRView> WebXRView::create(XREye eye, Ref<WebXRRigidTransform>&& transform, Ref<Float32Array>&& projection) > { >- return adoptRef(*new WebXRView); >+ return adoptRef(*new WebXRView(eye, WTFMove(transform), WTFMove(projection))); > } > >-WebXRView::WebXRView() >- : m_eye(XREye::None) >+WebXRView::WebXRView(XREye eye, Ref<WebXRRigidTransform>&& transform, Ref<Float32Array>&& projection) >+ : m_eye(eye) >+ , m_transform(WTFMove(transform)) >+ , m_projection(projection) > { > } > > WebXRView::~WebXRView() = default; > >-void WebXRView::setProjectionMatrix(const Vector<float>& matrix) >-{ >- m_projectionMatrix = Float32Array::create(matrix.data(), matrix.size()); >-} >- > } // namespace WebCore > > #endif // ENABLE(WEBXR) >diff --git a/Source/WebCore/Modules/webxr/WebXRView.h b/Source/WebCore/Modules/webxr/WebXRView.h >index 39a09ce10baaa2c2797c87557371c2bf788ac4e5..4b66069118268d4ab3f8576585a78c902030bbc9 100644 >--- a/Source/WebCore/Modules/webxr/WebXRView.h >+++ b/Source/WebCore/Modules/webxr/WebXRView.h >@@ -37,28 +37,25 @@ > > namespace WebCore { > >+class WebXRFrame; > class WebXRRigidTransform; > > class WebXRView : public RefCounted<WebXRView> { > WTF_MAKE_ISO_ALLOCATED_EXPORT(WebXRView, WEBCORE_EXPORT); > public: >- WEBCORE_EXPORT static Ref<WebXRView> create(); >+ WEBCORE_EXPORT static Ref<WebXRView> create(XREye, Ref<WebXRRigidTransform>&&, Ref<Float32Array>&&); > WEBCORE_EXPORT ~WebXRView(); > > XREye eye() const { return m_eye; } >- const Float32Array& projectionMatrix() const { return *m_projectionMatrix; } >- const WebXRRigidTransform& transform() const { return *m_transform; } >- >- void setEye(XREye eye) { m_eye = eye; } >- WEBCORE_EXPORT void setProjectionMatrix(const Vector<float>&); >- void setTransform(RefPtr<WebXRRigidTransform>&& viewOffset) { m_transform = WTFMove(viewOffset); } >+ const Float32Array& projectionMatrix() const { return m_projection.get(); } >+ const WebXRRigidTransform& transform() const { return m_transform.get(); } > > private: >- WebXRView(); >+ WebXRView(XREye, Ref<WebXRRigidTransform>&&, Ref<Float32Array>&&); > > XREye m_eye; >- RefPtr<Float32Array> m_projectionMatrix; >- RefPtr<WebXRRigidTransform> m_transform; >+ Ref<WebXRRigidTransform> m_transform; >+ Ref<Float32Array> m_projection; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/webxr/WebXRViewerPose.cpp b/Source/WebCore/Modules/webxr/WebXRViewerPose.cpp >index 6063c95f3643adab0a281da88b3cbae65a797b09..e49e6c7874ad323f5f5859334c277bb3bae2f1a2 100644 >--- a/Source/WebCore/Modules/webxr/WebXRViewerPose.cpp >+++ b/Source/WebCore/Modules/webxr/WebXRViewerPose.cpp >@@ -25,17 +25,24 @@ > > #include "config.h" > #include "WebXRViewerPose.h" >+#include <wtf/IsoMallocInlines.h> > > #if ENABLE(WEBXR) > > namespace WebCore { > >-Ref<WebXRViewerPose> WebXRViewerPose::create() >+WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRViewerPose); >+ >+Ref<WebXRViewerPose> WebXRViewerPose::create(Ref<WebXRRigidTransform>&& transform, bool emulatedPosition) >+{ >+ return adoptRef(*new WebXRViewerPose(WTFMove(transform), emulatedPosition)); >+} >+ >+WebXRViewerPose::WebXRViewerPose(Ref<WebXRRigidTransform>&& transform, bool emulatedPosition) >+ : WebXRPose(WTFMove(transform), emulatedPosition) > { >- return adoptRef(*new WebXRViewerPose); > } > >-WebXRViewerPose::WebXRViewerPose() = default; > WebXRViewerPose::~WebXRViewerPose() = default; > > const Vector<Ref<WebXRView>>& WebXRViewerPose::views() const >@@ -43,6 +50,11 @@ const Vector<Ref<WebXRView>>& WebXRViewerPose::views() const > return m_views; > } > >+void WebXRViewerPose::setViews(Vector<Ref<WebXRView>>&& views) >+{ >+ m_views = WTFMove(views); >+} >+ > } // namespace WebCore > > #endif // ENABLE(WEBXR) >diff --git a/Source/WebCore/Modules/webxr/WebXRViewerPose.h b/Source/WebCore/Modules/webxr/WebXRViewerPose.h >index a4ed25b10c25319a6e9218528064e51c8d4d8f20..e9f0a39d85b7eace7013ca18429d2b3cbb80dcae 100644 >--- a/Source/WebCore/Modules/webxr/WebXRViewerPose.h >+++ b/Source/WebCore/Modules/webxr/WebXRViewerPose.h >@@ -37,18 +37,24 @@ > namespace WebCore { > > class WebXRViewerPose : public WebXRPose { >+ WTF_MAKE_ISO_ALLOCATED(WebXRViewerPose); > public: >- static Ref<WebXRViewerPose> create(); >- ~WebXRViewerPose(); >+ static Ref<WebXRViewerPose> create(Ref<WebXRRigidTransform>&&, bool emulatedPosition); >+ virtual ~WebXRViewerPose(); > > const Vector<Ref<WebXRView>>& views() const; >+ void setViews(Vector<Ref<WebXRView>>&&); > > private: >- WebXRViewerPose(); >+ WebXRViewerPose(Ref<WebXRRigidTransform>&&, bool emulatedPosition); >+ >+ bool isViewerPose() const final { return true; } > > Vector<Ref<WebXRView>> m_views; > }; > > } // namespace WebCore > >+SPECIALIZE_TYPE_TRAITS_WEBXRPOSE(WebXRViewerPose, isViewerPose()) >+ > #endif // ENABLE(WEBXR) >diff --git a/Source/WebCore/Modules/webxr/WebXRViewerPose.idl b/Source/WebCore/Modules/webxr/WebXRViewerPose.idl >index d1beb2c086f89bfafdf5e0bf1f95c0f48c607613..6a76de843549fbf063d0ba5d4113a0152950b2e4 100644 >--- a/Source/WebCore/Modules/webxr/WebXRViewerPose.idl >+++ b/Source/WebCore/Modules/webxr/WebXRViewerPose.idl >@@ -28,7 +28,8 @@ > Conditional=WEBXR, > SecureContext, > Exposed=Window, >- ImplementationLacksVTable, >+ JSGenerateToJSObject, >+ JSGenerateToNativeObject, > InterfaceName=XRViewerPose > ] interface WebXRViewerPose : WebXRPose { > [SameObject] readonly attribute FrozenArray<WebXRView> views; >diff --git a/Source/WebCore/Modules/webxr/XREye.h b/Source/WebCore/Modules/webxr/XREye.h >index ea1ea7e1e7d8226325f60c826fffbc0b9ba4d66f..f9a343bda447497f6dda5449908e4d99d9fc97d3 100644 >--- a/Source/WebCore/Modules/webxr/XREye.h >+++ b/Source/WebCore/Modules/webxr/XREye.h >@@ -27,13 +27,11 @@ > > #if ENABLE(WEBXR) > >+#include "PlatformXR.h" >+ > namespace WebCore { > >-enum class XREye { >- None, >- Left, >- Right, >-}; >+using XREye = PlatformXR::Eye; > > } // namespace WebCore > >diff --git a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp >index a7e4e0142c4a34a5eadd7973f4db4725853df0c1..b2ec14584b56c06c8688a7586b940a26821d809c 100644 >--- a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp >+++ b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp >@@ -584,15 +584,15 @@ TransformationMatrix::TransformationMatrix(const AffineTransform& t) > // FIXME: Once https://bugs.webkit.org/show_bug.cgi?id=220856 is addressed we can reuse this function in TransformationMatrix::recompose4(). > TransformationMatrix TransformationMatrix::fromQuaternion(double qx, double qy, double qz, double qw) > { >- const double xx = qx * qx; >- const double yy = qy * qy; >- const double zz = qz * qz; >- const double xz = qx * qz; >- const double xy = qx * qy; >- const double yz = qy * qz; >- const double xw = qw * qx; >- const double yw = qw * qy; >- const double zw = qw * qz; >+ double xx = qx * qx; >+ double yy = qy * qy; >+ double zz = qz * qz; >+ double xz = qx * qz; >+ double xy = qx * qy; >+ double yz = qy * qz; >+ double xw = qw * qx; >+ double yw = qw * qy; >+ double zw = qw * qz; > > return TransformationMatrix(1 - 2 * (yy + zz), 2 * (xy + zw), 2 * (xz - yw), 0, > 2 * (xy - zw), 1 - 2 * (xx + zz), 2 * (yz + xw), 0, >@@ -600,6 +600,34 @@ TransformationMatrix TransformationMatrix::fromQuaternion(double qx, double qy, > 0, 0, 0, 1); > } > >+ >+TransformationMatrix TransformationMatrix::fromProjection(double fovUp, double fovDown, double fovLeft, double fovRight, double depthNear, double depthFar) >+{ >+ double upTan = tan(fovUp); >+ double downTan = tan(fovDown); >+ double leftTan = tan(fovLeft); >+ double rightTan = tan(fovRight); >+ double xScale = 2.0 / (leftTan + rightTan); >+ double yScale = 2.0 / (upTan + downTan); >+ double invDepth = 1.0 / (depthNear - depthFar); >+ >+ return TransformationMatrix(xScale, 0.0f, 0.0f, 0.0f, >+ 0.0f, yScale, 0.0f, 0.0f, >+ (leftTan - rightTan) * xScale * -0.5, (upTan - downTan) * yScale * 0.5, (depthNear + depthFar) * invDepth, -1.0f, >+ 0.0f, 0.0f, (2.0f * depthFar * depthNear) * invDepth, 0.0f); >+} >+ >+TransformationMatrix TransformationMatrix::fromProjection(double fovy, double aspect, double depthNear, double depthFar) >+{ >+ double f = 1.0f / tanf(fovy / 2); >+ double invDepth = 1.0f / (depthNear - depthFar); >+ >+ return TransformationMatrix(f / aspect, 0.0f, 0.0f, 0.0f, >+ 0.0f, f, 0.0f, 0.0f, >+ 0.0f, 0.0f, (depthFar + depthNear) * invDepth, -1.0f, >+ 0.0f, 0.0f, (2.0f * depthFar * depthNear) * invDepth, 0.0f); >+} >+ > TransformationMatrix& TransformationMatrix::scale(double s) > { > return scaleNonUniform(s, s); >diff --git a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h >index 600e7d0b1ce26a7c2421d58561cc574b04a17b29..5f725ad66ef77091e9fb066098b8da758f5af90f 100644 >--- a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h >+++ b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h >@@ -121,6 +121,10 @@ public: > > static TransformationMatrix fromQuaternion(double qx, double qy, double qz, double qw); > >+ // Field of view in radians >+ static TransformationMatrix fromProjection(double fovUp, double fovDown, double fovLeft, double fovRight, double depthNear, double depthFar); >+ static TransformationMatrix fromProjection(double fovy, double aspect, double depthNear, double depthFar); >+ > static const TransformationMatrix identity; > > void setMatrix(double a, double b, double c, double d, double e, double f) >diff --git a/Source/WebCore/platform/xr/PlatformXR.h b/Source/WebCore/platform/xr/PlatformXR.h >index 4325f3375cf3028a47dffcc6df59bb74383500d5..e3721d886ea99a0df9082e58e255cd32d0f7de8b 100644 >--- a/Source/WebCore/platform/xr/PlatformXR.h >+++ b/Source/WebCore/platform/xr/PlatformXR.h >@@ -24,6 +24,7 @@ > #include <wtf/CompletionHandler.h> > #include <wtf/HashMap.h> > #include <wtf/UniqueRef.h> >+#include <wtf/Variant.h> > #include <wtf/Vector.h> > #include <wtf/WeakPtr.h> > >@@ -43,6 +44,12 @@ enum class ReferenceSpaceType { > Unbounded > }; > >+enum class Eye { >+ None, >+ Left, >+ Right, >+}; >+ > #if ENABLE(WEBXR) > > class TrackingAndRenderingClient : public CanMakeWeakPtr<TrackingAndRenderingClient> { >@@ -79,29 +86,51 @@ public: > virtual void initializeReferenceSpace(ReferenceSpaceType) = 0; > > struct FrameData { >- long predictedDisplayTime; >- struct ViewData { >- struct { >- WebCore::FloatPoint3D position; >- struct { >- float x; >- float y; >- float z; >- float w; >- } orientation; >- } pose; >- struct { >- float rUp; >- float rDown; >- float rLeft; >- float rRight; >- } fov; >+ struct FloatQuaternion { >+ float x { 0.0f }; >+ float y { 0.0f }; >+ float z { 0.0f }; >+ float w { 1.0f }; >+ }; >+ >+ struct Pose { >+ WebCore::FloatPoint3D position; >+ FloatQuaternion orientation; > }; >- Vector<ViewData> viewPoses; >+ >+ struct Fov { >+ // In radians >+ float up { 0.0f }; >+ float down { 0.0f }; >+ float left { 0.0f }; >+ float right { 0.0f }; >+ }; >+ >+ using Projection = Variant<Fov, std::array<float, 16>, std::nullptr_t>; >+ >+ struct View { >+ Pose offset; >+ Projection projection = { nullptr }; >+ }; >+ >+ bool isTrackingValid { false }; >+ bool isPositionValid { false }; >+ bool isPositionEmulated { false }; >+ long predictedDisplayTime { 0 }; >+ Pose origin; >+ Optional<Pose> floorTransform; >+ Vector<View> views; >+ }; >+ >+ struct ViewData { >+ bool active { false }; >+ Eye eye { Eye::None }; > }; >+ >+ virtual Vector<ViewData> views(SessionMode) const = 0; >+ > using RequestFrameCallback = Function<void(FrameData&&)>; > virtual void requestFrame(RequestFrameCallback&&) = 0; >- > protected: > Device() = default; > >diff --git a/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.cpp b/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.cpp >index cc4d72153c6eeafdf2162e9882a9e07758b21df7..b94e871f57b897c7e4849a47f4a64c3330d6d176 100644 >--- a/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.cpp >+++ b/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.cpp >@@ -299,6 +299,28 @@ Device::ListOfEnabledFeatures OpenXRDevice::enumerateReferenceSpaces(XrSession& > return enabledFeatures; > } > >+XrSpace OpenXRDevice::createReferenceSpace(XrReferenceSpaceType type) >+{ >+ ASSERT(&RunLoop::current() == &m_queue.runLoop()); >+ ASSERT(m_session != XR_NULL_HANDLE); >+ ASSERT(m_instance != XR_NULL_HANDLE); >+ >+ XrPosef identityPose { >+ .orientation = { .x = 0, .y = 0, .z = 0, .w = 1.0 }, >+ .position = { .x = 0, .y = 0, .z = 0 } >+ }; >+ >+ auto spaceCreateInfo = createStructure<XrReferenceSpaceCreateInfo, XR_TYPE_REFERENCE_SPACE_CREATE_INFO>(); >+ spaceCreateInfo.referenceSpaceType = type; >+ spaceCreateInfo.poseInReferenceSpace = identityPose; >+ >+ XrSpace space; >+ auto result = xrCreateReferenceSpace(m_session, &spaceCreateInfo, &space); >+ RETURN_IF_FAILED(result, "xrCreateReferenceSpace", m_instance, XR_NULL_HANDLE); >+ >+ return space; >+} >+ > void OpenXRDevice::collectSupportedSessionModes() > { > ASSERT(&RunLoop::current() == &m_queue.runLoop()); >@@ -368,15 +390,6 @@ void OpenXRDevice::collectConfigurationViews() > } > } > >-WebCore::IntSize OpenXRDevice::recommendedResolution(SessionMode mode) >-{ >- auto configType = mode == SessionMode::Inline ? XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO : XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO; >- auto viewsIterator = m_configurationViews.find(configType); >- if (viewsIterator != m_configurationViews.end()) >- return { static_cast<int>(viewsIterator->value[0].recommendedImageRectWidth), static_cast<int>(viewsIterator->value[0].recommendedImageRectHeight) }; >- return Device::recommendedResolution(mode); >-} >- > XrViewConfigurationType toXrViewConfigurationType(SessionMode mode) > { > switch (mode) { >@@ -400,6 +413,15 @@ static bool isSessionReady(XrSessionState state) > return state >= XR_SESSION_STATE_READY && state < XR_SESSION_STATE_STOPPING; > } > >+WebCore::IntSize OpenXRDevice::recommendedResolution(SessionMode mode) >+{ >+ auto configType = toXrViewConfigurationType(mode); >+ auto viewsIterator = m_configurationViews.find(configType); >+ if (viewsIterator != m_configurationViews.end()) >+ return { static_cast<int>(viewsIterator->value[0].recommendedImageRectWidth), static_cast<int>(viewsIterator->value[0].recommendedImageRectHeight) }; >+ return Device::recommendedResolution(mode); >+} >+ > void OpenXRDevice::initializeTrackingAndRendering(SessionMode mode) > { > m_queue.dispatch([this, mode]() { >@@ -414,6 +436,9 @@ void OpenXRDevice::initializeTrackingAndRendering(SessionMode mode) > sessionCreateInfo.systemId = m_systemId; > auto result = xrCreateSession(m_instance, &sessionCreateInfo, &m_session); > RETURN_IF_FAILED(result, "xrEnumerateInstanceExtensionProperties", m_instance); >+ >+ m_localSpace = createReferenceSpace(XR_REFERENCE_SPACE_TYPE_LOCAL); >+ m_viewSpace = createReferenceSpace(XR_REFERENCE_SPACE_TYPE_VIEW); > }); > } > >@@ -457,6 +482,12 @@ void OpenXRDevice::shutDownTrackingAndRendering() > }); > } > >+void OpenXRDevice::initializeReferenceSpace(PlatformXR::ReferenceSpaceType spaceType) >+{ >+ if ((spaceType == ReferenceSpaceType::LocalFloor || spaceType == ReferenceSpaceType::BoundedFloor) && m_stageSpace == XR_NULL_HANDLE) >+ m_stageSpace = createReferenceSpace(XR_REFERENCE_SPACE_TYPE_STAGE); >+} >+ > void OpenXRDevice::waitUntilStopping() > { > ASSERT(&RunLoop::current() == &m_queue.runLoop()); >@@ -526,14 +557,20 @@ void OpenXRDevice::endSession() > }); > } > >+static Device::FrameData::Pose XrPosefToPose(XrPosef pose) >+{ >+ Device::FrameData::Pose result; >+ result.orientation = { pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w }; >+ result.position = { pose.position.x, pose.position.y, pose.position.z }; >+ return result; >+} > >-Device::FrameData::ViewData xrViewToViewData(XrView view) >+static Device::FrameData::View xrViewToPose(XrView view) > { >- Device::FrameData::ViewData data; >- data.fov = { view.fov.angleUp, view.fov.angleDown, view.fov.angleLeft, view.fov.angleRight }; >- data.pose.orientation = { view.pose.orientation.x, view.pose.orientation.y, view.pose.orientation.z, view.pose.orientation.w }; >- data.pose.position = { view.pose.position.x, view.pose.position.y, view.pose.position.z }; >- return data; >+ Device::FrameData::View pose; >+ pose.projection = Device::FrameData::Fov { view.fov.angleUp, view.fov.angleDown, view.fov.angleLeft, view.fov.angleRight }; >+ pose.offset = XrPosefToPose(view.pose); >+ return pose; > } > > void OpenXRDevice::requestFrame(RequestFrameCallback&& callback) >@@ -562,13 +599,22 @@ void OpenXRDevice::requestFrame(RequestFrameCallback&& callback) > frameData.predictedDisplayTime = frameState.predictedDisplayTime; > > if (isSessionActive(m_sessionState)) { >+ // Query head location >+ auto location = createStructure<XrSpaceLocation, XR_TYPE_SPACE_LOCATION>(); >+ xrLocateSpace(m_viewSpace, m_localSpace, frameState.predictedDisplayTime, &location); >+ frameData.isTrackingValid = location.locationFlags & XR_SPACE_LOCATION_ORIENTATION_VALID_BIT; >+ frameData.isPositionValid = location.locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT; >+ frameData.isPositionEmulated = location.locationFlags & XR_SPACE_LOCATION_POSITION_TRACKED_BIT; >+ >+ if (frameData.isTrackingValid) >+ frameData.origin = XrPosefToPose(location.pose); >+ > ASSERT(m_configurationViews.contains(m_currentViewConfigurationType)); > const auto& configurationView = m_configurationViews.get(m_currentViewConfigurationType); > > auto viewLocateInfo = createStructure<XrViewLocateInfo, XR_TYPE_VIEW_LOCATE_INFO>(); > viewLocateInfo.displayTime = predictedTime; >- // FIXME: use the current reference space. >- // viewLocateInfo.space = m_localSpace; >+ viewLocateInfo.space = m_localSpace; > > uint32_t viewCount = configurationView.size(); > Vector<XrView> views(viewCount, [] { >@@ -583,7 +629,14 @@ void OpenXRDevice::requestFrame(RequestFrameCallback&& callback) > result = xrLocateViews(m_session, &viewLocateInfo, &viewState, viewCount, &viewCountOutput, views.data()); > if (!XR_FAILED(result)) { > for (auto& view : views) >- frameData.viewPoses.append(xrViewToViewData(view)); >+ frameData.views.append(xrViewToPose(view)); >+ } >+ >+ // Query floor transform >+ if (m_stageSpace != XR_NULL_HANDLE) { >+ auto floorLocation = createStructure<XrSpaceLocation, XR_TYPE_SPACE_LOCATION>(); >+ xrLocateSpace(m_stageSpace, m_localSpace, frameState.predictedDisplayTime, &floorLocation); >+ frameData.floorTransform = { XrPosefToPose(floorLocation.pose) }; > } > } > >@@ -600,6 +653,21 @@ void OpenXRDevice::requestFrame(RequestFrameCallback&& callback) > }); > } > >+Vector<Device::ViewData> OpenXRDevice::views(SessionMode mode) const >+{ >+ Vector<Device::ViewData> views; >+ auto configurationType = toXrViewConfigurationType(mode); >+ >+ if (configurationType == XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO) >+ views.append({ .active = true, .eye = Eye::None }); >+ else { >+ ASSERT(configurationType == XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO); >+ views.append({ .active = true, Eye::Left }); >+ views.append({ .active = true, Eye::Right }); >+ } >+ return views; >+} >+ > } // namespace PlatformXR > > #endif // ENABLE(WEBXR) && USE(OPENXR) >diff --git a/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.h b/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.h >index 5bebe69669327db2c815b556aedd1ca99b46e176..02d194e6271eba6b2a8448702795a609ea29073d 100644 >--- a/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.h >+++ b/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.h >@@ -51,12 +51,13 @@ private: > void collectConfigurationViews(); > > ListOfEnabledFeatures enumerateReferenceSpaces(XrSession&) const; >- void initializeReferenceSpace(ReferenceSpaceType) final { }; >+ XrSpace createReferenceSpace(XrReferenceSpaceType); > > WebCore::IntSize recommendedResolution(SessionMode) final; > > void initializeTrackingAndRendering(SessionMode) final; > void shutDownTrackingAndRendering() final; >+ void initializeReferenceSpace(PlatformXR::ReferenceSpaceType) final; > bool supportsSessionShutdownNotification() const final { return true; } > void waitUntilStopping(); > >@@ -68,6 +69,8 @@ private: > > void requestFrame(RequestFrameCallback&&) final; > >+ Vector<ViewData> views(SessionMode) const final; >+ > using ViewConfigurationPropertiesMap = HashMap<XrViewConfigurationType, XrViewConfigurationProperties, IntHash<XrViewConfigurationType>, WTF::StrongEnumHashTraits<XrViewConfigurationType>>; > ViewConfigurationPropertiesMap m_viewConfigurationProperties; > using ViewConfigurationViewsMap = HashMap<XrViewConfigurationType, Vector<XrViewConfigurationView>, IntHash<XrViewConfigurationType>, WTF::StrongEnumHashTraits<XrViewConfigurationType>>; >@@ -81,6 +84,9 @@ private: > WorkQueue& m_queue; > > XrViewConfigurationType m_currentViewConfigurationType; >+ XrSpace m_localSpace { XR_NULL_HANDLE }; >+ XrSpace m_viewSpace { XR_NULL_HANDLE }; >+ XrSpace m_stageSpace { XR_NULL_HANDLE }; > }; > > } // namespace PlatformXR >diff --git a/Source/WebCore/testing/WebFakeXRDevice.cpp b/Source/WebCore/testing/WebFakeXRDevice.cpp >index 54018da7ebb53dd51942de766149672ff1ac8457..bf38142bfc9de9bb78df840fdc15af4a98f81455 100644 >--- a/Source/WebCore/testing/WebFakeXRDevice.cpp >+++ b/Source/WebCore/testing/WebFakeXRDevice.cpp >@@ -32,14 +32,20 @@ > #include "JSDOMPromiseDeferred.h" > #include "WebFakeXRInputController.h" > #include <wtf/CompletionHandler.h> >+#include <wtf/MathExtras.h> > > namespace WebCore { > > static constexpr Seconds FakeXRFrameTime = 15_ms; > >-void FakeXRView::setFieldOfView(FakeXRViewInit::FieldOfViewInit fov) >+void FakeXRView::setProjection(const Vector<float>& projection) > { >- m_fov = fov; >+ std::copy(std::begin(projection), std::end(projection), std::begin(m_projection)); >+} >+ >+void FakeXRView::setFieldOfView(const FakeXRViewInit::FieldOfViewInit& fov) >+{ >+ m_fov = PlatformXR::Device::FrameData::Fov { deg2rad(fov.upDegrees), deg2rad(fov.downDegrees), deg2rad(fov.leftDegrees), deg2rad(fov.rightDegrees) }; > } > > SimulatedXRDevice::SimulatedXRDevice() >@@ -74,31 +80,72 @@ void SimulatedXRDevice::stopTimer() > > void SimulatedXRDevice::frameTimerFired() > { >- auto callbacks = WTFMove(m_callbacks); >- for (auto& callback : callbacks) >- callback({ }); >+ auto updates = WTFMove(m_pendingUpdates); >+ for (auto& update : updates) >+ update(); >+ >+ FrameData data; >+ if (m_viewerOrigin) { >+ data.origin = *m_viewerOrigin; >+ data.isTrackingValid = true; >+ data.isPositionValid = true; >+ } >+ >+ if (m_floorOrigin) >+ data.floorTransform = { *m_floorOrigin }; >+ >+ for (auto& fakeView : m_views) { >+ FrameData::View view; >+ view.offset = fakeView->offset(); >+ if (fakeView->fieldOfView().hasValue()) >+ view.projection = { *fakeView->fieldOfView() }; >+ else >+ view.projection = { fakeView->projection() }; >+ >+ data.views.append(view); >+ } >+ >+ if (m_FrameCallback) >+ m_FrameCallback(WTFMove(data)); > } > > void SimulatedXRDevice::requestFrame(RequestFrameCallback&& callback) > { >- m_callbacks.append(WTFMove(callback)); >+ m_FrameCallback = WTFMove(callback); > if (!m_frameTimer.isActive()) > m_frameTimer.startOneShot(FakeXRFrameTime); > } > >+ >+Vector<PlatformXR::Device::ViewData> SimulatedXRDevice::views(PlatformXR::SessionMode mode) const >+{ >+ if (mode == PlatformXR::SessionMode::ImmersiveVr) >+ return { { .active = true, PlatformXR::Eye::Left }, { .active = true, PlatformXR::Eye::Right } }; >+ >+ return { { .active = true, PlatformXR::Eye::None } }; >+} >+ >+void SimulatedXRDevice::scheduleOnNextFrame(Function<void()>&& func) >+{ >+ m_pendingUpdates.append(WTFMove(func)); >+} >+ >+ > WebFakeXRDevice::WebFakeXRDevice() = default; > > void WebFakeXRDevice::setViews(const Vector<FakeXRViewInit>& views) > { >- Vector<Ref<FakeXRView>>& deviceViews = m_device.views(); >- deviceViews.clear(); >+ m_device.scheduleOnNextFrame([this, views]() { >+ Vector<Ref<FakeXRView>> deviceViews; > >- // TODO: do in next animation frame. >- for (auto& viewInit : views) { >- auto view = parseView(viewInit); >- if (!view.hasException()) >- deviceViews.append(view.releaseReturnValue()); >- } >+ for (auto& viewInit : views) { >+ auto view = parseView(viewInit); >+ if (!view.hasException()) >+ deviceViews.append(view.releaseReturnValue()); >+ } >+ >+ m_device.setViews(WTFMove(deviceViews)); >+ }); > } > > void WebFakeXRDevice::disconnect(DOMPromiseDeferred<void>&& promise) >@@ -108,71 +155,73 @@ void WebFakeXRDevice::disconnect(DOMPromiseDeferred<void>&& promise) > > void WebFakeXRDevice::setViewerOrigin(FakeXRRigidTransformInit origin, bool emulatedPosition) > { >- auto rigidTransform = parseRigidTransform(origin); >- if (rigidTransform.hasException()) >+ auto result = parseRigidTransform(origin); >+ if (result.hasException()) > return; > >- // TODO: do in next animation frame. >- m_device.setViewerOrigin(rigidTransform.releaseReturnValue()); >- m_device.setEmulatedPosition(emulatedPosition); >+ auto pose = result.releaseReturnValue(); >+ >+ m_device.scheduleOnNextFrame([this, pose = WTFMove(pose), emulatedPosition]() mutable { >+ m_device.setViewerOrigin(WTFMove(pose)); >+ m_device.setEmulatedPosition(emulatedPosition); >+ }); > } > > void WebFakeXRDevice::clearViewerOrigin() > { >- // TODO: do in next animation frame. >- m_device.setViewerOrigin(nullptr); >+ m_device.scheduleOnNextFrame([this]() { >+ m_device.setViewerOrigin(WTF::nullopt); >+ }); > } > > void WebFakeXRDevice::simulateVisibilityChange(XRVisibilityState) > { > } > >-void WebFakeXRDevice::setBoundsGeometry(Vector<FakeXRBoundsPoint>) >+void WebFakeXRDevice::setBoundsGeometry(Vector<FakeXRBoundsPoint>&&) > { > } > > void WebFakeXRDevice::setFloorOrigin(FakeXRRigidTransformInit origin) > { >- auto rigidTransform = parseRigidTransform(origin); >- if (rigidTransform.hasException()) >+ auto result = parseRigidTransform(origin); >+ if (result.hasException()) > return; > >- // TODO: do in next animation frame. >- m_device.setFloorOrigin(rigidTransform.releaseReturnValue()); >+ auto pose = result.releaseReturnValue(); >+ >+ m_device.scheduleOnNextFrame([this, pose = WTFMove(pose)]() mutable { >+ m_device.setFloorOrigin(WTFMove(pose)); >+ }); > } > > void WebFakeXRDevice::clearFloorOrigin() > { >- // TODO: do in next animation frame. >- m_device.setFloorOrigin(nullptr); >+ m_device.scheduleOnNextFrame([this]() { >+ m_device.setFloorOrigin(WTF::nullopt); >+ }); > } > > void WebFakeXRDevice::simulateResetPose() > { > } > >+ > Ref<WebFakeXRInputController> WebFakeXRDevice::simulateInputSourceConnection(FakeXRInputSourceInit) > { > return WebFakeXRInputController::create(); > } > >-ExceptionOr<Ref<WebXRRigidTransform>> WebFakeXRDevice::parseRigidTransform(const FakeXRRigidTransformInit& init) >+ExceptionOr<PlatformXR::Device::FrameData::Pose> WebFakeXRDevice::parseRigidTransform(const FakeXRRigidTransformInit& init) > { > if (init.position.size() != 3 || init.orientation.size() != 4) > return Exception { TypeError }; > >- DOMPointInit position; >- position.x = init.position[0]; >- position.y = init.position[1]; >- position.z = init.position[2]; >- >- DOMPointInit orientation; >- orientation.x = init.orientation[0]; >- orientation.y = init.orientation[1]; >- orientation.z = init.orientation[2]; >- orientation.w = init.orientation[3]; >+ PlatformXR::Device::FrameData::Pose pose; >+ pose.position = { init.position[0], init.position[1], init.position[2] }; >+ pose.orientation = { init.orientation[0], init.orientation[1], init.orientation[2], init.orientation[3] }; > >- return WebXRRigidTransform::create(position, orientation); >+ return pose; > } > > ExceptionOr<Ref<FakeXRView>> WebFakeXRDevice::parseView(const FakeXRViewInit& init) >@@ -182,22 +231,17 @@ ExceptionOr<Ref<FakeXRView>> WebFakeXRDevice::parseView(const FakeXRViewInit& in > > if (init.projectionMatrix.size() != 16) > return Exception { TypeError }; >- fakeView->view()->setProjectionMatrix(init.projectionMatrix); >+ fakeView->setProjection(init.projectionMatrix); > > auto viewOffset = parseRigidTransform(init.viewOffset); > if (viewOffset.hasException()) > return viewOffset.releaseException(); >- fakeView->view()->setTransform(viewOffset.releaseReturnValue()); >+ fakeView->setOffset(viewOffset.releaseReturnValue()); > > fakeView->setResolution(init.resolution); > > if (init.fieldOfView) { > fakeView->setFieldOfView(init.fieldOfView.value()); >- // TODO: Set viewâs projection matrix to the projection matrix >- // corresponding to this field of view, and depth values equal to >- // depthNear and depthFar of any XRSession associated with the device. >- // If there currently is none, use the default values of near=0.1, >- // far=1000.0. > } > > return fakeView; >diff --git a/Source/WebCore/testing/WebFakeXRDevice.h b/Source/WebCore/testing/WebFakeXRDevice.h >index 391bfc347eef9aaaf17bd2ba8b6ba436f00046d5..3a6b0e857653f37c4d18c61187c312e9d817db72 100644 >--- a/Source/WebCore/testing/WebFakeXRDevice.h >+++ b/Source/WebCore/testing/WebFakeXRDevice.h >@@ -33,8 +33,6 @@ > #include "JSDOMPromiseDeferred.h" > #include "PlatformXR.h" > #include "WebFakeXRInputController.h" >-#include "WebXRRigidTransform.h" >-#include "WebXRView.h" > #include "XRVisibilityState.h" > #include <wtf/RefCounted.h> > #include <wtf/Vector.h> >@@ -43,21 +41,28 @@ namespace WebCore { > class FakeXRView final : public RefCounted<FakeXRView> { > public: > static Ref<FakeXRView> create(XREye eye) { return adoptRef(*new FakeXRView(eye)); } >+ using Pose = PlatformXR::Device::FrameData::Pose; >+ using Fov = PlatformXR::Device::FrameData::Fov; > >- RefPtr<WebXRView> view() { return m_view; } >- void setResolution(FakeXRViewInit::DeviceResolution resolution) { m_resolution = resolution; } >- void setFieldOfView(FakeXRViewInit::FieldOfViewInit); >+ XREye eye() const { return m_eye; } >+ const Pose& offset() const { return m_offset; } >+ const std::array<float, 16>& projection() const { return m_projection; } >+ const Optional<Fov>& fieldOfView() const { return m_fov;} > >+ void setResolution(FakeXRViewInit::DeviceResolution resolution) { m_resolution = resolution; } >+ void setOffset(Pose&& offset) { m_offset = WTFMove(offset); } >+ void setProjection(const Vector<float>&); >+ void setFieldOfView(const FakeXRViewInit::FieldOfViewInit&); > private: > FakeXRView(XREye eye) >- { >- m_view = WebXRView::create(); >- m_view->setEye(eye); >- } >+ : m_eye(eye) { } >+ > >- RefPtr<WebXRView> m_view; >+ XREye m_eye; > FakeXRViewInit::DeviceResolution m_resolution; >- FakeXRViewInit::FieldOfViewInit m_fov; >+ Pose m_offset; >+ std::array<float, 16> m_projection; >+ Optional<Fov> m_fov; > }; > > class SimulatedXRDevice final : public PlatformXR::Device { >@@ -65,31 +70,35 @@ class SimulatedXRDevice final : public PlatformXR::Device { > public: > SimulatedXRDevice(); > ~SimulatedXRDevice(); >- void setNativeBoundsGeometry(Vector<FakeXRBoundsPoint> geometry) { m_nativeBoundsGeometry = geometry; } >- void setViewerOrigin(RefPtr<WebXRRigidTransform>&& origin) { m_viewerOrigin = WTFMove(origin); } >- void setFloorOrigin(RefPtr<WebXRRigidTransform>&& origin) { m_floorOrigin = WTFMove(origin); } >+ void setViews(Vector<Ref<FakeXRView>>&& views) { m_views = WTFMove(views); } >+ void setNativeBoundsGeometry(const Vector<FakeXRBoundsPoint>& geometry) { m_nativeBoundsGeometry = geometry; } >+ void setViewerOrigin(Optional<FrameData::Pose>&& origin) { m_viewerOrigin = WTFMove(origin); } >+ void setFloorOrigin(Optional<FrameData::Pose>&& origin) { m_floorOrigin = WTFMove(origin); } > void setEmulatedPosition(bool emulated) { m_emulatedPosition = emulated; } > Vector<Ref<FakeXRView>>& views() { return m_views; } > void setSupportsShutdownNotification(bool supportsShutdownNotification) { m_supportsShutdownNotification = supportsShutdownNotification; } > void simulateShutdownCompleted(); >+ void scheduleOnNextFrame(Function<void()>&&); > private: > void initializeTrackingAndRendering(PlatformXR::SessionMode) final { } > void shutDownTrackingAndRendering() final; > bool supportsSessionShutdownNotification() const final { return m_supportsShutdownNotification; } > void initializeReferenceSpace(PlatformXR::ReferenceSpaceType) final { } >+ Vector<PlatformXR::Device::ViewData> views(PlatformXR::SessionMode) const final; > void requestFrame(RequestFrameCallback&&) final; > > void stopTimer(); > void frameTimerFired(); > > Optional<Vector<FakeXRBoundsPoint>> m_nativeBoundsGeometry; >- RefPtr<WebXRRigidTransform> m_viewerOrigin; >- RefPtr<WebXRRigidTransform> m_floorOrigin; >+ Optional<FrameData::Pose> m_viewerOrigin; >+ Optional<FrameData::Pose> m_floorOrigin; > bool m_emulatedPosition { false }; > Vector<Ref<FakeXRView>> m_views; > bool m_supportsShutdownNotification { false }; > Timer m_frameTimer; >- Vector<RequestFrameCallback> m_callbacks; >+ RequestFrameCallback m_FrameCallback; >+ Vector<Function<void()>> m_pendingUpdates; > }; > > class WebFakeXRDevice final : public RefCounted<WebFakeXRDevice> { >@@ -106,7 +115,7 @@ public: > > void simulateVisibilityChange(XRVisibilityState); > >- void setBoundsGeometry(Vector<FakeXRBoundsPoint> boundsCoordinates); >+ void setBoundsGeometry(Vector<FakeXRBoundsPoint>&& boundsCoordinates); > > void setFloorOrigin(FakeXRRigidTransformInit); > >@@ -127,7 +136,7 @@ public: > private: > WebFakeXRDevice(); > >- static ExceptionOr<Ref<WebXRRigidTransform>> parseRigidTransform(const FakeXRRigidTransformInit&); >+ static ExceptionOr<PlatformXR::Device::FrameData::Pose> parseRigidTransform(const FakeXRRigidTransformInit&); > > SimulatedXRDevice m_device; > }; >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 63ef520ae391e70b62189082ee6742848d4aa3c0..24bdc62dde58bdc5b427b3ee4c18df2e48fc529f 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,15 @@ >+2021-02-15 Imanol Fernandez <ifernandez@igalia.com> and Sergio Villar Senin <svillar@igalia.com> >+ >+ Implement WebXR getViewerPose and getPose >+ https://bugs.webkit.org/show_bug.cgi?id=221225 >+ <rdar://problem/74112910> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Mark pose related WebXR tests as passing. >+ >+ * platform/wpe/TestExpectations: >+ > 2021-02-14 Peng Liu <peng.liu6@apple.com> > > [GPUP] Move UseGPUProcessForMediaEnabled from WebPreferencesInternal to WebPreferencesExperimental >diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog >index 0a60ff145df1dfe8287f0b309dd54b1853701a9b..63a9195f474ddd08a9bf8d9f285947ba5e981f5f 100644 >--- a/LayoutTests/imported/w3c/ChangeLog >+++ b/LayoutTests/imported/w3c/ChangeLog >@@ -1,3 +1,24 @@ >+2021-02-15 Imanol Fernandez <ifernandez@igalia.com> and Sergio Villar Senin <svillar@igalia.com> >+ >+ Implement WebXR getViewerPose and getPose >+ https://bugs.webkit.org/show_bug.cgi?id=221225 >+ <rdar://problem/74112910> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Mark pose and reference space WebXR tests as passing. >+ >+ * web-platform-tests/webxr/xrFrame_getPose.https-expected.txt: Added. >+ * web-platform-tests/webxr/xrFrame_getViewerPose_getPose.https-expected.txt: Added. >+ * web-platform-tests/webxr/xrReferenceSpace_originOffset_viewer.https-expected.txt: Added. >+ * web-platform-tests/webxr/xrReferenceSpace_relationships.https-expected.txt: Added. >+ * web-platform-tests/webxr/xrSession_requestAnimationFrame_data_valid.https-expected.txt: Added. >+ * web-platform-tests/webxr/xrSession_requestAnimationFrame_getViewerPose.https-expected.txt: Added. >+ * web-platform-tests/webxr/xrSession_viewer_referenceSpace.https-expected.txt: Added. >+ * web-platform-tests/webxr/xrView_eyes.https-expected.txt: Added. >+ * web-platform-tests/webxr/xrView_match.https-expected.txt: Added. >+ * web-platform-tests/webxr/xrView_oneframeupdate.https-expected.txt: Added. >+ > 2021-02-12 Sergio Villar Senin <svillar@igalia.com> > > [css-flexbox] Another WPT test import >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/xrFrame_getPose.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrFrame_getPose.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..49623d4f8a17f85ff827cc58e85833504f966928 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrFrame_getPose.https-expected.txt >@@ -0,0 +1,4 @@ >+ >+PASS XRFrame.getPose works for immersive sessions >+PASS XRFrame.getPose works for non-immersive sessions >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/xrFrame_getViewerPose_getPose.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrFrame_getViewerPose_getPose.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..b61be3901378d90605bb263d61bfbe8bdaf20e0e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrFrame_getViewerPose_getPose.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS XRFrame getViewerPose(refSpace) matches getPose(viewer, refSpace). >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/xrReferenceSpace_originOffset_viewer.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrReferenceSpace_originOffset_viewer.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..6df9f2ba6a5819f04f10cf57bbcc9f5506955ffa >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrReferenceSpace_originOffset_viewer.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS Creating XRReferenceSpace origin offset off of `viewer` space works. >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/xrReferenceSpace_relationships.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrReferenceSpace_relationships.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..c1ecc1b2bef82f61ab1b4aaef8ab1910366bcdd6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrReferenceSpace_relationships.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS Bounded space, viewer space, local and local-floor space have correct poses w.r.t. each other >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_data_valid.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_data_valid.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..5d9f391a764f488b8f7e3182cc86e820b01f3057 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_data_valid.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS RequestAnimationFrame resolves with good data >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_getViewerPose.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_getViewerPose.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..b2e67dafee5c3c810ad9a29a3ed5ccd99ca570a5 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_getViewerPose.https-expected.txt >@@ -0,0 +1,4 @@ >+ >+PASS XRFrame getViewerPose updates on the next frame for non-immersive sessions >+PASS XRFrame getViewerPose updates on the next frame for immersive sessions >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/xrSession_viewer_referenceSpace.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrSession_viewer_referenceSpace.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..3b5621a4e1b3681bc4de2457d79cbf5bed2c8811 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrSession_viewer_referenceSpace.https-expected.txt >@@ -0,0 +1,4 @@ >+ >+PASS Identity reference space provides correct poses for inline sessions >+PASS Identity reference space provides correct poses for immersive sessions >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/xrView_eyes.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrView_eyes.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..4cdac2de12a10c669bcb5983aa302da59bb69f9e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrView_eyes.https-expected.txt >@@ -0,0 +1,4 @@ >+ >+PASS XRView.eye is correct for immersive sessions >+PASS XRView.eye is correct for non-immersive sessions >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/xrView_match.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrView_match.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..113f6bc9e65ec6f134613b9e2b1f471bca359405 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrView_match.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS XRFrame contains the expected views >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/xrView_oneframeupdate.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrView_oneframeupdate.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..ce022158f0b5dac7331fc6e587a0090d3f58bd60 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrView_oneframeupdate.https-expected.txt >@@ -0,0 +1,3 @@ >+ >+PASS XRView projection matrices update near and far depths on the next frame >+ >diff --git a/LayoutTests/platform/wpe/TestExpectations b/LayoutTests/platform/wpe/TestExpectations >index 332fcd03fc521f8c8dac913756197c1ac617eca7..dde981e637ef4418cce56358d45b019875cae581 100644 >--- a/LayoutTests/platform/wpe/TestExpectations >+++ b/LayoutTests/platform/wpe/TestExpectations >@@ -638,26 +638,36 @@ 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 ] >-webkit.org/b/209859 webkit.org/b/215637 imported/w3c/web-platform-tests/webxr/xrSession_cancelAnimationFrame.https.html [ Pass Failure ] >-webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrSession_cancelAnimationFrame_invalidhandle.https.html [ Pass ] >-webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrSession_features_deviceSupport.https.html [ Pass ] >-webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_callback_calls.https.html [ Pass ] >-imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_timestamp.https.html [ Pass ] >-webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrSession_requestReferenceSpace.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/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 ] >+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 ] > webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrWebGLLayer_constructor.https.html [ Pass ] > webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrWebGLLayer_framebuffer_sameObject.https.html [ Pass ] > imported/w3c/web-platform-tests/webxr/navigator_xr_sameObject.https.html [ Pass ] >-imported/w3c/web-platform-tests/webxr/xrFrame_session_sameObject.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 ] > imported/w3c/web-platform-tests/webxr/xrRigidTransform_inverse.https.html [ Pass ] > imported/w3c/web-platform-tests/webxr/xrRigidTransform_matrix.https.html [ Pass ] >+imported/w3c/web-platform-tests/webxr/xrSession_cancelAnimationFrame.https.html [ Pass ] >+imported/w3c/web-platform-tests/webxr/xrSession_cancelAnimationFrame_invalidhandle.https.html [ Pass ] >+imported/w3c/web-platform-tests/webxr/xrSession_end.https.html [ Pass ] >+imported/w3c/web-platform-tests/webxr/xrSession_features_deviceSupport.https.html [ Pass ] > imported/w3c/web-platform-tests/webxr/xrSession_prevent_multiple_exclusive.https.html [ Pass ] >+imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_callback_calls.https.html [ Pass ] >+imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_data_valid.https.html [ Pass ] >+imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_getViewerPose.https.html [ Pass ] >+imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_timestamp.https.html [ Pass ] >+imported/w3c/web-platform-tests/webxr/xrSession_requestReferenceSpace.https.html [ Pass ] >+imported/w3c/web-platform-tests/webxr/xrSession_viewer_referenceSpace.https.html [ Pass ] > imported/w3c/web-platform-tests/webxr/render_state_vertical_fov_immersive.https.html [ Pass ] > imported/w3c/web-platform-tests/webxr/render_state_update.https.html [ Pass ] >-imported/w3c/web-platform-tests/webxr/xrSession_end.https.html [ Pass ] > http/wpt/webxr/xrSession_end_device_reports_shutdown.https.html [ Pass ] > http/wpt/webxr/xrSession_ended_by_system.https.html [ Pass ] > http/wpt/webxr/xrSession_reject_multiple_end.https.html [ Pass ]
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 221225
:
418928
|
420125
|
420304
|
420336
|
420452
|
420521
|
420660
|
420818