Changeset 273132 in webkit


Ignore:
Timestamp:
Feb 19, 2021 1:07:11 AM (3 years ago)
Author:
svillar@igalia.com
Message:

Implement WebXR getViewerPose and getPose
https://bugs.webkit.org/show_bug.cgi?id=221225
<rdar://problem/74112910>

Reviewed by Youenn Fablet.

LayoutTests/imported/w3c:

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.

Source/WebCore:

  • 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:

LayoutTests:

Mark pose related WebXR tests as passing.

  • platform/wpe/TestExpectations:
Location:
trunk
Files:
10 added
34 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r273129 r273132  
     12021-02-19  Imanol Fernandez  <ifernandez@igalia.com> and Sergio Villar Senin  <svillar@igalia.com>
     2
     3        Implement WebXR getViewerPose and getPose
     4        https://bugs.webkit.org/show_bug.cgi?id=221225
     5        <rdar://problem/74112910>
     6
     7        Reviewed by Youenn Fablet.
     8
     9        Mark pose related WebXR tests as passing.
     10
     11        * platform/wpe/TestExpectations:
     12
    1132021-02-18  Simon Fraser  <simon.fraser@apple.com>
    214
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r273073 r273132  
     12021-02-19  Imanol Fernandez  <ifernandez@igalia.com> and Sergio Villar Senin  <svillar@igalia.com>
     2
     3        Implement WebXR getViewerPose and getPose
     4        https://bugs.webkit.org/show_bug.cgi?id=221225
     5        <rdar://problem/74112910>
     6
     7        Reviewed by Youenn Fablet.
     8
     9        Mark pose and reference space WebXR tests as passing.
     10
     11        * web-platform-tests/webxr/xrFrame_getPose.https-expected.txt: Added.
     12        * web-platform-tests/webxr/xrFrame_getViewerPose_getPose.https-expected.txt: Added.
     13        * web-platform-tests/webxr/xrReferenceSpace_originOffset_viewer.https-expected.txt: Added.
     14        * web-platform-tests/webxr/xrReferenceSpace_relationships.https-expected.txt: Added.
     15        * web-platform-tests/webxr/xrSession_requestAnimationFrame_data_valid.https-expected.txt: Added.
     16        * web-platform-tests/webxr/xrSession_requestAnimationFrame_getViewerPose.https-expected.txt: Added.
     17        * web-platform-tests/webxr/xrSession_viewer_referenceSpace.https-expected.txt: Added.
     18        * web-platform-tests/webxr/xrView_eyes.https-expected.txt: Added.
     19        * web-platform-tests/webxr/xrView_match.https-expected.txt: Added.
     20        * web-platform-tests/webxr/xrView_oneframeupdate.https-expected.txt: Added.
     21
    1222021-02-18  Martin Robinson  <mrobinson@igalia.com>
    223
  • trunk/LayoutTests/platform/wpe/TestExpectations

    r273070 r273132  
    635635webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrDevice_requestSession_non_immersive_no_gesture.https.html [ Pass ]
    636636webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrDevice_requestSession_optionalFeatures.https.html [ Pass ]
    637 webkit.org/b/209859 webkit.org/b/215637 imported/w3c/web-platform-tests/webxr/xrSession_cancelAnimationFrame.https.html [ Pass Failure ]
    638 webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrSession_cancelAnimationFrame_invalidhandle.https.html [ Pass ]
    639 webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrSession_features_deviceSupport.https.html [ Pass ]
    640 webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_callback_calls.https.html [ Pass ]
    641 imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_timestamp.https.html [ Pass ]
    642 webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrSession_requestReferenceSpace.https.html [ Pass ]
     637imported/w3c/web-platform-tests/webxr/xrFrame_getViewerPose_getPose.https.html [ Pass ]
     638imported/w3c/web-platform-tests/webxr/xrFrame_getPose.https.html [ Pass ]
     639imported/w3c/web-platform-tests/webxr/xrFrame_session_sameObject.https.html [ Pass ]
    643640imported/w3c/web-platform-tests/webxr/xrSession_viewer_availability.https.html [ Pass ]
    644641webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/ar-module/idlharness.https.window.html [ Pass ]
    645642webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/ar-module/xrDevice_isSessionSupported_immersive-ar.https.html [ Pass ]
     643imported/w3c/web-platform-tests/webxr/xrView_eyes.https.html [ Pass ]
     644imported/w3c/web-platform-tests/webxr/xrView_match.https.html [ Pass ]
     645imported/w3c/web-platform-tests/webxr/xrView_oneframeupdate.https.html [ Pass ]
    646646webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrWebGLLayer_constructor.https.html [ Pass ]
    647647webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrWebGLLayer_framebuffer_sameObject.https.html [ Pass ]
    648648imported/w3c/web-platform-tests/webxr/navigator_xr_sameObject.https.html [ Pass ]
    649 imported/w3c/web-platform-tests/webxr/xrFrame_session_sameObject.https.html [ Pass ]
     649imported/w3c/web-platform-tests/webxr/xrReferenceSpace_originOffset_viewer.https.html [ Pass ]
     650imported/w3c/web-platform-tests/webxr/xrReferenceSpace_relationships.https.html [ Pass ]
    650651imported/w3c/web-platform-tests/webxr/xrRigidTransform_constructor.https.html [ Pass ]
    651652imported/w3c/web-platform-tests/webxr/xrRigidTransform_inverse.https.html [ Pass ]
    652653imported/w3c/web-platform-tests/webxr/xrRigidTransform_matrix.https.html [ Pass ]
     654imported/w3c/web-platform-tests/webxr/xrSession_cancelAnimationFrame.https.html [ Pass ]
     655imported/w3c/web-platform-tests/webxr/xrSession_cancelAnimationFrame_invalidhandle.https.html [ Pass ]
     656imported/w3c/web-platform-tests/webxr/xrSession_end.https.html [ Pass ]
     657imported/w3c/web-platform-tests/webxr/xrSession_features_deviceSupport.https.html [ Pass ]
    653658imported/w3c/web-platform-tests/webxr/xrSession_prevent_multiple_exclusive.https.html [ Pass ]
     659imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_callback_calls.https.html [ Pass ]
     660imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_data_valid.https.html [ Pass ]
     661imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_getViewerPose.https.html [ Pass ]
     662imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_timestamp.https.html [ Pass ]
     663imported/w3c/web-platform-tests/webxr/xrSession_requestReferenceSpace.https.html [ Pass ]
     664imported/w3c/web-platform-tests/webxr/xrSession_viewer_referenceSpace.https.html [ Pass ]
    654665imported/w3c/web-platform-tests/webxr/render_state_vertical_fov_immersive.https.html [ Pass ]
    655666imported/w3c/web-platform-tests/webxr/render_state_update.https.html [ Pass ]
    656 imported/w3c/web-platform-tests/webxr/xrSession_end.https.html [ Pass ]
    657667http/wpt/webxr/xrSession_end_device_reports_shutdown.https.html [ Pass ]
    658668http/wpt/webxr/xrSession_ended_by_system.https.html [ Pass ]
  • trunk/Source/WebCore/ChangeLog

    r273129 r273132  
     12021-02-19  Imanol Fernandez  <ifernandez@igalia.com> and Sergio Villar Senin  <svillar@igalia.com>
     2
     3        Implement WebXR getViewerPose and getPose
     4        https://bugs.webkit.org/show_bug.cgi?id=221225
     5        <rdar://problem/74112910>
     6
     7        Reviewed by Youenn Fablet.
     8
     9        - Improve PlatformXR::FrameData struct.
     10        - Implement WebXRFrame getViewerPose and getPose.
     11        - Implement WebXRReferenceSpace offset, origin and effective tranforms.
     12        - Implement WebXRBoundedReferenceSpace nativeOrigin.
     13        - Apply frame updates in WebXRSession.
     14        - Implement views for OpenXR and DummyInlineDevice inline sessions.
     15        - Query and complete all the new FrameData in the OpenXR port.
     16        - Complete the WebFakeXRDevice implementation for WebXR WPT tests.
     17
     18        Tested by the WebXR WPT tests
     19
     20        * Modules/webxr/WebXRBoundedReferenceSpace.cpp: Implement nativeOrigina and getOffsetReferenceSpace.
     21        (WebCore::WebXRBoundedReferenceSpace::create):
     22        (WebCore::WebXRBoundedReferenceSpace::WebXRBoundedReferenceSpace):
     23        (WebCore::WebXRBoundedReferenceSpace::nativeOrigin const):
     24        (WebCore::WebXRBoundedReferenceSpace::boundsGeometry const):
     25        (WebCore::WebXRBoundedReferenceSpace::getOffsetReferenceSpace):
     26        * Modules/webxr/WebXRBoundedReferenceSpace.h:
     27
     28        * Modules/webxr/WebXRFrame.cpp: Implement WebXR getViewerPose and getPose.
     29        (WebCore::WebXRFrame::create):
     30        (WebCore::WebXRFrame::WebXRFrame):
     31        (WebCore::WebXRFrame::mustPosesBeLimited):
     32        (WebCore::WebXRFrame::populatePose):
     33        (WebCore::WebXRFrame::getViewerPose):
     34        (WebCore::WebXRFrame::getPose):
     35        (WebCore::WebXRFrame::matrixFromPose): add helper function.
     36        * Modules/webxr/WebXRFrame.h:
     37        (WebCore::WebXRFrame::setFrameData):
     38        * Modules/webxr/WebXRFrame.idl: add MayThrowException.
     39
     40        * Modules/webxr/WebXRPose.cpp: Add WebXRRigidTransform constructor parameter. Add specialize type traits.
     41        (WebCore::WebXRPose::create):
     42        (WebCore::WebXRPose::WebXRPose):
     43        * Modules/webxr/WebXRPose.h:
     44        (WebCore::WebXRPose::isViewerPose const):
     45        * Modules/webxr/WebXRPose.idl: Remove ImplementationLacksVTable
     46
     47        * Modules/webxr/WebXRReferenceSpace.cpp: Implement offset, origin and effective tranforms.
     48        (WebCore::WebXRReferenceSpace::create):
     49        (WebCore::WebXRReferenceSpace::WebXRReferenceSpace):
     50        (WebCore::WebXRReferenceSpace::nativeOrigin const):
     51        (WebCore::WebXRReferenceSpace::getOffsetReferenceSpace):
     52        (WebCore::WebXRReferenceSpace::floorOriginTransform const):
     53        (WebCore:: const):
     54        * Modules/webxr/WebXRReferenceSpace.h:
     55        (WebCore::WebXRReferenceSpace::type const):
     56        * Modules/webxr/WebXRReferenceSpace.idl: Add SkipVTableValidation.
     57
     58        * Modules/webxr/WebXRSession.cpp: Apply frame updates for frame. Add active views data.
     59        (WebCore::WebXRSession::WebXRSession):
     60        (WebCore::WebXRSession::requestReferenceSpace): Use WeakPtr instead Ref for WebXRSession.
     61        (WebCore::WebXRSession::onFrame):
     62        (WebCore::WebXRSession::posesCanBeReported const): add
     63        * Modules/webxr/WebXRSession.h:
     64
     65        * Modules/webxr/WebXRSpace.cpp: Add nativeOrigin and effectiveOrigin member functions. Add specialize type traits.
     66        (WebCore::WebXRSpace::WebXRSpace):
     67        (WebCore::WebXRSpace::effectiveOrigin const):
     68        * Modules/webxr/WebXRSpace.h:
     69        (WebCore::WebXRSpace::session const):
     70        (WebCore::WebXRSpace::isReferenceSpace const):
     71        (WebCore::WebXRSpace::isBoundedReferenceSpace const):
     72
     73        * Modules/webxr/WebXRSystem.cpp: Implement views for DummyInlineDevice.
     74        (WebCore::WebXRSystem::DummyInlineDevice::requestFrame):
     75        (WebCore::WebXRSystem::DummyInlineDevice::views const):
     76        * Modules/webxr/WebXRSystem.h:
     77
     78        * Modules/webxr/WebXRView.cpp: Pass WebXRRigidTransform in the constructor.
     79        (WebCore::WebXRView::create):
     80        (WebCore::WebXRView::WebXRView):
     81        (WebCore::WebXRView::setProjectionMatrix): Use std::array to match device data.
     82        * Modules/webxr/WebXRView.h:
     83        (WebCore::WebXRView::projectionMatrix const):
     84        (WebCore::WebXRView::transform const):
     85
     86        * Modules/webxr/WebXRViewerPose.cpp: Add views setter. Add specialize type traits.
     87        (WebCore::WebXRViewerPose::create):
     88        (WebCore::WebXRViewerPose::WebXRViewerPose):
     89        (WebCore::WebXRViewerPose::setViews):
     90        * Modules/webxr/WebXRViewerPose.h:
     91        * Modules/webxr/WebXRViewerPose.idl: Remove ImplementationLacksVTable. Add JSGenerateToNativeObject.
     92
     93        * Modules/webxr/XREye.h: Reuse PlatformXR enum.
     94
     95        * platform/graphics/transforms/TransformationMatrix.cpp: Add projection matrix utility functions.
     96        (WebCore::TransformationMatrix::fromProjection):
     97        * platform/graphics/transforms/TransformationMatrix.h:
     98
     99        * platform/xr/PlatformXR.h: Improve FrameData.
     100
     101        * platform/xr/openxr/PlatformXROpenXR.cpp: Query and complete all the new FrameData.
     102        (PlatformXR::OpenXRDevice::createReferenceSpace): add helper function.
     103        (PlatformXR::OpenXRDevice::recommendedResolution): Query resolution data from OpenXR.
     104        (PlatformXR::OpenXRDevice::initializeTrackingAndRendering): Initialize local and view XrSpaces.
     105        (PlatformXR::OpenXRDevice::initializeReferenceSpace): Lazily initialize stage XrSpace.
     106        (PlatformXR::XrPosefToPose): add helper function.
     107        (PlatformXR::xrViewToPose): add helper function.
     108        (PlatformXR::OpenXRDevice::requestFrame): Complete all the new frame Data
     109        (PlatformXR::OpenXRDevice::views const): Implement view data for OpenXR
     110        * platform/xr/openxr/PlatformXROpenXR.h:
     111
     112        * testing/WebFakeXRDevice.cpp: Complete the required implementation for WebXR WPT tests.
     113        (WebCore::FakeXRView::setProjection):
     114        (WebCore::FakeXRView::setFieldOfView):
     115        (WebCore::SimulatedXRDevice::frameTimerFired):
     116        (WebCore::SimulatedXRDevice::requestFrame):
     117        (WebCore::SimulatedXRDevice::views const):
     118        (WebCore::SimulatedXRDevice::scheduleOnNextFrame):
     119        (WebCore::WebFakeXRDevice::setViews):
     120        (WebCore::WebFakeXRDevice::setViewerOrigin):
     121        (WebCore::WebFakeXRDevice::clearViewerOrigin):
     122        (WebCore::WebFakeXRDevice::setBoundsGeometry):
     123        (WebCore::WebFakeXRDevice::setFloorOrigin):
     124        (WebCore::WebFakeXRDevice::clearFloorOrigin):
     125        (WebCore::WebFakeXRDevice::parseRigidTransform):
     126        (WebCore::WebFakeXRDevice::parseView):
     127        * testing/WebFakeXRDevice.h:
     128
    11292021-02-18  Simon Fraser  <simon.fraser@apple.com>
    2130
  • trunk/Source/WebCore/Modules/webxr/WebXRBoundedReferenceSpace.cpp

    r262299 r273132  
    3030
    3131#include "DOMPointReadOnly.h"
     32#include "Document.h"
     33#include "WebXRRigidTransform.h"
     34#include "WebXRSession.h"
    3235#include <wtf/IsoMallocInlines.h>
    3336
     
    3841Ref<WebXRBoundedReferenceSpace> WebXRBoundedReferenceSpace::create(Document& document, Ref<WebXRSession>&& session, XRReferenceSpaceType type)
    3942{
    40     return adoptRef(*new WebXRBoundedReferenceSpace(document, WTFMove(session), type));
     43    return adoptRef(*new WebXRBoundedReferenceSpace(document, WTFMove(session), WebXRRigidTransform::create(), type));
    4144}
    4245
    43 WebXRBoundedReferenceSpace::WebXRBoundedReferenceSpace(Document& document, Ref<WebXRSession>&& session, XRReferenceSpaceType type)
    44     : WebXRReferenceSpace(document, WTFMove(session), type)
     46
     47Ref<WebXRBoundedReferenceSpace> WebXRBoundedReferenceSpace::create(Document& document, Ref<WebXRSession>&& session, Ref<WebXRRigidTransform>&& offset, XRReferenceSpaceType type)
     48{
     49    return adoptRef(*new WebXRBoundedReferenceSpace(document, WTFMove(session), WTFMove(offset), type));
     50}
     51
     52
     53WebXRBoundedReferenceSpace::WebXRBoundedReferenceSpace(Document& document, Ref<WebXRSession>&& session, Ref<WebXRRigidTransform>&& offset, XRReferenceSpaceType type)
     54    : WebXRReferenceSpace(document, WTFMove(session), WTFMove(offset), type)
    4555{
    4656}
     
    4858WebXRBoundedReferenceSpace::~WebXRBoundedReferenceSpace() = default;
    4959
     60TransformationMatrix WebXRBoundedReferenceSpace::nativeOrigin() const
     61{
     62    // https://immersive-web.github.io/webxr/#dom-xrreferencespacetype-bounded-floor.
     63    // Bounded floor space should be at the same height as local floor space.
     64    return floorOriginTransform();
     65}
     66
    5067const Vector<Ref<DOMPointReadOnly>>& WebXRBoundedReferenceSpace::boundsGeometry() const
    5168{
     69    // FIXME: get data from device
    5270    return m_boundsGeometry;
     71}
     72
     73RefPtr<WebXRReferenceSpace> WebXRBoundedReferenceSpace::getOffsetReferenceSpace(const WebXRRigidTransform& offsetTransform)
     74{
     75    auto* document = downcast<Document>(scriptExecutionContext());
     76    if (!document)
     77        return nullptr;
     78
     79    // https://immersive-web.github.io/webxr/#dom-xrreferencespace-getoffsetreferencespace
     80    // Set offsetSpace’s origin offset to the result of multiplying base’s origin offset by originOffset in the relevant realm of base.
     81    auto offset = WebXRRigidTransform::create(originOffset().rawTransform() * offsetTransform.rawTransform());
     82
     83    // FIXME: set offsetSpace’s boundsGeometry to base’s boundsGeometry, with each point multiplied by the inverse of originOffset.
     84    return create(*document, m_session.copyRef(), WTFMove(offset), m_type);
    5385}
    5486
  • trunk/Source/WebCore/Modules/webxr/WebXRBoundedReferenceSpace.h

    r262299 r273132  
    2626#pragma once
    2727
     28#if ENABLE(WEBXR)
     29
    2830#include "WebXRReferenceSpace.h"
    2931#include <wtf/IsoMalloc.h>
     
    3133#include <wtf/Vector.h>
    3234
    33 #if ENABLE(WEBXR)
    34 
    3535namespace WebCore {
    3636
    3737class DOMPointReadOnly;
    3838
    39 class WebXRBoundedReferenceSpace : public WebXRReferenceSpace {
     39class WebXRBoundedReferenceSpace final: public WebXRReferenceSpace {
    4040    WTF_MAKE_ISO_ALLOCATED(WebXRBoundedReferenceSpace);
    4141public:
    4242    static Ref<WebXRBoundedReferenceSpace> create(Document&, Ref<WebXRSession>&&, XRReferenceSpaceType);
     43    static Ref<WebXRBoundedReferenceSpace> create(Document&, Ref<WebXRSession>&&, Ref<WebXRRigidTransform>&&, XRReferenceSpaceType);
    4344
    4445    virtual ~WebXRBoundedReferenceSpace();
    4546
     47    TransformationMatrix nativeOrigin() const final;
    4648    const Vector<Ref<DOMPointReadOnly>>& boundsGeometry() const;
     49    RefPtr<WebXRReferenceSpace> getOffsetReferenceSpace(const WebXRRigidTransform&) final;
    4750
    4851private:
    49     WebXRBoundedReferenceSpace(Document&, Ref<WebXRSession>&&, XRReferenceSpaceType);
     52    WebXRBoundedReferenceSpace(Document&, Ref<WebXRSession>&&, Ref<WebXRRigidTransform>&&, XRReferenceSpaceType);
     53
     54    bool isBoundedReferenceSpace() const final { return true; }
    5055
    5156    Vector<Ref<DOMPointReadOnly>> m_boundsGeometry;
     
    5459} // namespace WebCore
    5560
     61SPECIALIZE_TYPE_TRAITS_WEBXRSPACE(WebXRBoundedReferenceSpace, isBoundedReferenceSpace())
     62
    5663#endif // ENABLE(WEBXR)
  • trunk/Source/WebCore/Modules/webxr/WebXRFrame.cpp

    r272734 r273132  
    2929#if ENABLE(WEBXR)
    3030
     31#include "WebXRBoundedReferenceSpace.h"
     32#include "WebXRReferenceSpace.h"
    3133#include "WebXRSession.h"
    3234#include "WebXRViewerPose.h"
     
    3739WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRFrame);
    3840
    39 Ref<WebXRFrame> WebXRFrame::create(Ref<WebXRSession>&& session)
    40 {
    41     return adoptRef(*new WebXRFrame(WTFMove(session)));
    42 }
    43 
    44 WebXRFrame::WebXRFrame(Ref<WebXRSession>&& session)
    45     : m_session(WTFMove(session))
     41Ref<WebXRFrame> WebXRFrame::create(Ref<WebXRSession>&& session, IsAnimationFrame isAnimationFrame)
     42{
     43    return adoptRef(*new WebXRFrame(WTFMove(session), isAnimationFrame));
     44}
     45
     46WebXRFrame::WebXRFrame(Ref<WebXRSession>&& session, IsAnimationFrame isAnimationFrame)
     47    : m_isAnimationFrame(isAnimationFrame == IsAnimationFrame::Yes)
     48    , m_session(WTFMove(session))
    4649{
    4750}
     
    4952WebXRFrame::~WebXRFrame() = default;
    5053
    51 
    52 RefPtr<WebXRViewerPose> WebXRFrame::getViewerPose(const WebXRReferenceSpace&)
    53 {
    54     return { };
    55 }
    56 
    57 RefPtr<WebXRPose> WebXRFrame::getPose(const WebXRSpace&, const WebXRSpace&)
    58 {
    59     return { };
     54bool WebXRFrame::isOutsideNativeBoundsOfBoundedReferenceSpace(const WebXRSpace& space, const WebXRSpace&) const
     55{
     56    if (!is<WebXRBoundedReferenceSpace>(space))
     57        return false;
     58
     59    // FIXME: return true whenever the distance from the bounded geometry of
     60    // |space| to the native origin of |other| space is greater than 1m
     61    // (suggested by specs).
     62
     63    return false;
     64}
     65
     66bool WebXRFrame::isLocalReferenceSpace(const WebXRSpace& space) const
     67{
     68    if (!is<WebXRReferenceSpace>(space))
     69        return false;
     70
     71    auto type = downcast<WebXRReferenceSpace>(space).type();
     72    if (type == XRReferenceSpaceType::Local || type == XRReferenceSpaceType::LocalFloor)
     73        return true;
     74
     75    return false;
     76}
     77
     78// https://immersive-web.github.io/webxr/#poses-must-be-limited
     79bool WebXRFrame::mustPosesBeLimited(const WebXRSpace& space, const WebXRSpace& baseSpace) const
     80{
     81    if (isOutsideNativeBoundsOfBoundedReferenceSpace(space, baseSpace)
     82        || isOutsideNativeBoundsOfBoundedReferenceSpace(baseSpace, space))
     83        return true;
     84
     85    if (isLocalReferenceSpace(space) || isLocalReferenceSpace(baseSpace)) {
     86        // FIXME: If the distance between native origins of spaces is greater
     87        // than 15m (suggested by specs) return true.
     88    }
     89
     90    return false;
     91}
     92
     93struct WebXRFrame::PopulatedPose {
     94    TransformationMatrix transform;
     95    bool emulatedPosition { false };
     96};
     97
     98// https://immersive-web.github.io/webxr/#populate-the-pose
     99ExceptionOr<Optional<WebXRFrame::PopulatedPose>> WebXRFrame::populatePose(const Document& document, const WebXRSpace& space, const WebXRSpace& baseSpace)
     100{
     101    // 1. If frame’s active boolean is false, throw an InvalidStateError and abort these steps.
     102    if (!m_active)
     103        return Exception { InvalidStateError };
     104
     105    // 2. Let session be frame’s session object.
     106    // 3. If space’s session does not equal session, throw an InvalidStateError and abort these steps.
     107    if (&space.session() != m_session.ptr())
     108        return Exception { InvalidStateError };
     109
     110    // 4. If baseSpace’s session does not equal session, throw an InvalidStateError and abort these steps.
     111    if (&baseSpace.session() != m_session.ptr())
     112        return Exception { InvalidStateError };
     113
     114    // 5. Check if poses may be reported and, if not, throw a SecurityError and abort these steps.
     115    if (!m_session->posesCanBeReported(document))
     116        return Exception { SecurityError };
     117
     118    // 6. Let limit be the result of whether poses must be limited between space and baseSpace.
     119    // 7. Let transform be pose’s transform.
     120    // 8. Query the XR device's tracking system for space’s pose relative to baseSpace at the frame’s time.
     121
     122    if (!m_data.isTrackingValid) {
     123        // FIXME: check if space’s pose relative to baseSpace has been determined in the past.
     124        // Anyway this emulation is usually provided by the system in the pose (e.g. OpenXR)
     125        // so we shouldn't hit this path in most XRPlatform ports.
     126        return { WTF::nullopt };
     127    }
     128
     129    auto baseTransform = baseSpace.effectiveOrigin();
     130    if (!baseTransform.isInvertible())
     131        return { WTF::nullopt };
     132
     133    auto transform =  *baseTransform.inverse() * space.effectiveOrigin();
     134    bool emulatedPosition = m_data.isPositionEmulated || !m_data.isPositionValid;
     135
     136    bool limit = mustPosesBeLimited(space, baseSpace);
     137    if (limit) {
     138        // FIXME: apply pose limits logic
     139        // https://immersive-web.github.io/webxr/#poses-must-be-limited
     140    }
     141
     142    return { PopulatedPose { transform, emulatedPosition } };
     143}
     144
     145// https://immersive-web.github.io/webxr/#dom-xrframe-getviewerpose
     146ExceptionOr<RefPtr<WebXRViewerPose>> WebXRFrame::getViewerPose(const Document& document, const WebXRReferenceSpace& referenceSpace)
     147{
     148    // 1. Let frame be this.
     149    // 2. Let session be frame’s session object.
     150    // 3. If frame’s animationFrame boolean is false, throw an InvalidStateError and abort these steps.
     151    if (!m_isAnimationFrame)
     152        return Exception { InvalidStateError };
     153
     154    // 4. Let pose be a new XRViewerPose object in the relevant realm of session.
     155    // 5. Populate the pose of session’s viewer reference space in referenceSpace at the time represented by frame into pose.
     156    auto populatePoseResult = populatePose(document, m_session->viewerReferenceSpace(), referenceSpace);
     157    if (populatePoseResult.hasException())
     158        return populatePoseResult.releaseException();
     159
     160    // 6. If pose is null return null.
     161    auto populateValue = populatePoseResult.releaseReturnValue();
     162    if (!populateValue.hasValue())
     163        return nullptr;
     164
     165    RefPtr<WebXRViewerPose> pose = WebXRViewerPose::create(WebXRRigidTransform::create(populateValue->transform), populateValue->emulatedPosition);
     166
     167    // 7. Let xrviews be an empty list.
     168    Vector<Ref<WebXRView>> xrViews;
     169    // 8. For each active view view in the list of views on session, perform the following steps:
     170    for (auto& view : m_session->views()) {
     171        auto index = xrViews.size();
     172        if (!view.active || m_data.views.size() <= index)
     173            continue;
     174
     175        // 8.1 Let xrview be a new XRView object in the relevant realm of session.
     176        // 8.2 Initialize xrview’s underlying view to view.
     177        // 8.3 Initialize xrview’s eye to view’s eye.
     178        // 8.4 Initialize xrview’s frame time to frame’s time.
     179        // 8.5 Initialize xrview’s session to session.
     180        // 8.6. Let offset be an new XRRigidTransform object equal to the view offset of view in the relevant realm of session.
     181        // 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
     182        auto offset = matrixFromPose(m_data.views[index].offset);
     183        auto transform = WebXRRigidTransform::create(pose->transform().rawTransform() * offset);
     184
     185        // Set projection matrix for each view
     186        std::array<float, 16> projection = switchOn(m_data.views[index].projection, [&](const PlatformXR::Device::FrameData::Fov& fov) {
     187            double near = m_session->renderState().depthNear();
     188            double far = m_session->renderState().depthFar();
     189            return TransformationMatrix::fromProjection(fov.up, fov.down, fov.left, fov.right, near, far).toColumnMajorFloatArray();
     190        }, [&](const std::array<float, 16>& matrix) {
     191            return matrix;
     192        }, [&](std::nullptr_t&) {
     193            // Use aspect projection for inline sessions
     194            double fov =  m_session->renderState().inlineVerticalFieldOfView().valueOr(piOverTwoDouble);
     195            float aspect = 1;
     196            auto layer = m_session->renderState().baseLayer();
     197            if (layer)
     198                aspect = static_cast<double>(layer->framebufferWidth()) / static_cast<double>(layer->framebufferHeight());
     199            double near = m_session->renderState().depthNear();
     200            double far = m_session->renderState().depthFar();
     201            return TransformationMatrix::fromProjection(fov, aspect, near, far).toColumnMajorFloatArray();
     202        });
     203
     204        auto xrView = WebXRView::create(view.eye, WTFMove(transform), Float32Array::create(projection.data(), projection.size()));
     205
     206        //  8.8. Append xrview to xrviews
     207        xrViews.append(WTFMove(xrView));
     208    }
     209
     210    // 9. Set pose’s views to xrviews
     211    pose->setViews(WTFMove(xrViews));
     212
     213    // 10. Return pose.
     214    return pose;
     215}
     216
     217ExceptionOr<RefPtr<WebXRPose>> WebXRFrame::getPose(const Document& document, const WebXRSpace& space, const WebXRSpace& baseSpace)
     218{
     219    // 1. Let frame be this.
     220    // 2. Let pose be a new XRPose object in the relevant realm of frame.
     221    // 3. Populate the pose of space in baseSpace at the time represented by frame into pose.
     222
     223    auto populatePoseResult = populatePose(document, space, baseSpace);
     224    if (populatePoseResult.hasException())
     225        return populatePoseResult.releaseException();
     226
     227    auto populateValue = populatePoseResult.releaseReturnValue();
     228    if (!populateValue.hasValue())
     229        return nullptr;
     230
     231    // 4. Return pose.
     232    return RefPtr<WebXRPose>(WebXRPose::create(WebXRRigidTransform::create(populateValue->transform), populateValue->emulatedPosition));
     233}
     234
     235TransformationMatrix WebXRFrame::matrixFromPose(const PlatformXR::Device::FrameData::Pose& pose)
     236{
     237    TransformationMatrix matrix;
     238    matrix.translate3d(pose.position.x(), pose.position.y(), pose.position.z());
     239    matrix.multiply(TransformationMatrix::fromQuaternion(pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w));
     240    return matrix;
    60241}
    61242
  • trunk/Source/WebCore/Modules/webxr/WebXRFrame.h

    r272734 r273132  
    2929
    3030#include "DOMHighResTimeStamp.h"
     31#include "ExceptionOr.h"
     32#include "PlatformXR.h"
    3133#include <wtf/IsoMalloc.h>
    3234#include <wtf/Ref.h>
     
    3638namespace WebCore {
    3739
     40class Document;
    3841class WebXRPose;
    3942class WebXRReferenceSpace;
     
    4548    WTF_MAKE_ISO_ALLOCATED(WebXRFrame);
    4649public:
    47     static Ref<WebXRFrame> create(Ref<WebXRSession>&&);
     50    enum class IsAnimationFrame : bool { No, Yes };
     51    static Ref<WebXRFrame> create(Ref<WebXRSession>&&, IsAnimationFrame);
    4852    ~WebXRFrame();
    4953
    5054    const WebXRSession& session() const { return m_session.get(); }
    5155
    52     RefPtr<WebXRViewerPose> getViewerPose(const WebXRReferenceSpace&);
    53     RefPtr<WebXRPose> getPose(const WebXRSpace&, const WebXRSpace&);
     56    ExceptionOr<RefPtr<WebXRViewerPose>> getViewerPose(const Document&, const WebXRReferenceSpace&);
     57    ExceptionOr<RefPtr<WebXRPose>> getPose(const Document&, const WebXRSpace&, const WebXRSpace&);
    5458
    5559    void setTime(DOMHighResTimeStamp time) { m_time = time; }
     60    void setFrameData(PlatformXR::Device::FrameData&& data) { m_data = WTFMove(data); }
     61
    5662    void setActive(bool active) { m_active = active; }
    5763    bool isActive() const { return m_active; }
    5864
     65    static TransformationMatrix matrixFromPose(const PlatformXR::Device::FrameData::Pose&);
     66
    5967private:
    60     explicit WebXRFrame(Ref<WebXRSession>&&);
     68    WebXRFrame(Ref<WebXRSession>&&, IsAnimationFrame);
     69
     70    bool isOutsideNativeBoundsOfBoundedReferenceSpace(const WebXRSpace&, const WebXRSpace&) const;
     71    bool isLocalReferenceSpace(const WebXRSpace&) const;
     72    bool mustPosesBeLimited(const WebXRSpace&, const WebXRSpace&) const;
     73
     74    struct PopulatedPose;
     75    ExceptionOr<Optional<PopulatedPose>> populatePose(const Document&, const WebXRSpace&, const WebXRSpace&);
    6176
    6277    bool m_active { false };
    63     DOMHighResTimeStamp m_time;
     78    bool m_isAnimationFrame { false };
     79    DOMHighResTimeStamp m_time { 0 };
     80    PlatformXR::Device::FrameData m_data;
    6481    Ref<WebXRSession> m_session;
    6582};
  • trunk/Source/WebCore/Modules/webxr/WebXRFrame.idl

    r258498 r273132  
    3434    [SameObject] readonly attribute WebXRSession session;
    3535
    36     WebXRViewerPose? getViewerPose(WebXRReferenceSpace referenceSpace);
    37     WebXRPose? getPose(WebXRSpace space, WebXRSpace baseSpace);
     36    [MayThrowException, CallWith=Document] WebXRViewerPose? getViewerPose(WebXRReferenceSpace referenceSpace);
     37    [MayThrowException, CallWith=Document] WebXRPose? getPose(WebXRSpace space, WebXRSpace baseSpace);
    3838};
  • trunk/Source/WebCore/Modules/webxr/WebXRPose.cpp

    r258498 r273132  
    3636WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRPose);
    3737
    38 Ref<WebXRPose> WebXRPose::create()
     38Ref<WebXRPose> WebXRPose::create(Ref<WebXRRigidTransform>&& transform, bool emulatedPosition)
    3939{
    40     return adoptRef(*new WebXRPose);
     40    return adoptRef(*new WebXRPose(WTFMove(transform), emulatedPosition));
    4141}
    4242
    43 WebXRPose::WebXRPose()
    44     : m_transform(WebXRRigidTransform::create())
     43WebXRPose::WebXRPose(Ref<WebXRRigidTransform>&& transform, bool emulatedPosition)
     44    : m_transform(WTFMove(transform)), m_emulatedPosition(emulatedPosition)
    4545{
    4646}
  • trunk/Source/WebCore/Modules/webxr/WebXRPose.h

    r258498 r273132  
    2727
    2828#if ENABLE(WEBXR)
    29 
    3029#include <wtf/IsoMalloc.h>
    3130#include <wtf/Ref.h>
     
    3938    WTF_MAKE_ISO_ALLOCATED(WebXRPose);
    4039public:
    41     static Ref<WebXRPose> create();
    42     ~WebXRPose();
     40    static Ref<WebXRPose> create(Ref<WebXRRigidTransform>&&, bool emulatedPosition);
     41    virtual ~WebXRPose();
    4342
    4443    const WebXRRigidTransform& transform() const;
    4544    bool emulatedPosition() const;
    4645
     46    virtual bool isViewerPose() const { return false; }
     47
    4748protected:
    48     WebXRPose();
     49    WebXRPose(Ref<WebXRRigidTransform>&&, bool emulatedPosition);
    4950
    5051    Ref<WebXRRigidTransform> m_transform;
     
    5455} // namespace WebCore
    5556
     57#define SPECIALIZE_TYPE_TRAITS_WEBXRPOSE(ToValueTypeName, predicate)                    \
     58SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName)                               \
     59    static bool isType(const WebCore::WebXRPose& context) { return context.predicate; } \
     60SPECIALIZE_TYPE_TRAITS_END()
     61
    5662#endif // ENABLE(WEBXR)
  • trunk/Source/WebCore/Modules/webxr/WebXRPose.idl

    r258498 r273132  
    2929    SecureContext,
    3030    Exposed=Window,
    31     ImplementationLacksVTable,
    3231    InterfaceName=XRPose
    3332] interface WebXRPose {
  • trunk/Source/WebCore/Modules/webxr/WebXRReferenceSpace.cpp

    r262299 r273132  
    3030
    3131#include "Document.h"
     32#include "WebXRFrame.h"
     33#include "WebXRRigidTransform.h"
    3234#include "WebXRSession.h"
    3335#include <wtf/IsoMallocInlines.h>
     
    3537namespace WebCore {
    3638
     39static constexpr double DefaultUserHeightInMeters = 1.65;
     40
    3741WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRReferenceSpace);
    3842
    3943Ref<WebXRReferenceSpace> WebXRReferenceSpace::create(Document& document, Ref<WebXRSession>&& session, XRReferenceSpaceType type)
    4044{
    41     return adoptRef(*new WebXRReferenceSpace(document, WTFMove(session), type));
     45    // https://immersive-web.github.io/webxr/#xrspace-native-origin
     46    // The transform from the effective space to the native origin's space is
     47    // defined by an origin offset, which is an XRRigidTransform initially set
     48    // to an identity transform.
     49    return adoptRef(*new WebXRReferenceSpace(document, WTFMove(session), WebXRRigidTransform::create(), type));
    4250}
    4351
    44 WebXRReferenceSpace::WebXRReferenceSpace(Document& document, Ref<WebXRSession>&& session, XRReferenceSpaceType type)
    45     : WebXRSpace(document, WTFMove(session))
     52Ref<WebXRReferenceSpace> WebXRReferenceSpace::create(Document& document, Ref<WebXRSession>&& session, Ref<WebXRRigidTransform>&& offset, XRReferenceSpaceType type)
     53{
     54    return adoptRef(*new WebXRReferenceSpace(document, WTFMove(session), WTFMove(offset), type));
     55}
     56
     57WebXRReferenceSpace::WebXRReferenceSpace(Document& document, Ref<WebXRSession>&& session, Ref<WebXRRigidTransform>&& offset, XRReferenceSpaceType type)
     58    : WebXRSpace(document, WTFMove(offset))
     59    , m_session(WTFMove(session))
    4660    , m_type(type)
    4761{
     
    5064WebXRReferenceSpace::~WebXRReferenceSpace() = default;
    5165
    52 RefPtr<WebXRReferenceSpace> WebXRReferenceSpace::getOffsetReferenceSpace(const WebXRRigidTransform&)
     66
     67TransformationMatrix WebXRReferenceSpace::nativeOrigin() const
    5368{
    54     if (!scriptExecutionContext())
     69    TransformationMatrix identity;
     70
     71    // We assume that poses got from the devices are in local space.
     72    // This will require more complex logic if we add ports with different default coordinates.
     73    switch (m_type) {
     74    case XRReferenceSpaceType::Viewer: {
     75        // Return the current pose. Content rendered in viewer pose will stay in fixed point on HMDs.
     76        auto& data = m_session->frameData();
     77        return WebXRFrame::matrixFromPose(data.origin);
     78    }
     79    case XRReferenceSpaceType::Local:
     80        // Data from the device is already in local, use the identity matrix.
     81        return identity;
     82    case XRReferenceSpaceType::Unbounded:
     83        // Local and unbounded use the same device space, use the identity matrix.
     84        return identity;
     85    case XRReferenceSpaceType::LocalFloor: {
     86        // Use the floor transform provided by the device or fallback to a default height.
     87        return floorOriginTransform();
     88    }
     89    case XRReferenceSpaceType::BoundedFloor:
     90    default:
     91        // BoundedFloor is handled by WebXRBoundedReferenceSpace subclass
     92        RELEASE_ASSERT_NOT_REACHED();
     93    }
     94
     95    return identity;
     96}
     97
     98RefPtr<WebXRReferenceSpace> WebXRReferenceSpace::getOffsetReferenceSpace(const WebXRRigidTransform& offsetTransform)
     99{
     100    auto* document = downcast<Document>(scriptExecutionContext());
     101    if (!document)
    55102        return nullptr;
    56     ASSERT(is<Document>(scriptExecutionContext()));
    57     return create(downcast<Document>(*scriptExecutionContext()), m_session.copyRef(), m_type);
     103
     104    // https://immersive-web.github.io/webxr/#dom-xrreferencespace-getoffsetreferencespace
     105    // Set offsetSpace’s origin offset to the result of multiplying base’s origin offset by originOffset in the relevant realm of base.
     106    auto offset = WebXRRigidTransform::create(originOffset().rawTransform() * offsetTransform.rawTransform());
     107
     108    return create(*document, m_session.copyRef(), WTFMove(offset), m_type);
     109}
     110
     111TransformationMatrix WebXRReferenceSpace::floorOriginTransform() const
     112{
     113    auto& data = m_session->frameData();
     114    if (!data.floorTransform) {
     115        TransformationMatrix defautTransform;
     116        defautTransform.translate3d(0.0, -DefaultUserHeightInMeters, 0.0);
     117        return defautTransform;
     118    }
     119
     120    // https://immersive-web.github.io/webxr/#dom-xrreferencespacetype-local-floor
     121    // Get floor estimation from the device
     122    // FIXME: Round to nearest 1cm to prevent fingerprinting
     123    return WebXRFrame::matrixFromPose(*data.floorTransform);
    58124}
    59125
  • trunk/Source/WebCore/Modules/webxr/WebXRReferenceSpace.h

    r262299 r273132  
    3838class WebXRSession;
    3939
    40 class WebXRReferenceSpace : public WebXRSpace {
     40class WebXRReferenceSpace : public RefCounted<WebXRReferenceSpace>, public WebXRSpace {
    4141    WTF_MAKE_ISO_ALLOCATED(WebXRReferenceSpace);
    4242public:
    4343    static Ref<WebXRReferenceSpace> create(Document&, Ref<WebXRSession>&&, XRReferenceSpaceType);
     44    static Ref<WebXRReferenceSpace> create(Document&, Ref<WebXRSession>&&, Ref<WebXRRigidTransform>&&, XRReferenceSpaceType);
    4445
    4546    virtual ~WebXRReferenceSpace();
    4647
    47     RefPtr<WebXRReferenceSpace> getOffsetReferenceSpace(const WebXRRigidTransform&);
     48    using RefCounted<WebXRReferenceSpace>::ref;
     49    using RefCounted<WebXRReferenceSpace>::deref;
     50
     51    WebXRSession& session() const final { return m_session.get(); }
     52    TransformationMatrix nativeOrigin() const override;
     53    virtual RefPtr<WebXRReferenceSpace> getOffsetReferenceSpace(const WebXRRigidTransform&);
     54    XRReferenceSpaceType type() const { return m_type; }
    4855
    4956protected:
    50     WebXRReferenceSpace(Document&, Ref<WebXRSession>&&, XRReferenceSpaceType);
     57    WebXRReferenceSpace(Document&, Ref<WebXRSession>&&, Ref<WebXRRigidTransform>&&, XRReferenceSpaceType);
    5158
     59    bool isReferenceSpace() const final { return true; }
     60
     61    TransformationMatrix floorOriginTransform() const;
     62
     63    Ref<WebXRSession> m_session;
    5264    XRReferenceSpaceType m_type;
     65
     66private:
     67    void refEventTarget() final { ref(); }
     68    void derefEventTarget() final { deref(); }
    5369};
    5470
    5571} // namespace WebCore
    5672
     73SPECIALIZE_TYPE_TRAITS_WEBXRSPACE(WebXRReferenceSpace, isReferenceSpace())
     74
    5775#endif // ENABLE(WEBXR)
  • trunk/Source/WebCore/Modules/webxr/WebXRReferenceSpace.idl

    r258498 r273132  
    3131    JSGenerateToJSObject,
    3232    JSGenerateToNativeObject,
     33    SkipVTableValidation,
    3334    InterfaceName=XRReferenceSpace
    3435] interface WebXRReferenceSpace : WebXRSpace {
  • trunk/Source/WebCore/Modules/webxr/WebXRSession.cpp

    r272734 r273132  
    2929#if ENABLE(WEBXR)
    3030
     31#include "Document.h"
    3132#include "EventNames.h"
    3233#include "JSWebXRReferenceSpace.h"
     
    3435#include "WebXRFrame.h"
    3536#include "WebXRSystem.h"
     37#include "WebXRView.h"
    3638#include "XRFrameRequestCallback.h"
    3739#include "XRRenderStateInit.h"
     
    5658    , m_device(makeWeakPtr(device))
    5759    , m_activeRenderState(WebXRRenderState::create(mode))
     60    , m_viewerReferenceSpace(makeUnique<WebXRViewerSpace>(document, *this))
    5861    , m_timeOrigin(MonotonicTime::now())
     62    , m_views(device.views(mode))
    5963{
    6064    m_device->initializeTrackingAndRendering(mode);
     
    479483
    480484    // Queue a task to perform the following steps.
    481     queueTaskKeepingObjectAlive(*this, TaskSource::WebXR, [this, frameData = WTFMove(frameData)]() {
     485    queueTaskKeepingObjectAlive(*this, TaskSource::WebXR, [this, frameData = WTFMove(frameData)]() mutable {
    482486        if (m_ended)
    483487            return;
     488
     489        m_frameData = frameData;
    484490        //  1.Let now be the current high resolution time.
    485491        auto now = (MonotonicTime::now() - m_timeOrigin).milliseconds();
    486492
    487         auto frame = WebXRFrame::create(makeRef(*this));
     493        auto frame = WebXRFrame::create(makeRef(*this), WebXRFrame::IsAnimationFrame::Yes);
    488494        //  2.Let frame be session’s animation frame.
    489495        //  3.Set frame’s time to frameTime.
     
    509515
    510516            // 6.4.Apply frame updates for frame.
    511             // FIXME: implement.
     517            frame->setFrameData(WTFMove(frameData));
    512518
    513519            // 6.5.For each entry in session’s list of currently running animation frame callbacks, in order:
     
    538544}
    539545
     546// https://immersive-web.github.io/webxr/#poses-may-be-reported
     547bool WebXRSession::posesCanBeReported(const Document& document) const
     548{
     549    // 1. If session’s relevant global object is not the current global object, return false.
     550    auto* sessionDocument = downcast<Document>(scriptExecutionContext());
     551    if (!sessionDocument || sessionDocument->domWindow() != document.domWindow())
     552        return false;
     553
     554    // 2. If session's visibilityState in not "visible", return false.
     555    if (m_visibilityState != XRVisibilityState::Visible)
     556        return false;
     557
     558    // 5. Determine if the pose data can be returned as follows:
     559    // The procedure in the specs tries to ensure that we apply measures to
     560    // prevent fingerprintint in pose data and return false in case we don't.
     561    // We're going to apply them so let's just return true.
     562    return true;
     563}
     564
    540565} // namespace WebCore
    541566
  • trunk/Source/WebCore/Modules/webxr/WebXRSession.h

    r272734 r273132  
    3434#include "WebXRInputSourceArray.h"
    3535#include "WebXRRenderState.h"
    36 #include "WebXRSpace.h"
    3736#include "XREnvironmentBlendMode.h"
    3837#include "XRInteractionMode.h"
     
    4948
    5049class XRFrameRequestCallback;
    51 class WebXRReferenceSpace;
    5250class WebXRSystem;
     51class WebXRView;
     52class WebXRViewerSpace;
    5353struct XRRenderStateInit;
    5454
     
    9191    XRSessionMode mode() const { return m_mode; }
    9292
     93    const Vector<PlatformXR::Device::ViewData>& views() const { return m_views; }
     94    const PlatformXR::Device::FrameData& frameData() const { return m_frameData; }
     95    const WebXRViewerSpace& viewerReferenceSpace() const { return *m_viewerReferenceSpace; }
     96    bool posesCanBeReported(const Document&) const;
     97
    9398private:
    9499    WebXRSession(Document&, WebXRSystem&, XRSessionMode, PlatformXR::Device&);
     
    129134    RefPtr<WebXRRenderState> m_activeRenderState;
    130135    RefPtr<WebXRRenderState> m_pendingRenderState;
     136    std::unique_ptr<WebXRViewerSpace> m_viewerReferenceSpace;
    131137    MonotonicTime m_timeOrigin;
    132138
    133139    unsigned m_nextCallbackId { 1 };
    134140    Vector<Ref<XRFrameRequestCallback>> m_callbacks;
     141
     142    Vector<PlatformXR::Device::ViewData> m_views;
     143    PlatformXR::Device::FrameData m_frameData;
    135144
    136145    double m_minimumInlineFOV { 0.0 };
  • trunk/Source/WebCore/Modules/webxr/WebXRSpace.cpp

    r262300 r273132  
    2929#if ENABLE(WEBXR)
    3030
     31#include "DOMPointReadOnly.h"
    3132#include "Document.h"
     33#include "WebXRRigidTransform.h"
    3234#include "WebXRSession.h"
    3335#include <wtf/IsoMallocInlines.h>
     
    3739WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRSpace);
    3840
    39 WebXRSpace::WebXRSpace(Document& document, Ref<WebXRSession>&& session)
     41WebXRSpace::WebXRSpace(Document& document, Ref<WebXRRigidTransform>&& offset)
    4042    : ContextDestructionObserver(&document)
    41     , m_session(WTFMove(session))
     43    , m_originOffset(WTFMove(offset))
    4244{
    4345}
     
    4547WebXRSpace::~WebXRSpace() = default;
    4648
     49TransformationMatrix WebXRSpace::effectiveOrigin() const
     50{
     51    // https://immersive-web.github.io/webxr/#xrspace-effective-origin
     52    // The effective origin can be obtained by multiplying origin offset and the native origin.
     53    return m_originOffset->rawTransform() * nativeOrigin();
     54}
     55
     56
     57WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRViewerSpace);
     58
     59WebXRViewerSpace::WebXRViewerSpace(Document& document, WebXRSession& session)
     60    : WebXRSpace(document, WebXRRigidTransform::create())
     61    , m_session(session)
     62{
     63}
     64
     65WebXRViewerSpace::~WebXRViewerSpace() = default;
     66
     67TransformationMatrix WebXRViewerSpace::nativeOrigin() const
     68{
     69    return WebXRFrame::matrixFromPose(m_session.frameData().origin);
     70}
     71
     72
    4773} // namespace WebCore
    4874
  • trunk/Source/WebCore/Modules/webxr/WebXRSpace.h

    r262299 r273132  
    3030#include "ContextDestructionObserver.h"
    3131#include "EventTarget.h"
     32#include "TransformationMatrix.h"
    3233#include <wtf/RefCounted.h>
    3334
     
    3637class Document;
    3738class ScriptExecutionContext;
     39class WebXRRigidTransform;
    3840class WebXRSession;
    3941
    40 class WebXRSpace : public RefCounted<WebXRSpace>, public EventTargetWithInlineData, public ContextDestructionObserver {
     42class WebXRSpace : public EventTargetWithInlineData, public ContextDestructionObserver {
    4143    WTF_MAKE_ISO_ALLOCATED(WebXRSpace);
    4244public:
    4345    virtual ~WebXRSpace();
    4446
    45     using RefCounted<WebXRSpace>::ref;
    46     using RefCounted<WebXRSpace>::deref;
     47    virtual WebXRSession& session() const = 0;
     48    virtual TransformationMatrix nativeOrigin() const = 0;
     49    TransformationMatrix effectiveOrigin() const;
     50
     51    virtual bool isReferenceSpace() const { return false; }
     52    virtual bool isBoundedReferenceSpace() const { return false; }
    4753
    4854protected:
    49     WebXRSpace(Document&, Ref<WebXRSession>&&);
     55    WebXRSpace(Document&, Ref<WebXRRigidTransform>&&);
     56
     57    const WebXRRigidTransform& originOffset() const { return m_originOffset.get(); }
    5058
    5159    // EventTarget
    52     ScriptExecutionContext* scriptExecutionContext() const override { return ContextDestructionObserver::scriptExecutionContext(); }
    53 
    54     Ref<WebXRSession> m_session;
     60    ScriptExecutionContext* scriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); }
    5561
    5662private:
    5763    // EventTarget
    58     EventTargetInterface eventTargetInterface() const override { return WebXRSpaceEventTargetInterfaceType; }
    59     void refEventTarget() override { ref(); }
    60     void derefEventTarget() override { deref(); }
     64    EventTargetInterface eventTargetInterface() const final { return WebXRSpaceEventTargetInterfaceType; }
     65
     66    Ref<WebXRRigidTransform> m_originOffset;
     67};
     68
     69// https://immersive-web.github.io/webxr/#xrsession-viewer-reference-space
     70// This is a helper class to implement the viewer space owned by a WebXRSession.
     71// It avoids a circular reference between the session and the reference space.
     72class WebXRViewerSpace : public WebXRSpace {
     73    WTF_MAKE_ISO_ALLOCATED(WebXRViewerSpace);
     74public:
     75    WebXRViewerSpace(Document&, WebXRSession&);
     76    virtual ~WebXRViewerSpace();
     77
     78private:
     79    WebXRSession& session() const final { return m_session; }
     80    TransformationMatrix nativeOrigin() const final;
     81
     82    void refEventTarget() final { RELEASE_ASSERT_NOT_REACHED(); }
     83    void derefEventTarget() final { RELEASE_ASSERT_NOT_REACHED(); }
     84
     85    WebXRSession& m_session;
    6186};
    6287
    6388} // namespace WebCore
    6489
     90#define SPECIALIZE_TYPE_TRAITS_WEBXRSPACE(ToValueTypeName, predicate) \
     91SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \
     92    static bool isType(const WebCore::WebXRSpace& context) { return context.predicate; } \
     93SPECIALIZE_TYPE_TRAITS_END()
     94
    6595#endif // ENABLE(WEBXR)
  • trunk/Source/WebCore/Modules/webxr/WebXRSystem.cpp

    r272734 r273132  
    522522
    523523    auto raf = InlineRequestAnimationFrameCallback::create(*m_scriptExecutionContext, [callback = WTFMove(callback)]() mutable {
    524         callback({ });
     524        PlatformXR::Device::FrameData data;
     525        data.isTrackingValid = true;
     526        data.isPositionValid = true;
     527        data.views.append({ });
     528        callback(WTFMove(data));
    525529    });
    526530
     
    528532}
    529533
     534Vector<PlatformXR::Device::ViewData> WebXRSystem::DummyInlineDevice::views(XRSessionMode) const
     535{
     536    return { { .active = true, PlatformXR::Eye::None } };
     537}
     538
    530539
    531540} // namespace WebCore
  • trunk/Source/WebCore/Modules/webxr/WebXRSystem.h

    r272734 r273132  
    112112        void initializeTrackingAndRendering(PlatformXR::SessionMode) final { }
    113113        void shutDownTrackingAndRendering() final { }
    114         void initializeReferenceSpace(PlatformXR::ReferenceSpaceType) final { };
     114        void initializeReferenceSpace(PlatformXR::ReferenceSpaceType) final { }
    115115
    116116        void requestFrame(PlatformXR::Device::RequestFrameCallback&&) final;
     117        Vector<Device::ViewData> views(XRSessionMode) const final;
    117118    };
    118119    DummyInlineDevice m_defaultInlineDevice;
  • trunk/Source/WebCore/Modules/webxr/WebXRView.cpp

    r260884 r273132  
    3737WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRView);
    3838
    39 Ref<WebXRView> WebXRView::create()
     39Ref<WebXRView> WebXRView::create(XREye eye, Ref<WebXRRigidTransform>&& transform, Ref<Float32Array>&& projection)
    4040{
    41     return adoptRef(*new WebXRView);
     41    return adoptRef(*new WebXRView(eye, WTFMove(transform), WTFMove(projection)));
    4242}
    4343
    44 WebXRView::WebXRView()
    45     : m_eye(XREye::None)
     44WebXRView::WebXRView(XREye eye, Ref<WebXRRigidTransform>&& transform, Ref<Float32Array>&& projection)
     45    : m_eye(eye)
     46    , m_transform(WTFMove(transform))
     47    , m_projection(projection)
    4648{
    4749}
     
    4951WebXRView::~WebXRView() = default;
    5052
    51 void WebXRView::setProjectionMatrix(const Vector<float>& matrix)
    52 {
    53     m_projectionMatrix = Float32Array::create(matrix.data(), matrix.size());
    54 }
    55 
    5653} // namespace WebCore
    5754
  • trunk/Source/WebCore/Modules/webxr/WebXRView.h

    r270067 r273132  
    3838namespace WebCore {
    3939
     40class WebXRFrame;
    4041class WebXRRigidTransform;
    4142
     
    4344    WTF_MAKE_ISO_ALLOCATED_EXPORT(WebXRView, WEBCORE_EXPORT);
    4445public:
    45     WEBCORE_EXPORT static Ref<WebXRView> create();
     46    WEBCORE_EXPORT static Ref<WebXRView> create(XREye, Ref<WebXRRigidTransform>&&, Ref<Float32Array>&&);
    4647    WEBCORE_EXPORT ~WebXRView();
    4748
    4849    XREye eye() const { return m_eye; }
    49     const Float32Array& projectionMatrix() const { return *m_projectionMatrix; }
    50     const WebXRRigidTransform& transform() const { return *m_transform; }
    51 
    52     void setEye(XREye eye) { m_eye = eye; }
    53     WEBCORE_EXPORT void setProjectionMatrix(const Vector<float>&);
    54     void setTransform(RefPtr<WebXRRigidTransform>&& viewOffset) { m_transform = WTFMove(viewOffset); }
     50    const Float32Array& projectionMatrix() const { return m_projection.get(); }
     51    const WebXRRigidTransform& transform() const { return m_transform.get(); }
    5552
    5653private:
    57     WebXRView();
     54    WebXRView(XREye, Ref<WebXRRigidTransform>&&, Ref<Float32Array>&&);
    5855
    5956    XREye m_eye;
    60     RefPtr<Float32Array> m_projectionMatrix;
    61     RefPtr<WebXRRigidTransform> m_transform;
     57    Ref<WebXRRigidTransform> m_transform;
     58    Ref<Float32Array> m_projection;
    6259};
    6360
  • trunk/Source/WebCore/Modules/webxr/WebXRViewerPose.cpp

    r258498 r273132  
    2626#include "config.h"
    2727#include "WebXRViewerPose.h"
     28#include <wtf/IsoMallocInlines.h>
    2829
    2930#if ENABLE(WEBXR)
     
    3132namespace WebCore {
    3233
    33 Ref<WebXRViewerPose> WebXRViewerPose::create()
     34WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRViewerPose);
     35
     36Ref<WebXRViewerPose> WebXRViewerPose::create(Ref<WebXRRigidTransform>&& transform, bool emulatedPosition)
    3437{
    35     return adoptRef(*new WebXRViewerPose);
     38    return adoptRef(*new WebXRViewerPose(WTFMove(transform), emulatedPosition));
    3639}
    3740
    38 WebXRViewerPose::WebXRViewerPose() = default;
     41WebXRViewerPose::WebXRViewerPose(Ref<WebXRRigidTransform>&& transform, bool emulatedPosition)
     42    : WebXRPose(WTFMove(transform), emulatedPosition)
     43{
     44}
     45
    3946WebXRViewerPose::~WebXRViewerPose() = default;
    4047
     
    4451}
    4552
     53void WebXRViewerPose::setViews(Vector<Ref<WebXRView>>&& views)
     54{
     55    m_views = WTFMove(views);
     56}
     57
    4658} // namespace WebCore
    4759
  • trunk/Source/WebCore/Modules/webxr/WebXRViewerPose.h

    r258498 r273132  
    3838
    3939class WebXRViewerPose : public WebXRPose {
     40    WTF_MAKE_ISO_ALLOCATED(WebXRViewerPose);
    4041public:
    41     static Ref<WebXRViewerPose> create();
    42     ~WebXRViewerPose();
     42    static Ref<WebXRViewerPose> create(Ref<WebXRRigidTransform>&&, bool emulatedPosition);
     43    virtual ~WebXRViewerPose();
    4344
    4445    const Vector<Ref<WebXRView>>& views() const;
     46    void setViews(Vector<Ref<WebXRView>>&&);
    4547
    4648private:
    47     WebXRViewerPose();
     49    WebXRViewerPose(Ref<WebXRRigidTransform>&&, bool emulatedPosition);
     50
     51    bool isViewerPose() const final { return true; }
    4852
    4953    Vector<Ref<WebXRView>> m_views;
     
    5256} // namespace WebCore
    5357
     58SPECIALIZE_TYPE_TRAITS_WEBXRPOSE(WebXRViewerPose, isViewerPose())
     59
    5460#endif // ENABLE(WEBXR)
  • trunk/Source/WebCore/Modules/webxr/WebXRViewerPose.idl

    r258498 r273132  
    2929    SecureContext,
    3030    Exposed=Window,
    31     ImplementationLacksVTable,
     31    JSGenerateToJSObject,
     32    JSGenerateToNativeObject,
    3233    InterfaceName=XRViewerPose
    3334] interface WebXRViewerPose : WebXRPose {
  • trunk/Source/WebCore/Modules/webxr/XREye.h

    r258498 r273132  
    2828#if ENABLE(WEBXR)
    2929
     30#include "PlatformXR.h"
     31
    3032namespace WebCore {
    3133
    32 enum class XREye {
    33     None,
    34     Left,
    35     Right,
    36 };
     34using XREye = PlatformXR::Eye;
    3735
    3836} // namespace WebCore
  • trunk/Source/WebCore/platform/graphics/transforms/TransformationMatrix.cpp

    r271941 r273132  
    585585TransformationMatrix TransformationMatrix::fromQuaternion(double qx, double qy, double qz, double qw)
    586586{
    587     const double xx = qx * qx;
    588     const double yy = qy * qy;
    589     const double zz = qz * qz;
    590     const double xz = qx * qz;
    591     const double xy = qx * qy;
    592     const double yz = qy * qz;
    593     const double xw = qw * qx;
    594     const double yw = qw * qy;
    595     const double zw = qw * qz;
     587    double xx = qx * qx;
     588    double yy = qy * qy;
     589    double zz = qz * qz;
     590    double xz = qx * qz;
     591    double xy = qx * qy;
     592    double yz = qy * qz;
     593    double xw = qw * qx;
     594    double yw = qw * qy;
     595    double zw = qw * qz;
    596596
    597597    return TransformationMatrix(1 - 2 * (yy + zz), 2 * (xy + zw), 2 * (xz - yw), 0,
     
    599599        2 * (xz + yw), 2 * (yz - xw), 1 - 2 * (xx + yy), 0,
    600600        0, 0, 0, 1);
     601}
     602
     603
     604TransformationMatrix TransformationMatrix::fromProjection(double fovUp, double fovDown, double fovLeft, double fovRight, double depthNear, double depthFar)
     605{
     606    double upTan = tan(fovUp);
     607    double downTan = tan(fovDown);
     608    double leftTan = tan(fovLeft);
     609    double rightTan = tan(fovRight);
     610    double xScale = 2.0 / (leftTan + rightTan);
     611    double yScale = 2.0 / (upTan + downTan);
     612    double invDepth = 1.0 / (depthNear - depthFar);
     613
     614    return TransformationMatrix(xScale, 0.0f, 0.0f, 0.0f,
     615        0.0f, yScale, 0.0f, 0.0f,
     616        (leftTan - rightTan) * xScale * -0.5, (upTan - downTan) * yScale * 0.5, (depthNear + depthFar) * invDepth, -1.0f,
     617        0.0f, 0.0f, (2.0f * depthFar * depthNear) * invDepth, 0.0f);
     618}
     619
     620TransformationMatrix TransformationMatrix::fromProjection(double fovy, double aspect, double depthNear, double depthFar)
     621{
     622    double f = 1.0f / tanf(fovy / 2);
     623    double invDepth = 1.0f / (depthNear - depthFar);
     624
     625    return TransformationMatrix(f / aspect, 0.0f, 0.0f, 0.0f,
     626        0.0f, f, 0.0f, 0.0f,
     627        0.0f, 0.0f, (depthFar + depthNear) * invDepth, -1.0f,
     628        0.0f, 0.0f, (2.0f * depthFar * depthNear) * invDepth, 0.0f);
    601629}
    602630
  • trunk/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h

    r271941 r273132  
    121121
    122122    static TransformationMatrix fromQuaternion(double qx, double qy, double qz, double qw);
     123
     124    // Field of view in radians
     125    static TransformationMatrix fromProjection(double fovUp, double fovDown, double fovLeft, double fovRight, double depthNear, double depthFar);
     126    static TransformationMatrix fromProjection(double fovy, double aspect, double depthNear, double depthFar);
    123127
    124128    static const TransformationMatrix identity;
  • trunk/Source/WebCore/platform/xr/PlatformXR.h

    r272734 r273132  
    2525#include <wtf/HashMap.h>
    2626#include <wtf/UniqueRef.h>
     27#include <wtf/Variant.h>
    2728#include <wtf/Vector.h>
    2829#include <wtf/WeakPtr.h>
     
    4243    BoundedFloor,
    4344    Unbounded
     45};
     46
     47enum class Eye {
     48    None,
     49    Left,
     50    Right,
    4451};
    4552
     
    8087
    8188    struct FrameData {
    82         long predictedDisplayTime;
    83         struct ViewData {
    84             struct {
    85                 WebCore::FloatPoint3D position;
    86                 struct {
    87                     float x;
    88                     float y;
    89                     float z;
    90                     float w;
    91                 } orientation;
    92             } pose;
    93             struct {
    94                 float rUp;
    95                 float rDown;
    96                 float rLeft;
    97                 float rRight;
    98             } fov;
     89        struct FloatQuaternion {
     90            float x { 0.0f };
     91            float y { 0.0f };
     92            float z { 0.0f };
     93            float w { 1.0f };
    9994        };
    100         Vector<ViewData> viewPoses;
     95
     96        struct Pose {
     97            WebCore::FloatPoint3D position;
     98            FloatQuaternion orientation;
     99        };
     100
     101        struct Fov {
     102            // In radians
     103            float up { 0.0f };
     104            float down { 0.0f };
     105            float left { 0.0f };
     106            float right { 0.0f };
     107        };
     108
     109        using Projection = Variant<Fov, std::array<float, 16>, std::nullptr_t>;
     110
     111        struct View {
     112            Pose offset;
     113            Projection projection = { nullptr };
     114        };
     115
     116        bool isTrackingValid { false };
     117        bool isPositionValid { false };
     118        bool isPositionEmulated { false };
     119        long predictedDisplayTime { 0 };
     120        Pose origin;
     121        Optional<Pose> floorTransform;
     122        Vector<View> views;
    101123    };
     124
     125    struct ViewData {
     126        bool active { false };
     127        Eye eye { Eye::None };
     128    };
     129
     130    virtual Vector<ViewData> views(SessionMode) const = 0;
     131
    102132    using RequestFrameCallback = Function<void(FrameData&&)>;
    103133    virtual void requestFrame(RequestFrameCallback&&) = 0;
    104 
    105134protected:
    106135    Device() = default;
  • trunk/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.cpp

    r272734 r273132  
    300300}
    301301
     302XrSpace OpenXRDevice::createReferenceSpace(XrReferenceSpaceType type)
     303{
     304    ASSERT(&RunLoop::current() == &m_queue.runLoop());
     305    ASSERT(m_session != XR_NULL_HANDLE);
     306    ASSERT(m_instance != XR_NULL_HANDLE);
     307
     308    XrPosef identityPose {
     309        .orientation = { .x = 0, .y = 0, .z = 0, .w = 1.0 },
     310        .position = { .x = 0, .y = 0, .z = 0 }
     311    };
     312
     313    auto spaceCreateInfo = createStructure<XrReferenceSpaceCreateInfo, XR_TYPE_REFERENCE_SPACE_CREATE_INFO>();
     314    spaceCreateInfo.referenceSpaceType = type;
     315    spaceCreateInfo.poseInReferenceSpace = identityPose;
     316
     317    XrSpace space;
     318    auto result = xrCreateReferenceSpace(m_session, &spaceCreateInfo, &space);
     319    RETURN_IF_FAILED(result, "xrCreateReferenceSpace", m_instance, XR_NULL_HANDLE);
     320
     321    return space;
     322}
     323
    302324void OpenXRDevice::collectSupportedSessionModes()
    303325{
     
    369391}
    370392
    371 WebCore::IntSize OpenXRDevice::recommendedResolution(SessionMode mode)
    372 {
    373     auto configType = mode == SessionMode::Inline ? XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO : XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
    374     auto viewsIterator = m_configurationViews.find(configType);
    375     if (viewsIterator != m_configurationViews.end())
    376         return { static_cast<int>(viewsIterator->value[0].recommendedImageRectWidth), static_cast<int>(viewsIterator->value[0].recommendedImageRectHeight) };
    377     return Device::recommendedResolution(mode);
    378 }
    379 
    380393XrViewConfigurationType toXrViewConfigurationType(SessionMode mode)
    381394{
     
    401414}
    402415
     416WebCore::IntSize OpenXRDevice::recommendedResolution(SessionMode mode)
     417{
     418    auto configType = toXrViewConfigurationType(mode);
     419    auto viewsIterator = m_configurationViews.find(configType);
     420    if (viewsIterator != m_configurationViews.end())
     421        return { static_cast<int>(viewsIterator->value[0].recommendedImageRectWidth), static_cast<int>(viewsIterator->value[0].recommendedImageRectHeight) };
     422    return Device::recommendedResolution(mode);
     423}
     424
    403425void OpenXRDevice::initializeTrackingAndRendering(SessionMode mode)
    404426{
     
    415437        auto result = xrCreateSession(m_instance, &sessionCreateInfo, &m_session);
    416438        RETURN_IF_FAILED(result, "xrEnumerateInstanceExtensionProperties", m_instance);
     439
     440        m_localSpace = createReferenceSpace(XR_REFERENCE_SPACE_TYPE_LOCAL);
     441        m_viewSpace = createReferenceSpace(XR_REFERENCE_SPACE_TYPE_VIEW);
    417442    });
    418443}
     
    456481        waitUntilStopping();
    457482    });
     483}
     484
     485void OpenXRDevice::initializeReferenceSpace(PlatformXR::ReferenceSpaceType spaceType)
     486{
     487    if ((spaceType == ReferenceSpaceType::LocalFloor || spaceType == ReferenceSpaceType::BoundedFloor) && m_stageSpace == XR_NULL_HANDLE)
     488        m_stageSpace = createReferenceSpace(XR_REFERENCE_SPACE_TYPE_STAGE);
    458489}
    459490
     
    527558}
    528559
    529 
    530 Device::FrameData::ViewData xrViewToViewData(XrView view)
    531 {
    532     Device::FrameData::ViewData data;
    533     data.fov = { view.fov.angleUp, view.fov.angleDown, view.fov.angleLeft, view.fov.angleRight };
    534     data.pose.orientation = { view.pose.orientation.x, view.pose.orientation.y, view.pose.orientation.z, view.pose.orientation.w };
    535     data.pose.position = { view.pose.position.x, view.pose.position.y, view.pose.position.z };
    536     return data;
     560static Device::FrameData::Pose XrPosefToPose(XrPosef pose)
     561{
     562    Device::FrameData::Pose result;
     563    result.orientation = { pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w };
     564    result.position = { pose.position.x, pose.position.y, pose.position.z };
     565    return result;
     566}
     567
     568static Device::FrameData::View xrViewToPose(XrView view)
     569{
     570    Device::FrameData::View pose;
     571    pose.projection = Device::FrameData::Fov { view.fov.angleUp, view.fov.angleDown, view.fov.angleLeft, view.fov.angleRight };
     572    pose.offset = XrPosefToPose(view.pose);
     573    return pose;
    537574}
    538575
     
    563600
    564601        if (isSessionActive(m_sessionState)) {
     602            // Query head location
     603            auto location = createStructure<XrSpaceLocation, XR_TYPE_SPACE_LOCATION>();
     604            xrLocateSpace(m_viewSpace, m_localSpace, frameState.predictedDisplayTime, &location);
     605            frameData.isTrackingValid = location.locationFlags & XR_SPACE_LOCATION_ORIENTATION_VALID_BIT;
     606            frameData.isPositionValid = location.locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT;
     607            frameData.isPositionEmulated = location.locationFlags & XR_SPACE_LOCATION_POSITION_TRACKED_BIT;
     608
     609            if (frameData.isTrackingValid)
     610                frameData.origin = XrPosefToPose(location.pose);
     611           
    565612            ASSERT(m_configurationViews.contains(m_currentViewConfigurationType));
    566613            const auto& configurationView = m_configurationViews.get(m_currentViewConfigurationType);
     
    568615            auto viewLocateInfo = createStructure<XrViewLocateInfo, XR_TYPE_VIEW_LOCATE_INFO>();
    569616            viewLocateInfo.displayTime = predictedTime;
    570             // FIXME: use the current reference space.
    571             // viewLocateInfo.space = m_localSpace;
     617            viewLocateInfo.space = m_localSpace;
    572618
    573619            uint32_t viewCount = configurationView.size();
     
    584630            if (!XR_FAILED(result)) {
    585631                for (auto& view : views)
    586                     frameData.viewPoses.append(xrViewToViewData(view));
     632                    frameData.views.append(xrViewToPose(view));
     633            }
     634
     635            // Query floor transform
     636            if (m_stageSpace != XR_NULL_HANDLE) {
     637                auto floorLocation = createStructure<XrSpaceLocation, XR_TYPE_SPACE_LOCATION>();
     638                xrLocateSpace(m_stageSpace, m_localSpace, frameState.predictedDisplayTime, &floorLocation);
     639                frameData.floorTransform = { XrPosefToPose(floorLocation.pose) };
    587640            }
    588641        }
     
    601654}
    602655
     656Vector<Device::ViewData> OpenXRDevice::views(SessionMode mode) const
     657{
     658    Vector<Device::ViewData> views;
     659    auto configurationType = toXrViewConfigurationType(mode);
     660
     661    if (configurationType == XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO)
     662        views.append({ .active = true, .eye = Eye::None });
     663    else {
     664        ASSERT(configurationType == XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO);
     665        views.append({ .active = true, Eye::Left });
     666        views.append({ .active = true, Eye::Right });
     667    }
     668    return views;
     669}
     670
    603671} // namespace PlatformXR
    604672
  • trunk/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.h

    r272734 r273132  
    5252
    5353    ListOfEnabledFeatures enumerateReferenceSpaces(XrSession&) const;
    54     void initializeReferenceSpace(ReferenceSpaceType) final { };
     54    XrSpace createReferenceSpace(XrReferenceSpaceType);
    5555
    5656    WebCore::IntSize recommendedResolution(SessionMode) final;
     
    5858    void initializeTrackingAndRendering(SessionMode) final;
    5959    void shutDownTrackingAndRendering() final;
     60    void initializeReferenceSpace(PlatformXR::ReferenceSpaceType) final;
    6061    bool supportsSessionShutdownNotification() const final { return true; }
    6162    void waitUntilStopping();
     
    6869
    6970    void requestFrame(RequestFrameCallback&&) final;
     71
     72    Vector<ViewData> views(SessionMode) const final;
    7073
    7174    using ViewConfigurationPropertiesMap = HashMap<XrViewConfigurationType, XrViewConfigurationProperties, IntHash<XrViewConfigurationType>, WTF::StrongEnumHashTraits<XrViewConfigurationType>>;
     
    8285
    8386    XrViewConfigurationType m_currentViewConfigurationType;
     87    XrSpace m_localSpace { XR_NULL_HANDLE };
     88    XrSpace m_viewSpace { XR_NULL_HANDLE };
     89    XrSpace m_stageSpace { XR_NULL_HANDLE };
    8490};
    8591
  • trunk/Source/WebCore/testing/WebFakeXRDevice.cpp

    r272734 r273132  
    3333#include "WebFakeXRInputController.h"
    3434#include <wtf/CompletionHandler.h>
     35#include <wtf/MathExtras.h>
    3536
    3637namespace WebCore {
     
    3839static constexpr Seconds FakeXRFrameTime = 15_ms;
    3940
    40 void FakeXRView::setFieldOfView(FakeXRViewInit::FieldOfViewInit fov)
    41 {
    42     m_fov = fov;
     41void FakeXRView::setProjection(const Vector<float>& projection)
     42{
     43    std::copy(std::begin(projection), std::end(projection), std::begin(m_projection));
     44}
     45
     46void FakeXRView::setFieldOfView(const FakeXRViewInit::FieldOfViewInit& fov)
     47{
     48    m_fov = PlatformXR::Device::FrameData::Fov { deg2rad(fov.upDegrees), deg2rad(fov.downDegrees), deg2rad(fov.leftDegrees), deg2rad(fov.rightDegrees) };
    4349}
    4450
     
    7581void SimulatedXRDevice::frameTimerFired()
    7682{
    77     auto callbacks = WTFMove(m_callbacks);
    78     for (auto& callback : callbacks)
    79         callback({ });
     83    auto updates = WTFMove(m_pendingUpdates);
     84    for (auto& update : updates)
     85        update();
     86
     87    FrameData data;
     88    if (m_viewerOrigin) {
     89        data.origin = *m_viewerOrigin;
     90        data.isTrackingValid = true;
     91        data.isPositionValid = true;
     92    }
     93
     94    if (m_floorOrigin)
     95        data.floorTransform = { *m_floorOrigin };
     96
     97    for (auto& fakeView : m_views) {
     98        FrameData::View view;
     99        view.offset = fakeView->offset();
     100        if (fakeView->fieldOfView().hasValue())
     101            view.projection = { *fakeView->fieldOfView() };
     102        else
     103            view.projection = { fakeView->projection() };
     104       
     105        data.views.append(view);
     106    }
     107
     108    if (m_FrameCallback)
     109        m_FrameCallback(WTFMove(data));
    80110}
    81111
    82112void SimulatedXRDevice::requestFrame(RequestFrameCallback&& callback)
    83113{
    84     m_callbacks.append(WTFMove(callback));
     114    m_FrameCallback = WTFMove(callback);
    85115    if (!m_frameTimer.isActive())
    86116        m_frameTimer.startOneShot(FakeXRFrameTime);
    87117}
    88118
     119Vector<PlatformXR::Device::ViewData> SimulatedXRDevice::views(PlatformXR::SessionMode mode) const
     120{
     121    if (mode == PlatformXR::SessionMode::ImmersiveVr)
     122        return { { .active = true, PlatformXR::Eye::Left }, { .active = true, PlatformXR::Eye::Right } };
     123
     124    return { { .active = true, PlatformXR::Eye::None } };
     125}
     126
     127void SimulatedXRDevice::scheduleOnNextFrame(Function<void()>&& func)
     128{
     129    m_pendingUpdates.append(WTFMove(func));
     130}
     131
    89132WebFakeXRDevice::WebFakeXRDevice() = default;
    90133
    91134void WebFakeXRDevice::setViews(const Vector<FakeXRViewInit>& views)
    92135{
    93     Vector<Ref<FakeXRView>>& deviceViews = m_device.views();
    94     deviceViews.clear();
    95 
    96     // TODO: do in next animation frame.
    97     for (auto& viewInit : views) {
    98         auto view = parseView(viewInit);
    99         if (!view.hasException())
    100             deviceViews.append(view.releaseReturnValue());
    101     }
     136    m_device.scheduleOnNextFrame([this, views]() {
     137        Vector<Ref<FakeXRView>> deviceViews;
     138
     139        for (auto& viewInit : views) {
     140            auto view = parseView(viewInit);
     141            if (!view.hasException())
     142                deviceViews.append(view.releaseReturnValue());
     143        }
     144
     145        m_device.setViews(WTFMove(deviceViews));
     146    });
    102147}
    103148
     
    109154void WebFakeXRDevice::setViewerOrigin(FakeXRRigidTransformInit origin, bool emulatedPosition)
    110155{
    111     auto rigidTransform = parseRigidTransform(origin);
    112     if (rigidTransform.hasException())
     156    auto result = parseRigidTransform(origin);
     157    if (result.hasException())
    113158        return;
    114159
    115     // TODO: do in next animation frame.
    116     m_device.setViewerOrigin(rigidTransform.releaseReturnValue());
    117     m_device.setEmulatedPosition(emulatedPosition);
     160    auto pose = result.releaseReturnValue();
     161
     162    m_device.scheduleOnNextFrame([this, pose = WTFMove(pose), emulatedPosition]() mutable {
     163        m_device.setViewerOrigin(WTFMove(pose));
     164        m_device.setEmulatedPosition(emulatedPosition);
     165    });
    118166}
    119167
    120168void WebFakeXRDevice::clearViewerOrigin()
    121169{
    122     // TODO: do in next animation frame.
    123     m_device.setViewerOrigin(nullptr);
     170    m_device.scheduleOnNextFrame([this]() {
     171        m_device.setViewerOrigin(WTF::nullopt);
     172    });
    124173}
    125174
     
    128177}
    129178
    130 void WebFakeXRDevice::setBoundsGeometry(Vector<FakeXRBoundsPoint>)
     179void WebFakeXRDevice::setBoundsGeometry(Vector<FakeXRBoundsPoint>&&)
    131180{
    132181}
     
    134183void WebFakeXRDevice::setFloorOrigin(FakeXRRigidTransformInit origin)
    135184{
    136     auto rigidTransform = parseRigidTransform(origin);
    137     if (rigidTransform.hasException())
     185    auto result = parseRigidTransform(origin);
     186    if (result.hasException())
    138187        return;
    139188
    140     // TODO: do in next animation frame.
    141     m_device.setFloorOrigin(rigidTransform.releaseReturnValue());
     189    auto pose = result.releaseReturnValue();
     190
     191    m_device.scheduleOnNextFrame([this, pose = WTFMove(pose)]() mutable {
     192        m_device.setFloorOrigin(WTFMove(pose));
     193    });
    142194}
    143195
    144196void WebFakeXRDevice::clearFloorOrigin()
    145197{
    146     // TODO: do in next animation frame.
    147     m_device.setFloorOrigin(nullptr);
     198    m_device.scheduleOnNextFrame([this]() {
     199        m_device.setFloorOrigin(WTF::nullopt);
     200    });
    148201}
    149202
     
    157210}
    158211
    159 ExceptionOr<Ref<WebXRRigidTransform>> WebFakeXRDevice::parseRigidTransform(const FakeXRRigidTransformInit& init)
     212ExceptionOr<PlatformXR::Device::FrameData::Pose> WebFakeXRDevice::parseRigidTransform(const FakeXRRigidTransformInit& init)
    160213{
    161214    if (init.position.size() != 3 || init.orientation.size() != 4)
    162215        return Exception { TypeError };
    163216
    164     DOMPointInit position;
    165     position.x = init.position[0];
    166     position.y = init.position[1];
    167     position.z = init.position[2];
    168 
    169     DOMPointInit orientation;
    170     orientation.x = init.orientation[0];
    171     orientation.y = init.orientation[1];
    172     orientation.z = init.orientation[2];
    173     orientation.w = init.orientation[3];
    174 
    175     return WebXRRigidTransform::create(position, orientation);
     217    PlatformXR::Device::FrameData::Pose pose;
     218    pose.position = { init.position[0], init.position[1], init.position[2] };
     219    pose.orientation = { init.orientation[0], init.orientation[1], init.orientation[2], init.orientation[3] };
     220
     221    return pose;
    176222}
    177223
     
    183229    if (init.projectionMatrix.size() != 16)
    184230        return Exception { TypeError };
    185     fakeView->view()->setProjectionMatrix(init.projectionMatrix);
     231    fakeView->setProjection(init.projectionMatrix);
    186232
    187233    auto viewOffset = parseRigidTransform(init.viewOffset);
    188234    if (viewOffset.hasException())
    189235        return viewOffset.releaseException();
    190     fakeView->view()->setTransform(viewOffset.releaseReturnValue());
     236    fakeView->setOffset(viewOffset.releaseReturnValue());
    191237
    192238    fakeView->setResolution(init.resolution);
     
    194240    if (init.fieldOfView) {
    195241        fakeView->setFieldOfView(init.fieldOfView.value());
    196         // TODO: Set view’s projection matrix to the projection matrix
    197         // corresponding to this field of view, and depth values equal to
    198         // depthNear and depthFar of any XRSession associated with the device.
    199         // If there currently is none, use the default values of near=0.1,
    200         // far=1000.0.
    201242    }
    202243
  • trunk/Source/WebCore/testing/WebFakeXRDevice.h

    r272734 r273132  
    3434#include "PlatformXR.h"
    3535#include "WebFakeXRInputController.h"
    36 #include "WebXRRigidTransform.h"
    37 #include "WebXRView.h"
    3836#include "XRVisibilityState.h"
    3937#include <wtf/RefCounted.h>
     
    4442public:
    4543    static Ref<FakeXRView> create(XREye eye) { return adoptRef(*new FakeXRView(eye)); }
     44    using Pose = PlatformXR::Device::FrameData::Pose;
     45    using Fov = PlatformXR::Device::FrameData::Fov;
    4646
    47     RefPtr<WebXRView> view() { return m_view; }
     47    XREye eye() const { return m_eye; }
     48    const Pose& offset() const { return m_offset; }
     49    const std::array<float, 16>& projection() const { return m_projection; }
     50    const Optional<Fov>& fieldOfView() const { return m_fov;}
     51
    4852    void setResolution(FakeXRViewInit::DeviceResolution resolution) { m_resolution = resolution; }
    49     void setFieldOfView(FakeXRViewInit::FieldOfViewInit);
    50 
     53    void setOffset(Pose&& offset) { m_offset = WTFMove(offset); }
     54    void setProjection(const Vector<float>&);
     55    void setFieldOfView(const FakeXRViewInit::FieldOfViewInit&);
    5156private:
    5257    FakeXRView(XREye eye)
    53     {
    54         m_view = WebXRView::create();
    55         m_view->setEye(eye);
    56     }
     58        : m_eye(eye) { }
    5759
    58     RefPtr<WebXRView> m_view;
     60
     61    XREye m_eye;
    5962    FakeXRViewInit::DeviceResolution m_resolution;
    60     FakeXRViewInit::FieldOfViewInit m_fov;
     63    Pose m_offset;
     64    std::array<float, 16> m_projection;
     65    Optional<Fov> m_fov;
    6166};
    6267
     
    6671    SimulatedXRDevice();
    6772    ~SimulatedXRDevice();
    68     void setNativeBoundsGeometry(Vector<FakeXRBoundsPoint> geometry) { m_nativeBoundsGeometry = geometry; }
    69     void setViewerOrigin(RefPtr<WebXRRigidTransform>&& origin) { m_viewerOrigin = WTFMove(origin); }
    70     void setFloorOrigin(RefPtr<WebXRRigidTransform>&& origin) { m_floorOrigin = WTFMove(origin); }
     73    void setViews(Vector<Ref<FakeXRView>>&& views) { m_views = WTFMove(views); }
     74    void setNativeBoundsGeometry(const Vector<FakeXRBoundsPoint>& geometry) { m_nativeBoundsGeometry = geometry; }
     75    void setViewerOrigin(Optional<FrameData::Pose>&& origin) { m_viewerOrigin = WTFMove(origin); }
     76    void setFloorOrigin(Optional<FrameData::Pose>&& origin) { m_floorOrigin = WTFMove(origin); }
    7177    void setEmulatedPosition(bool emulated) { m_emulatedPosition = emulated; }
    7278    Vector<Ref<FakeXRView>>& views() { return m_views; }
    7379    void setSupportsShutdownNotification(bool supportsShutdownNotification) { m_supportsShutdownNotification = supportsShutdownNotification; }
    7480    void simulateShutdownCompleted();
     81    void scheduleOnNextFrame(Function<void()>&&);
    7582private:
    7683    void initializeTrackingAndRendering(PlatformXR::SessionMode) final { }
     
    7885    bool supportsSessionShutdownNotification() const final { return m_supportsShutdownNotification; }
    7986    void initializeReferenceSpace(PlatformXR::ReferenceSpaceType) final { }
     87    Vector<PlatformXR::Device::ViewData> views(PlatformXR::SessionMode) const final;
    8088    void requestFrame(RequestFrameCallback&&) final;
    8189
     
    8492
    8593    Optional<Vector<FakeXRBoundsPoint>> m_nativeBoundsGeometry;
    86     RefPtr<WebXRRigidTransform> m_viewerOrigin;
    87     RefPtr<WebXRRigidTransform> m_floorOrigin;
     94    Optional<FrameData::Pose> m_viewerOrigin;
     95    Optional<FrameData::Pose> m_floorOrigin;
    8896    bool m_emulatedPosition { false };
    8997    Vector<Ref<FakeXRView>> m_views;
    9098    bool m_supportsShutdownNotification { false };
    9199    Timer m_frameTimer;
    92     Vector<RequestFrameCallback> m_callbacks;
     100    RequestFrameCallback m_FrameCallback;
     101    Vector<Function<void()>> m_pendingUpdates;
    93102};
    94103
     
    107116    void simulateVisibilityChange(XRVisibilityState);
    108117
    109     void setBoundsGeometry(Vector<FakeXRBoundsPoint> boundsCoordinates);
     118    void setBoundsGeometry(Vector<FakeXRBoundsPoint>&& boundsCoordinates);
    110119
    111120    void setFloorOrigin(FakeXRRigidTransformInit);
     
    128137    WebFakeXRDevice();
    129138
    130     static ExceptionOr<Ref<WebXRRigidTransform>> parseRigidTransform(const FakeXRRigidTransformInit&);
     139    static ExceptionOr<PlatformXR::Device::FrameData::Pose> parseRigidTransform(const FakeXRRigidTransformInit&);
    131140
    132141    SimulatedXRDevice m_device;
Note: See TracChangeset for help on using the changeset viewer.