Skip to content
Merged
Show file tree
Hide file tree
Changes from 148 commits
Commits
Show all changes
152 commits
Select commit Hold shift + click to select a range
d15a73d
Delete the legacy desktop JNI implementation
sargunv Jul 25, 2026
28e7948
Remove the Nix dev shell and pin shellcheck
sargunv Jul 25, 2026
15b7b96
Prepare Java 25 and MapLibre Native FFI dependency resolution
sargunv Jul 25, 2026
05d1979
Use Zulu rather than Temurin for Java 25
sargunv Jul 25, 2026
cd2f3fe
Define the desktop map host SPI
sargunv Jul 25, 2026
80c8243
Record the native FFI semantics that constrain the desktop session
sargunv Jul 25, 2026
2350686
Bring up DesktopMapSession and restore desktop compilation
sargunv Jul 25, 2026
39094ad
Start an upstream feedback log for maplibre-native-ffi
sargunv Jul 25, 2026
7b555db
Add LWJGL for the default desktop host bridge
sargunv Jul 25, 2026
6a5088d
Render the first desktop map through the Vulkan-to-OpenGL bridge
sargunv Jul 25, 2026
3e8fe55
Pin the Compose and Skiko internals the default host reflects into
sargunv Jul 25, 2026
b255ecd
Add the JSON conversions the desktop style API is built on
sargunv Jul 25, 2026
48e61b8
Encode compiled expressions as MapLibre style JSON
sargunv Jul 25, 2026
8116117
Port the Windows Direct3D 12 and macOS Metal host bridges
sargunv Jul 25, 2026
e094615
Implement the desktop style, source, and layer families
sargunv Jul 25, 2026
3315603
Correct the rendering-regression note: it was suspend, not code
sargunv Jul 25, 2026
44394d5
Load Compose resource URIs through a desktop resource provider
sargunv Jul 25, 2026
73853ad
Give the desktop cache an OS-appropriate location and a size limit
sargunv Jul 25, 2026
9c09e42
Measure whether two runtimes can share one cache database
sargunv Jul 25, 2026
2d0732e
Package a Java 25 runtime and verify what the distribution ships
sargunv Jul 25, 2026
3e33f35
Document the desktop setup and re-baseline the status table
sargunv Jul 25, 2026
fcc422c
Record the opaque non-HTTP URI failure as FFI feedback
sargunv Jul 25, 2026
048b055
Wire desktop map input, and keep the pump alive between frames
sargunv Jul 25, 2026
d9638fa
Add offline support, fix desktop teardown, and align the demo's features
sargunv Jul 25, 2026
8598ce9
Fix desktop layer attachment: source ordering and null properties
sargunv Jul 25, 2026
9a9b747
Apply map setup made before the map exists
sargunv Jul 25, 2026
9770e0a
Wire rendered feature queries and test the desktop stack headlessly
sargunv Jul 25, 2026
ed36ea1
Cover layer re-add and the first camera position headlessly
sargunv Jul 25, 2026
2c52395
Redraw after style mutations, and answer the supercluster queries
sargunv Jul 25, 2026
d9cba6b
Aim the cluster typing fix at the FFI, not at mbgl
sargunv Jul 25, 2026
5d47d07
Implement source feature queries on desktop
sargunv Jul 25, 2026
518ad0b
Bring the completion checklist up to date
sargunv Jul 25, 2026
ffeb666
Scope the branch to what the FFI backs, and record the API audit
sargunv Jul 25, 2026
b5ef8d5
Correct why the typed source and layer adders go unused
sargunv Jul 25, 2026
34788d2
Mark the typed source and layer adders as FFI gaps in code
sargunv Jul 25, 2026
b6e1978
Record common API gaps found by the FFI coverage audit
sargunv Jul 25, 2026
6dcebd0
Frame the API gaps around the shared integration, not today's SDKs
sargunv Jul 25, 2026
43eb879
Drop the MapProjectionHandle feedback entry; it was wrong
sargunv Jul 26, 2026
96ca6ab
Own meters-per-pixel and visible region instead of requesting them
sargunv Jul 26, 2026
c2e33e2
Triage the error-model entries against the FFI's actual design
sargunv Jul 26, 2026
8222626
Stop swallowing render session failures
sargunv Jul 26, 2026
bb6e4c1
Verify four more feedback entries against source
sargunv Jul 26, 2026
ab6c4a2
Verify the feedback doc against source and probes
sargunv Jul 26, 2026
927c5de
Finish verifying the feedback doc, and guard the style setter it exposed
sargunv Jul 26, 2026
03a9b8b
Delete the borrowed-texture resize entry; there is nothing to ask for
sargunv Jul 26, 2026
e4161f3
Delete the MapHandle.resize entry; the coupling is correct
sargunv Jul 26, 2026
0a00fcd
Drop the renderUpdate entry; it is fixed by mln-ffi #338
sargunv Jul 26, 2026
ca5da41
Reattribute the cluster id typing constraint; it is ours
sargunv Jul 26, 2026
9f4c486
Drop the box query entry for mln-ffi #339, and cite #340
sargunv Jul 26, 2026
e94d842
Drop the options equality entry for mln-ffi #342
sargunv Jul 26, 2026
feb2e6b
Track upstream fixes in a ledger instead of by memory
sargunv Jul 26, 2026
2c6f7ca
Fold mln-ffi's triage into the feedback doc and our comments
sargunv Jul 26, 2026
58fe37e
Argue the layer JSON rationale rather than citing policy
sargunv Jul 26, 2026
0e526f9
Adopt the current mln-ffi snapshot and give the map its own thread
sargunv Jul 30, 2026
751ecef
Release retired textures off the renderer thread
sargunv Jul 30, 2026
e9360a1
Record source-layer in the symbol, fill and fill-extrusion descriptors
sargunv Jul 30, 2026
0a067f6
Run the desktop GPU tests for real on macOS
sargunv Jul 30, 2026
bb85e3e
Write down what makes a style switch survivable
sargunv Jul 30, 2026
34cb253
Make keyboard input reachable and implement double-click zoom
sargunv Jul 30, 2026
ae4172f
Pivot pointer zooms on the centre when the pointer may not pan
sargunv Jul 30, 2026
8463644
Ease keyboard and double-click input instead of jumping
sargunv Jul 30, 2026
8a0fa06
Close live map sessions if the process exits undisposed
sargunv Jul 30, 2026
2abbd7e
Adopt the maplibre-native-ffi snapshot the branch had drifted off
sargunv Aug 4, 2026
6b7ce92
Implement the three FFI gaps #441 closed, and settle the fourth
sargunv Aug 4, 2026
7190a58
Attach computed and image sources through their typed adders
sargunv Aug 4, 2026
5c0a273
Restore every key a base-style layer reported
sargunv Aug 4, 2026
3a7f41a
Keep the renderer across a resize, and survive a frame that throws
sargunv Aug 4, 2026
6d6efc5
Settle the two macOS Metal host questions with evidence
sargunv Aug 4, 2026
ea5cc2a
Fail the desktop GPU tests when there is no Vulkan loader
sargunv Aug 4, 2026
9153fd1
Bring the ledgers up to date with what the snapshot bump settled
sargunv Aug 4, 2026
f512dce
Upgrade to Compose Multiplatform 1.11.1
sargunv Aug 4, 2026
fecfa71
Give the Gradle daemon enough heap to link the iOS release frameworks
sargunv Aug 4, 2026
196a4a4
Keep presenting a retired target until a newer one has been drawn
sargunv Aug 4, 2026
a3b1c23
Run the demo on compose-glfw, and prove the host SPI is replaceable
sargunv Aug 4, 2026
3da2227
Delete two host capabilities nothing ever read
sargunv Aug 4, 2026
0ca6cf9
Drop the library's Swing dependency, and the AWT assumption behind it
sargunv Aug 4, 2026
a0919a0
Delete the map literal AST nodes, which nothing could construct
sargunv Aug 4, 2026
2d81849
Give CI a Vulkan implementation so the desktop GPU tests can run
sargunv Aug 4, 2026
c750afa
Bound every CI job, after one burned six hours on a hang
sargunv Aug 4, 2026
d480f6e
Drop the packaging checks, and a comment that stopped being true
sargunv Aug 4, 2026
5366223
Derive the Windows Skiko device offset instead of trusting it
sargunv Aug 4, 2026
0fc7976
Test the offline packs, including that they survive a restart
sargunv Aug 4, 2026
33bf3b4
Stop reading resources on MapLibre's network thread
sargunv Aug 4, 2026
e2909ef
Round-trip every layer property, and fix the four bugs that found
sargunv Aug 4, 2026
c4f72af
Make the completion checklist describe the suite that exists
sargunv Aug 4, 2026
0cded49
Point the overlap TODOs at MapLibre Native rather than the FFI
sargunv Aug 5, 2026
251cad8
Own the runtime, its cache budget, and its provider in one place
sargunv Aug 5, 2026
16eccfa
Ask each demo style for the font its glyph endpoint actually serves
sargunv Aug 5, 2026
203c39f
Show the map's real frame rate in the render options demo
sargunv Aug 5, 2026
d0011b6
Reload the source list when sources change, not every commit
sargunv Aug 5, 2026
aa95101
Stop the frame cap halving the rate at the display's own refresh
sargunv Aug 5, 2026
cc81856
Write down why the pump keeps its park bound
sargunv Aug 5, 2026
10b796f
Test that a settled map stops asking to be drawn
sargunv Aug 5, 2026
6235d0e
Delete DesktopHostCapabilities from the host SPI
sargunv Aug 5, 2026
aad08d2
Retire the process-exit crash entry and its workaround
sargunv Aug 5, 2026
e10153f
Close the last feedback entry, leaving none open
sargunv Aug 5, 2026
a1af151
Retire the FFI feedback ledger and mark the rewrite complete
sargunv Aug 5, 2026
ecc5d78
Report a camera move per gesture, not per jump
sargunv Aug 5, 2026
b4379cb
Cut the desktop documentation down to what a reader needs
sargunv Aug 5, 2026
b085ae8
Drop the snapshot repository from the desktop setup
sargunv Aug 5, 2026
c82bb0a
Cut the comments this rewrite over-wrote
sargunv Aug 5, 2026
5ff0dda
Avoid restricting the buildSrc toolchain
sargunv Aug 5, 2026
56f637a
Park the runtime pumps on a wake rather than a bound
sargunv Aug 6, 2026
45304d3
Answer the review's smaller questions in the code
sargunv Aug 6, 2026
9c98203
Narrow the desktop host SPI to a GPU context handoff
sargunv Aug 6, 2026
e7e5719
Stabilize Linux OpenGL texture handoff
sargunv Aug 6, 2026
0be5e23
desktop glfw mise task
sargunv Aug 6, 2026
379df7d
Exercise desktop GPU presentation paths
sargunv Aug 6, 2026
508b048
Fix fractional desktop framebuffer scaling
sargunv Aug 6, 2026
b838032
fix cancellation
sargunv Aug 6, 2026
8df9ba1
Split the FFI integration out of desktop into mlnFfiShared
sargunv Aug 6, 2026
8aa57c6
Tune the desktop gestures to MapLibre GL JS, via GestureOptions
sargunv Aug 6, 2026
5faf86c
Skip the platform-specific tests rather than passing them
sargunv Aug 6, 2026
3eff526
Publish a native runtime artifact per platform and backend
sargunv Aug 6, 2026
85ae95e
Keep Windows map frames alive through resize
sargunv Aug 6, 2026
b1a9db6
Fix mise postinstall hooks
sargunv Aug 6, 2026
50cc476
Supply MoltenVK to macOS desktop tests
sargunv Aug 6, 2026
c012249
Share desktop test runtime dependencies
sargunv Aug 6, 2026
e64dfd4
Drop the redundant macOS Vulkan install, and correct the frame rate kdoc
sargunv-bot Aug 7, 2026
d50689b
nits
sargunv Aug 7, 2026
11f487a
clarify
sargunv Aug 7, 2026
4b88659
test: strengthen desktop behavior coverage
sargunv Aug 7, 2026
a691a5e
Address desktop FFI review feedback
sargunv Aug 7, 2026
901ba11
Share Desktop FFI tests and gestures
sargunv Aug 7, 2026
13944e4
Fix gesture resize and momentum handling
sargunv Aug 7, 2026
14e1939
Address desktop FFI review feedback
sargunv Aug 7, 2026
d2c5113
Merge remote-tracking branch 'origin/main' into desktop-ffi-rewrite
sargunv Aug 7, 2026
ece95f5
Fix desktop FFI test startup failures
sargunv Aug 7, 2026
e603416
Acquire test frames on the consumer context
sargunv Aug 7, 2026
3cb278b
Stabilize Windows desktop tests
sargunv Aug 7, 2026
a2bac08
Install Windows Vulkan loader in desktop CI
sargunv Aug 7, 2026
1c8cee0
Address verified Codex review findings
sargunv Aug 7, 2026
6bc744b
Show desktop test failure details
sargunv-bot Aug 7, 2026
2d69c10
Match Linux test surfaces to Skiko
sargunv-bot Aug 7, 2026
6fdbdc9
Fix desktop frame ownership and gesture continuation
sargunv Aug 7, 2026
4da89c3
Address remaining desktop review findings
sargunv Aug 7, 2026
981059c
Fix reflected void method invocation
sargunv Aug 7, 2026
71b02bb
Restore desktop scroll zoom rate
sargunv Aug 7, 2026
c25b59b
fix style flake and vulkan lifetime
sargunv Aug 7, 2026
9832d1d
Stabilize interrupted fling test
sargunv Aug 7, 2026
21973ec
Close desktop renderer after resize failure
sargunv Aug 7, 2026
667736a
Require app-scoped desktop cache
sargunv Aug 7, 2026
cc86edf
use real release
sargunv Aug 7, 2026
c244778
address desktop ffi review findings
sargunv Aug 8, 2026
1322a68
address follow-up desktop ffi findings
sargunv Aug 8, 2026
4ba3cec
converge desktop ffi ownership protocols
sargunv Aug 8, 2026
f6a43f1
make desktop cache configuration app-wide
sargunv Aug 8, 2026
8214299
drain after every owner task batch
sargunv Aug 8, 2026
f89d62e
simplify desktop ffi map lifecycle
sargunv Aug 8, 2026
700cb44
simplify desktop ffi runtime startup
sargunv Aug 8, 2026
a6e9e0f
simplify desktop ffi lifecycle edges
sargunv Aug 8, 2026
1997e9f
stabilize linux interop style wait
sargunv Aug 8, 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
217 changes: 217 additions & 0 deletions .agents/docs/COMMON_API_GAPS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
# Common API gaps

