Support for WebGPU backend in iOS SDK, core (#4103)
This commit is contained in:
@@ -15,6 +15,8 @@
|
||||
- [Documentation](./platforms/ios/ios-documentation.md)
|
||||
- [Release](./platforms/ios/release.md)
|
||||
- [Development Apps](./platforms/ios/dev-apps.md)
|
||||
- [Rendering Backends](./platforms/ios/ios-rendering-backends.md)
|
||||
- [WebGPU](./platforms/ios/ios-webgpu.md)
|
||||
- [macOS](./platforms/macos/README.md)
|
||||
- [Linux](./platforms/linux/README.md)
|
||||
- [Using Docker](./platforms/linux/using-docker.md)
|
||||
|
||||
@@ -24,15 +24,15 @@ You can find an app that uses GLFW in [`platform/glfw`](https://github.com/mapli
|
||||
|
||||
## Rendering Backends
|
||||
|
||||
Originally the project only supported OpenGL 2.0. In 2023, the [renderer was modularized](https://github.com/maplibre/maplibre-native/blob/main/design-proposals/2022-10-27-rendering-modularization.md) allowing for the implementation of alternate rendering backends. The first alternate rendering backend that was implemented was [Metal](https://maplibre.org/news/2024-01-19-metal-support-for-maplibre-native-ios-is-here/), followed by [Vulkan](https://maplibre.org/news/2024-12-12-maplibre-android-vulkan/). In the future other rendering backends could be implemented such as WebGPU.
|
||||
Originally the project only supported OpenGL 2.0. In 2023, the [renderer was modularized](https://github.com/maplibre/maplibre-native/blob/main/design-proposals/2022-10-27-rendering-modularization.md) allowing for the implementation of alternate rendering backends. The first alternate rendering backend that was implemented was [Metal](https://maplibre.org/news/2024-01-19-metal-support-for-maplibre-native-ios-is-here/), followed by [Vulkan](https://maplibre.org/news/2024-12-12-maplibre-android-vulkan/), and recently [WebGPU](https://maplibre.org/news/2025-10-04-maplibre-newsletter-september-2025/).
|
||||
|
||||
What platforms support which rendering backend can be found below.
|
||||
|
||||
|
||||
| Platform | OpenGL ES 3.0 | Vulkan 1.0 | Metal | WebGPU |
|
||||
| -------- | -------------- | ---------- | ------ | ------- |
|
||||
| Android | ✅ | ✅ | ❌ | ❌ |
|
||||
| iOS | ❌ | ❌ | ✅ | ❌ |
|
||||
| Android | ✅ | ✅ | ❌ | ✅ |
|
||||
| iOS | ❌ | ❌ | ✅ | ✅ |
|
||||
| Linux | ✅ | ✅ | ❌ | ✅ |
|
||||
| Windows | ✅ | ❌ | ❌ | ❓ |
|
||||
| macOS | ❌ | ✅ | ✅[^1] | ✅ |
|
||||
|
||||
45
docs/mdbook/src/platforms/ios/ios-rendering-backends.md
Normal file
45
docs/mdbook/src/platforms/ios/ios-rendering-backends.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Rendering Backends
|
||||
|
||||
MapLibre Native for iOS supports multiple rendering backends. The backend is selected at build time through CMake presets.
|
||||
|
||||
## Available backends
|
||||
|
||||
| Preset | Backend | Status | Notes |
|
||||
|---|---|---|---|
|
||||
| `ios-metal` | Metal | Stable | Default, recommended for production |
|
||||
| `ios-webgpu-dawn` | WebGPU (Dawn) | Experimental | Uses Metal internally, see [WebGPU](./ios-webgpu.md) |
|
||||
| `ios-webgpu-wgpu` | WebGPU (wgpu-native) | Experimental | Uses Metal internally, see [WebGPU](./ios-webgpu.md) |
|
||||
|
||||
## Building with a specific backend
|
||||
|
||||
Each preset generates an Xcode project in its own build directory:
|
||||
|
||||
```bash
|
||||
# Metal (default)
|
||||
cmake --preset ios-metal -DDEVELOPMENT_TEAM_ID=YOUR_TEAM_ID
|
||||
xed build-ios/MapLibre\ Native.xcodeproj
|
||||
|
||||
# WebGPU (Dawn)
|
||||
cmake --preset ios-webgpu-dawn -DDEVELOPMENT_TEAM_ID=YOUR_TEAM_ID
|
||||
xed build-ios-webgpu-dawn/MapLibre\ Native.xcodeproj
|
||||
|
||||
# WebGPU (wgpu-native)
|
||||
cmake --preset ios-webgpu-wgpu -DDEVELOPMENT_TEAM_ID=YOUR_TEAM_ID
|
||||
xed build-ios-webgpu-wgpu/MapLibre\ Native.xcodeproj
|
||||
```
|
||||
|
||||
Then build the `app` target in Xcode, or from the command line:
|
||||
|
||||
```bash
|
||||
cmake --build build-ios-webgpu-wgpu -- -sdk iphonesimulator -arch arm64
|
||||
```
|
||||
|
||||
## How it works
|
||||
|
||||
Each preset passes different CMake variables that control which native rendering code gets compiled:
|
||||
|
||||
- `ios-metal`: `-DMLN_WITH_METAL=ON`
|
||||
- `ios-webgpu-dawn`: `-DMLN_WITH_WEBGPU=ON -DMLN_WEBGPU_IMPL_DAWN=ON`
|
||||
- `ios-webgpu-wgpu`: `-DMLN_WITH_WEBGPU=ON -DMLN_WEBGPU_IMPL_WGPU=ON`
|
||||
|
||||
Only one backend is active per build. The Objective-C layer is shared across backends, with renderer-specific code selected at compile time via `#if MLN_WEBGPU_IMPL_DAWN` / `#elif MLN_WEBGPU_IMPL_WGPU` conditionals in `MLNMapView+WebGPU.mm`.
|
||||
65
docs/mdbook/src/platforms/ios/ios-webgpu.md
Normal file
65
docs/mdbook/src/platforms/ios/ios-webgpu.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# WebGPU on iOS
|
||||
|
||||
The iOS platform supports WebGPU as a rendering backend alongside Metal. There are two WebGPU implementations: **Dawn** (Google) and **wgpu-native** (Rust). Both use Metal as the GPU backend on iOS.
|
||||
|
||||
## Building with Dawn
|
||||
|
||||
Dawn is fetched and built from source via CMake `FetchContent`, so no extra setup is needed. The first build takes a while because Dawn pulls in abseil, SPIRV-Tools, Tint, etc. Subsequent builds are incremental.
|
||||
|
||||
```bash
|
||||
cmake --preset ios-webgpu-dawn
|
||||
cmake --build build-ios-webgpu-dawn -- -sdk iphonesimulator -arch arm64
|
||||
```
|
||||
|
||||
## Building with wgpu-native
|
||||
|
||||
wgpu-native requires a pre-built static library for the target architecture. The CMake build will attempt to build it from source if cargo is available, but cross-compilation for iOS needs some setup.
|
||||
|
||||
### 1. Install the Rust iOS targets
|
||||
|
||||
```bash
|
||||
# For simulator (Apple Silicon Mac)
|
||||
rustup target add aarch64-apple-ios-sim
|
||||
|
||||
# For device
|
||||
rustup target add aarch64-apple-ios
|
||||
```
|
||||
|
||||
### 2. Cross-compile wgpu-native
|
||||
|
||||
For the iOS Simulator:
|
||||
|
||||
```bash
|
||||
cd vendor/wgpu-native
|
||||
BINDGEN_EXTRA_CLANG_ARGS="--target=arm64-apple-ios -isysroot $(xcrun --sdk iphoneos --show-sdk-path)" \
|
||||
cargo build --release --target aarch64-apple-ios-sim \
|
||||
--no-default-features --features metal,wgsl,spirv,glsl
|
||||
```
|
||||
|
||||
For a physical device:
|
||||
|
||||
```bash
|
||||
cd vendor/wgpu-native
|
||||
BINDGEN_EXTRA_CLANG_ARGS="--target=arm64-apple-ios -isysroot $(xcrun --sdk iphoneos --show-sdk-path)" \
|
||||
cargo build --release --target aarch64-apple-ios \
|
||||
--no-default-features --features metal,wgsl,spirv,glsl
|
||||
```
|
||||
|
||||
The `BINDGEN_EXTRA_CLANG_ARGS` environment variable is required so that bindgen's macro fallback can find iOS system headers when generating FFI bindings.
|
||||
|
||||
This produces `vendor/wgpu-native/target/<target>/release/libwgpu_native.a`, which the CMake build picks up automatically.
|
||||
|
||||
### 3. Configure and build
|
||||
|
||||
```bash
|
||||
cmake --preset ios-webgpu-wgpu
|
||||
cmake --build build-ios-webgpu-wgpu -- -sdk iphonesimulator -arch arm64
|
||||
```
|
||||
|
||||
If the pre-built library is not found and cargo is available, CMake will attempt to build wgpu-native automatically during configuration.
|
||||
|
||||
## Implementation notes
|
||||
|
||||
The native backend lives in `platform/ios/src/MLNMapView+WebGPU.mm`. It uses `#if MLN_WEBGPU_IMPL_DAWN` / `#elif MLN_WEBGPU_IMPL_WGPU` conditionals for the API differences between the two implementations, following the same pattern as the Android and desktop backends.
|
||||
|
||||
Both backends use a plain `UIView` with a `CAMetalLayer` (not `MTKView`) for the WebGPU surface. The rendering view has `userInteractionEnabled = NO` so touch events pass through to the parent `MLNMapView`.
|
||||
Reference in New Issue
Block a user