From 04e52210d732125e58f00e1a1a777a69e0f3af35 Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Tue, 5 May 2026 10:25:18 +0100 Subject: [PATCH] Restore support for building ANGLE for macOS 10.15 This (partially) reverts upstream ANGLE commit d28c6adf936bb811b5eb992919a0df88624eed3f. Upstream ANGLE no longer supports macOS < 12, but Firefox still needs to support 10.15. This patch allows ANGLE's Metal backend, and the translator's GLSL and MSL backends to be built with a minimum macOS version of 10.15. Note, however, that the `angle_metal_backend` target is compiled with the `-Wno-unguarded-availability` flag, so this does not guarantee that all uses of modern APIs are correctly guarded. Nor does it guarantee that Metal shader code emitted by the translator targets a version of Metal supported on older OS versions. While Firefox can therefore safely use the translator's GLSL backend on older macOS versions, both the Metal backend and the translator's MSL backend will not be safe to use. --- src/common/apple_platform_utils.mm | 9 +++++++-- src/gpu_info_util/SystemInfo_macos.mm | 24 ++++++++++++++++++++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/common/apple_platform_utils.mm b/src/common/apple_platform_utils.mm index 635abb6..8d0f6a6 100644 --- a/src/common/apple_platform_utils.mm +++ b/src/common/apple_platform_utils.mm @@ -122,8 +122,13 @@ bool IsMetalRendererAvailable() #if defined(ANGLE_PLATFORM_MACOS) || defined(ANGLE_PLATFORM_MACCATALYST) bool GetMacosMachineModel(std::string *outMachineModel) { - io_service_t platformExpert = IOServiceGetMatchingService( - kIOMainPortDefault, IOServiceMatching("IOPlatformExpertDevice")); +# if TARGET_OS_OSX && __MAC_OS_X_VERSION_MIN_REQUIRED < 120000 + const mach_port_t mainPort = kIOMasterPortDefault; +# else + const mach_port_t mainPort = kIOMainPortDefault; +# endif + io_service_t platformExpert = + IOServiceGetMatchingService(mainPort, IOServiceMatching("IOPlatformExpertDevice")); if (platformExpert == IO_OBJECT_NULL) { diff --git a/src/gpu_info_util/SystemInfo_macos.mm b/src/gpu_info_util/SystemInfo_macos.mm index 40c5ec9..17cccfa 100644 --- a/src/gpu_info_util/SystemInfo_macos.mm +++ b/src/gpu_info_util/SystemInfo_macos.mm @@ -55,6 +55,11 @@ bool GetEntryProperty(io_registry_entry_t entry, CFStringRef name, uint32_t *val // Gathers the vendor and device IDs for GPUs listed in the IORegistry. void GetIORegistryDevices(std::vector *devices) { +#if TARGET_OS_OSX && __MAC_OS_X_VERSION_MIN_REQUIRED < 120000 + const mach_port_t mainPort = kIOMasterPortDefault; +#else + const mach_port_t mainPort = kIOMainPortDefault; +#endif constexpr uint32_t kNumServices = 2; const char *kServiceNames[kNumServices] = {"IOGraphicsAccelerator2", "AGXAccelerator"}; const bool kServiceIsGraphicsAccelerator2[kNumServices] = {true, false}; @@ -65,7 +70,7 @@ void GetIORegistryDevices(std::vector *devices) ANGLE_UNSAFE_TODO(IOServiceMatching(kServiceNames[i])); io_iterator_t entryIterator; - if (IOServiceGetMatchingServices(kIOMainPortDefault, matchDictionary, &entryIterator) != + if (IOServiceGetMatchingServices(mainPort, matchDictionary, &entryIterator) != kIOReturnSuccess) { continue; @@ -145,6 +150,12 @@ void GetIORegistryDevices(std::vector *devices) void ForceGPUSwitchIndex(SystemInfo *info) { +#if TARGET_OS_OSX && __MAC_OS_X_VERSION_MIN_REQUIRED < 120000 + const mach_port_t mainPort = kIOMasterPortDefault; +#else + const mach_port_t mainPort = kIOMainPortDefault; +#endif + // Early-out if on a single-GPU system if (info->gpus.size() < 2) { @@ -160,7 +171,7 @@ void ForceGPUSwitchIndex(SystemInfo *info) return; CFMutableDictionaryRef matchDictionary = IORegistryEntryIDMatching(gpuID); - io_service_t gpuEntry = IOServiceGetMatchingService(kIOMainPortDefault, matchDictionary); + io_service_t gpuEntry = IOServiceGetMatchingService(mainPort, matchDictionary); if (gpuEntry == IO_OBJECT_NULL) { @@ -257,6 +268,12 @@ uint64_t GetGpuIDFromOpenGLDisplayMask(uint32_t displayMask) // Get VendorID from metal device's registry ID VendorID GetVendorIDFromMetalDeviceRegistryID(uint64_t registryID) { +#if TARGET_OS_OSX && __MAC_OS_X_VERSION_MIN_REQUIRED < 120000 + const mach_port_t mainPort = kIOMasterPortDefault; +#else + const mach_port_t mainPort = kIOMainPortDefault; +#endif + // Get a matching dictionary for the IOGraphicsAccelerator2 CFMutableDictionaryRef matchingDict = IORegistryEntryIDMatching(registryID); if (matchingDict == nullptr) @@ -266,8 +283,7 @@ VendorID GetVendorIDFromMetalDeviceRegistryID(uint64_t registryID) // IOServiceGetMatchingService will consume the reference on the matching dictionary, // so we don't need to release the dictionary. - io_registry_entry_t acceleratorEntry = - IOServiceGetMatchingService(kIOMainPortDefault, matchingDict); + io_registry_entry_t acceleratorEntry = IOServiceGetMatchingService(mainPort, matchingDict); if (acceleratorEntry == IO_OBJECT_NULL) { return 0; -- 2.43.0