Capabilities MapLibre Native FFI provides that MapLibre Compose has no
cross-platform API for.

This is a staging document: a place to write findings down while they are fresh,
to be converted into issues rather than lived in. Its counterpart tracked what
we wanted _from_ maplibre-native-ffi and is gone, because nothing is left open
against it. This is the other direction — what we could build _with_ it.

## When these land

Not now, and deliberately. The sequence they belong to is:

1. Rewrite the desktop platform on maplibre-native-ffi — the branch this
document came from — and upstream fixes until the result is something we are
happy with.
2. Once it surpasses the Android and iOS integrations in quality, rewrite those
on maplibre-native-ffi too.
3. Redesign the public API and internal architecture around one common
maplibre-native-ffi integration instead of three different native ones,
deciding along the way whether web folds in via Wasm or stays on MapLibre GL
JS.
4. Implement the missing common APIs once — twice at most, if web stays separate
— against that shared integration.

Everything below is step 4 work. Implementing any of it today means writing it
separately against the Android SDK, the iOS SDK, the FFI, and MapLibre GL JS:
four implementations of the same feature, three of which are thrown away at step
2. That cost is the reason the sequence exists.

The corollary is that **what the FFI can do is the target surface**. Whether the
Android or iOS SDK exposes a capability today does not decide whether it belongs
here; those SDKs are on their way out. Where current availability is noted below
it is context, not a gate.

