Skip to content
Open
Show file tree
Hide file tree
Changes from 76 commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
4b43e77
Funnel tgfx GPU backend calls through pag::Devices to decouple libpag…
leiyue123 Aug 25, 2026
511719d
Add Metal backend implementation and per-backend baseline isolation a…
leiyue123 Aug 25, 2026
ce62cb1
Extend pag::MtlTextureInfo with pixel format and add Metal id<MTLEven…
leiyue123 Aug 25, 2026
80a39a8
Add Metal platform surface API for iOS and macOS via MetalGPUDrawable…
leiyue123 Aug 25, 2026
59c82ec
Add Metal-specific PAGSurface / pagx::PAGSurface test coverage and fi…
leiyue123 Aug 25, 2026
beb3562
Un-gate PAGBlendTest.Blend from OpenGL and add three PAGBlendMetalTes…
leiyue123 Aug 25, 2026
ef63903
Support Metal backend in PAGView on iOS and macOS.
leiyue123 Sep 1, 2026
e61559c
Automatically raise iOS deployment target to 13.0 for Metal builds.
leiyue123 Sep 1, 2026
a5d166d
Fix PAGView Metal backend: drawableSize, device retry, and public cla…
leiyue123 Sep 1, 2026
8eec508
Fix macOS PAGView Metal rendering by enabling layer backing.
leiyue123 Sep 1, 2026
b088a47
Document Metal backend generation in the iOS README.
leiyue123 Sep 1, 2026
e88c5e2
Update the iOS PAGViewer demo to build with the Metal backend.
leiyue123 Sep 1, 2026
deaf39b
Document Metal backend generation in the macOS README.
leiyue123 Sep 1, 2026
924467d
Fix autotest backend naming and align argument handling with tgfx.
leiyue123 Sep 1, 2026
4cffcae
Skip baseline image generation in the autotest CI pipeline.
leiyue123 Sep 1, 2026
885092e
Mark PAGView Metal support as complete in the backend decoupling doc.
leiyue123 Sep 1, 2026
5b193c4
Upgrade tgfx and adapt filter uniform block bindings to shader-stage …
leiyue123 Sep 3, 2026
c777d2d
Merge remote-tracking branch 'origin/main' into feature/thunderllei_g…
leiyue123 Sep 3, 2026
00880fd
Fix code formatting in PAGView Metal implementation.
leiyue123 Sep 3, 2026
2239e2c
Fall back gracefully when main branch lacks per-backend UpdateBaselin…
leiyue123 Sep 3, 2026
d23cc88
Exclude Devices_Metal.mm from non-Apple builds to avoid missing cc1ob…
leiyue123 Sep 3, 2026
cb4749d
Declare tgfx task-threading APIs on the PAG module type for TGFXBind.
leiyue123 Sep 3, 2026
fed0c27
Declare all PAGSurface factory methods unconditionally in public head…
leiyue123 Sep 9, 2026
0f0abcc
Derive BackendSemaphore initialized state from backend and handle so …
leiyue123 Sep 9, 2026
3397269
Remove MTLCreateSystemDefaultDevice from PAGView so MetalWindow lazil…
leiyue123 Sep 9, 2026
3dd83c1
Capture the owning device from external textures so Metal rejects dra…
leiyue123 Sep 9, 2026
4473734
Retain the MTLDevice in MetalExternalDeviceRef manually since libpag …
leiyue123 Sep 9, 2026
f6a1a9c
Derive the async worker device from the external texture on Metal so …
leiyue123 Sep 17, 2026
891acfb
Walk back to the owning device from the wrapped surface so pagx rende…
leiyue123 Sep 17, 2026
1db81ac
Require the owning device when wrapping a tgfx Surface so pagx render…
leiyue123 Sep 17, 2026
fd36e5c
Read the Metal pixel format from the real MTLTexture so readback and …
leiyue123 Sep 17, 2026
45a1a61
Dispatch semaphore forwarding by backend with explicit switch so unsu…
leiyue123 Sep 22, 2026
56be752
Add pure logic tests for BackendSemaphore cross backend guards and To…
leiyue123 Sep 22, 2026
54d2f0d
Reject combining non OpenGL backends at configure time and count back…
leiyue123 Sep 22, 2026
73be597
Handle setFrameSize and backing property changes on macOS so the draw…
leiyue123 Sep 22, 2026
64f470a
Document that makeSnapshot is unreliable on the Metal backend because…
leiyue123 Sep 22, 2026
7e013eb
Serialize drawable size updates with the render flush on iOS and docu…
leiyue123 Sep 22, 2026
653e2cb
Restore the iOS demo to the OpenGL defaults and raise the Metal deplo…
leiyue123 Sep 22, 2026
1e65b15
Add a backend accessor to BackendSemaphore to match BackendTexture an…
leiyue123 Sep 22, 2026
0f94f5a
Replace the flat Metal semaphore accessors with a public MtlEventInfo…
leiyue123 Sep 22, 2026
d9a9133
Rename the C semaphore initializer to init_metal to match initMetal a…
leiyue123 Sep 22, 2026
bc1add3
Drop the redundant CAMetalLayer forward declarations already provided…
leiyue123 Sep 22, 2026
fdf3e1f
Document the main thread and resize requirements of FromMTKView.
leiyue123 Sep 22, 2026
8e36ac3
Document that FromMetalLayer and FromMTKView require the caller to ke…
leiyue123 Sep 22, 2026
4c5d5ba
Fix the fabricated ownership claim in the MetalGPUDrawable comment an…
leiyue123 Sep 22, 2026
42d7390
Remove FromMTKView whose thread and device injection constraints outw…
leiyue123 Sep 22, 2026
45bf4a5
Add the missing MTLDevice adoption note to the macOS FromMetalLayer d…
leiyue123 Sep 22, 2026
f769936
Document that FromMetalLayer callers must maintain the layer drawable…
leiyue123 Sep 22, 2026
d3104fe
Create the Metal window eagerly in FromLayer so FromMetalLayer fails …
leiyue123 Sep 22, 2026
37c3fcf
Keep the TGFX task thread methods out of the public PAG interface by …
leiyue123 Sep 28, 2026
815ef70
Fix stale symbol references and wrong API basis in comments and align…
leiyue123 Sep 28, 2026
9576dd0
Share the Metal layer setup between the platform PAGViews rename the …
leiyue123 Sep 28, 2026
ac97041
Deduplicate the decoder compatibility flag move test includes to the …
leiyue123 Sep 28, 2026
9ebdbea
Raise the default macOS deployment target to 11.0 for the Xcode 27 li…
leiyue123 Sep 28, 2026
9dcc3be
Merge branch 'main' into feature/thunderllei_gpu_backend
leiyue123 Sep 28, 2026
e1923d1
Move the per backend test infrastructure out of this PR so CI keeps u…
leiyue123 Sep 28, 2026
48ffdcc
Drop the internal investigation and design docs from the PR.
leiyue123 Sep 28, 2026
0f40e78
Remove references to the local backend decoupling doc from source com…
leiyue123 Sep 28, 2026
f02c5dc
Resolve the tgfx dependency conflict in favor of the main branch revi…
leiyue123 Sep 28, 2026
7ddff1a
Adopt the tgfx device deduplication so Metal surfaces on the same MTL…
leiyue123 Sep 28, 2026
abb1d39
Accept the baseline changes caused by the tgfx background blur fix.
leiyue123 Sep 28, 2026
b6ec8e8
Make the default device lock reentrant so code that fetches the defau…
leiyue123 Sep 29, 2026
eaddca9
Raise the Metal iOS deployment target to 15.0 to match the Xcode 27 S…
leiyue123 Sep 29, 2026
f80d2c0
Update the Chinese iOS readme to the 15.0 Metal deployment target.
leiyue123 Sep 29, 2026
52a97fa
Update the mac readmes to the 12.0 deployment floor.
leiyue123 Sep 29, 2026
e6ef33f
Silence the CAEAGLLayer deprecation warning inside the public iOS hea…
leiyue123 Sep 29, 2026
44eec4a
Define GLES_SILENCE_DEPRECATION locally in the iOS GL touching files …
leiyue123 Sep 29, 2026
7712322
Silence the CAEAGLLayer deprecation warnings in the iOS private heade…
leiyue123 Sep 29, 2026
04de461
Declare a single scene manifest in the iOS demo so the Xcode 27 runti…
leiyue123 Sep 29, 2026
47b1739
Adopt the UIScene configuration callbacks in the iOS demo AppDelegate…
leiyue123 Sep 29, 2026
1140b42
Complete the scene lifecycle migration by declaring the AppDelegate a…
leiyue123 Sep 29, 2026
d079847
Split the iOS demo scene lifecycle into a dedicated SceneDelegate to …
leiyue123 Sep 29, 2026
8871f97
Remove the unused tlsLockedDevice record that failed the web build wi…
leiyue123 Sep 30, 2026
3029423
Fix the sync mode deadlock and duplicate resizes and restore the cach…
leiyue123 Oct 8, 2026
71c176a
Merge branch 'refs/heads/main' into feature/thunderllei_gpu_backend
leiyue123 Oct 9, 2026
0cc9eeb
Add macOS and iOS Metal compile jobs to the build workflow
leiyue123 Oct 9, 2026
3d4133f
Split surface APIs into per backend categories fix Metal pixel buffer…
leiyue123 Oct 13, 2026
1ddf02f
Reject backend mismatched texture descriptions at resource factory en…
leiyue123 Oct 13, 2026
3fa7d40
Export the generated umbrella header and compile only the selected ba…
leiyue123 Oct 13, 2026
73ef4e6
Merge branch 'main' into feature/thunderllei_gpu_backend
leiyue123 Oct 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,107 @@ jobs:
name: ios_build
path: ios

