The ProGPU integration ships the same two package IDs in separate Avalonia 12 and Avalonia 11 version lanes:
| Avalonia lane | Package | Assembly | Purpose |
|---|---|---|---|
| 12.1.1 | ProGPU.Avalonia.Rendering 12.1.1-preview.63 |
Avalonia.ProGpu |
ProGPU/WebGPU rendering backend |
| 12.1.1 | ProGPU.Avalonia.SilkNet 12.1.1-preview.63 |
Avalonia.SilkNet |
Cross-platform Silk.NET windowing backend |
| 11.3.20 | ProGPU.Avalonia.Rendering 11.3.20-preview.63 |
Avalonia.ProGpu |
Shared-source ProGPU/WebGPU rendering backend |
| 11.3.20 | ProGPU.Avalonia.SilkNet 11.3.20-preview.63 |
Avalonia.SilkNet |
Shared-source Silk.NET windowing backend |
| native ABI | ProGPU.Backend.Native 0.1.0-preview.63 |
ProGPU.Backend.Native |
Experimental typed C++ renderer host with isolated wgpu-native and provider-resolved Dawn binaries for Linux, macOS, and Windows x64/arm64 |
| native ABI | ProGPU.Backend.Dawn 0.1.0-preview.63 |
ProGPU.Backend.Dawn |
Exact-ABI Dawn device, IOSurface shared memory, and timeline fences |
The Avalonia 12 packages are built against exactly Avalonia 12.1.1; the
Avalonia 11 packages are built against exactly Avalonia 11.3.20. Both lanes
use ProGPU 0.1.0-preview.63. They intentionally use ProGPU.* package IDs;
no Avalonia.* package ID is published by the normal NuGet.org release lane.
The separately gated private/local replacement lane described below produces
an exact-identity Avalonia package and must never be pushed to NuGet.org.
The NuGet package page uses docs/progpu-package-readme.md. Keep its install, startup, API lease, and troubleshooting instructions current when package contracts change.
The original package artwork is maintained as build/Assets/ProGpuAvaloniaIcon.svg and rendered to build/Assets/ProGpuAvaloniaIcon.png. NuGet uses the PNG, and both files are included in each integration package.
All four integration projects live in this repository and reference the local ProGPU runtime projects. Build the Avalonia 12 lane with:
dotnet build src/ProGPU.Avalonia.Rendering/ProGPU.Avalonia.Rendering.csproj
dotnet build src/ProGPU.Avalonia.SilkNet/ProGPU.Avalonia.SilkNet.csprojBuild the Avalonia 11 lane with:
dotnet build src/ProGPU.Avalonia.Rendering.V11/ProGPU.Avalonia.Rendering.V11.csproj
dotnet build src/ProGPU.Avalonia.SilkNet.V11/ProGPU.Avalonia.SilkNet.V11.csprojThe v11 projects contain no duplicated backend implementation. They source-link
the Avalonia 12 project sources and define AVALONIA11; conditionals are limited
to concrete Avalonia API differences. Warning AVA3001 is expected because the
backends implement Avalonia platform interfaces that are intentionally private.
The package dependencies are exact pins, so upgrading Avalonia requires a
matching integration build.
The portable package lane builds the reviewed ACadSharp submodule feature
commit as ACadSharp.ProGPU before it builds ProGPU.CAD. Both artifacts use
the common ProGPU package version, and the ProGPU.CAD nuspec must contain an
exact dependency on ACadSharp.ProGPU with no dependency on upstream
ACadSharp. The distinct identity keeps source and package behavior aligned
without modifying or impersonating the upstream package. Package verification
also requires lib/net10.0/ACadSharp.dll in the fork artifact.
The ACadSharp fork package is a release artifact, not an ordinary upstream
replacement. Local validation may pack it into artifacts/packages; external
publication is performed only by the authorized release workflow.
Run the focused paired pack and dependency/content audit with:
PROGPU_PACKAGE_GROUP=cad ./eng/progpu-pack.shThat lane also restores, builds, and runs a clean net10.0 package-only consumer
in a fresh NuGet cache. The consumer uses both ProGPU.CAD and its transitive
ACadSharp API, and its resolved asset graph must contain ACadSharp.ProGPU but
not upstream ACadSharp.
The four integration projects are explicitly packable even though the repository defaults new projects to non-packable. Validate the complete exact-source replacement stack with:
./tools/pack-avalonia-progpu-stack.shThis builds the exact-identity Avalonia replacement, compares its public ABI
with the separately pinned source-replacement Avalonia lane, packs the ProGPU runtime dependency closure and
both Avalonia integration lanes, and rejects runtime reflection in the
renderer and Silk.NET assemblies.
The source-built Control Catalog starts with Silk.NET windowing and ProGPU rendering when no renderer argument is supplied:
./integration/AvaloniaSourceControlCatalog/run.shControlCatalog uses the managed ProGPU OpenType shaper by default. Pass
--harfbuzz to use Avalonia's previous HarfBuzz backend for correctness and
performance comparison.
The independent Skia/HarfBuzz reference process is
integration/AvaloniaSkiaControlCatalogReference.
The main-window title identifies the configured windowing platform, rendering platform, compositor, and text shaper. ProGPU lanes replace the configured rendering label after the first rendered frame with the observed presentation path (Silk.NET WebGPU surface, Dawn Metal IOSurface, Dawn D3D12 HWND, Dawn Vulkan Xlib, or Avalonia framebuffer). The Skia reference lane reports Skia, the Avalonia retained compositor, and HarfBuzz. This uses typed startup and frame-diagnostic contracts only; it performs no reflection or runtime assembly probing.
The RenderDemo and Sandbox integration hosts compile the unchanged official Avalonia 12.1.1 sample projects from the prepared pinned source tree. The ProGPU-owned startup assemblies replace only platform selection:
./integration/AvaloniaSourceRenderDemo/run.sh
./integration/AvaloniaSourceSandbox/run.shBoth use Silk.NET windowing, the ProGPU renderer/compositor, the compatible
Avalonia.Skia contract assembly, and ProGPU OpenType shaping. Pass
--harfbuzz to either host for a shaping comparison. Neither host copies an
Avalonia sample into the ProGPU tree.
Their bounded hardware smoke mode exits after observing real ProGPU frames and writes the presentation path, draw count, retained-scene count, and fallback count:
./integration/AvaloniaSourceRenderDemo/run.sh \
--smoke-frames 4 \
--smoke-output /tmp/progpu-renderdemo.json
./integration/AvaloniaSourceSandbox/run.sh \
--smoke-frames 1 \
--smoke-output /tmp/progpu-sandbox.jsonThe preparation script is safe to rerun. It applies the retained-compositor foundation and then the focused text, ControlCatalog, package, native presentation, and source-sample patches without applying overlapping legacy hunks twice.
The Silk.NET backend implements Avalonia window chrome through typed native controllers. Requests made before native-window creation are retained and replayed when the window is initialized. Supported contracts include extended client area and margins, title-bar height hints, system-decoration modes, managed decoration requests, minimize/maximize/resize permissions, taskbar visibility, topmost/enabled state, owners, native size constraints, backdrop selection, move/resize drags, and popup shadow hints.
On macOS, transparent, blur, acrylic, and Mica hints map to the closest native
vibrancy/backdrop behavior and popup shadows use NSWindow shadow state. On
Windows, popup shadow hints use the native drop-shadow window class style.
Unsupported combinations retain deterministic Avalonia state instead of using
reflection or probing private runtime objects.
Run the package-only native chrome contract with:
PROGPU_PACKAGE_SMOKE_WINDOW_CHROME=1 \
PROGPU_PACKAGE_SMOKE_FRAMES=8 \
./integration/ProGpuAvaloniaPackageSmoke/run.sh localRun every ControlCatalog page in a fresh Release process and collect FPS, frame-time, allocation, retained-memory, physical-footprint, and ProGPU GPU resource metrics with:
./tools/profile-avalonia-controlcatalog.shThe default is the pinned source-built Avalonia runtime, ProGPU renderer,
managed ProGPU shaper, and Silk.NET windowing. Set
PROGPU_AVALONIA_BACKENDS=source-progpu,source-progpu-harfbuzz for an
apples-to-apples shaping sweep of the replacement runtime. The skia lane is
the official Avalonia Skia/HarfBuzz reference process. Use
PROGPU_AVALONIA_PAGE_FILTER to run a
regular-expression subset. The
generated summary.json, summary.md, per-page logs, optional screenshots, and
failures.tsv are written under artifacts/avalonia-controlcatalog-profile.
The Silk.NET render timer follows the primary display refresh rate; set
PROGPU_AVALONIA_RENDER_FPS=60 (or another value from 24 through 360) when a
fixed-rate comparison is required.
The macOS non-Silk presentation matrix is selected with:
PROGPU_AVALONIA_BACKENDS=source-progpu-native,source-progpu-native-harfbuzz,source-progpu,skia \
PROGPU_AVALONIA_PAGE_FILTER='^Buttons$' \
./tools/profile-avalonia-controlcatalog.shThe native lane builds the exact Avalonia.Native source into isolated Xcode
DerivedData, installs it into the ControlCatalog output, deletes the
intermediates, and launches --native-windowing with Dawn presentation
required. Results include physical render-target dimensions and DPI so a
lower-resolution surface cannot appear to be a memory optimization.
Run the pinned Avalonia text conformance corpus against the ProGPU shaper with:
./tools/test-avalonia-progpu-text.shThe script builds the exact official 12.1.1 source-lane test executable and runs the complete
text-formatting namespace plus GlyphRunTests. The test bodies and assertions
remain upstream; only the typed ProGPU test bootstrap selects
ProGpuTextShaper.
Run the pinned Avalonia retained-compositor revision contract with:
./tools/test-avalonia-progpu-compositor.shThis verifies that visual-state changes advance the retained scene revision without invalidating immutable draw-list content, while replacing draw-list content advances both contracts.
On a desktop with a working Silk.NET/WebGPU surface, run the retained versus flattened pixel contract with:
./tools/test-avalonia-progpu-retained-pixels.shThe script compares exact PNG bytes for Buttons, Composition, Acrylic, BitmapCache, Canvas, AdornerLayer, Clipboard, HeaderedContentControl, Notifications, bounded native geometry/text-option fixtures, native blur and offset/color/opacity drop-shadow fixtures, and all BitmapCache option fixtures. It requires gradient and recorded-picture opacity masks, unclipped and clipped adorners, including rotated conic gradients, standard visual effects, and the geometry-clip workload to remain inside the retained ProGPU scene with zero fallback nodes.
The full-compositor replacement design and its package compatibility gates are
in
AVALONIA_COMPOSITOR_BACKEND_ARCHITECTURE.md.
Pack the ProGPU 0.1.0-preview.63 portable runtime packages first, then pack
both integration lanes:
PROGPU_PACKAGE_GROUP=portable ./eng/progpu-pack.sh
./scripts/progpu-pack.shThe package-only application can perform that sequence and then restore in an isolated package cache:
PROGPU_INTEGRATION_BUILD_ONLY=1 \
./integration/ProGpuAvaloniaPackageSmoke/run.sh localSet PROGPU_PACKAGE_SOURCE to use another absolute local package directory. The
expected integration output is eight files: a .nupkg and .snupkg for each of
the four package/version entries.
Build the complete private/local replacement stack with:
./tools/pack-avalonia-progpu-stack.shThis creates an Avalonia 12.1.1 package from the exact official tag plus
the reviewed typed compositor seam, then compiles the ProGPU renderer against
that seam. It also packs the ten-package avalonia-runtime dependency
closure (Backend, Backend.Dawn, Text.Shaping, Transpiler, Vector,
Text, Compute, Scene, and SkiaSharp) from the same checkout. The
verifier compares every
packed lib and ref assembly for
net10.0 and net8.0 against the official package with strict ApiCompat,
checks assembly identities, verifies the packed Avalonia.Base bytes are the
validated source build, and requires the package provenance notice.
Because its package ID and version intentionally collide with the official
package, this artifact is only for an isolated private/local feed. It is the
actual NuGet bait-and-switch lane: applications keep
PackageReference Include="Avalonia" Version="12.1.1" while the feed supplies
the ProGPU source build. It must not be published to NuGet.org.
Exercise a clean package-only consumer and fail if restore selects the official binary instead of the validated local replacement:
PROGPU_INTEGRATION_BUILD_ONLY=1 \
./integration/ProGpuAvaloniaPackageSmoke/run.sh replacementThe isolated consumer restores into a fresh NuGet package directory, builds against the local feed, and validates the exact assembly identities selected by the project. The replacement package tool performs the package-content and ABI checks before the consumer is launched.
Publish and execute that same exact restored stack under NativeAOT:
PROGPU_PACKAGE_SOURCE=artifacts/avalonia-replacement \
PROGPU_REUSE_REPLACEMENT_STACK=1 \
PROGPU_INTEGRATION_NATIVE_AOT=1 \
PROGPU_INTEGRATION_SMOKE=1 \
./integration/ProGpuAvaloniaPackageSmoke/run.sh replacementThis is a runtime gate, not only a linker check. The native executable must
render frames, use the retained compositor, and report zero fallback nodes.
The host RID is selected automatically; an explicit compatible RID can be
provided through PROGPU_INTEGRATION_RUNTIME_IDENTIFIER. The isolated
packages, AOT compiler output, and published binary are removed when the
runner exits.
The final preview.27 replacement stack passed this gate from the exact
artifacts/avalonia-replacement bytes. The isolated package-only build
completed with zero warnings, the macOS arm64 NativeAOT executable was
22,266,520 bytes and rendered 40 frames with zero fallback nodes, and the
ordinary smoke rendered 28 frames with zero fallbacks. The multi-window smoke
rendered 70 aggregate frames across two retained scenes; the survivor remained
renderable after both owner-first and borrower-first shared-device disposal.
The checked-in gate also caught and fixed input-device list mutation during
owner disposal. Its NativeAOT runner now restores the IL compiler into the
isolated cache and rejects an IL-only self-contained publish.
NativeAOT analysis warnings were confined to the third-party Silk.NET loader
and ImageSharp assemblies; Avalonia.ProGpu.dll and Avalonia.SilkNet.dll
remain clean under the runtime-reflection metadata audit.
Keep the API key out of command history and repository files. From Bash:
read -rsp "NuGet API key: " NUGET_API_KEY && printf '\n'
export NUGET_API_KEY
./scripts/progpu-publish.sh
unset NUGET_API_KEYprogpu-publish.sh repacks, validates all expected artifacts, and pushes each package with --skip-duplicate; dotnet nuget push discovers and uploads the matching symbol package automatically. Override NUGET_SOURCE only when publishing to another NuGet-compatible server.
Release order:
- Tag and publish ProGPU
0.1.0-preview.63. - Confirm the required ProGPU packages are available from NuGet.org.
- Pack and test both Avalonia integration lanes.
- Publish the two
12.1.1-preview.63packages and the two11.3.20-preview.63packages.
<ItemGroup>
<PackageReference Include="Avalonia" Version="12.1.1" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="12.1.1" />
<PackageReference Include="ProGPU.Avalonia.Rendering" Version="12.1.1-preview.63" />
<PackageReference Include="ProGPU.Avalonia.SilkNet" Version="12.1.1-preview.63" />
</ItemGroup>Configure both backends before starting the desktop lifetime:
using Avalonia.Rendering.Composition;
public static AppBuilder BuildAvaloniaApp() =>
AppBuilder.Configure<App>()
.UseSilkNet()
.UseProGpu()
.With(new CompositionOptions
{
UseRegionDirtyRectClipping = false
})
.UseProGpuTextShaping()
.WithInterFont();UseSkia() remains available as a compatibility alias for the ProGPU renderer, but UseProGpu() avoids ambiguity with Avalonia's Skia package.
The renderer also exposes Avalonia's ISkiaSharpApiLeaseFeature source
contract over ProGPU.SkiaSharp, allowing existing custom draw operations to
keep using lease.SkCanvas after recompilation. Do not reference the official
Avalonia.Skia package in this lane; its assembly and native SkiaSharp
identities are a different binary contract. See
docs/AVALONIA_SKIASHARP_LEASE_COMPATIBILITY_RESEARCH.md for the design and
conformance record.
Use IProGpuApiLeaseFeature from ICustomDrawOperation.Render for scoped
access to the ProGPU scene command recorder and active WgpuContext. The
lease lifetime and package-facing API contract are documented in
docs/progpu-package-readme.md.
For Avalonia 11 applications, use the same package IDs with
11.3.20-preview.63 and pin the Avalonia packages to 11.3.20.
The cross-engine design review and validation evidence are recorded in
docs/progpu-avalonia-rendering-research.md.