# ProGPU rendering and Silk.NET windowing The ProGPU integration ships the same two package IDs in separate Avalonia 12 and Avalonia 11 version lanes: | Avalonia lane | Package | Assembly | Purpose | | --- | --- | --- | --- | | 12.0.5 | `ProGPU.Avalonia.Rendering` `12.0.5-preview.31` | `Avalonia.ProGpu` | ProGPU/WebGPU rendering backend | | 12.0.5 | `ProGPU.Avalonia.SilkNet` `12.0.5-preview.31` | `Avalonia.SilkNet` | Cross-platform Silk.NET windowing backend | | 11.3.18 | `ProGPU.Avalonia.Rendering` `11.3.18-preview.31` | `Avalonia.ProGpu` | Shared-source ProGPU/WebGPU rendering backend | | 11.3.18 | `ProGPU.Avalonia.SilkNet` `11.3.18-preview.31` | `Avalonia.SilkNet` | Shared-source Silk.NET windowing backend | | native ABI | `ProGPU.Backend.Dawn` `0.1.0-preview.31` | `ProGPU.Backend.Dawn` | Exact-ABI Dawn device, IOSurface shared memory, and timeline fences | The Avalonia 12 packages are built against exactly Avalonia `12.0.5`; the Avalonia 11 packages are built against exactly Avalonia `11.3.18`. Both lanes use ProGPU `0.1.0-preview.31`. 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. ## Development projects All four integration projects live in this repository and reference the local ProGPU runtime projects. Build the Avalonia 12 lane with: ```bash dotnet build src/ProGPU.Avalonia.Rendering/ProGPU.Avalonia.Rendering.csproj dotnet build src/ProGPU.Avalonia.SilkNet/ProGPU.Avalonia.SilkNet.csproj ``` Build the Avalonia 11 lane with: ```bash dotnet build src/ProGPU.Avalonia.Rendering.V11/ProGPU.Avalonia.Rendering.V11.csproj dotnet build src/ProGPU.Avalonia.SilkNet.V11/ProGPU.Avalonia.SilkNet.V11.csproj ``` The 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 four integration projects are explicitly packable even though the repository defaults new projects to non-packable. Validate the complete exact-source replacement stack with: ```bash ./tools/pack-avalonia-progpu-stack.sh ``` This builds the exact-identity `Avalonia` replacement, compares its public ABI with official Avalonia 12.0.5, packs the ProGPU runtime dependency closure and both Avalonia integration lanes, and rejects runtime reflection in the renderer and Silk.NET assemblies. ## Control Catalog defaults The source-built Control Catalog starts with Silk.NET windowing and ProGPU rendering when no renderer argument is supplied: ```bash ./integration/AvaloniaSourceControlCatalog/run.sh ``` ControlCatalog 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. ## Official source sample hosts The RenderDemo and Sandbox integration hosts compile the unchanged official Avalonia 12.0.5 sample projects from the prepared pinned source tree. The ProGPU-owned startup assemblies replace only platform selection: ```bash ./integration/AvaloniaSourceRenderDemo/run.sh ./integration/AvaloniaSourceSandbox/run.sh ``` Both 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: ```bash ./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.json ``` The 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. ## Silk.NET window chrome 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: ```bash PROGPU_PACKAGE_SMOKE_WINDOW_CHROME=1 \ PROGPU_PACKAGE_SMOKE_FRAMES=8 \ ./integration/ProGpuAvaloniaPackageSmoke/run.sh local ``` Run every ControlCatalog page in a fresh Release process and collect FPS, frame-time, allocation, retained-memory, physical-footprint, and ProGPU GPU resource metrics with: ```bash ./tools/profile-avalonia-controlcatalog.sh ``` The 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: ```bash PROGPU_AVALONIA_BACKENDS=source-progpu-native,source-progpu-native-harfbuzz,source-progpu,skia \ PROGPU_AVALONIA_PAGE_FILTER='^Buttons$' \ ./tools/profile-avalonia-controlcatalog.sh ``` The 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: ```bash ./tools/test-avalonia-progpu-text.sh ``` The script builds the exact official 12.0.5 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: ```bash ./tools/test-avalonia-progpu-compositor.sh ``` This 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: ```bash ./tools/test-avalonia-progpu-retained-pixels.sh ``` The 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`](AVALONIA_COMPOSITOR_BACKEND_ARCHITECTURE.md). ## Pack locally Pack the ProGPU `0.1.0-preview.31` portable runtime packages first, then pack both integration lanes: ```bash PROGPU_PACKAGE_GROUP=portable ./eng/progpu-pack.sh ./scripts/progpu-pack.sh ``` The package-only application can perform that sequence and then restore in an isolated package cache: ```bash PROGPU_INTEGRATION_BUILD_ONLY=1 \ ./integration/ProGpuAvaloniaPackageSmoke/run.sh local ``` Set `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. ## Exact-identity private replacement package Build the complete private/local replacement stack with: ```bash ./tools/pack-avalonia-progpu-stack.sh ``` This creates an `Avalonia` `12.0.5` package from the exact official tag plus the reviewed typed compositor seam, then compiles the ProGPU renderer against that seam. It also packs the nine-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.0.5"` 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: ```bash PROGPU_INTEGRATION_BUILD_ONLY=1 \ ./integration/ProGpuAvaloniaPackageSmoke/run.sh replacement ``` The 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: ```bash PROGPU_PACKAGE_SOURCE=artifacts/avalonia-replacement \ PROGPU_REUSE_REPLACEMENT_STACK=1 \ PROGPU_INTEGRATION_NATIVE_AOT=1 \ PROGPU_INTEGRATION_SMOKE=1 \ ./integration/ProGpuAvaloniaPackageSmoke/run.sh replacement ``` This 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. ## Publish to NuGet.org Keep the API key out of command history and repository files. From Bash: ```bash read -rsp "NuGet API key: " NUGET_API_KEY && printf '\n' export NUGET_API_KEY ./scripts/progpu-publish.sh unset NUGET_API_KEY ``` `progpu-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: 1. Tag and publish ProGPU `0.1.0-preview.31`. 2. Confirm the required ProGPU packages are available from NuGet.org. 3. Pack and test both Avalonia integration lanes. 4. Publish the two `12.0.5-preview.31` packages and the two `11.3.18-preview.31` packages. ## Consume the packages ```xml ``` Configure both backends before starting the desktop lifetime: ```csharp using Avalonia.Rendering.Composition; public static AppBuilder BuildAvaloniaApp() => AppBuilder.Configure() .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. 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.18-preview.31` and pin the Avalonia packages to `11.3.18`. The cross-engine design review and validation evidence are recorded in `docs/progpu-avalonia-rendering-research.md`.