mac_metal:
# Compile-only verification of the Metal backend on macOS. Building PAGFullTest covers all
# test modules on top of the library itself. Running the Metal tests (PAGFullTest_Metal)
# requires the per-backend test infrastructure, which lands in a follow-up PR.
runs-on: macos-14
steps:
- name: Check Out Repo
uses: actions/checkout@v4

- name: Get Third-Party Cache
id: third-party-cache
uses: actions/cache/restore@v4
with:
path: |
third_party
key: third-party-mac-metal-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}
restore-keys: |
third-party-mac-metal-
third-party-autotest-

- uses: tecolicom/actions-use-homebrew-tools@v1
with:
tools: ninja yasm

- name: Run depsync
run: |
npm install depsync -g
depsync
shell: bash

- name: Build macOS Metal
run: |
mkdir -p third_party/tgfx/out/cache
cmake -G Ninja -DPAG_USE_METAL=ON -DPAG_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Debug -B build-metal
cmake --build build-metal --target PAGFullTest -- -j 12

- name: Save Third-Party Cache
if: ${{ (github.event_name == 'push') && (steps.third-party-cache.outputs.cache-hit != 'true') }}
uses: actions/cache/save@v4
with:
path: |
third_party
key: third-party-mac-metal-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}

ios_metal:
# Compile-only verification of the Metal backend on iOS devices (arm64). The deployment
# target is raised to 15.0 automatically by the top-level CMakeLists when Metal is enabled.
runs-on: macos-latest
steps:
- name: Check Out Repo
uses: actions/checkout@v4