Found by diffing the public surface of `MapHandle`, `RuntimeHandle`, and
`RenderSessionHandle` against desktop call sites during the desktop rewrite.
Nothing here is a desktop bug.

## Architecture to fix at step 3

Not missing capabilities — shapes in the common layer that the desktop rewrite
had to work around, and that step 3 is the moment to fix rather than reproduce.
Both are cross-platform; desktop is only where they became visible.

**A layer reaches the style before its source does.** Compose inserts nodes and
calls the applier's `onEndChanges`, which is where `LayerManager` reaches
MapLibre, and only afterwards dispatches remember-observers, where
`SourceReferenceEffect` lives. So a layer names a source that does not exist
yet. The mobile SDKs tolerate that; the C API rejects it. Desktop works around
it by having a layer attach its own source first, with `Source.attach` made
idempotent so the effect's later add is harmless. The ordering is fragile on
every platform — only desktop is strict enough to notice — so the workaround
belongs in the shared layer, or the ordering does.

**Unloading the outgoing style is a contract no platform states.** Switching a
style has to mark the previous one unloaded, because `LayerManager` skips anchor
validation against an unloaded style, and that is what stops content briefly
composed into the dying node from throwing
`Layer ID '...' not found in base
style` out of the applier. Both mobile
adapters happen to do it, by calling `onStyleChanged(this, null)` from
`setBaseStyle`; nothing says they must, and desktop did not, which is how the
style selector came to crash. Timing is part of it: the unload has to be
reported before the content subcomposition applies its inserts, which on Android
falls out of `AndroidView`'s `update` block running inside the parent's apply. A
shared integration should make this the common layer's job rather than something
each platform rediscovers.

