Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: b0baaeaf0cd873d4019bc487495cb80e46859404
      
https://github.com/WebKit/WebKit/commit/b0baaeaf0cd873d4019bc487495cb80e46859404
  Author: Sergio Villar Senin <[email protected]>
  Date:   2026-05-07 (Thu, 07 May 2026)

  Changed paths:
    M Source/WebCore/Modules/webxr/WebXRSession.cpp
    M Source/WebKit/UIProcess/XR/openxr/OpenXRLayer.cpp
    M Source/WebKit/UIProcess/XR/openxr/PlatformXROpenXR.cpp
    M Source/WebKit/UIProcess/XR/openxr/PlatformXROpenXR.h

  Log Message:
  -----------
  [WebXR Layers] Crashes in OpenXRLayer's endFrame() for various layer types
https://bugs.webkit.org/show_bug.cgi?id=314069

Reviewed by Dan Glastonbury.

Soon after receiving a scheduleAnimationFrame() call, the UIProcess calls
beginFrame, which acquires a swapchain image for every active layer
(active layers are notified via requestData coming from WebProcess).
Then WebProcess renders into those textures and eventually calls
submitFrame() with the set of active layers (specified by WebXR when
calling updateRenderState) causing the UIProcess to release all those
acquired images. It's critical to perfectly pair each acquireImage call with
their correspondent releaseImage call, otherwise calling any of those
twice in a row would cause an exception.

The problem arises because JavaScript can call updateRenderState() at
any point — including between a frame callback and the corresponding
submitFrame() — to install a different set of active layers. Per the WebXR
spec, the new layer list takes effect at the start of the next frame. However,
due to the asynchronous nature of most of those calls, the OpenXR
render queue can receive the next scheduleAnimationFrame() message
(carrying the updated layer list, which overwrites activeLayerHandles)
before it receives the submitFrame() message for the current frame.

Should endFrame() check activeLayerHandles at that point, it would be
looking at the new frame's list, not the one that beginFrame() actually
used when acquiring swapchain images. This produces two failure
scenarios, both of which violate invariants that the OpenXR runtime enforces:

- A layer acquired in beginFrame() but absent from the updated list would
  never be released, leading to two consecutive acquireImage calls.
- A layer present in submitFrame()'s payload but not acquired in the matching
  beginFrame() would be released without a prior acquire.

To ensure consistency, we do snapshot the list of layers available at
beginFrame() and filter out those layers received in submitFrame() that
are not present in the snapshot. This way, we avoid the two problems
mentioned above. The worst case scenario is a layer (or various layers)
not rendered for a single frame.

Apart from revamping the OpenXR pipeline we are also adding a general
purpose fix. As per specs[1] applyind the pending render state should be
done at the very end of the XR animation frame. We used to do it
before calling each one of the currently running animation frame
callbacks, which was wrong. This reduces the amount of potentially
problematic cases in which there is a mismatch between the active
layers at the beginning and end of a frame, but does not remove them all.

We're also unconditionally updating the input sources independently of
the frame shouldRender status. With the above reorganization, the first
frame could not get rendered (as the active render state is not applied
yet), so the input sources were not updated, and some tests started to fail.

[1] https://www.w3.org/TR/webxr/#ref-for-apply-the-pending-render-state

No new tests, as this requires an actual OpenXR runtime running on a
device to reproduce the crashes. The fake XR device we use for testing
does not obviously use OpenXR. The changes in WebXRSession are covered
by existing tests.

* Source/WebCore/Modules/webxr/WebXRSession.cpp:
(WebCore::WebXRSession::onFrame):
* Source/WebKit/UIProcess/XR/openxr/OpenXRLayer.cpp:
* Source/WebKit/UIProcess/XR/openxr/PlatformXROpenXR.cpp:
(WebKit::OpenXRCoordinator::startSession):
(WebKit::OpenXRCoordinator::endSessionIfExists):
(WebKit::OpenXRCoordinator::scheduleAnimationFrame):
(WebKit::OpenXRCoordinator::submitFrame):
(WebKit::OpenXRCoordinator::populateFrameData):
(WebKit::OpenXRCoordinator::beginFrame):
(WebKit::OpenXRCoordinator::endFrame):
(WebKit::OpenXRCoordinator::maybeBeginFrame):
(WebKit::OpenXRCoordinator::waitForSessionReady):
(WebKit::OpenXRCoordinator::renderLoop): Deleted.
* Source/WebKit/UIProcess/XR/openxr/PlatformXROpenXR.h:

Canonical link: https://commits.webkit.org/312788@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to