- name: Get Third-Party Cache
id: third-party-cache
uses: actions/cache/restore@v4
with:
path: |
third_party
key: third-party-ios-metal-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}
restore-keys: |
third-party-ios-metal-
third-party-ios-

- uses: tecolicom/actions-use-homebrew-tools@v1
with:
tools: ninja yasm

- name: Install Build Tools
run: |
chmod +x install_tools.sh
./install_tools.sh
shell: bash

- name: Run depsync
run: |
npm install depsync -g
depsync
shell: bash

- name: Build iOS Metal
run: |
mkdir -p third_party/tgfx/out/cache
cd ios
node gen_ios -DPAG_USE_METAL=ON
xcodebuild -workspace PAGViewer.xcworkspace -scheme PAGViewer -configuration Release -sdk iphoneos -arch arm64 CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO

- name: Save Third-Party Cache
if: ${{ (github.event_name == 'push') && (steps.third-party-cache.outputs.cache-hit != 'true') }}
uses: actions/cache/save@v4
with:
path: |
third_party
key: third-party-ios-metal-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}

- name: Job Failed
if: ${{ failure() }}
uses: actions/upload-artifact@v4
with:
name: ios_metal_build
path: ios

android:
runs-on: ubuntu-latest
steps:
Expand Down
116 changes: 112 additions & 4 deletions CMakeLists.txt
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)
Expand All @@ -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)
Expand Down Expand Up @@ -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

Copy link
Copy Markdown
Collaborator

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 行处并修正版本号。

# 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)
Expand Down Expand Up @@ -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)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Major] 非 GL 后端之间没有互斥,且 libpag 与 tgfx 的选择优先级相反 → 链接期 undefined symbol

证据链:

  1. :110-115 的互斥块只把 PAG_USE_OPENGL / QT / SwiftShader / ANGLE 置 OFF,Metal / Vulkan / D3D12 / WebGPU 彼此无互斥(而 :104-106 的注释却声称 "mutually exclusive with each other");
  2. 此处是 5 个独立的 if(不是 elseif),可同时定义多个 TGFX_USE_*;
  3. 两个开关都会透传给 tgfx(:722-723 / :750-751 / :788-789);
  4. tgfx CMakeLists.txt:98-136 是带优先级的 if/elseif 链:VULKAN > D3D12 > METAL > WEBGPU,命中 Vulkan 后显式 set(TGFX_USE_METAL OFF);且 :98-100 允许 macOS 开 Vulkan,不会被平台校验挡掉;
  5. tgfx 作为子目录,其 set(... OFF) 只影响自身 directory scope,libpag 的 PAG_DEFINES 已在此处定型,不会被回写;
  6. Devices_Metal.mm 仍会被编译(:260-265 只在 NOT APPLE 时排除)。