**Offline manager ownership has no lifecycle.** The FFI integration keeps one
offline manager, dedicated thread, and native runtime alive for every distinct
`MlnFfiRuntimeOptions` value passed to `rememberOfflineManager`. This preserves
downloads when the composable that acquired the manager leaves composition,
because MapLibre holds active download state in memory, but dynamically changing
options retains every previous runtime until process exit. The shared
integration should replace the global cache with an explicit application-scoped
owner: one that can outlive navigation, can be created once per options value,
and can be closed deliberately when the application is prepared to stop that
runtime's active downloads. Composition-level disposal, weak references, and
automatic eviction are not substitutes because each can silently interrupt a
download.

## Style light

Position, color, intensity, and anchor of the style's light source, which fill
extrusions shade against.

- FFI: `setStyleLightJson`, `setStyleLightProperty`, `styleLightProperty`

Naturally a Compose API: a `Light` composable inside `MaplibreMap`'s content,
set the same way layers are.

## Feature state

Per-feature state that expressions read with `feature-state`, used for hover and
selection styling without rebuilding source data.

- FFI: `setFeatureState`, `getFeatureState`, `removeFeatureState` on the render
session

The read side already exists in the common API
(`org.maplibre.compose.expressions.dsl.Feature.state`), so this is the missing
half of a feature we already ship. Neither the Android nor the iOS SDK exposes
the write side today, which is a reason to do it on the shared integration
rather than before it.

