diff --git a/patches/0001-metal-drawable-timeout-safety.patch b/patches/0001-metal-drawable-timeout-safety.patch new file mode 100644 index 0000000..526b9a8 --- /dev/null +++ b/patches/0001-metal-drawable-timeout-safety.patch @@ -0,0 +1,40 @@ +From d0d1a5aad7d52a698581fe969b80460a4712c9f8 Mon Sep 17 00:00:00 2001 +From: MAJigsaw77 <77043862+MAJigsaw77@users.noreply.github.com> +Date: Thu, 16 Apr 2026 01:20:32 +0300 +Subject: [PATCH] Avoid blocking on nextDrawable; skip busy frames + +--- + src/libANGLE/renderer/metal/SurfaceMtl.mm | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/src/libANGLE/renderer/metal/SurfaceMtl.mm b/src/libANGLE/renderer/metal/SurfaceMtl.mm +index e57fb5018b..69e5f3d500 100644 +--- a/src/libANGLE/renderer/metal/SurfaceMtl.mm ++++ b/src/libANGLE/renderer/metal/SurfaceMtl.mm +@@ -461,6 +461,7 @@ egl::Error WindowSurfaceMtl::initialize(const egl::Display *display) + mMetalLayer.get().device = metalDevice; + mMetalLayer.get().pixelFormat = mColorFormat.metalFormat; + mMetalLayer.get().framebufferOnly = NO; // Support blitting and glReadPixels ++ mMetalLayer.get().allowsNextDrawableTimeout = YES; // No indefinite waits + + #if TARGET_OS_OSX || TARGET_OS_MACCATALYST + // Autoresize with parent layer. +@@ -651,12 +652,9 @@ angle::Result WindowSurfaceMtl::obtainNextDrawable(const gl::Context *context) + mCurrentDrawable = [mMetalLayer nextDrawable]; + if (!mCurrentDrawable) + { +- // The GPU might be taking too long finishing its rendering to the previous frame. +- // Try again, indefinitely wait until the previous frame render finishes. +- // TODO: this may wait forever here +- mMetalLayer.get().allowsNextDrawableTimeout = NO; +- mCurrentDrawable = [mMetalLayer nextDrawable]; +- mMetalLayer.get().allowsNextDrawableTimeout = YES; ++ // GPU is too busy, skip this frame. ++ // We will try to get drawable again in next frame. ++ return angle::Result::Continue; + } + + if (!mColorTexture) +-- +2.47.1.windows.1 + diff --git a/patches/0002-metal-skip-rendering-when-backbuffer-just-resized.patch b/patches/0002-metal-skip-rendering-when-backbuffer-just-resized.patch new file mode 100644 index 0000000..f482fa7 --- /dev/null +++ b/patches/0002-metal-skip-rendering-when-backbuffer-just-resized.patch @@ -0,0 +1,26 @@ +From f0bb382b1f7a1ca97848e3b8ab92f94f79401d95 Mon Sep 17 00:00:00 2001 +From: MAJigsaw77 <77043862+MAJigsaw77@users.noreply.github.com> +Date: Thu, 16 Apr 2026 09:00:58 +0300 +Subject: [PATCH] Skip frame when backbuffer resized + +--- + src/libANGLE/renderer/metal/SurfaceMtl.mm | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/libANGLE/renderer/metal/SurfaceMtl.mm b/src/libANGLE/renderer/metal/SurfaceMtl.mm +index 69e5f3d500..f55b1d11f5 100644 +--- a/src/libANGLE/renderer/metal/SurfaceMtl.mm ++++ b/src/libANGLE/renderer/metal/SurfaceMtl.mm +@@ -647,6 +647,9 @@ angle::Result WindowSurfaceMtl::obtainNextDrawable(const gl::Context *context) + if (checkIfLayerResized(context)) + { + contextMtl->onBackbufferResized(context, this); ++ ++ // Skip rendering this frame since the backbuffer was just resized/recreated ++ return angle::Result::Continue; + } + + mCurrentDrawable = [mMetalLayer nextDrawable]; +-- +2.47.1.windows.1 + diff --git a/patches/0003-metal-limit-metal-layer-maximum-drawable-count.patch b/patches/0003-metal-limit-metal-layer-maximum-drawable-count.patch new file mode 100644 index 0000000..2b184b4 --- /dev/null +++ b/patches/0003-metal-limit-metal-layer-maximum-drawable-count.patch @@ -0,0 +1,24 @@ +From c8c5326dcf35723611aa2d7db3bd1b0ff64cfbe8 Mon Sep 17 00:00:00 2001 +From: MAJigsaw77 <77043862+MAJigsaw77@users.noreply.github.com> +Date: Thu, 16 Apr 2026 09:24:02 +0300 +Subject: [PATCH] Limit Metal layer drawable count to 2 + +--- + src/libANGLE/renderer/metal/SurfaceMtl.mm | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/libANGLE/renderer/metal/SurfaceMtl.mm b/src/libANGLE/renderer/metal/SurfaceMtl.mm +index f55b1d11f5..f00d8b7faf 100644 +--- a/src/libANGLE/renderer/metal/SurfaceMtl.mm ++++ b/src/libANGLE/renderer/metal/SurfaceMtl.mm +@@ -462,6 +462,7 @@ egl::Error WindowSurfaceMtl::initialize(const egl::Display *display) + mMetalLayer.get().pixelFormat = mColorFormat.metalFormat; + mMetalLayer.get().framebufferOnly = NO; // Support blitting and glReadPixels + mMetalLayer.get().allowsNextDrawableTimeout = YES; // No indefinite waits ++ mMetalLayer.get().maximumDrawableCount = 2; // Low-latency swapchain depth (min buffering, system may extend) + + #if TARGET_OS_OSX || TARGET_OS_MACCATALYST + // Autoresize with parent layer. +-- +2.47.1.windows.1 + diff --git a/patches/0001-Bend-ANGLE-rules-for-MAX_TEXTURE_SIZE-unconditionally.patch b/patches/SE/0001-Bend-ANGLE-rules-for-MAX_TEXTURE_SIZE-unconditionally.patch similarity index 100% rename from patches/0001-Bend-ANGLE-rules-for-MAX_TEXTURE_SIZE-unconditionally.patch rename to patches/SE/0001-Bend-ANGLE-rules-for-MAX_TEXTURE_SIZE-unconditionally.patch diff --git a/patches/0002-Enable-D3D9-support-for-ANGLE_DEFAULT_PLATFORM.patch b/patches/SE/0002-Enable-D3D9-support-for-ANGLE_DEFAULT_PLATFORM.patch similarity index 100% rename from patches/0002-Enable-D3D9-support-for-ANGLE_DEFAULT_PLATFORM.patch rename to patches/SE/0002-Enable-D3D9-support-for-ANGLE_DEFAULT_PLATFORM.patch diff --git a/patches/0003-Drop-verbose-debug-details-from-GL_RENDERER-and-GL_VERSION.patch b/patches/SE/0003-Drop-verbose-debug-details-from-GL_RENDERER-and-GL_VERSION.patch similarity index 100% rename from patches/0003-Drop-verbose-debug-details-from-GL_RENDERER-and-GL_VERSION.patch rename to patches/SE/0003-Drop-verbose-debug-details-from-GL_RENDERER-and-GL_VERSION.patch diff --git a/patches/0004-force-enable-Intel-OpenGL-ES-drivers.patch b/patches/SE/0004-force-enable-Intel-OpenGL-ES-drivers.patch similarity index 100% rename from patches/0004-force-enable-Intel-OpenGL-ES-drivers.patch rename to patches/SE/0004-force-enable-Intel-OpenGL-ES-drivers.patch diff --git a/source/angle/Build.hx b/source/angle/Build.hx index 926e5a5..a860c86 100644 --- a/source/angle/Build.hx +++ b/source/angle/Build.hx @@ -97,10 +97,14 @@ class Build // Copy angle's libs. for (buildConfig in buildConfigs) { - final libsToCopy:Array = ANGLE_LIBS; + var libsToCopy:Array = ANGLE_LIBS; if (buildPlatform == 'windows') - libsToCopy.push('d3dcompiler_47'); + libsToCopy = ['d3dcompiler_47', 'libEGL', 'libGLESv2', 'vk_swiftshader']; + else if (buildPlatform == 'linux') + libsToCopy = ['libEGL', 'libGLESv2', 'libvk_swiftshader']; + else if (buildPlatform == 'macos') + libsToCopy = ['libEGL', 'libGLESv2', 'libVkICD_mock_icd']; for (lib in libsToCopy) { @@ -145,6 +149,11 @@ class Build iosFrameworksToCombine.get(lib)?.get(buildConfig.environment)?.push(libDestination); } } + + if (buildPlatform == 'windows') + FileUtil.copyFile('angle/${buildConfig.getExportPath()}/vk_swiftshader_icd.json', 'build/$buildPlatform/bin/${buildConfig.cpu}/vk_swiftshader_icd.json'); + else if (buildPlatform == 'linux') + FileUtil.copyFile('angle/${buildConfig.getExportPath()}/vk_swiftshader_icd.json', 'build/$buildPlatform/lib/${buildConfig.cpu}/vk_swiftshader_icd.json'); } if (buildPlatform == 'macos') @@ -242,7 +251,18 @@ class Build renderingBackends.push('angle_enable_metal=false'); // Disable Metal backend renderingBackends.push('angle_enable_null=false'); // Disable Null backend renderingBackends.push('angle_enable_wgpu=false'); // Disable WebGPU backend - renderingBackends.push('angle_enable_swiftshader=false'); // Disable SwiftShader + if (buildPlatform != 'android') + { + renderingBackends.push('angle_enable_swiftshader=true'); // Enable SwiftShader + if (buildPlatform == 'windows') + { + renderingBackends.push('use_swiftshader_with_subzero=false'); // Disable Subzero for SwiftShader + } + } + else + { + renderingBackends.push('angle_enable_swiftshader=false'); // Disable SwiftShader + } if (buildPlatform == 'windows') { @@ -258,13 +278,7 @@ class Build renderingBackends.push('angle_enable_vulkan=true'); // Enable Vulkan backend renderingBackends.push('angle_enable_vulkan_api_dump_layer=false'); // Disable Vulkan API dump layer renderingBackends.push('angle_enable_vulkan_validation_layers=false'); // Disable Vulkan validation layers - renderingBackends.push('angle_use_custom_libvulkan=false'); // Use system Vulkan loader only - - if (buildPlatform == 'linux') - { - renderingBackends.push('angle_use_x11=true'); // Use X11 frontend - renderingBackends.push('angle_use_wayland=true'); // Use Wayland frontend - } + renderingBackends.push('angle_use_custom_libvulkan=false'); // Use system Vulkan loader if (buildPlatform == 'windows') { @@ -346,15 +360,19 @@ class Build if (buildPlatform != 'ios') { renderingBackends.push('angle_enable_gl=true'); // Enable OpenGL backend + renderingBackends.push('angle_enable_vulkan=true'); // Enable Vulkan backend + renderingBackends.push('angle_enable_vulkan_api_dump_layer=false'); // Disable Vulkan API dump layer + renderingBackends.push('angle_enable_vulkan_validation_layers=false'); // Disable Vulkan validation layers + renderingBackends.push('angle_use_custom_libvulkan=true'); // Use ANGLE's Vulkan loader } else { renderingBackends.push('angle_enable_gl=false'); // Disable OpenGL backend + renderingBackends.push('angle_enable_vulkan=false'); // Disable Vulkan backend } renderingBackends.push('angle_enable_metal=true'); // Enable Metal backend renderingBackends.push('angle_enable_null=false'); // Disable Null backend renderingBackends.push('angle_enable_wgpu=false'); // Disable WebGPU backend - renderingBackends.push('angle_enable_vulkan=false'); // Disable Vulkan backend renderingBackends.push('angle_enable_swiftshader=false'); // Disable SwiftShader if (buildPlatform == 'macos') @@ -434,7 +452,7 @@ class Build if (buildPlatform == 'ios') targetConfig.args.push('ios_enable_code_signing=false'); else if (buildPlatform == 'android') - targetConfig.args.push('android_ndk_api_level=26'); + targetConfig.args.push('android_ndk_api_level=24'); } @:noCompletion diff --git a/source/angle/Setup.hx b/source/angle/Setup.hx index 7c20559..168eda5 100644 --- a/source/angle/Setup.hx +++ b/source/angle/Setup.hx @@ -45,6 +45,8 @@ class Setup // Configure and sync ANGLE dependencies FileUtil.goAndBackFromDir('angle', function():Void { + final platform:String = Platform.getBuildPlatform(); + // Hard-pin ANGLE to a specific commit Sys.command('git', ['checkout', ANGLE_COMMIT]); @@ -62,37 +64,31 @@ class Setup gclientFile.push(' "managed": False,'); gclientFile.push(' }'); gclientFile.push(']'); + gclientFile.push(''); + if (platform == 'windows') + gclientFile.push('target_os = ["win"]'); + else if (platform == 'linux') + gclientFile.push('target_os = ["linux"]'); + else if (platform == 'mac') + gclientFile.push('target_os = ["mac"]'); + else if (platform == 'android') + gclientFile.push('target_os = ["android"]'); + else if (platform == 'ios') + gclientFile.push('target_os = ["ios"]'); File.saveContent('.gclient', gclientFile.join('\n')); } // Syncing ANGLE dependencies with gclient... Sys.command('gclient', ['sync', '--no-history', '--shallow', '--jobs', '8']); + Sys.command('gclient', ['runhooks']); - // For some reason gclient does not add some stuff so we have to clone it ourselves. - FileUtil.goAndBackFromDir('third_party', function():Void - { - if (!FileSystem.exists('android_sdk/BUILD.gn')) - { - FileUtil.deletePath('android_sdk'); - Sys.command('git', ['clone', 'https://chromium.googlesource.com/chromium/src/third_party/android_sdk']); - } - - if (!FileSystem.exists('ijar/BUILD.gn')) + // weird MSVC quirk + if (platform == 'windows') + FileUtil.goAndBackFromDir('third_party/SwiftShader/third_party/llvm-10.0', function():Void { - FileUtil.deletePath('ijar'); - Sys.command('git', ['clone', 'https://chromium.googlesource.com/chromium/src/third_party/ijar']); - } - - FileUtil.goAndBackFromDir('cpu_features', function():Void - { - if (!FileSystem.exists('src/ndk_compat')) - { - FileUtil.deletePath('src'); - Sys.command('git', ['clone', 'https://github.com/google/cpu_features', 'src', '-b', 'v0.8.0']); - } + Sys.command("sed -i '/SuccIterator(InstructionT \\*Inst)/i\\ SuccIterator() : Inst(nullptr), Idx(0) {}' llvm/include/llvm/IR/CFG.h"); }); - }); - + FileUtil.applyGitPatchesFromDir('../../patches'); });