Repository navigation
Add Metal backend support on Apple platforms #3717
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 76 commits
4b43e77
511719d
ce62cb1
80a39a8
59c82ec
beb3562
ef63903
e61559c
a5d166d
8eec508
b088a47
e88c5e2
deaf39b
924467d
4cffcae
885092e
5b193c4
c777d2d
00880fd
2239e2c
d23cc88
cb4749d
fed0c27
0f0abcc
3397269
3dd83c1
4473734
f6a1a9c
891acfb
1db81ac
fd36e5c
45a1a61
56be752
54d2f0d
73be597
64f470a
7e013eb
653e2cb
1e65b15
0f94f5a
d9a9133
bc1add3
fdf3e1f
8e36ac3
4c5d5ba
42d7390
45bf4a5
f769936
d3104fe
37c3fcf
815ef70
9576dd0
ac97041
9ebdbea
9dcc3be
e1923d1
48ffdcc
0f40e78
f02c5dc
7ddff1a
abb1d39
b6ec8e8
eaddca9
f80d2c0
52a97fa
e6ef33f
44eec4a
7712322
04de461
47b1739
1140b42
d079847
8871f97
3029423
71c176a
0cc9eeb
3d4133f
1ddf02f
3fa7d40
73ef4e6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,15 @@ | ||
| cmake_minimum_required(VERSION 3.13) | ||
|
|
||
| # The iOS toolchain (third_party/vendor_tools/ios.toolchain.cmake) reads DEPLOYMENT_TARGET while | ||
| # configuring the project and derives both the deployment target and the compiler target triple | ||
| # from it. Apple toolchains reject iOS deployment targets below 15.0 (Xcode 26/27 SDKs), and | ||
| # the tgfx Metal backend has its own >= 13.0 floor that 15.0 satisfies, so Metal builds must | ||
| # pre-set the minimum before configuration. This only applies to iOS builds; macOS keeps its own | ||
| # default. Callers can override with -DDEPLOYMENT_TARGET=... explicitly. | ||
| if (PAG_USE_METAL AND NOT DEFINED DEPLOYMENT_TARGET AND PLATFORM MATCHES "^(OS|SIMULATOR)") | ||
| set(DEPLOYMENT_TARGET "15.0" CACHE STRING "Minimum iOS deployment target" FORCE) | ||
| endif () | ||
|
|
||
| project(PAG) | ||
|
|
||
| if (APPLE) | ||
|
|
@@ -25,6 +36,10 @@ set(CMAKE_CXX_VISIBILITY_PRESET hidden) | |
|
|
||
| # Options for building libpag | ||
| option(PAG_USE_OPENGL "Allow use of OpenGL as GPU backend" ON) | ||
| option(PAG_USE_METAL "Use Metal as the GPU backend on Apple platforms" OFF) | ||
| option(PAG_USE_VULKAN "Use Vulkan as the GPU backend" OFF) | ||
| option(PAG_USE_D3D12 "Use D3D12 as the GPU backend on Windows" OFF) | ||
| option(PAG_USE_WEBGPU "Use WebGPU as the GPU backend on Web" OFF) | ||
| option(PAG_USE_SWIFTSHADER "Allow build with the SwiftShader library" OFF) | ||
| option(PAG_USE_ANGLE "Allow build with the ANGLE library" OFF) | ||
| option(PAG_USE_QT "Allow build with QT frameworks" OFF) | ||
|
|
@@ -87,6 +102,62 @@ if (MACOS AND CLION_IDE AND NOT HasParent) | |
| option(PAG_BUILD_TESTS "Build libpag tests" ON) | ||
| endif () | ||
|
|
||
| # Non-GL backends (Metal / Vulkan / D3D12 / WebGPU) are mutually exclusive with each other and | ||
| # with OpenGL. If any non-GL backend is enabled, disable OpenGL and all GL-only variants | ||
| # (QT / SwiftShader / ANGLE). This mirrors the mutual-exclusion contract enforced in | ||
| # third_party/tgfx/CMakeLists.txt, and must run BEFORE the existing QT / SwiftShader mutual- | ||
| # exclusion block so the "if (PAG_USE_QT OR PAG_USE_SWIFTSHADER OR PAG_USE_ANGLE) set(PAG_USE_OPENGL ON)" | ||
| # fixup further down does not accidentally re-enable GL. | ||
| # | ||
| # The non-GL backends must not be combined: libpag passes each PAG_USE_* to tgfx unchanged, but | ||
| # tgfx resolves them with its own priority chain (Vulkan > D3D12 > Metal > WebGPU) and silently | ||
| # disables the losers. A combination would leave libpag compiling backend glue (Devices_*.cpp) | ||
| # for a backend tgfx never built, failing at link time with undefined symbols. | ||
| set(PAG_NON_GL_BACKENDS_COUNT 0) | ||
| foreach (backend PAG_USE_METAL PAG_USE_VULKAN PAG_USE_D3D12 PAG_USE_WEBGPU) | ||
| if (${backend}) | ||
| math(EXPR PAG_NON_GL_BACKENDS_COUNT "${PAG_NON_GL_BACKENDS_COUNT} + 1") | ||
| endif () | ||
| endforeach () | ||
| if (PAG_NON_GL_BACKENDS_COUNT GREATER 1) | ||
| message(FATAL_ERROR | ||
| "Only one non-OpenGL backend may be enabled at a time " | ||
| "(PAG_USE_METAL / PAG_USE_VULKAN / PAG_USE_D3D12 / PAG_USE_WEBGPU).") | ||
| endif () | ||
|
|
||
| if (PAG_USE_METAL OR PAG_USE_VULKAN OR PAG_USE_D3D12 OR PAG_USE_WEBGPU) | ||
| foreach (gl_variant PAG_USE_OPENGL PAG_USE_QT PAG_USE_SWIFTSHADER PAG_USE_ANGLE) | ||
| if (${gl_variant}) | ||
| message(WARNING "${gl_variant} is ignored because a non-OpenGL backend is enabled.") | ||
| endif () | ||
| endforeach () | ||
| set(PAG_USE_OPENGL OFF) | ||
| set(PAG_USE_QT OFF) | ||
| set(PAG_USE_SWIFTSHADER OFF) | ||
| set(PAG_USE_ANGLE OFF) | ||
| endif () | ||
|
|
||
| # The Metal backend requires iOS 13+ (see the tgfx deployment-target check) and supports the iOS | ||
| # simulator on arm64 only. Raise the deployment target automatically when Metal is selected so | ||
| # `gen_ios -DPAG_USE_METAL=ON` needs no extra flags (as documented in ios/README.md). Without this | ||
| # the toolchain's iOS default (9.0) flows into tgfx and trips its >= 13.0 check. Must run before | ||
| # tgfx is added via add_subdirectory(). Metal also only exists on Apple platforms — reject it | ||
| # elsewhere up front instead of failing later with a pile of undefined symbols. | ||
| if (PAG_USE_METAL AND NOT APPLE) | ||
| message(FATAL_ERROR "PAG_USE_METAL is only supported on Apple platforms.") | ||
| endif () | ||
| # The Metal backend supports the iOS simulator on arm64 only. | ||
| if (PAG_USE_METAL AND IOS) | ||
| set(CMAKE_XCODE_ATTRIBUTE_EXCLUDED_ARCHS[sdk=iphonesimulator*] "x86_64") | ||
| endif () | ||
|
|
||
| if (NOT PAG_USE_OPENGL AND NOT PAG_USE_METAL AND NOT PAG_USE_VULKAN | ||
| AND NOT PAG_USE_D3D12 AND NOT PAG_USE_WEBGPU) | ||
| message(FATAL_ERROR | ||
| "At least one GPU backend must be enabled " | ||
| "(PAG_USE_OPENGL / PAG_USE_METAL / PAG_USE_VULKAN / PAG_USE_D3D12 / PAG_USE_WEBGPU).") | ||
| endif () | ||
|
|
||
| if (PAG_USE_QT) | ||
| set(PAG_USE_SWIFTSHADER OFF) | ||
| set(PAG_USE_ANGLE OFF) | ||
|
|
@@ -120,6 +191,26 @@ if (PAG_USE_QT OR PAG_USE_SWIFTSHADER OR PAG_USE_ANGLE) | |
| set(PAG_USE_OPENGL ON) | ||
| endif () | ||
|
|
||
| # Expose the selected tgfx backend to libpag sources. The Devices_* implementation files dispatch | ||
| # on this macro to pick the right tgfx backend headers; kept in sync with the TGFX_USE_* variables | ||
| # passed to tgfx further down. libpag defines its own copy instead of relying on tgfx's PRIVATE | ||
| # compile definitions, so tgfx can change its visibility policy without breaking libpag. | ||
| if (PAG_USE_OPENGL) | ||
| list(APPEND PAG_DEFINES TGFX_USE_OPENGL) | ||
| endif () | ||
| if (PAG_USE_METAL) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Major] 非 GL 后端之间没有互斥,且 libpag 与 tgfx 的选择优先级相反 → 链接期 undefined symbol 证据链:
于是 macOS 上 放大器是 建议:
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 已在 commit 54d2f0d 中修复:按建议补了非 GL 后端之间的互斥——CMake configure 阶段统计 |
||
| list(APPEND PAG_DEFINES TGFX_USE_METAL) | ||
| endif () | ||
| if (PAG_USE_VULKAN) | ||
| list(APPEND PAG_DEFINES TGFX_USE_VULKAN) | ||
| endif () | ||
| if (PAG_USE_D3D12) | ||
| list(APPEND PAG_DEFINES TGFX_USE_D3D12) | ||
| endif () | ||
| if (PAG_USE_WEBGPU) | ||
| list(APPEND PAG_DEFINES TGFX_USE_WEBGPU) | ||
| endif () | ||
|
|
||
| if (PAG_USE_FFAVC) | ||
| set(PAG_USE_LIBAVC OFF) | ||
| endif () | ||
|
|
@@ -201,6 +292,13 @@ file(GLOB_RECURSE SRC_FILES | |
| src/base/*.* | ||
| src/codec/*.* | ||
| src/rendering/*.*) | ||
| # Devices_Metal.mm is an Objective-C++ file; it only has content under TGFX_USE_METAL. On non-Apple | ||
| # platforms the GCC toolchain lacks the Objective-C++ frontend (`cc1objplus`) and would fail even | ||
| # compiling an empty .mm. Drop it from the source list outside of Apple. | ||
| if (NOT APPLE) | ||
| list(FILTER SRC_FILES EXCLUDE REGEX "src/rendering/gpu/Devices_Metal\\.mm$") | ||
| list(FILTER SRC_FILES EXCLUDE REGEX "src/base/utils/TGFXCast_Metal\\.mm$") | ||
| endif () | ||
| list(APPEND PAG_FILES ${SRC_FILES}) | ||
|
|
||
| if (PAG_BUILD_PAGX) | ||
|
|
@@ -465,8 +563,7 @@ elseif (IOS) | |
| find_library(OpenGLES_LIBS OpenGLES REQUIRED) | ||
| list(APPEND PAG_SHARED_LIBS ${OpenGLES_LIBS}) | ||
| list(APPEND PAG_DEFINES GLES_SILENCE_DEPRECATION) | ||
| else () | ||
| # Uses Metal instead. | ||
| elseif (PAG_USE_METAL) | ||
| find_library(Metal_LIBS Metal REQUIRED) | ||
| list(APPEND PAG_SHARED_LIBS ${Metal_LIBS}) | ||
| endif () | ||
|
|
@@ -508,8 +605,7 @@ elseif (MACOS) | |
| find_library(OpenGL_LIBS OpenGL REQUIRED) | ||
| list(APPEND PAG_SHARED_LIBS ${OpenGL_LIBS}) | ||
| list(APPEND PAG_DEFINES GL_SILENCE_DEPRECATION) | ||
| else () | ||
| # Uses Metal instead. | ||
| elseif (PAG_USE_METAL) | ||
| find_library(Metal_LIBS Metal REQUIRED) | ||
| list(APPEND PAG_SHARED_LIBS ${Metal_LIBS}) | ||
| endif () | ||
|
|
@@ -665,6 +761,10 @@ elseif (HAS_CUSTOM_TGFX_DIR) | |
| message("TGFX_DIR: ${TGFX_DIR}") | ||
| list(APPEND PAG_INCLUDES ${TGFX_DIR}/include) | ||
| set(TGFX_USE_OPENGL ${PAG_USE_OPENGL}) | ||
| set(TGFX_USE_METAL ${PAG_USE_METAL}) | ||
| set(TGFX_USE_VULKAN ${PAG_USE_VULKAN}) | ||
| set(TGFX_USE_D3D12 ${PAG_USE_D3D12}) | ||
| set(TGFX_USE_WEBGPU ${PAG_USE_WEBGPU}) | ||
| set(TGFX_USE_QT ${PAG_USE_QT}) | ||
| set(TGFX_USE_SWIFTSHADER ${PAG_USE_SWIFTSHADER}) | ||
| set(TGFX_USE_ANGLE ${PAG_USE_ANGLE}) | ||
|
|
@@ -689,6 +789,10 @@ else () | |
| if (EXISTS ${TGFX_CACHE_DIR}) | ||
| message("TGFX_CACHE_DIR: ${TGFX_CACHE_DIR}") | ||
| list(APPEND TGFX_OPTIONS "-DTGFX_USE_OPENGL=${PAG_USE_OPENGL}") | ||
| list(APPEND TGFX_OPTIONS "-DTGFX_USE_METAL=${PAG_USE_METAL}") | ||
| list(APPEND TGFX_OPTIONS "-DTGFX_USE_VULKAN=${PAG_USE_VULKAN}") | ||
| list(APPEND TGFX_OPTIONS "-DTGFX_USE_D3D12=${PAG_USE_D3D12}") | ||
| list(APPEND TGFX_OPTIONS "-DTGFX_USE_WEBGPU=${PAG_USE_WEBGPU}") | ||
| list(APPEND TGFX_OPTIONS "-DTGFX_USE_QT=${PAG_USE_QT}") | ||
| list(APPEND TGFX_OPTIONS "-DTGFX_USE_SWIFTSHADER=${PAG_USE_SWIFTSHADER}") | ||
| list(APPEND TGFX_OPTIONS "-DTGFX_USE_ANGLE=${PAG_USE_ANGLE}") | ||
|
|
@@ -723,6 +827,10 @@ else () | |
| else () | ||
| message("TGFX_DIR: ${TGFX_DIR}") | ||
| set(TGFX_USE_OPENGL ${PAG_USE_OPENGL}) | ||
| set(TGFX_USE_METAL ${PAG_USE_METAL}) | ||
| set(TGFX_USE_VULKAN ${PAG_USE_VULKAN}) | ||
| set(TGFX_USE_D3D12 ${PAG_USE_D3D12}) | ||
| set(TGFX_USE_WEBGPU ${PAG_USE_WEBGPU}) | ||
| set(TGFX_USE_QT ${PAG_USE_QT}) | ||
| set(TGFX_USE_SWIFTSHADER ${PAG_USE_SWIFTSHADER}) | ||
| set(TGFX_USE_ANGLE ${PAG_USE_ANGLE}) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[A9] 这段注释描述的是「Metal 选中时自动提升部署目标」,但下方 if 块只有 NOT APPLE 的 FATAL_ERROR 和 EXCLUDED_ARCHS,真正的部署目标设置在文件顶部 9-11 行;且注释写 iOS 13+,代码与 README 实际是 15.0。建议删除或合并到 9-11 行处并修正版本号。