Design question: feature state lives on the render session, like the queries, so
it needs the same access path sources use for cluster queries.

## Custom geometry source

A source whose tiles are generated by application code on demand rather than
fetched or held in memory. The basis for on-the-fly grids, procedural geometry,
and very large client-side datasets.

- FFI: `addCustomGeometrySource`, `setCustomGeometrySourceTileData`,
`invalidateCustomGeometrySourceTile`, `invalidateCustomGeometrySourceRegion`

Design question: the callback boundary. MapLibre calls back on its own worker
threads to ask for a tile, which has to become something safe and idiomatic to
implement from Kotlin.

## Location indicator layer

MapLibre's built-in user-location puck — a style layer with a position, bearing,
and accuracy radius, rendered by the map rather than composed over it.

- FFI: `addLocationIndicatorLayer`, `setLocationIndicatorLocation`,
`setLocationIndicatorBearing`, `setLocationIndicatorAccuracyRadius`,
`setLocationIndicatorImageName`

Worth weighing against drawing the puck as ordinary layers from
`org.maplibre.compose.location`, which is portable and already how the demo does
it. The native indicator's advantage is that it interpolates and renders in the
same frame as the map.

## Projection mode

Switching between Mercator and globe projections.

- FFI: `projectionMode`

## Style transition options

