diff --git a/.github/jobs/ios.yml b/.github/jobs/ios.yml index a5d71e12d..893199682 100644 --- a/.github/jobs/ios.yml +++ b/.github/jobs/ios.yml @@ -2,6 +2,7 @@ parameters: name: "" vmImage: "" deploymentTarget: "15" + xcodeVersion: "" jobs: - job: ${{parameters.name}} @@ -15,8 +16,8 @@ jobs: vmImage: ${{parameters.vmImage}} - script: | - sudo xcode-select --switch /Applications/Xcode_$(XCODE_VERSION).app/Contents/Developer - displayName: "Select Xcode $(XCODE_VERSION)" + sudo xcode-select --switch /Applications/Xcode_${{parameters.xcodeVersion}}.app/Contents/Developer + displayName: "Select Xcode ${{parameters.xcodeVersion}}" - script: | cmake -G Xcode -B build/iOS -D IOS=ON -D DEPLOYMENT_TARGET=${{parameters.deploymentTarget}} -D BABYLON_DEBUG_TRACE=ON -D CMAKE_IOS_INSTALL_COMBINED=NO diff --git a/.github/jobs/macos.yml b/.github/jobs/macos.yml index 5cd97cc1d..68ba487c1 100644 --- a/.github/jobs/macos.yml +++ b/.github/jobs/macos.yml @@ -3,6 +3,7 @@ parameters: vmImage: "" enableSanitizers: false generator: Xcode + xcodeVersion: "" jobs: - job: ${{parameters.name}} @@ -19,8 +20,8 @@ jobs: vmImage: ${{parameters.vmImage}} - script: | - sudo xcode-select --switch /Applications/Xcode_$(XCODE_VERSION).app/Contents/Developer - displayName: "Select XCode $(XCODE_VERSION)" + sudo xcode-select --switch /Applications/Xcode_${{parameters.xcodeVersion}}.app/Contents/Developer + displayName: "Select Xcode ${{parameters.xcodeVersion}}" - script: | cmake -G "${{parameters.generator}}" -B build/macOS -D BABYLON_DEBUG_TRACE=ON -D ENABLE_SANITIZERS=$(SANITIZER_FLAG) -D BABYLON_NATIVE_TESTS_USE_NOOP_METAL_DEVICE=ON diff --git a/.github/jobs/test_install_ios.yml b/.github/jobs/test_install_ios.yml index 1f1321963..6448719df 100644 --- a/.github/jobs/test_install_ios.yml +++ b/.github/jobs/test_install_ios.yml @@ -2,6 +2,7 @@ parameters: name: "" vmImage: "" deploymentTarget: "15" + xcodeVersion: "" jobs: - job: ${{parameters.name}} @@ -15,8 +16,8 @@ jobs: vmImage: ${{parameters.vmImage}} - script: | - sudo xcode-select --switch /Applications/Xcode_$(XCODE_VERSION).app/Contents/Developer - displayName: "Select Xcode $(XCODE_VERSION)" + sudo xcode-select --switch /Applications/Xcode_${{parameters.xcodeVersion}}.app/Contents/Developer + displayName: "Select Xcode ${{parameters.xcodeVersion}}" - script: | cmake -B build/iOS -G Xcode -D IOS=ON -D DEPLOYMENT_TARGET=${{parameters.deploymentTarget}} -D CMAKE_IOS_INSTALL_COMBINED=NO -D BABYLON_NATIVE_BUILD_APPS=OFF -D BABYLON_DEBUG_TRACE=ON diff --git a/.github/jobs/test_install_macos.yml b/.github/jobs/test_install_macos.yml index f0850decd..9c9f7d057 100644 --- a/.github/jobs/test_install_macos.yml +++ b/.github/jobs/test_install_macos.yml @@ -1,6 +1,7 @@ parameters: name: "" vmImage: "" + xcodeVersion: "" jobs: - job: ${{parameters.name}} @@ -14,8 +15,8 @@ jobs: vmImage: ${{parameters.vmImage}} - script: | - sudo xcode-select --switch /Applications/Xcode_$(XCODE_VERSION).app/Contents/Developer - displayName: "Select XCode $(XCODE_VERSION)" + sudo xcode-select --switch /Applications/Xcode_${{parameters.xcodeVersion}}.app/Contents/Developer + displayName: "Select Xcode ${{parameters.xcodeVersion}}" - script: | cmake -B build/macOS -G Xcode -D BABYLON_NATIVE_BUILD_APPS=OFF -D BABYLON_DEBUG_TRACE=ON diff --git a/Core/Graphics/Source/DeviceImpl_iOS.mm b/Core/Graphics/Source/DeviceImpl_iOS.mm index d77d17243..011ce2692 100644 --- a/Core/Graphics/Source/DeviceImpl_iOS.mm +++ b/Core/Graphics/Source/DeviceImpl_iOS.mm @@ -5,6 +5,15 @@ #import #import + +namespace +{ + bool IsValidScale(float scale) + { + return !std::isinf(scale) && scale > 0; + } +} + namespace Babylon::Graphics { void DeviceImpl::ConfigureBgfxPlatformData(bgfx::PlatformData& pd, WindowT window) @@ -19,12 +28,32 @@ float DeviceImpl::GetDevicePixelRatio(WindowT window) { // contentsScale can return 0 if it hasn't been set yet. - // Fallback to the scale from the main screen. float scale = static_cast(((CAMetalLayer*)window).contentsScale); - if (std::isinf(scale) || scale <= 0) + if (IsValidScale(scale)) { - scale = UIScreen.mainScreen.scale; + return scale; } - return scale; + + // Prefer getting the scale from the active window scene's trait collection. + if (@available(iOS 17.0, *)) + { + for (UIScene* scene in UIApplication.sharedApplication.connectedScenes) + { + if ([scene isKindOfClass:[UIWindowScene class]]) + { + scale = static_cast(((UIWindowScene*)scene).traitCollection.displayScale); + if (IsValidScale(scale)) + { + return scale; + } + } + } + } + + // Fallback for older iOS versions or if no active scene was found. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + return UIScreen.mainScreen.scale; +#pragma clang diagnostic pop } } diff --git a/Dependencies/xr/Source/ARKit/XR.mm b/Dependencies/xr/Source/ARKit/XR.mm index d1bf5f6fe..82a8ed6c9 100644 --- a/Dependencies/xr/Source/ARKit/XR.mm +++ b/Dependencies/xr/Source/ARKit/XR.mm @@ -257,18 +257,19 @@ - (void) UnlockAnchors { Returns the orientation of the app */ - (UIInterfaceOrientation)orientation { - UIApplication* sharedApplication = [UIApplication sharedApplication]; -#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_13_0) - UIScene* scene = [[[sharedApplication connectedScenes] allObjects] firstObject]; - return [(UIWindowScene*)scene interfaceOrientation]; -#else - if (@available(iOS 13.0, *)) { - return [[[[sharedApplication windows] firstObject] windowScene] interfaceOrientation]; + UIApplication* app = [UIApplication sharedApplication]; + if (@available(iOS 26.0, *)) { + UIWindowScene* windowScene = (UIWindowScene*)[[[app connectedScenes] allObjects] firstObject]; + return windowScene.effectiveGeometry.interfaceOrientation; } - else { - return [sharedApplication statusBarOrientation]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + if (@available(iOS 13.0, *)) { + UIWindowScene* windowScene = [[[app windows] firstObject] windowScene]; + return [windowScene interfaceOrientation]; } -#endif + return [app statusBarOrientation]; +#pragma clang diagnostic pop } /** diff --git a/Plugins/NativeCamera/Source/Apple/CameraDevice.mm b/Plugins/NativeCamera/Source/Apple/CameraDevice.mm index d8b7393d5..8cfbc5922 100644 --- a/Plugins/NativeCamera/Source/Apple/CameraDevice.mm +++ b/Plugins/NativeCamera/Source/Apple/CameraDevice.mm @@ -900,23 +900,27 @@ - (void) reset { } #if (TARGET_OS_IPHONE) + +static UIInterfaceOrientation GetCurrentInterfaceOrientation(UIApplication* app) { + if (@available(iOS 26.0, *)) { + UIWindowScene* windowScene = (UIWindowScene*)[[[app connectedScenes] allObjects] firstObject]; + return windowScene.effectiveGeometry.interfaceOrientation; + } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + if (@available(iOS 13.0, *)) { + UIWindowScene* windowScene = [[[app windows] firstObject] windowScene]; + return [windowScene interfaceOrientation]; + } + return [app statusBarOrientation]; +#pragma clang diagnostic pop +} + /** Updates target video orientation. */ - (void)updateOrientation { - UIApplication* sharedApplication{[UIApplication sharedApplication]}; - UIInterfaceOrientation orientation{UIInterfaceOrientationUnknown}; -#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_13_0) - UIScene* scene{[[[sharedApplication connectedScenes] allObjects] firstObject]}; - orientation = [(UIWindowScene*)scene interfaceOrientation]; -#else - if (@available(iOS 13.0, *)) { - orientation = [[[[sharedApplication windows] firstObject] windowScene] interfaceOrientation]; - } - else { - orientation = [sharedApplication statusBarOrientation]; - } -#endif + UIInterfaceOrientation orientation = GetCurrentInterfaceOrientation([UIApplication sharedApplication]); // Convert from UIInterfaceOrientation to VideoOrientation. switch (orientation) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 7cb9e015a..687a1bc91 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,8 +9,6 @@ variables: value: 3.31.6 - name: NDK_VERSION value: 28.2.13676358 - - name: XCODE_VERSION - value: 16.4 jobs: # Apple @@ -18,31 +16,50 @@ jobs: parameters: name: MacOS vmImage: macOS-latest + xcodeVersion: "16.4" - template: .github/jobs/macos.yml parameters: name: MacOS_Ninja vmImage: macOS-latest + xcodeVersion: "16.4" generator: Ninja Multi-Config - template: .github/jobs/macos.yml parameters: name: MacOS_Sanitizers vmImage: macOS-latest + xcodeVersion: "16.4" enableSanitizers: true - template: .github/jobs/ios.yml parameters: name: iOS_iOS180 vmImage: macOS-latest + xcodeVersion: "16.4" deploymentTarget: 18.0 - template: .github/jobs/ios.yml parameters: name: iOS_iOS175 vmImage: macOS-latest + xcodeVersion: "16.4" deploymentTarget: 17.5 + # Xcode 26 + - template: .github/jobs/macos.yml + parameters: + name: MacOS_Xcode26 + vmImage: macOS-latest + xcodeVersion: "26.3" + + - template: .github/jobs/ios.yml + parameters: + name: iOS_Xcode26 + vmImage: macOS-latest + xcodeVersion: "26.3" + deploymentTarget: 26.0 + # Win32 - template: .github/jobs/win32.yml parameters: @@ -166,6 +183,7 @@ jobs: parameters: name: iOS_Installation vmImage: macOS-latest + xcodeVersion: "16.4" deploymentTarget: 17.2 - template: .github/jobs/test_install_linux.yml parameters: @@ -175,6 +193,7 @@ jobs: parameters: name: MacOS_Installation vmImage: macOS-latest + xcodeVersion: "16.4" - template: .github/jobs/test_install_win32.yml parameters: name: Win32_Installation