Source code
Revision control
Copy as Markdown
Other Tools
From 04e52210d732125e58f00e1a1a777a69e0f3af35 Mon Sep 17 00:00:00 2001
From: Jamie Nicol <jnicol@mozilla.com>
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<GPUDeviceInfo> *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<GPUDeviceInfo> *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<GPUDeviceInfo> *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