Skip to content
5 changes: 3 additions & 2 deletions .github/jobs/ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ parameters:
name: ""
vmImage: ""
deploymentTarget: "15"
xcodeVersion: ""

jobs:
- job: ${{parameters.name}}
Expand All @@ -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
Expand Down
5 changes: 3 additions & 2 deletions .github/jobs/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ parameters:
vmImage: ""
enableSanitizers: false
generator: Xcode
xcodeVersion: ""

jobs:
- job: ${{parameters.name}}
Expand All @@ -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
Expand Down
5 changes: 3 additions & 2 deletions .github/jobs/test_install_ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ parameters:
name: ""
vmImage: ""
deploymentTarget: "15"
xcodeVersion: ""

jobs:
- job: ${{parameters.name}}
Expand All @@ -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
Expand Down
5 changes: 3 additions & 2 deletions .github/jobs/test_install_macos.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
parameters:
name: ""
vmImage: ""
xcodeVersion: ""

jobs:
- job: ${{parameters.name}}
Expand All @@ -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
Expand Down
37 changes: 33 additions & 4 deletions Core/Graphics/Source/DeviceImpl_iOS.mm
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@
#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>


namespace
{
bool IsValidScale(float scale)
{
return !std::isinf(scale) && scale > 0;
}
}

namespace Babylon::Graphics
{
void DeviceImpl::ConfigureBgfxPlatformData(bgfx::PlatformData& pd, WindowT window)
Expand All @@ -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<float>(((CAMetalLayer*)window).contentsScale);
if (std::isinf(scale) || scale <= 0)
if (IsValidScale(scale))
{
scale = UIScreen.mainScreen.scale;
Copy link
Copy Markdown
Contributor

@bghgary bghgary Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand what it's doing here. Does this code actually work? The documentation says traitCollection.displayScale is 0.0 by default.

https://developer.apple.com/documentation/uikit/uitraitcollection/displayscale?language=objc

FYI @ryantrem

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<float>(((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
}
}
21 changes: 11 additions & 10 deletions Dependencies/xr/Source/ARKit/XR.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

/**
Expand Down
30 changes: 17 additions & 13 deletions Plugins/NativeCamera/Source/Apple/CameraDevice.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
23 changes: 21 additions & 2 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,40 +9,57 @@ variables:
value: 3.31.6
- name: NDK_VERSION
value: 28.2.13676358
- name: XCODE_VERSION
value: 16.4

jobs:
# Apple
- template: .github/jobs/macos.yml
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:
Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand Down
Loading