WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Add co-authors to the changelog messages
bug-220979-20210126173040.patch (text/plain), 44.80 KB, created by
Imanol Fernandez
on 2021-01-26 08:30:42 PST
(
hide
)
Description:
Add co-authors to the changelog messages
Filename:
MIME Type:
Creator:
Imanol Fernandez
Created:
2021-01-26 08:30:42 PST
Size:
44.80 KB
patch
obsolete
>Subversion Revision: 271881 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 3f136cac488f44e8a0a5cb8773ad26b9f821693b..b736c37abc3c3de6f0d4e742fe347a6affa0c2d1 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,69 @@ >+2021-01-26 Sergio Villar Senin <svillar@igalia.com> and Imanol Fernandez <ifernandez@igalia.com> >+ >+ Complete XRSession::requestAnimationFrame implementation >+ https://bugs.webkit.org/show_bug.cgi?id=220979 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ - Properly implement the render loop for immersive and inline XR sessions >+ - Apply pending render state changes >+ >+ Tested by the WebXR platform tests. >+ >+ * Modules/webxr/WebXRFrame.cpp: >+ (WebCore::WebXRFrame::create): >+ (WebCore::WebXRFrame::WebXRFrame): >+ (WebCore::WebXRFrame::session const): >+ * Modules/webxr/WebXRFrame.h: >+ (WebCore::WebXRFrame::setTime): >+ (WebCore::WebXRFrame::setActive): >+ (WebCore::WebXRFrame::isActive const): >+ * Modules/webxr/WebXRRenderState.h: >+ (WebCore::WebXRRenderState::setOutputCanvas): >+ (WebCore::WebXRRenderState::compositionDisabled const): >+ (WebCore::WebXRRenderState::setCompositionDisabled): >+ * Modules/webxr/WebXRSession.cpp: >+ (WebCore::WebXRSession::WebXRSession): >+ (WebCore::WebXRSession::requestReferenceSpace): >+ (WebCore::WebXRSession::requestAnimationFrame): >+ (WebCore::WebXRSession::applyPendingRenderState): >+ (WebCore::WebXRSession::frameShouldBeRendered const): >+ (WebCore::WebXRSession::requestFrame): >+ (WebCore::WebXRSession::onFrame): >+ * Modules/webxr/WebXRSession.h: >+ * Modules/webxr/WebXRSystem.cpp: >+ (WebCore::WebXRSystem::WebXRSystem): >+ (WebCore::WebXRSystem::DummyInlineDevice::DummyInlineDevice): >+ (WebCore::WebXRSystem::DummyInlineDevice::requestFrame): >+ * Modules/webxr/WebXRSystem.h: >+ * Modules/webxr/WebXRWebGLLayer.cpp: >+ (WebCore::WebXRWebGLLayer::canvas const): >+ * Modules/webxr/WebXRWebGLLayer.h: >+ (WebCore::WebXRWebGLLayer::compositionDisabled const): >+ (WebCore::WebXRWebGLLayer::setCompositionDisabled): >+ * platform/xr/PlatformXR.h: >+ * platform/xr/openxr/PlatformXROpenXR.cpp: >+ (PlatformXR::toXrReferenceSpaceType): >+ (PlatformXR::OpenXRDevice::initializeReferenceSpace): >+ (PlatformXR::OpenXRDevice::resetSession): >+ (PlatformXR::OpenXRDevice::shutDownTrackingAndRendering): >+ (PlatformXR::OpenXRDevice::pollEvents): >+ (PlatformXR::sessionIsVisible): >+ (PlatformXR::sessionShouldStop): >+ (PlatformXR::sessionIsActive): >+ (PlatformXR::OpenXRDevice::beginSession): >+ (PlatformXR::xrViewToViewData): >+ (PlatformXR::OpenXRDevice::requestFrame): >+ * platform/xr/openxr/PlatformXROpenXR.h: >+ * testing/WebFakeXRDevice.cpp: >+ (WebCore::SimulatedXRDevice::SimulatedXRDevice): >+ (WebCore::SimulatedXRDevice::~SimulatedXRDevice): >+ (WebCore::SimulatedXRDevice::frameTimerFired): >+ (WebCore::SimulatedXRDevice::initializeTrackingAndRendering): >+ (WebCore::SimulatedXRDevice::requestFrame): >+ (WebCore::SimulatedXRDevice::shutDownTrackingAndRendering): >+ * testing/WebFakeXRDevice.h: >+ > 2021-01-26 Zalan Bujtas <zalan@apple.com> > > [LFC][IFC] Incorrect inline box width with horizontal alignment >diff --git a/Source/WebCore/Modules/webxr/WebXRFrame.cpp b/Source/WebCore/Modules/webxr/WebXRFrame.cpp >index 935dc127c9d07a7c8d2384154587d5135887ae1a..ecfbbb9d511d6a045c46eeac9d082a71a5233493 100644 >--- a/Source/WebCore/Modules/webxr/WebXRFrame.cpp >+++ b/Source/WebCore/Modules/webxr/WebXRFrame.cpp >@@ -36,13 +36,15 @@ namespace WebCore { > > WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRFrame); > >-Ref<WebXRFrame> WebXRFrame::create(Ref<WebXRSession>&& session) >+Ref<WebXRFrame> WebXRFrame::create(WebXRSession* session, bool isAnimationFrame) > { >- return adoptRef(*new WebXRFrame(WTFMove(session))); >+ return adoptRef(*new WebXRFrame(session, isAnimationFrame)); > } > >-WebXRFrame::WebXRFrame(Ref<WebXRSession>&& session) >- : m_session(WTFMove(session)) >+WebXRFrame::WebXRFrame(WebXRSession* session, bool isAnimationFrame) >+ : m_active(false) >+ , m_animationFrame(isAnimationFrame) >+ , m_session(session) > { > } > >@@ -50,7 +52,8 @@ WebXRFrame::~WebXRFrame() = default; > > const WebXRSession& WebXRFrame::session() const > { >- return m_session; >+ ASSERT(m_session); >+ return *m_session; > } > > RefPtr<WebXRViewerPose> WebXRFrame::getViewerPose(const WebXRReferenceSpace&) >diff --git a/Source/WebCore/Modules/webxr/WebXRFrame.h b/Source/WebCore/Modules/webxr/WebXRFrame.h >index 808a6764f0d2c5ae61e4d658c28250579fe5b627..89bec08b42cfea4c7bd91b1612e4d8c26ae153b6 100644 >--- a/Source/WebCore/Modules/webxr/WebXRFrame.h >+++ b/Source/WebCore/Modules/webxr/WebXRFrame.h >@@ -27,6 +27,7 @@ > > #if ENABLE(WEBXR) > >+#include "DOMHighResTimeStamp.h" > #include <wtf/IsoMalloc.h> > #include <wtf/Ref.h> > #include <wtf/RefCounted.h> >@@ -43,7 +44,7 @@ class WebXRViewerPose; > class WebXRFrame : public RefCounted<WebXRFrame> { > WTF_MAKE_ISO_ALLOCATED(WebXRFrame); > public: >- static Ref<WebXRFrame> create(Ref<WebXRSession>&&); >+ static Ref<WebXRFrame> create(WebXRSession*, bool isAnimationFrame = false); > ~WebXRFrame(); > > const WebXRSession& session() const; >@@ -51,10 +52,19 @@ public: > RefPtr<WebXRViewerPose> getViewerPose(const WebXRReferenceSpace&); > RefPtr<WebXRPose> getPose(const WebXRSpace&, const WebXRSpace&); > >+ void setTime(DOMHighResTimeStamp time) { m_time = time; } >+ void setActive(bool active) { m_active = active; } >+ bool isActive() const { return m_active; } >+ > private: >- WebXRFrame(Ref<WebXRSession>&&); >+ WebXRFrame(WebXRSession*, bool isAnimationFrame); >+ >+ bool m_active; >+ bool m_animationFrame; >+ DOMHighResTimeStamp m_time; > >- Ref<WebXRSession> m_session; >+ // Session owns the frame. >+ WebXRSession* m_session; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/webxr/WebXRRenderState.h b/Source/WebCore/Modules/webxr/WebXRRenderState.h >index 1e4363f1f19431e4a1ec958f1bfa2b47074577a2..e6d43c04689598b53da6d4bbb73f2dc1a413a2c2 100644 >--- a/Source/WebCore/Modules/webxr/WebXRRenderState.h >+++ b/Source/WebCore/Modules/webxr/WebXRRenderState.h >@@ -56,6 +56,10 @@ public: > void setBaseLayer(WebXRWebGLLayer* baseLayer) { m_baseLayer = baseLayer; } > > HTMLCanvasElement* outputCanvas() const { return m_outputCanvas.get(); } >+ void setOutputCanvas(HTMLCanvasElement* canvas) { m_outputCanvas = makeWeakPtr(canvas); } >+ >+ bool compositionDisabled() const { return m_compositionDisabled; } >+ void setCompositionDisabled(bool compositionDisabled) { m_compositionDisabled = compositionDisabled; } > > private: > explicit WebXRRenderState(Optional<double> fieldOfView); >@@ -69,6 +73,7 @@ private: > Optional<double> m_inlineVerticalFieldOfView; // in radians > RefPtr<WebXRWebGLLayer> m_baseLayer; > WeakPtr<HTMLCanvasElement> m_outputCanvas; >+ bool m_compositionDisabled { false }; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/webxr/WebXRSession.cpp b/Source/WebCore/Modules/webxr/WebXRSession.cpp >index b663d52d06bb209a4371f7a2131398853a78f5ab..84cb57cc12b60a8af00fab5340b25fcb9cc6ec3e 100644 >--- a/Source/WebCore/Modules/webxr/WebXRSession.cpp >+++ b/Source/WebCore/Modules/webxr/WebXRSession.cpp >@@ -55,10 +55,15 @@ WebXRSession::WebXRSession(Document& document, WebXRSystem& system, XRSessionMod > , m_mode(mode) > , m_device(makeWeakPtr(device)) > , m_activeRenderState(WebXRRenderState::create(mode)) >- , m_animationTimer(*this, &WebXRSession::animationTimerFired) >+ , m_timeOrigin(MonotonicTime::now()) >+ , m_animationFrame(WebXRFrame::create(this, true)) > { > m_device->initializeTrackingAndRendering(mode); > >+ // https://immersive-web.github.io/webxr/#ref-for-dom-xrreferencespacetype-viewer%E2%91%A2 >+ // Every session MUST support viewer XRReferenceSpaces. >+ m_device->initializeReferenceSpace(XRReferenceSpaceType::Viewer); >+ > suspendIfNeeded(); > } > >@@ -199,61 +204,34 @@ void WebXRSession::requestReferenceSpace(XRReferenceSpaceType type, RequestRefer > } > // 1. Let promise be a new Promise. > // 2. Run the following steps in parallel: >- scriptExecutionContext()->postTask([this, promise = WTFMove(promise), type] (auto& context) mutable { >- // 2.1. Create a reference space, referenceSpace, with the XRReferenceSpaceType type. >- // 2.2. If referenceSpace is null, reject promise with a NotSupportedError and abort these steps. >+ scriptExecutionContext()->postTask([this, promise = WTFMove(promise), type](auto& context) mutable { >+ // 2.1. If the result of running reference space is supported for type and session is false, queue a task to reject promise >+ // with a NotSupportedError and abort these steps. > if (!referenceSpaceIsSupported(type)) { >- promise.reject(Exception { NotSupportedError }); >+ queueTaskKeepingObjectAlive(*this, TaskSource::WebXR, [promise = WTFMove(promise)]() mutable { >+ promise.reject(Exception { NotSupportedError }); >+ }); > return; > } >- >- // https://immersive-web.github.io/webxr/#create-a-reference-space >- RefPtr<WebXRReferenceSpace> referenceSpace; >- if (type == XRReferenceSpaceType::BoundedFloor) >- referenceSpace = WebXRBoundedReferenceSpace::create(downcast<Document>(context), makeRef(*this), type); >- else >- referenceSpace = WebXRReferenceSpace::create(downcast<Document>(context), makeRef(*this), type); >- >- // 2.3. Resolve promise with referenceSpace. >- // 3. Return promise. >- promise.resolve(referenceSpace.releaseNonNull()); >+ // 2.2. Set up any platform resources required to track reference spaces of type type. >+ m_device->initializeReferenceSpace(type); >+ >+ // 2.3. Queue a task to run the following steps: >+ queueTaskKeepingObjectAlive(*this, TaskSource::WebXR, [this, type, promise = WTFMove(promise), protectedDocument = makeRef(downcast<Document>(context))]() mutable { >+ // 2.4. Create a reference space, referenceSpace, with type and session. >+ // https://immersive-web.github.io/webxr/#create-a-reference-space >+ RefPtr<WebXRReferenceSpace> referenceSpace; >+ if (type == XRReferenceSpaceType::BoundedFloor) >+ referenceSpace = WebXRBoundedReferenceSpace::create(protectedDocument, makeRef(*this), type); >+ else >+ referenceSpace = WebXRReferenceSpace::create(protectedDocument, makeRef(*this), type); >+ >+ // 2.5. Resolve promise with referenceSpace. >+ promise.resolve(referenceSpace.releaseNonNull()); >+ }); > }); > } > >-void WebXRSession::animationTimerFired() >-{ >- m_lastAnimationFrameTimestamp = MonotonicTime::now(); >- >- if (m_callbacks.isEmpty()) >- return; >- >- // TODO: retrieve frame from platform. >- auto frame = WebXRFrame::create(*this); >- >- m_runningCallbacks.swap(m_callbacks); >- for (auto& callback : m_runningCallbacks) { >- if (callback->isCancelled()) >- continue; >- callback->handleEvent(m_lastAnimationFrameTimestamp.secondsSinceEpoch().milliseconds(), frame.get()); >- } >- >- m_runningCallbacks.clear(); >-} >- >-void WebXRSession::scheduleAnimation() >-{ >- if (m_animationTimer.isActive()) >- return; >- >- if (m_ended) >- return; >- >- // TODO: use device's refresh rate. Let's start with 60fps. >- Seconds animationInterval = 15_ms; >- Seconds scheduleDelay = std::max(animationInterval - (MonotonicTime::now() - m_lastAnimationFrameTimestamp), 0_s); >- m_animationTimer.startOneShot(scheduleDelay); >-} >- > // https://immersive-web.github.io/webxr/#dom-xrsession-requestanimationframe > unsigned WebXRSession::requestAnimationFrame(Ref<XRFrameRequestCallback>&& callback) > { >@@ -266,7 +244,8 @@ unsigned WebXRSession::requestAnimationFrame(Ref<XRFrameRequestCallback>&& callb > callback->setCallbackId(newId); > m_callbacks.append(WTFMove(callback)); > >- scheduleAnimation(); >+ if (m_callbacks.size() == 1 && !m_animationFrame->isActive()) >+ requestFrame(); > > // 4. Return session's animation frame callback identifier's current value. > return newId; >@@ -371,6 +350,133 @@ void WebXRSession::stop() > { > } > >+void WebXRSession::applyPendingRenderState() >+{ >+ // https: //immersive-web.github.io/webxr/#apply-the-pending-render-state >+ // 1. Let activeState be sessionâs active render state. >+ // 2. Let newState be sessionâs pending render state. >+ // 3. Set sessionâs pending render state to null. >+ auto newState = m_pendingRenderState; >+ ASSERT(newState); >+ >+ // 4. Let oldBaseLayer be activeStateâs baseLayer. >+ // 5. Let oldLayers be activeStateâs layers. >+ // FIXME: those are only needed for step 6.2. >+ >+ // 6.1 Set activeState to newState. >+ m_activeRenderState = newState; >+ >+ // 6.2 If oldBaseLayer is not equal to activeStateâs baseLayer, oldLayers is not equal to activeStateâs layers, or the dimensions of any of the layers have changed, update the viewports for session. >+ // FIXME: implement this. >+ >+ // 6.3 If activeStateâs inlineVerticalFieldOfView is less than sessionâs minimum inline field of view set activeStateâs inlineVerticalFieldOfView to sessionâs minimum inline field of view. >+ if (m_activeRenderState->inlineVerticalFieldOfView() < m_minimumInlineFOV) >+ m_activeRenderState->setInlineVerticalFieldOfView(m_minimumInlineFOV); >+ >+ // 6.4 If activeStateâs inlineVerticalFieldOfView is greater than sessionâs maximum inline field of view set activeStateâs inlineVerticalFieldOfView to sessionâs maximum inline field of view. >+ if (m_activeRenderState->inlineVerticalFieldOfView() > m_maximumInlineFOV) >+ m_activeRenderState->setInlineVerticalFieldOfView(m_maximumInlineFOV); >+ >+ // 6.5 If activeStateâs depthNear is less than sessionâs minimum near clip plane set activeStateâs depthNear to sessionâs minimum near clip plane. >+ if (m_activeRenderState->depthNear() < m_minimumNearClipPlane) >+ m_activeRenderState->setDepthNear(m_minimumNearClipPlane); >+ >+ // 6.6 If activeStateâs depthFar is greater than sessionâs maximum far clip plane set activeStateâs depthFar to sessionâs maximum far clip plane. >+ if (m_activeRenderState->depthFar() > m_maximumFarClipPlane) >+ m_activeRenderState->setDepthFar(m_maximumFarClipPlane); >+ >+ // 6.7 Let baseLayer be activeStateâs baseLayer. >+ auto baseLayer = m_activeRenderState->baseLayer(); >+ >+ // 6.8 Set activeStateâs composition disabled and output canvas as follows: >+ m_activeRenderState->setCompositionDisabled(true); >+ if (m_mode == XRSessionMode::Inline && is<WebXRWebGLLayer>(baseLayer) && baseLayer->compositionDisabled()) { >+ m_activeRenderState->setCompositionDisabled(true); >+ m_activeRenderState->setOutputCanvas(baseLayer->canvas()); >+ } else { >+ m_activeRenderState->setCompositionDisabled(false); >+ m_activeRenderState->setOutputCanvas(nullptr); >+ } >+} >+ >+// https://immersive-web.github.io/webxr/#should-be-rendered >+bool WebXRSession::frameShouldBeRendered() const >+{ >+ if (!m_activeRenderState->baseLayer()) >+ return false; >+ if (m_mode == XRSessionMode::Inline && !m_activeRenderState->outputCanvas()) >+ return false; >+ return true; >+} >+ >+void WebXRSession::requestFrame() >+{ >+ m_device->requestFrame([this, protectedThis = makeRef(*this)](PlatformXR::Device::FrameData frameData) { >+ onFrame(frameData); >+ }); >+} >+ >+void WebXRSession::onFrame(PlatformXR::Device::FrameData frameData) >+{ >+ ASSERT(isMainThread()); >+ >+ if (m_ended) >+ return; >+ >+ // Queue a task to perform the following steps. >+ queueTaskKeepingObjectAlive(*this, TaskSource::WebXR, [this, frameData]() { >+ // 1.Let now be the current high resolution time. >+ DOMHighResTimeStamp now = (MonotonicTime::now() - m_timeOrigin).milliseconds(); >+ >+ // 2.Let frame be sessionâs animation frame. >+ // 3.Set frameâs time to frameTime. >+ m_animationFrame->setTime(static_cast<DOMHighResTimeStamp>(frameData.predictedDisplayTime)); >+ >+ // 4. For each view in list of views, set viewâs viewport modifiable flag to true. >+ // 5. If the active flag of any view in the list of views has changed since the last XR animation frame, update the viewports. >+ // FIXME: implement. >+ >+ // FIXME: I moved step 7 before 6 because of https://github.com/immersive-web/webxr/issues/1164 >+ // 7.If sessionâs pending render state is not null, apply the pending render state. >+ if (m_pendingRenderState) >+ applyPendingRenderState(); >+ >+ // 6. If the frame should be rendered for session: >+ if (frameShouldBeRendered()) { >+ // 6.1.Set sessionâs list of currently running animation frame callbacks to be sessionâs list of animation frame callbacks. >+ // 6.2.Set sessionâs list of animation frame callbacks to the empty list. >+ m_runningCallbacks.swap(m_callbacks); >+ >+ // 6.3.Set frameâs active boolean to true. >+ m_animationFrame->setActive(true); >+ >+ // 6.4.Apply frame updates for frame. >+ // FIXME: implement. >+ >+ // 6.5.For each entry in sessionâs list of currently running animation frame callbacks, in order: >+ for (auto& callback : m_runningCallbacks) { >+ // 6.6.If the entryâs cancelled boolean is true, continue to the next entry. >+ if (callback->isCancelled()) >+ continue; >+ // 6.7.Invoke the Web IDL callback function for entry, passing now and frame as the arguments >+ callback->handleEvent(now, m_animationFrame.get()); >+ >+ // 6.8.If an exception is thrown, report the exception. >+ } >+ // 6.9.Set sessionâs list of currently running animation frame callbacks to the empty list. >+ m_runningCallbacks.clear(); >+ >+ // 6.10.Set frameâs active boolean to false. >+ m_animationFrame->setActive(false); >+ >+ // Request next frame if users have called session.requestAnimationFrame during the animation frame. >+ if (!m_callbacks.isEmpty()) >+ requestFrame(); >+ } >+ >+ }); >+} >+ > } // namespace WebCore > > #endif // ENABLE(WEBXR) >diff --git a/Source/WebCore/Modules/webxr/WebXRSession.h b/Source/WebCore/Modules/webxr/WebXRSession.h >index e4c27db4b90d921e21555a6a286906e98c63a0e8..597aca384a08fcc6a63ad50aeec146280e256457 100644 >--- a/Source/WebCore/Modules/webxr/WebXRSession.h >+++ b/Source/WebCore/Modules/webxr/WebXRSession.h >@@ -30,7 +30,7 @@ > #include "ActiveDOMObject.h" > #include "EventTarget.h" > #include "JSDOMPromiseDeferred.h" >-#include "Timer.h" >+#include "WebXRFrame.h" > #include "WebXRInputSourceArray.h" > #include "WebXRRenderState.h" > #include "WebXRSpace.h" >@@ -101,11 +101,13 @@ private: > > void shutdown(); > >- void animationTimerFired(); >- void scheduleAnimation(); >- > bool referenceSpaceIsSupported(XRReferenceSpaceType) const; > >+ bool frameShouldBeRendered() const; >+ void requestFrame(); >+ void onFrame(PlatformXR::Device::FrameData); >+ void applyPendingRenderState(); >+ > XREnvironmentBlendMode m_environmentBlendMode; > XRInteractionMode m_interactionMode; > XRVisibilityState m_visibilityState; >@@ -117,13 +119,20 @@ private: > WeakPtr<PlatformXR::Device> m_device; > RefPtr<WebXRRenderState> m_activeRenderState; > RefPtr<WebXRRenderState> m_pendingRenderState; >+ MonotonicTime m_timeOrigin; > > unsigned m_nextCallbackId { 1 }; > Vector<Ref<XRFrameRequestCallback>> m_callbacks; > Vector<Ref<XRFrameRequestCallback>> m_runningCallbacks; > >- Timer m_animationTimer; >- MonotonicTime m_lastAnimationFrameTimestamp; >+ Ref<WebXRFrame> m_animationFrame; >+ >+ double m_minimumInlineFOV { 0.0 }; >+ double m_maximumInlineFOV { piFloat }; >+ >+ // In meters. >+ double m_minimumNearClipPlane { 0.1 }; >+ double m_maximumFarClipPlane { 1000.0 }; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/webxr/WebXRSystem.cpp b/Source/WebCore/Modules/webxr/WebXRSystem.cpp >index 12a9f21e724a12ddc15da9a84c1b82eb4d17d4d8..5c6ddb45b44f67813090982fc84feee1fca694ae 100644 >--- a/Source/WebCore/Modules/webxr/WebXRSystem.cpp >+++ b/Source/WebCore/Modules/webxr/WebXRSystem.cpp >@@ -35,6 +35,7 @@ > #include "JSWebXRSession.h" > #include "JSXRReferenceSpaceType.h" > #include "PlatformXR.h" >+#include "RequestAnimationFrameCallback.h" > #include "RuntimeEnabledFeatures.h" > #include "SecurityOrigin.h" > #include "UserGestureIndicator.h" >@@ -49,11 +50,6 @@ namespace WebCore { > > WTF_MAKE_ISO_ALLOCATED_IMPL(WebXRSystem); > >-WebXRSystem::DummyInlineDevice::DummyInlineDevice() >-{ >- setEnabledFeatures(XRSessionMode::Inline, { XRReferenceSpaceType::Viewer }); >-} >- > Ref<WebXRSystem> WebXRSystem::create(ScriptExecutionContext& scriptExecutionContext) > { > return adoptRef(*new WebXRSystem(scriptExecutionContext)); >@@ -61,6 +57,7 @@ Ref<WebXRSystem> WebXRSystem::create(ScriptExecutionContext& scriptExecutionCont > > WebXRSystem::WebXRSystem(ScriptExecutionContext& scriptExecutionContext) > : ActiveDOMObject(&scriptExecutionContext) >+ , m_defaultInlineDevice(scriptExecutionContext) > { > m_inlineXRDevice = makeWeakPtr(m_defaultInlineDevice); > suspendIfNeeded(); >@@ -475,6 +472,48 @@ void WebXRSystem::sessionEnded(WebXRSession& session) > m_inlineSessions.remove(session); > } > >+class InlineRequestAnimationFrameCallback: public RequestAnimationFrameCallback { >+public: >+ static Ref<InlineRequestAnimationFrameCallback> create(ScriptExecutionContext& scriptExecutionContext, Function<void()>&& callback) >+ { >+ return adoptRef(*new InlineRequestAnimationFrameCallback(scriptExecutionContext, WTFMove(callback))); >+ } >+ >+ InlineRequestAnimationFrameCallback(ScriptExecutionContext& scriptExecutionContext, Function<void()>&& callback) >+ : RequestAnimationFrameCallback(&scriptExecutionContext), m_callback(WTFMove(callback)) >+ { >+ >+ } >+ >+ CallbackResult<void> handleEvent(double highResTimeMs) override >+ { >+ UNUSED_PARAM(highResTimeMs); >+ m_callback(); >+ return { }; >+ } >+private: >+ Function<void()> m_callback; >+}; >+ >+ >+WebXRSystem::DummyInlineDevice::DummyInlineDevice(ScriptExecutionContext& scriptExecutionContext) >+ : m_scriptExecutionContext(&scriptExecutionContext) >+{ >+ setEnabledFeatures(XRSessionMode::Inline, { XRReferenceSpaceType::Viewer }); >+} >+ >+void WebXRSystem::DummyInlineDevice::requestFrame(PlatformXR::Device::RequestFrameCallback&& callback) >+{ >+ // Inline XR sessions rely on document.requestAnimationFrame to perform the render loop. >+ auto document = downcast<Document>(m_scriptExecutionContext); >+ auto raf = InlineRequestAnimationFrameCallback::create(*m_scriptExecutionContext, [callback = WTFMove(callback)]() mutable { >+ callback({ }); >+ }); >+ >+ document->requestAnimationFrame(raf); >+} >+ >+ > } // namespace WebCore > > #endif // ENABLE(WEBXR) >diff --git a/Source/WebCore/Modules/webxr/WebXRSystem.h b/Source/WebCore/Modules/webxr/WebXRSystem.h >index c762d46ac0e904a3983d397f686561d4c165b355..c33cf73b8124e6503821509a382094b930efb568 100644 >--- a/Source/WebCore/Modules/webxr/WebXRSystem.h >+++ b/Source/WebCore/Modules/webxr/WebXRSystem.h >@@ -106,11 +106,16 @@ private: > // https://immersive-web.github.io/webxr/#default-inline-xr-device > class DummyInlineDevice final : public PlatformXR::Device { > public: >- DummyInlineDevice(); >+ DummyInlineDevice(ScriptExecutionContext&); > > private: > void initializeTrackingAndRendering(PlatformXR::SessionMode) final { } > void shutDownTrackingAndRendering() final { } >+ void initializeReferenceSpace(PlatformXR::ReferenceSpaceType) final { }; >+ >+ void requestFrame(PlatformXR::Device::RequestFrameCallback&&) final; >+ >+ ScriptExecutionContext* m_scriptExecutionContext; > }; > DummyInlineDevice m_defaultInlineDevice; > >diff --git a/Source/WebCore/Modules/webxr/WebXRWebGLLayer.cpp b/Source/WebCore/Modules/webxr/WebXRWebGLLayer.cpp >index 86dd11b00143bf80ea81ae2add8de84dc02d033f..14cc74b8e951a2ee1147df578005d6b8de47c625 100644 >--- a/Source/WebCore/Modules/webxr/WebXRWebGLLayer.cpp >+++ b/Source/WebCore/Modules/webxr/WebXRWebGLLayer.cpp >@@ -28,7 +28,9 @@ > > #if ENABLE(WEBXR) > >+#include "HTMLCanvasElement.h" > #include "IntSize.h" >+#include "OffscreenCanvas.h" > #include "WebGLFramebuffer.h" > #include "WebGLRenderingContext.h" > #if ENABLE(WEBGL2) >@@ -198,6 +200,23 @@ double WebXRWebGLLayer::getNativeFramebufferScaleFactor(const WebXRSession& sess > return (nativeSize / recommendedSize).width(); > } > >+HTMLCanvasElement* WebXRWebGLLayer::canvas() const >+{ >+ HTMLCanvasElement* c = WTF::switchOn(m_context, [](const RefPtr<WebGLRenderingContextBase>& baseContext) { >+ auto canvas = baseContext->canvas(); >+ return WTF::switchOn( >+ canvas, >+ [](const RefPtr<HTMLCanvasElement>& canvas) { >+ return canvas.get(); >+ }, >+ [](RefPtr<OffscreenCanvas>) { >+ ASSERT_NOT_REACHED("baseLayer of a WebXRWebGLLayer must be an HTMLCanvasElement"); >+ return nullptr; >+ }); >+ }); >+ return c; >+} >+ > } // namespace WebCore > > #endif // ENABLE(WEBXR) >diff --git a/Source/WebCore/Modules/webxr/WebXRWebGLLayer.h b/Source/WebCore/Modules/webxr/WebXRWebGLLayer.h >index 31755d8496a6a702e23329cfbf329b9cc4b8a9df..3f7587de89da6e231c943c4f905fc1cf18059295 100644 >--- a/Source/WebCore/Modules/webxr/WebXRWebGLLayer.h >+++ b/Source/WebCore/Modules/webxr/WebXRWebGLLayer.h >@@ -36,6 +36,7 @@ > > namespace WebCore { > >+class HTMLCanvasElement; > class IntSize; > class WebGLFramebuffer; > class WebGLRenderingContext; >@@ -74,6 +75,11 @@ public: > > const WebXRSession& session() { return m_session; } > >+ bool compositionDisabled() const { return m_isCompositionDisabled; } >+ void setCompositionDisabled(bool compositionDisabled) { m_isCompositionDisabled = compositionDisabled; } >+ >+ HTMLCanvasElement* canvas() const; >+ > private: > WebXRWebGLLayer(Ref<WebXRSession>&&, WebXRRenderingContext&&, const XRWebGLLayerInit&); > >diff --git a/Source/WebCore/platform/xr/PlatformXR.h b/Source/WebCore/platform/xr/PlatformXR.h >index 64550f4e01bf005bede184c0fea4db9312648b64..74e848e9236a618dd7e4d1c8766eaa7a52b21cb4 100644 >--- a/Source/WebCore/platform/xr/PlatformXR.h >+++ b/Source/WebCore/platform/xr/PlatformXR.h >@@ -18,6 +18,7 @@ > */ > #pragma once > >+#include "FloatPoint3D.h" > #include "IntSize.h" > #include <memory> > #include <wtf/CompletionHandler.h> >@@ -61,6 +62,25 @@ public: > > virtual void initializeTrackingAndRendering(SessionMode) = 0; > virtual void shutDownTrackingAndRendering() = 0; >+ virtual void initializeReferenceSpace(ReferenceSpaceType) = 0; >+ >+ struct FrameData { >+ long predictedDisplayTime; >+ struct ViewData { >+ struct { >+ WebCore::FloatPoint3D position; >+ struct { >+ float x, y, z, w; >+ } orientation; >+ } pose; >+ struct { >+ float rUp, rDown, rLeft, rRight; >+ } fov; >+ }; >+ Vector<ViewData> viewPoses; >+ }; >+ using RequestFrameCallback = WTF::Function<void(FrameData)>; >+ virtual void requestFrame(RequestFrameCallback&&) = 0; > > protected: > Device() = default; >diff --git a/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.cpp b/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.cpp >index fe865e671d70686de791f1400e6cf3e2c869ec22..ed0470e2a024e29b7f0b6e04a0e685438db8e2fd 100644 >--- a/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.cpp >+++ b/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.cpp >@@ -74,6 +74,9 @@ private: > > XrInstance m_instance { XR_NULL_HANDLE }; > Ref<WorkQueue> m_workQueue; >+ >+ using ReferenceSpacesMap = HashMap<ReferenceSpaceType, XrSpace*, IntHash<ReferenceSpaceType>, WTF::StrongEnumHashTraits<ReferenceSpaceType>>; >+ ReferenceSpacesMap m_referenceSpaces; > }; > > void Instance::Impl::enumerateApiLayerProperties() const >@@ -236,6 +239,24 @@ void Instance::enumerateImmersiveXRDevices(CompletionHandler<void(const DeviceLi > }); > } > >+static XrReferenceSpaceType toXrReferenceSpaceType(ReferenceSpaceType type) >+{ >+ switch (type) { >+ case ReferenceSpaceType::Viewer: >+ return XR_REFERENCE_SPACE_TYPE_VIEW; >+ case ReferenceSpaceType::Local: >+ return XR_REFERENCE_SPACE_TYPE_LOCAL; >+ case ReferenceSpaceType::LocalFloor: >+ case ReferenceSpaceType::BoundedFloor: >+ return XR_REFERENCE_SPACE_TYPE_STAGE; >+ case ReferenceSpaceType::Unbounded: >+ return XR_REFERENCE_SPACE_TYPE_UNBOUNDED_MSFT; >+ default: >+ ASSERT_NOT_REACHED("Unrecognized reference space type %d", type); >+ return XR_REFERENCE_SPACE_TYPE_VIEW; >+ }; >+} >+ > OpenXRDevice::OpenXRDevice(XrSystemId id, XrInstance instance, WorkQueue& queue, CompletionHandler<void()>&& callback) > : m_systemId(id) > , m_instance(instance) >@@ -304,6 +325,32 @@ Device::ListOfEnabledFeatures OpenXRDevice::enumerateReferenceSpaces(XrSession& > return enabledFeatures; > } > >+void OpenXRDevice::initializeReferenceSpace(ReferenceSpaceType type) >+{ >+ m_queue.dispatch([this, type]() { >+ ASSERT(m_session != XR_NULL_HANDLE); >+ ASSERT(m_instance != XR_NULL_HANDLE); >+ if (m_referenceSpaces.contains(type)) >+ return; >+ >+ XrPosef identityPose = { >+ .orientation = { .x = 0, .y = 0, .z = 0, .w = 1.0 }, >+ .position = { .x = 0, .y = 0, .z = 0 } >+ }; >+ >+ auto spaceCreateInfo = createStructure<XrReferenceSpaceCreateInfo, XR_TYPE_REFERENCE_SPACE_CREATE_INFO>(); >+ spaceCreateInfo.referenceSpaceType = toXrReferenceSpaceType(type); >+ spaceCreateInfo.poseInReferenceSpace = identityPose; >+ >+ XrSpace space; >+ auto result = xrCreateReferenceSpace(m_session, &spaceCreateInfo, &space); >+ RETURN_IF_FAILED(result, "xrCreateReferenceSpace", m_instance); >+ >+ m_referenceSpaces.add(type, space); >+ LOG(XR, "Created reference space of type %d", type); >+ }); >+} >+ > void OpenXRDevice::collectSupportedSessionModes() > { > ASSERT(&RunLoop::current() == &m_queue.runLoop()); >@@ -414,17 +461,160 @@ void OpenXRDevice::initializeTrackingAndRendering(SessionMode mode) > > void OpenXRDevice::resetSession() > { >- m_queue.dispatch([this]() { >- if (m_session == XR_NULL_HANDLE) >- return; >+ ASSERT(&RunLoop::current() == &m_queue.runLoop()); >+ if (m_session != XR_NULL_HANDLE) { > xrDestroySession(m_session); > m_session = XR_NULL_HANDLE; >- }); >+ } >+ m_sessionState = XR_SESSION_STATE_UNKNOWN; > } > > void OpenXRDevice::shutDownTrackingAndRendering() > { >- resetSession(); >+ // xrRequestExitSession() will transition the session to STOPPED state and then the requestFrame() method will call reset. >+ // If the session was not running we have to reset the session ourselves. >+ if (XR_FAILED(xrRequestExitSession(m_session))) { >+ resetSession(); >+ return; >+ } >+ >+ // Ensure that requestFrame() is called at least one more time to properly end the session. >+ callOnMainThread([this, weakThis = makeWeakPtr(this)]() { >+ if (!weakThis) >+ return; >+ requestFrame([](FrameData) { }); >+ }); >+} >+ >+void OpenXRDevice::pollEvents() >+{ >+ ASSERT(!isMainThread()); >+ auto runtimeEvent = createStructure<XrEventDataBuffer, XR_TYPE_EVENT_DATA_BUFFER>(); >+ while (xrPollEvent(m_instance, &runtimeEvent) == XR_SUCCESS) { >+ switch (runtimeEvent.type) { >+ case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED: { >+ auto* event = (XrEventDataSessionStateChanged*)&runtimeEvent; >+ m_sessionState = event->state; >+ break; >+ } >+ case XR_TYPE_EVENT_DATA_EVENTS_LOST: >+ case XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING: >+ case XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING: >+ case XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED: >+ case XR_TYPE_EVENT_DATA_MAIN_SESSION_VISIBILITY_CHANGED_EXTX: >+ case XR_TYPE_EVENT_DATA_VISIBILITY_MASK_CHANGED_KHR: >+ case XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT: >+ break; >+ default: >+ ASSERT_NOT_REACHED("Unhandled event type %d\n", runtimeEvent.type); >+ } >+ } >+} >+ >+bool sessionIsVisible(XrSessionState state) >+{ >+ return state <= XR_SESSION_STATE_FOCUSED; >+} >+ >+bool sessionShouldStop(XrSessionState state) >+{ >+ return state >= XR_SESSION_STATE_STOPPING; >+} >+ >+bool sessionIsActive(XrSessionState state) >+{ >+ return state == XR_SESSION_STATE_VISIBLE || state == XR_SESSION_STATE_FOCUSED; >+} >+ >+XrResult OpenXRDevice::beginSession() >+{ >+ ASSERT(!isMainThread()); >+ ASSERT(m_sessionState == XR_SESSION_STATE_READY); >+ >+ auto sessionBeginInfo = createStructure<XrSessionBeginInfo, XR_TYPE_SESSION_BEGIN_INFO>(); >+ sessionBeginInfo.primaryViewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO; >+ auto result = xrBeginSession(m_session, &sessionBeginInfo); >+#if !LOG_DISABLED >+ if (XR_FAILED(result)) >+ LOG(XR, "%s %s: %s\n", __func__, "xrBeginSession", resultToString(result, m_instance).utf8().data()); >+#endif >+ return result; >+} >+ >+Device::FrameData::ViewData xrViewToViewData(XrView view) >+{ >+ Device::FrameData::ViewData data; >+ data.fov = { view.fov.angleUp, view.fov.angleDown, view.fov.angleLeft, view.fov.angleRight }; >+ data.pose.orientation = { view.pose.orientation.x, view.pose.orientation.y, view.pose.orientation.z, view.pose.orientation.w }; >+ data.pose.position = { view.pose.position.x, view.pose.position.y, view.pose.position.z }; >+ return data; >+} >+ >+void OpenXRDevice::requestFrame(RequestFrameCallback&& callback) >+{ >+ m_queue.dispatch([this, callback = WTFMove(callback)]() mutable { >+ XrSessionState oldSessionState = m_sessionState; >+ pollEvents(); >+ if (sessionShouldStop(m_sessionState)) { >+ // FIXME: notify with some event. >+ xrEndSession(m_session); >+ resetSession(); >+ return; >+ } >+ >+ if (m_sessionState == XR_SESSION_STATE_READY && m_sessionState != oldSessionState) >+ beginSession(); >+ >+ auto frameState = createStructure<XrFrameState, XR_TYPE_FRAME_STATE>(); >+ auto frameWaitInfo = createStructure<XrFrameWaitInfo, XR_TYPE_FRAME_WAIT_INFO>(); >+ auto result = xrWaitFrame(m_session, &frameWaitInfo, &frameState); >+ RETURN_IF_FAILED(result, "xrWaitFrame", m_instance); >+ XrTime predictedTime = frameState.predictedDisplayTime; >+ >+ auto frameBeginInfo = createStructure<XrFrameBeginInfo, XR_TYPE_FRAME_BEGIN_INFO>(); >+ result = xrBeginFrame(m_session, &frameBeginInfo); >+ RETURN_IF_FAILED(result, "xrBeginFrame", m_instance); >+ >+ Device::FrameData frameData; >+ frameData.predictedDisplayTime = frameState.predictedDisplayTime; >+ >+ if (sessionIsActive(m_sessionState)) { >+ ASSERT(m_configurationViews.contains(m_currentViewConfigurationType)); >+ const auto& configurationView = m_configurationViews.get(m_currentViewConfigurationType); >+ >+ auto viewLocateInfo = createStructure<XrViewLocateInfo, XR_TYPE_VIEW_LOCATE_INFO>(); >+ viewLocateInfo.displayTime = predictedTime; >+ // FIXME: use the current reference space. >+ // viewLocateInfo.space = m_localSpace; >+ >+ uint32_t viewCount = configurationView.size(); >+ Vector<XrView> views(viewCount, [] { >+ XrView object; >+ std::memset(&object, 0, sizeof(XrView)); >+ object.type = XR_TYPE_VIEW; >+ return object; >+ }()); >+ >+ auto viewState = createStructure<XrViewState, XR_TYPE_VIEW_STATE>(); >+ uint32_t viewCountOutput; >+ result = xrLocateViews(m_session, &viewLocateInfo, &viewState, viewCount, &viewCountOutput, views.data()); >+ if (!XR_FAILED(result)) { >+ for (auto& view : views) >+ frameData.viewPoses.append(xrViewToViewData(view)); >+ } >+ } >+ >+ callOnMainThread([frameData, callback = WTFMove(callback)]() { >+ callback(frameData); >+ }); >+ >+ auto frameEndInfo = createStructure<XrFrameEndInfo, XR_TYPE_FRAME_END_INFO>(); >+ frameEndInfo.displayTime = predictedTime; >+ frameEndInfo.environmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE; >+ frameEndInfo.layerCount = 0; >+ result = xrEndFrame(m_session, &frameEndInfo); >+ RETURN_IF_FAILED(result, "xrEndFrame", m_instance); >+ }); > } > > } // namespace PlatformXR >diff --git a/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.h b/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.h >index aa2f780ef9129620f4412db49a0e8a042d58b529..62a3b529cf6db7331d1ba8c71c40ea4e99115789 100644 >--- a/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.h >+++ b/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.h >@@ -52,14 +52,19 @@ private: > void collectConfigurationViews(); > > ListOfEnabledFeatures enumerateReferenceSpaces(XrSession&) const; >+ void initializeReferenceSpace(ReferenceSpaceType) final; > > WebCore::IntSize recommendedResolution(SessionMode) final; > > void initializeTrackingAndRendering(SessionMode) final; > void shutDownTrackingAndRendering() final; > >+ void pollEvents(); >+ XrResult beginSession(); > void resetSession(); > >+ void requestFrame(RequestFrameCallback&&) final; >+ > using ViewConfigurationPropertiesMap = HashMap<XrViewConfigurationType, XrViewConfigurationProperties, IntHash<XrViewConfigurationType>, WTF::StrongEnumHashTraits<XrViewConfigurationType>>; > ViewConfigurationPropertiesMap m_viewConfigurationProperties; > using ViewConfigurationViewsMap = HashMap<XrViewConfigurationType, Vector<XrViewConfigurationView>, IntHash<XrViewConfigurationType>, WTF::StrongEnumHashTraits<XrViewConfigurationType>>; >@@ -68,10 +73,14 @@ private: > XrSystemId m_systemId; > XrInstance m_instance; > XrSession m_session { XR_NULL_HANDLE }; >+ XrSessionState m_sessionState { XR_SESSION_STATE_UNKNOWN }; > > WorkQueue& m_queue; > > XrViewConfigurationType m_currentViewConfigurationType; >+ >+ using ReferenceSpacesMap = HashMap<ReferenceSpaceType, XrSpace, IntHash<ReferenceSpaceType>, WTF::StrongEnumHashTraits<ReferenceSpaceType>>; >+ ReferenceSpacesMap m_referenceSpaces; > }; > > } // namespace PlatformXR >diff --git a/Source/WebCore/testing/WebFakeXRDevice.cpp b/Source/WebCore/testing/WebFakeXRDevice.cpp >index 2fadf3932505da54abe17d1912e4011921a49574..9f949f9285cda8bc7a637ab5793fb0e6502db024 100644 >--- a/Source/WebCore/testing/WebFakeXRDevice.cpp >+++ b/Source/WebCore/testing/WebFakeXRDevice.cpp >@@ -31,6 +31,7 @@ > #include "DOMPointReadOnly.h" > #include "JSDOMPromiseDeferred.h" > #include "WebFakeXRInputController.h" >+#include <wtf/CompletionHandler.h> > > namespace WebCore { > >@@ -156,6 +157,42 @@ ExceptionOr<Ref<FakeXRView>> WebFakeXRDevice::parseView(const FakeXRViewInit& in > return fakeView; > } > >+SimulatedXRDevice::SimulatedXRDevice() >+ : m_frameTimer(*this, &SimulatedXRDevice::frameTimerFired) >+{ >+ m_supportsOrientationTracking = true; >+} >+ >+SimulatedXRDevice::~SimulatedXRDevice() >+{ >+ m_frameTimer.stop(); >+} >+ >+void SimulatedXRDevice::frameTimerFired() >+{ >+ Vector<RequestFrameCallback> runningCallbacks; >+ runningCallbacks.swap(m_callbacks); >+ for (auto& callback : runningCallbacks) >+ callback({ }); >+} >+ >+void SimulatedXRDevice::initializeTrackingAndRendering(PlatformXR::SessionMode) >+{ >+} >+ >+void SimulatedXRDevice::requestFrame(RequestFrameCallback&& callback) >+{ >+ m_callbacks.append(WTFMove(callback)); >+ if (!m_frameTimer.isActive()) >+ m_frameTimer.startOneShot(15_ms); >+} >+ >+void SimulatedXRDevice::shutDownTrackingAndRendering() >+{ >+ if (m_frameTimer.isActive()) >+ m_frameTimer.stop(); >+} >+ > } // namespace WebCore > > #endif // ENABLE(WEBXR) >diff --git a/Source/WebCore/testing/WebFakeXRDevice.h b/Source/WebCore/testing/WebFakeXRDevice.h >index 97a1b95719e7b32bf8414bcfa34d690ed736770f..5a73eaf9e3668d9fe6f4150a1c940874f8460645 100644 >--- a/Source/WebCore/testing/WebFakeXRDevice.h >+++ b/Source/WebCore/testing/WebFakeXRDevice.h >@@ -63,20 +63,29 @@ private: > class SimulatedXRDevice final : public PlatformXR::Device { > WTF_MAKE_FAST_ALLOCATED; > public: >- SimulatedXRDevice() { m_supportsOrientationTracking = true; } >+ SimulatedXRDevice(); >+ ~SimulatedXRDevice(); > void setNativeBoundsGeometry(Vector<FakeXRBoundsPoint> geometry) { m_nativeBoundsGeometry = geometry; } > void setViewerOrigin(RefPtr<WebXRRigidTransform>&& origin) { m_viewerOrigin = WTFMove(origin); } > void setFloorOrigin(RefPtr<WebXRRigidTransform>&& origin) { m_floorOrigin = WTFMove(origin); } > void setEmulatedPosition(bool emulated) { m_emulatedPosition = emulated; } > Vector<Ref<FakeXRView>>& views() { return m_views; } > private: >- void initializeTrackingAndRendering(PlatformXR::SessionMode) final { } >- void shutDownTrackingAndRendering() final { } >+ void initializeTrackingAndRendering(PlatformXR::SessionMode) final; >+ void shutDownTrackingAndRendering() final; >+ void initializeReferenceSpace(PlatformXR::ReferenceSpaceType) final { } >+ void requestFrame(RequestFrameCallback&&) final; >+ >+ void frameTimerFired(); >+ > Optional<Vector<FakeXRBoundsPoint>> m_nativeBoundsGeometry; > RefPtr<WebXRRigidTransform> m_viewerOrigin; > RefPtr<WebXRRigidTransform> m_floorOrigin; > bool m_emulatedPosition { false }; > Vector<Ref<FakeXRView>> m_views; >+ >+ Timer m_frameTimer; >+ Vector<RequestFrameCallback> m_callbacks; > }; > > class WebFakeXRDevice final : public RefCounted<WebFakeXRDevice> { >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index a465b2662a129c1e432cb635034cfc02888c9837..0d36dd0e69247b809c27295da9a3ec3fc0a856f0 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,12 @@ >+2021-01-26 Sergio Villar Senin <svillar@igalia.com> and Imanol Fernandez <ifernandez@igalia.com> >+ >+ Complete XRSession::requestAnimationFrame implementation >+ https://bugs.webkit.org/show_bug.cgi?id=220979 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * platform/wpe/TestExpectations: >+ > 2021-01-25 Ryosuke Niwa <rniwa@webkit.org> > > Unreviewed, reverting r271514 and r271549 >diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog >index fe78156cfc8e09c6fc6888c6fa3a25f48a26dc55..a9fa502719fd1f68fe4f4c8fbbeb5216061b7956 100644 >--- a/LayoutTests/imported/w3c/ChangeLog >+++ b/LayoutTests/imported/w3c/ChangeLog >@@ -1,3 +1,14 @@ >+2021-01-26 Sergio Villar Senin <svillar@igalia.com> and Imanol Fernandez <ifernandez@igalia.com> >+ >+ Complete XRSession::requestAnimationFrame implementation >+ https://bugs.webkit.org/show_bug.cgi?id=220979 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Enable XRSession RAF tests. >+ >+ * web-platform-tests/webxr/xrSession_requestAnimationFrame_timestamp.https-expected.txt: Added. >+ > 2021-01-25 Chris Dumez <cdumez@apple.com> > > Support AbortSignal in addEventListenerOptions to unsubscribe from events >diff --git a/LayoutTests/imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_timestamp.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_timestamp.https-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..f58a423fc6b198112935bff2907278fda94fcc56 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_timestamp.https-expected.txt >@@ -0,0 +1,4 @@ >+ >+PASS XRFrame getViewerPose updates on the next frame for immersive >+PASS XRFrame getViewerPose updates on the next frame for non-immersive >+ >diff --git a/LayoutTests/platform/wpe/TestExpectations b/LayoutTests/platform/wpe/TestExpectations >index ea3f587917aac3e69ade48157f56f12d758b3478..21ad1b4876f3a7c6f3123712dd5128cefa16c4c0 100644 >--- a/LayoutTests/platform/wpe/TestExpectations >+++ b/LayoutTests/platform/wpe/TestExpectations >@@ -632,6 +632,7 @@ webkit.org/b/209859 webkit.org/b/215637 imported/w3c/web-platform-tests/webxr/xr > webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrSession_cancelAnimationFrame_invalidhandle.https.html [ Pass ] > webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrSession_features_deviceSupport.https.html [ Pass ] > webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_callback_calls.https.html [ Pass ] >+imported/w3c/web-platform-tests/webxr/xrSession_requestAnimationFrame_timestamp.https.html [ Pass ] > webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/xrSession_requestReferenceSpace.https.html [ Pass ] > webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/ar-module/idlharness.https.window.html [ Pass ] > webkit.org/b/209859 imported/w3c/web-platform-tests/webxr/ar-module/xrDevice_isSessionSupported_immersive-ar.https.html [ Pass ]
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 220979
:
418419
|
418423
|
418924
|
419157
|
419267
|
419579
|
419584
|
419699
|
419709
|
419713
|
419993