Skip to content

Commit

Permalink
[WebXR] Add WebXR backend to support immersive-ar backed by ARKit
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=262679
rdar://116502210

Reviewed by Dean Jackson.

ARKitCoordinator adds just enough support for WebXR page to query support for
immersive-ar, allowing the XR immersive-ar-session.html button to show `START
AR` instead of `AR NOT FOUND`

* Source/WTF/wtf/PlatformHave.h:
* Source/WebKit/Configurations/WebKit.xcconfig:
* Source/WebKit/Shared/XR/XRDeviceInfo.cpp:
(WebKit::XRDeviceInfo::encode const):
(WebKit::XRDeviceInfo::decode):
* Source/WebKit/Shared/XR/XRDeviceInfo.h:
* Source/WebKit/Shared/XR/XRDeviceProxy.cpp:
(WebKit::XRDeviceProxy::XRDeviceProxy):
* Source/WebKit/SourcesCocoa.txt:
* Source/WebKit/UIProcess/XR/ios/PlatformXRARKit.h: Added.
* Source/WebKit/UIProcess/XR/ios/PlatformXRARKit.mm: Added.
(WebKit::ARKitCoordinator::getPrimaryDeviceInfo):
(WebKit::ARKitCoordinator::requestPermissionOnSessionFeatures):
(WebKit::ARKitCoordinator::startSession):
(WebKit::ARKitCoordinator::endSessionIfExists):
(WebKit::ARKitCoordinator::scheduleAnimationFrame):
(WebKit::ARKitCoordinator::submitFrame):
(WebKit::ARKitCoordinator::connectSessionIfNeeded):
* Source/WebKit/UIProcess/XR/ios/PlatformXRSystemIOS.mm: Copied from Source/WebKit/Shared/XR/XRDeviceInfo.h.
(WebKit::PlatformXRSystem::xrCoordinator):
* Source/WebKit/UIProcess/ios/WebProcessProxyIOS.mm:
* Source/WebKit/WebKit.xcodeproj/project.pbxproj:

Canonical link: https://commits.webkit.org/269049@main
  • Loading branch information
djg committed Oct 7, 2023
1 parent b4ec9b5 commit 7ad679f
Show file tree
Hide file tree
Showing 18 changed files with 268 additions and 14 deletions.
4 changes: 4 additions & 0 deletions Source/WTF/wtf/PlatformHave.h
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,10 @@
#define HAVE_MDNS_FAST_REGISTRATION 1
#endif

#if PLATFORM(IOS)
#define HAVE_ARKIT 1
#endif

#if PLATFORM(IOS) || PLATFORM(VISION)
#define HAVE_ARKIT_QUICK_LOOK_PREVIEW_ITEM 1
#endif
Expand Down
4 changes: 4 additions & 0 deletions Source/WTF/wtf/PlatformUse.h
Original file line number Diff line number Diff line change
Expand Up @@ -311,9 +311,13 @@
#define USE_FONT_VARIANT_VIA_FEATURES 1
#define USE_OPENXR 0
#if !defined(HAVE_WEBXR_INTERNALS) && !HAVE(WEBXR_INTERNALS)
#if PLATFORM(IOS) && HAVE(ARKIT)
#define USE_ARKITXR_IOS 1
#else
#define USE_EMPTYXR 1
#endif
#endif
#endif

#if PLATFORM(COCOA)
#define USE_CG_CONTEXT_STROKE_LINE_SEGMENTS_WHEN_STROKING_PATH 1
Expand Down
11 changes: 3 additions & 8 deletions Source/WebCore/Modules/webxr/WebXRSession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,6 @@ const WebXRInputSourceArray& WebXRSession::inputSources() const
return m_inputSources;
}

static bool isImmersive(XRSessionMode mode)
{
return mode == XRSessionMode::ImmersiveAr || mode == XRSessionMode::ImmersiveVr;
}

// https://immersive-web.github.io/webxr/#dom-xrsession-updaterenderstate
ExceptionOr<void> WebXRSession::updateRenderState(const XRRenderStateInit& newState)
{
Expand Down Expand Up @@ -320,7 +315,7 @@ bool WebXRSession::supportsViewportScaling() const
auto device = m_device.get();
ASSERT(device);
// Only immersive sessions support viewport scaling.
return m_mode == XRSessionMode::ImmersiveVr && device && device->supportsViewportScaling();
return isImmersive(m_mode) && device && device->supportsViewportScaling();
}