于是 macOS 上 -DPAG_USE_METAL=ON -DPAG_USE_VULKAN=ON → tgfx 只编 Vulkan 后端,libpag 仍编 Devices_Metal.mm → 链接期 undefined symbol: tgfx::MetalDevice::Make()。而 Devices_Backend.cpp:28 的哨兵是 #if defined(TGFX_USE_OPENGL) || defined(TGFX_USE_METAL),Metal 有定义即命中第一分支 → 不报 #error → 恰好放过了它自称要消灭的失败形式(该文件注释原文:「instead of a late link-time undefined-symbol failure」)。

放大器是 :157-160 的注释:libpag 故意「定义自己的一份宏而不依赖 tgfx 的 PRIVATE 定义」——这正是让两侧后端选择产生分歧的机制。

建议::110 处补非 GL 后端之间的 FATAL_ERROR 互斥,且优先级与 tgfx 同序;同时把 Devices_Backend.cpp 的哨兵改为逐后端独立 #if + 计数校验,否则它对「多后端同时定义」永久失效。

适用范围说明:GL 与 Metal 之间互斥是有效的(:110-111 确实生效),不存在重复符号,那个方向是误报。本条只针对非 GL 后端之间,失效形式是 undefined symbol 而非重复定义。

另一处 Minor::110-115 全段无任何 message 调用,静默丢弃用户显式传入的 -DPAG_USE_QT=ON;而紧邻的 :117-122「一个后端都没开」却是 FATAL_ERROR,同段逻辑对两种误配置强度不对称。

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

已在 commit 54d2f0d 中修复:按建议补了非 GL 后端之间的互斥——CMake configure 阶段统计 PAG_NON_GL_BACKENDS_COUNT,大于 1 即 FATAL_ERROR(CMakeLists.txt:116-125),互斥时机在 tgfx add_subdirectory 与 QT/SwiftShader fixup 之前;同时对非 GL 后端开启时被忽略的 GL 系开关改为显式 WARNING 提示。Devices_Metal.mm / TGFXCast_Metal.mm 在非 Apple 平台从源列表剔除(commit d23cc88),Linux/Web 不再受 .mm 影响。

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 ()
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 ()
Expand Down Expand Up @@ -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 ()
Expand Down Expand Up @@ -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})
Expand All @@ -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}")
Expand Down Expand Up @@ -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})
Expand Down
14 changes: 14 additions & 0 deletions include/pag/c/pag_backend_semaphore.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,18 @@ PAG_EXPORT void pag_backend_semaphore_init_gl(pag_backend_semaphore* semaphore,

PAG_EXPORT void* pag_backend_semaphore_get_gl_sync(pag_backend_semaphore* semaphore);

/**
* Initialize the semaphore with a Metal id<MTLEvent> and a timeline signal value. Passing a
* null event leaves the semaphore uninitialized.
*/
PAG_EXPORT void pag_backend_semaphore_init_metal(pag_backend_semaphore* semaphore,
void* mtlEvent, unsigned long long value);

/**
* Copies the underlying id<MTLEvent> handle and timeline value into eventInfo. Returns false and
* leaves eventInfo untouched if the semaphore was not initialized for the Metal backend.
*/
PAG_EXPORT bool pag_backend_semaphore_get_mtl_event(pag_backend_semaphore* semaphore,
pag_mtl_event_info* eventInfo);

PAG_C_PLUS_PLUS_END_GUARD
8 changes: 8 additions & 0 deletions include/pag/c/pag_backend_texture.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ PAG_C_PLUS_PLUS_BEGIN_GUARD
PAG_EXPORT pag_backend_texture* pag_backend_texture_create_from_gl_texture_info(
pag_gl_texture_info textureInfo, int width, int height);

/**
* Creates a new pag_backend_texture from a Metal id<MTLTexture>. Release it by pag_release.
* The MTLTexture pointer inside textureInfo is stored as an opaque handle; libpag will not
* release it.
*/
PAG_EXPORT pag_backend_texture* pag_backend_texture_create_from_mtl_texture_info(
pag_mtl_texture_info textureInfo, int width, int height);

PAG_EXPORT bool pag_backend_texture_get_gl_texture_info(pag_backend_texture* texture,
pag_gl_texture_info* textureInfo);

Expand Down
6 changes: 6 additions & 0 deletions include/pag/c/pag_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ typedef struct pag_mtl_texture_info {
void* texture = nullptr;
} pag_mtl_texture_info;

// Sync info for an id<MTLEvent>. Always timeline-style (event pointer + signal value).
typedef struct pag_mtl_event_info {
void* event = nullptr;
unsigned long long value = 0;
} pag_mtl_event_info;

typedef struct pag_point {
float x;
float y;
Expand Down
Loading
Loading