The style's global transition duration and delay, and whether symbol placement
cross-fades. What every paint property's animation takes its default from, so
this is the one setting that changes how the whole map feels when data updates.

- FFI: `setStyleTransitionOptions`, `styleTransitionOptions`
([#465](https://github.com/maplibre/maplibre-native-ffi/pull/465))

Naturally a parameter on `MaplibreMap` or its style content, alongside the other
per-map options.

## HTTP header transforms

A hook to add or rewrite request headers for every resource the map fetches —
the usual home for an `Authorization` header or an API key that does not belong
in a URL.

- FFI: `setHttpHeaderTransform`, `clearHttpHeaderTransform`
([#509](https://github.com/maplibre/maplibre-native-ffi/pull/509))

Related to the resource-transform entry below, and worth designing with it: one
rewrites the URL, the other the headers, and an application adding credentials
needs whichever the server expects. Note the FFI reports this as unsupported on
OpenHarmony, whose HTTP client cannot intercept redirects, so a common API has
to tolerate a platform declining it.

## Missing style images

The event MapLibre raises when a style references a sprite that is not in the
loaded image set, so an application can supply it on demand instead of shipping
every icon up front. Desktop logs it today and can do nothing else, because
there is no common callback to route it to — and neither the Android nor the iOS
adapter exposes one either.

- FFI: the `MAP_STYLE_IMAGE_MISSING` runtime event, paired with the existing
`setStyleImage`

See the `MAP_STYLE_IMAGE_MISSING` branch in `DesktopMapSession.handleEvent`.

## Resource transform

A hook to rewrite every resource URL before it is requested — how applications
add API keys, route through a proxy, or redirect to a local mirror.

- FFI: `setResourceTransform`, `clearResourceTransform`

Desktop already has a broader mechanism in `DesktopResourceProvider`, which
serves resources rather than only rewriting their URLs. The shared integration
should decide which of the two is the public API, rather than shipping both.

## Offline database merge

Merging a side-loaded offline database into the running one, which is how an
application ships pre-downloaded regions rather than making every user download
them.

- FFI: `startMergeOfflineRegionsDatabase`,
`takeMergeOfflineRegionsDatabaseResult`

One suspending function on the existing `OfflineManager` interface, so this is
the smallest entry here.

## Map snapshots

- FFI: `requestStillImage`, `readPremultipliedRgba8`, and
[#282](https://github.com/maplibre/maplibre-native-ffi/pull/282), which adds a
synchronous render-to-completion so a consumer does not pump the loop frame by
frame across the language boundary

Already on the roadmap as
[#28](https://github.com/maplibre/maplibre-compose/issues/28), blocked on
decoupling the style API from the `MaplibreMap` composable. Recorded here only
so a future audit does not rediscover it as new.
19 changes: 0 additions & 19 deletions .clang-format

This file was deleted.

20 changes: 0 additions & 20 deletions .clang-tidy

This file was deleted.

17 changes: 0 additions & 17 deletions .github/actions/setup-cmake/action.yml

This file was deleted.

107 changes: 107 additions & 0 deletions .github/actions/setup-desktop-vulkan/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
name: Setup desktop Vulkan
description: >-
Give Linux and Windows runners Vulkan implementations compatible with their production bridge.

# Linux presents Lavapipe output through Mesa OpenGL. Windows uses dzn so Vulkan can import the
# D3D12 resource created by Skiko. macOS tests the Metal runtime and needs no Vulkan setup.

runs:
using: composite
steps:
- name: Install Mesa software drivers (Linux)
if: runner.os == 'Linux'
shell: bash
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends --yes \
libegl-mesa0 \
libgl1-mesa-dri \
libvulkan1 \
mesa-utils \
mesa-utils-extra \
mesa-vulkan-drivers
{
echo "EGL_PLATFORM=surfaceless"
echo "LIBGL_ALWAYS_SOFTWARE=true"
} >> "$GITHUB_ENV"

- name: Install the Vulkan runtime (Windows)
if: runner.os == 'Windows'
uses: jakoch/install-vulkan-sdk-action@37effcfa045411f8bfbbda26df2fd1b3bf3436fa # v1.6.0
with:
vulkan_version: 1.4.341.1
cache: true
stripdown: true
# dzn is an ICD, not the vulkan-1.dll loader that LWJGL opens.
install_runtime: true

- name: Install a dzn ICD (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"

function Save-CheckedArchive($Url, $Path, $ExpectedHash) {
Invoke-WebRequest -Uri $Url -OutFile $Path
$actualHash = (Get-FileHash $Path -Algorithm SHA256).Hash
if ($actualHash -ne $ExpectedHash) {
throw "Archive hash mismatch for $Url`: expected $ExpectedHash, got $actualHash"
}
}

function Register-VulkanDriver($Manifest) {
$driverKey = "HKLM:\SOFTWARE\Khronos\Vulkan\Drivers"
New-Item -Path $driverKey -Force | Out-Null
New-ItemProperty -Path $driverKey -Name $Manifest -PropertyType DWord -Value 0 -Force | Out-Null
}

$mesaVersion = "26.1.3"
if ($env:RUNNER_ARCH -eq "ARM64") {
$architecture = "arm64"
$expectedHash = "9F235A7A1195B91DC4140133D614FC7BA26A804DB16C43AE51F840FED5E84AD7"
$manifestName = "dzn_icd.aarch64.json"
} else {
$architecture = "x64"
$expectedHash = "58222C2972549FA617DE6485ADD07A5CE57B728AE005744D2FD14E419A7D670D"
$manifestName = "dzn_icd.x86_64.json"
}
$archiveName = "mesa-dzn-$architecture-$mesaVersion.7z"
$mesaUrl = "https://github.com/mmozeiko/build-mesa/releases/download/$mesaVersion/$archiveName"

$mesaArchive = Join-Path $env:RUNNER_TEMP $archiveName
$mesaRoot = Join-Path $env:RUNNER_TEMP "dzn-$mesaVersion-$env:RUNNER_ARCH"
Save-CheckedArchive $mesaUrl $mesaArchive $expectedHash
7z x $mesaArchive "-o$mesaRoot" -y | Out-Null

$driverManifest = Get-ChildItem $mesaRoot -Recurse -Filter $manifestName |
Select-Object -First 1
if (-not $driverManifest) {
throw "Missing dzn Vulkan ICD manifest $manifestName in $mesaArchive"
}

$driver = Get-ChildItem $mesaRoot -Recurse -Filter "vulkan_dzn.dll" |
Select-Object -First 1
if (-not $driver) {
throw "Missing dzn Vulkan driver in $mesaArchive"
}

Register-VulkanDriver $driverManifest.FullName
"VK_DRIVER_FILES=$($driverManifest.FullName)" >> $env:GITHUB_ENV
"Path=$($driver.Directory.FullName);$env:Path" >> $env:GITHUB_ENV

- name: Expose the Vulkan loader (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
$architecture = if ($env:RUNNER_ARCH -eq "ARM64") { "arm64" } else { "x64" }
$candidates = @("runtime\$architecture", "Bin", "bin") |
ForEach-Object { Join-Path $env:VULKAN_SDK $_ }
$directory = $candidates |
Where-Object { Test-Path (Join-Path $_ "vulkan-1.dll") } |
Select-Object -First 1
if ($directory) {
$directory | Out-File -FilePath $env:GITHUB_PATH -Append
} elseif (-not (Get-Command vulkan-1.dll -ErrorAction SilentlyContinue)) {
throw "No vulkan-1.dll in $($candidates -join ', ') or on PATH"
}
4 changes: 2 additions & 2 deletions .github/actions/setup-gradle/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ runs:
steps:
- uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: temurin
java-version: 21
distribution: zulu
java-version: 25
- uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0
with:
build-scan-publish: true
Expand Down
Loading
Loading