bool WebXRSession::isPositionEmulated() const
Expand Down Expand Up @@ -591,7 +586,7 @@ void WebXRSession::onFrame(PlatformXR::Device::FrameData&& frameData)
// 6. If the frame should be rendered for session:
if (frameShouldBeRendered() && m_frameData.shouldRender) {
// Prepare all layers for render
if (m_mode == XRSessionMode::ImmersiveVr && m_activeRenderState->baseLayer())
if (isImmersive(m_mode) && m_activeRenderState->baseLayer())
m_activeRenderState->baseLayer()->startFrame(m_frameData);

// 6.1.Set session’s list of currently running animation frame callbacks to be session’s list of animation frame callbacks.
Expand Down Expand Up @@ -628,7 +623,7 @@ void WebXRSession::onFrame(PlatformXR::Device::FrameData&& frameData)

// Submit current frame layers to the device.
Vector<PlatformXR::Device::Layer> frameLayers;
if (m_mode == XRSessionMode::ImmersiveVr && m_activeRenderState->baseLayer())
if (isImmersive(m_mode) && m_activeRenderState->baseLayer())
frameLayers.append(m_activeRenderState->baseLayer()->endFrame());

if (auto device = m_device.get())
Expand Down
6 changes: 3 additions & 3 deletions Source/WebCore/Modules/webxr/WebXRSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ void WebXRSystem::ensureImmersiveXRDeviceIsSelected(CompletionHandler<void()>&&

void WebXRSystem::obtainCurrentDevice(XRSessionMode mode, const JSFeatureList& requiredFeatures, const JSFeatureList& optionalFeatures, CompletionHandler<void(ThreadSafeWeakPtr<PlatformXR::Device>)>&& callback)
{
if (mode == XRSessionMode::ImmersiveAr || mode == XRSessionMode::ImmersiveVr) {
if (isImmersive(mode)) {
ensureImmersiveXRDeviceIsSelected([this, callback = WTFMove(callback)]() mutable {
callback(m_activeImmersiveDevice);
});
Expand Down Expand Up @@ -311,7 +311,7 @@ std::optional<WebXRSystem::ResolvedRequestedFeatures> WebXRSystem::resolveReques
// https://immersive-web.github.io/webxr/#default-features
auto requiredFeaturesWithDefaultFeatures = init.requiredFeatures;
requiredFeaturesWithDefaultFeatures.append(JSC::jsStringWithCache(globalObject.vm(), PlatformXR::sessionFeatureDescriptor(PlatformXR::SessionFeature::ReferenceSpaceTypeViewer)));
if (mode == XRSessionMode::ImmersiveAr || mode == XRSessionMode::ImmersiveVr)
if (isImmersive(mode))
requiredFeaturesWithDefaultFeatures.append(JSC::jsStringWithCache(globalObject.vm(), PlatformXR::sessionFeatureDescriptor(PlatformXR::SessionFeature::ReferenceSpaceTypeLocal)));

// 8. For each feature in requiredFeatures|optionalFeatures perform the following steps:
Expand Down Expand Up @@ -453,7 +453,7 @@ void WebXRSystem::requestSession(Document& document, XRSessionMode mode, const X
// 1. Let promise be a new Promise.
// 2. Let immersive be true if mode is an immersive session mode, and false otherwise.
// 3. Let global object be the relevant Global object for the XRSystem on which this method was invoked.
bool immersive = mode == XRSessionMode::ImmersiveAr || mode == XRSessionMode::ImmersiveVr;
bool immersive = isImmersive(mode);
Ref protectedDocument { document };
RefPtr globalObject = protectedDocument->domWindow();
if (!globalObject) {
Expand Down
6 changes: 6 additions & 0 deletions Source/WebCore/platform/xr/PlatformXR.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ enum class SessionMode : uint8_t {
ImmersiveAr,
};

inline bool isImmersive(SessionMode mode)
{
using enum PlatformXR::SessionMode;
return mode == ImmersiveAr || mode == ImmersiveVr;
}

enum class ReferenceSpaceType {
Viewer,
Local,
Expand Down
3 changes: 2 additions & 1 deletion Source/WebCore/platform/xr/cocoa/PlatformXRCocoa.mm
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@
#import "config.h"
#import "PlatformXRCocoa.h"

#if ENABLE(WEBXR) && USE(EMPTYXR)
#if ENABLE(WEBXR) && !USE(OPENXR)

#import "PlatformXR.h"
#import <wtf/NeverDestroyed.h>

using namespace WebCore;
Expand Down
3 changes: 2 additions & 1 deletion Source/WebKit/Configurations/WebKit.xcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,9 @@ WK_NETWORK_EXTENSION_LDFLAGS_macosx = -weak_framework NetworkExtension;
WK_APPSERVERSUPPORT_LDFLAGS[sdk=macosx*] = -framework AppServerSupport
WK_APPSERVERSUPPORT_LDFLAGS[sdk=iphone*] = -framework AppServerSupport

FRAMEWORK_AND_LIBRARY_LDFLAGS = -lobjc -framework CFNetwork -framework CoreAudio -framework CoreFoundation -framework CoreGraphics -framework CoreText -framework Foundation -framework ImageIO -framework IOKit -framework IOSurface -framework WebKitLegacy -lnetwork -framework Metal $(WK_APPSERVERSUPPORT_LDFLAGS) $(WK_ACCESSIBILITY_LDFLAGS) $(WK_APPKIT_LDFLAGS) $(WK_APPLE_PUSH_SERVICE_LDFLAGS) $(WK_BACKBOARD_SERVICES_LDFLAGS) $(WK_RUNNINGBOARD_SERVICES_LDFLAGS) $(WK_AUTHKIT_LDFLAGS) $(WK_CARBON_LDFLAGS) $(WK_CONTACTS_LDFLAGS) $(WK_CORE_PREDICTION_LDFLAGS) $(WK_CORE_SERVICES_LDFLAGS) $(WK_GRAPHICS_SERVICES_LDFLAGS) $(WK_LIBNETWORKEXTENSION_LDFLAGS) $(WK_LIBSANDBOX_LDFLAGS) $(WK_LIBWEBRTC_LDFLAGS) $(WK_MOBILE_CORE_SERVICES_LDFLAGS) $(WK_MOBILE_GESTALT_LDFLAGS) $(WK_PDFKIT_LDFLAGS) $(WK_PROTOTYPE_TOOLS_LDFLAGS) $(WK_SAFE_BROWSING_LDFLAGS) $(WK_SECURITY_INTERFACE_LDFLAGS) $(WK_UIKIT_LDFLAGS) $(WK_MRUIKIT_LDFLAGS) $(WK_UNIFORM_TYPE_IDENTIFIERS_LDFLAGS) $(WK_URL_FORMATTING_LDFLAGS) $(WK_WEBINSPECTORUI_LDFLAGS) $(WK_COORDINATOR_LDFLAGS) $(WK_INSTALL_COORDINATION_LDFLAGS) $(WK_APP_STORE_DAEMON_LDFLAGS) $(WK_POWERLOG_LDFLAGS) $(WK_FRONTBOARDSERVICES_LDFLAGS) $(WK_LIBBSM_LDFLAGS) $(WK_NETWORK_EXTENSION_LDFLAGS);
WK_ARKIT_LDFLAGS[sdk=iphone*] = -framework ARKit;

FRAMEWORK_AND_LIBRARY_LDFLAGS = -lobjc -framework CFNetwork -framework CoreAudio -framework CoreFoundation -framework CoreGraphics -framework CoreText -framework Foundation -framework ImageIO -framework IOKit -framework IOSurface -framework WebKitLegacy -lnetwork -framework Metal $(WK_APPSERVERSUPPORT_LDFLAGS) $(WK_ACCESSIBILITY_LDFLAGS) $(WK_APPKIT_LDFLAGS) $(WK_APPLE_PUSH_SERVICE_LDFLAGS) $(WK_BACKBOARD_SERVICES_LDFLAGS) $(WK_RUNNINGBOARD_SERVICES_LDFLAGS) $(WK_AUTHKIT_LDFLAGS) $(WK_CARBON_LDFLAGS) $(WK_CONTACTS_LDFLAGS) $(WK_CORE_PREDICTION_LDFLAGS) $(WK_CORE_SERVICES_LDFLAGS) $(WK_GRAPHICS_SERVICES_LDFLAGS) $(WK_LIBNETWORKEXTENSION_LDFLAGS) $(WK_LIBSANDBOX_LDFLAGS) $(WK_LIBWEBRTC_LDFLAGS) $(WK_MOBILE_CORE_SERVICES_LDFLAGS) $(WK_MOBILE_GESTALT_LDFLAGS) $(WK_PDFKIT_LDFLAGS) $(WK_PROTOTYPE_TOOLS_LDFLAGS) $(WK_SAFE_BROWSING_LDFLAGS) $(WK_SECURITY_INTERFACE_LDFLAGS) $(WK_UIKIT_LDFLAGS) $(WK_MRUIKIT_LDFLAGS) $(WK_UNIFORM_TYPE_IDENTIFIERS_LDFLAGS) $(WK_URL_FORMATTING_LDFLAGS) $(WK_WEBINSPECTORUI_LDFLAGS) $(WK_COORDINATOR_LDFLAGS) $(WK_INSTALL_COORDINATION_LDFLAGS) $(WK_APP_STORE_DAEMON_LDFLAGS) $(WK_POWERLOG_LDFLAGS) $(WK_FRONTBOARDSERVICES_LDFLAGS) $(WK_LIBBSM_LDFLAGS) $(WK_NETWORK_EXTENSION_LDFLAGS) $(WK_ARKIT_LDFLAGS);

// Prevent C++ standard library basic_stringstream, operator new, delete and their related exception types from being exported as weak symbols.
UNEXPORTED_SYMBOL_LDFLAGS = -Wl,-unexported_symbol -Wl,__ZTISt9bad_alloc -Wl,-unexported_symbol -Wl,__ZTISt9exception -Wl,-unexported_symbol -Wl,__ZTSSt9bad_alloc -Wl,-unexported_symbol -Wl,__ZTSSt9exception -Wl,-unexported_symbol -Wl,__ZdlPvS_ -Wl,-unexported_symbol -Wl,__ZnwmPv -Wl,-unexported_symbol -Wl,__Znwm -Wl,-unexported_symbol -Wl,__ZTVNSt3__117bad_function_callE -Wl,-unexported_symbol -Wl,__ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE0_NS_13basic_istreamIcS2_EE -Wl,-unexported_symbol -Wl,__ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE0_NS_14basic_iostreamIcS2_EE -Wl,-unexported_symbol -Wl,__ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE16_NS_13basic_ostreamIcS2_EE -Wl,-unexported_symbol -Wl,__ZTTNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE -Wl,-unexported_symbol -Wl,__ZTVNSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEEE -Wl,-unexported_symbol -Wl,__ZTVNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE -Wl,-unexported_symbol -Wl,__ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE8_NS_13basic_ostreamIcS2_EE;
Expand Down
1 change: 1 addition & 0 deletions Source/WebKit/Shared/XR/XRDeviceInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ struct XRDeviceInfo {
bool supportsOrientationTracking { false };
bool supportsStereoRendering { false };
PlatformXR::Device::FeatureList vrFeatures;
PlatformXR::Device::FeatureList arFeatures;
WebCore::IntSize recommendedResolution { 0, 0 };
};

Expand Down
4 changes: 3 additions & 1 deletion Source/WebKit/Shared/XR/XRDeviceProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ XRDeviceProxy::XRDeviceProxy(XRDeviceInfo&& deviceInfo, PlatformXRSystemProxy& x
m_recommendedResolution = deviceInfo.recommendedResolution;
if (!deviceInfo.vrFeatures.isEmpty())
setSupportedFeatures(SessionMode::ImmersiveVr, deviceInfo.vrFeatures);
if (!deviceInfo.arFeatures.isEmpty())
setSupportedFeatures(SessionMode::ImmersiveAr, deviceInfo.arFeatures);
}

void XRDeviceProxy::sessionDidEnd()
Expand All @@ -66,7 +68,7 @@ void XRDeviceProxy::updateSessionVisibilityState(PlatformXR::VisibilityState vis

void XRDeviceProxy::initializeTrackingAndRendering(const WebCore::SecurityOriginData& securityOriginData, PlatformXR::SessionMode sessionMode, const PlatformXR::Device::FeatureList& requestedFeatures)
{
if (sessionMode != PlatformXR::SessionMode::ImmersiveVr)
if (!isImmersive(sessionMode))
return;

if (!m_xrSystem)
Expand Down
1 change: 1 addition & 0 deletions Source/WebKit/Shared/XR/XRSystem.serialization.in
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ struct WebKit::XRDeviceInfo {
bool supportsOrientationTracking;
bool supportsStereoRendering;
PlatformXR::Device::FeatureList vrFeatures;
PlatformXR::Device::FeatureList arFeatures;
WebCore::IntSize recommendedResolution;
};
#endif
3 changes: 3 additions & 0 deletions Source/WebKit/SourcesCocoa.txt
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,9 @@ UIProcess/WebAuthentication/Mock/MockCcidService.mm

UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm

UIProcess/XR/ios/PlatformXRARKit.mm
UIProcess/XR/ios/PlatformXRSystemIOS.mm

WebProcess/API/Cocoa/WKWebProcess.cpp

WebProcess/ApplePay/WebPaymentCoordinator.cpp
Expand Down
58 changes: 58 additions & 0 deletions Source/WebKit/UIProcess/XR/ios/PlatformXRARKit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (C) 2023 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/


#pragma once

#if ENABLE(WEBXR) && USE(ARKITXR_IOS)

#import "PlatformXRCoordinator.h"

@class ARSession;

namespace WebKit {

class ARKitCoordinator final : public PlatformXRCoordinator {
WTF_MAKE_FAST_ALLOCATED;
public:
ARKitCoordinator();
virtual ~ARKitCoordinator() = default;

void getPrimaryDeviceInfo(DeviceInfoCallback&&) override;
void requestPermissionOnSessionFeatures(WebPageProxy&, const WebCore::SecurityOriginData&, PlatformXR::SessionMode, const PlatformXR::Device::FeatureList&, const PlatformXR::Device::FeatureList&, const PlatformXR::Device::FeatureList&, const PlatformXR::Device::FeatureList&, const PlatformXR::Device::FeatureList&, FeatureListCallback&&) override;

void startSession(WebPageProxy&, WeakPtr<SessionEventClient>&&, const WebCore::SecurityOriginData&, PlatformXR::SessionMode, const PlatformXR::Device::FeatureList&) override;
void endSessionIfExists(WebPageProxy&) override;

void scheduleAnimationFrame(WebPageProxy&, PlatformXR::Device::RequestFrameCallback&&) override;
void submitFrame(WebPageProxy&) override;

private:
XRDeviceIdentifier m_deviceIdentifier = XRDeviceIdentifier::generate();
};

} // namespace WebKit

#endif // ENABLE(WEBXR) && USE(ARKITXR_IOS)
109 changes: 109 additions & 0 deletions Source/WebKit/UIProcess/XR/ios/PlatformXRARKit.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright (C) 2023 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#import "config.h"
#import "PlatformXRARKit.h"

#import "APIUIClient.h"
#import "WebPageProxy.h"

#if ENABLE(WEBXR) && USE(ARKITXR_IOS)

#import <ARKit/ARKit.h>

namespace WebKit {

ARKitCoordinator::ARKitCoordinator()
{
ASSERT(RunLoop::isMain());
}

void ARKitCoordinator::getPrimaryDeviceInfo(DeviceInfoCallback&& callback)
{
RELEASE_LOG(XR, "ARKitCoordinator::getPrimaryDeviceInfo");
ASSERT(RunLoop::isMain());

if (!ARWorldTrackingConfiguration.isSupported) {
RELEASE_LOG_ERROR(XR, "ARKitCoordinator: WorldTrackingConfiguration is not supported");
return callback(std::nullopt);
}

NSArray<ARVideoFormat *> *supportedVideoFormats = ARWorldTrackingConfiguration.supportedVideoFormats;
if (![supportedVideoFormats count])
return callback(std::nullopt);

CGSize recommendedResolution = supportedVideoFormats[0].imageResolution;

ASSERT(m_deviceIdentifier);
XRDeviceInfo deviceInfo;
deviceInfo.identifier = m_deviceIdentifier;
deviceInfo.supportsOrientationTracking = true;
deviceInfo.supportsStereoRendering = false;
deviceInfo.recommendedResolution = WebCore::IntSize(recommendedResolution.width, recommendedResolution.height);
deviceInfo.arFeatures.append(PlatformXR::SessionFeature::ReferenceSpaceTypeUnbounded);
deviceInfo.arFeatures.append(PlatformXR::SessionFeature::ReferenceSpaceTypeLocalFloor);
deviceInfo.arFeatures.append(PlatformXR::SessionFeature::ReferenceSpaceTypeLocal);
deviceInfo.arFeatures.append(PlatformXR::SessionFeature::ReferenceSpaceTypeViewer);

callback(WTFMove(deviceInfo));
}

void ARKitCoordinator::requestPermissionOnSessionFeatures(WebPageProxy& page, const WebCore::SecurityOriginData& securityOriginData, PlatformXR::SessionMode mode, const PlatformXR::Device::FeatureList& granted, const PlatformXR::Device::FeatureList& consentRequired, const PlatformXR::Device::FeatureList& consentOptional, const PlatformXR::Device::FeatureList& requiredFeaturesRequested, const PlatformXR::Device::FeatureList& optionalFeaturesRequested, FeatureListCallback&& callback)
{
RELEASE_LOG(XR, "ARKitCoordinator::requestPermissionOnSessionFeatures");
if (mode == PlatformXR::SessionMode::Inline) {
callback(granted);
return;
}

page.uiClient().requestPermissionOnXRSessionFeatures(page, securityOriginData, mode, granted, consentRequired, consentOptional, requiredFeaturesRequested, optionalFeaturesRequested, [callback = WTFMove(callback)](std::optional<Vector<PlatformXR::SessionFeature>> userGranted) mutable {
callback(WTFMove(userGranted));
});
}

void ARKitCoordinator::startSession(WebPageProxy&, WeakPtr<SessionEventClient>&&, const WebCore::SecurityOriginData&, PlatformXR::SessionMode, const PlatformXR::Device::FeatureList&)
{
RELEASE_LOG(XR, "ARKitCoordinator::startSession");
}

void ARKitCoordinator::endSessionIfExists(WebPageProxy&)
{
RELEASE_LOG(XR, "ARKitCoordinator::endSessionIfExists");
}

void ARKitCoordinator::scheduleAnimationFrame(WebPageProxy&, PlatformXR::Device::RequestFrameCallback&& onFrameUpdateCallback)
{
RELEASE_LOG(XR, "ARKitCoordinator::scheduleAnimationFrame");
onFrameUpdateCallback({ });
}

void ARKitCoordinator::submitFrame(WebPageProxy&)
{
RELEASE_LOG(XR, "ARKitCoordinator::submitFrame");
}

} // namespace WebKit

#endif // ENABLE(WEBXR) && USE(ARKITXR_IOS)
52 changes: 52 additions & 0 deletions Source/WebKit/UIProcess/XR/ios/PlatformXRSystemIOS.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (C) 2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#if ENABLE(WEBXR) && PLATFORM(IOS)

#import "config.h"
#import "PlatformXRSystem.h"

#import "PlatformXRARKit.h"
#import <wtf/NeverDestroyed.h>

namespace WebKit {

PlatformXRCoordinator* PlatformXRSystem::xrCoordinator()
{
#if USE(ARKITXR_IOS)
static LazyNeverDestroyed<ARKitCoordinator> xrCoordinator;
static std::once_flag once;
std::call_once(once, [] {
xrCoordinator.construct();
});
return &xrCoordinator.get();
#else
return nullptr;
#endif // USE(ARKITXR_IOS)
}

} // namespace WebKit

#endif // ENABLE(WEBXR) && PLATFORM(IOS)
Loading

0 comments on commit 7ad679f

Please sign in to comment.