Vello Sparse Strips .NET Bindings
Comprehensive .NET 8.0 bindings for the Vello Sparse Strips CPU renderer with 100% API coverage, zero-allocation paths, and end-to-end tooling across native and managed layers.
Highlights
- Full surface area – All 34
RenderContextmethods, gradients, glyphs, masks, and blend modes implemented. - Modern .NET stack – Source generators via
LibraryImport, blittable structs,Span<T>APIs, and idiomaticIDisposablepatterns. - High performance – Zero-copy pixel access, SIMD (SSE2/AVX/AVX2/AVX512/NEON) detection, and multi-threaded render contexts.
- Cross-platform – Windows, Linux, and macOS across x64 and ARM64, plus experimental WebAssembly builds.
- Verified quality – 113 tests (unit, diagnostic, integration, performance) backed by BenchmarkDotNet harnesses.
- Batteries included – Fifteen sample apps, Avalonia UI host, and detailed docs for architecture, native builds, and FFI design.
NuGet Packages
Architecture Overview
SparseStrips/
├── extern/vello/ # Git submodule - Vello upstream repo
│ └── sparse_strips/
│ ├── vello_cpu/ # Core CPU renderer (Rust)
│ └── vello_common/ # Shared math/utilities
│
├── vello_cpu_ffi/ # Rust C-ABI FFI wrapper
│ ├── src/lib.rs # Exported functions
│ └── build.rs # Platform-specific build glue
│
├── dotnet/
│ ├── src/ # Shipping managed packages
│ │ ├── Vello/ # Public API
│ │ ├── Vello.Native/ # Low-level bindings
│ │ └── Vello.Avalonia/ # UI integration helpers
│ ├── samples/ # 15 demos (CLI + UI)
│ └── tests/ # Unit, diagnostics, perf, and integration suites
│
├── docs/ # Design + status docs
└── scripts/ # Platform build helpers
See docs/FFI_DESIGN.md, docs/API_COVERAGE.md, and docs/STATUS.md for deeper architecture notes.
System Requirements
- Rust 1.86+ with the relevant targets (MSVC, GNU, Clang, wasm32) for native builds.
- .NET 8.0 SDK for managed projects, tests, and sample apps.
- Platform toolchains:
- Windows: MSVC Build Tools or MinGW
- Linux: GCC or Clang +
musl/glibcdev packages as needed - macOS: Xcode Command Line Tools
Installation
Managed packages
Add the packages required by your application profile:
dotnet add package Vello
dotnet add package Vello.Avalonia # Optional UI hostThe Vello.Native package is pulled automatically as an implementation detail.
Native artifacts
The bindings expect the vello_cpu_ffi dynamic library to sit next to your application binaries. Use the provided scripts (see Building From Source) or ship the prebaked binaries produced by CI.
Quick Start
using Vello; using Vello.Geometry; // Create 800x600 render context using var context = new RenderContext(800, 600); // Set magenta paint context.SetPaint(Color.Magenta); // Draw filled rectangle context.FillRect(Rect.FromXYWH(100, 100, 200, 150)); // Render to pixmap and inspect pixels using var pixmap = new Pixmap(800, 600); context.RenderToPixmap(pixmap); ReadOnlySpan<PremulRgba8> pixels = pixmap.GetPixels(); Console.WriteLine($"First pixel: R={pixels[0].R}, G={pixels[0].G}, B={pixels[0].B}");
User Guide
1. Prepare the native runtime
- Initialize the Vello submodule (
git submodule update --init --recursive). - Install Rust 1.86+ and platform targets (
rustup target add x86_64-pc-windows-msvc, etc.). - Run the platform script from
scripts/(e.g.,./scripts/build-linux.sh). Each script produces bothDebugandReleasebinaries undervello_cpu_ffi/target/<triple>/<profile>/.
Detailed notes for every platform live in docs/native-build.md, covering toolchain quirks, environment variables, and artifact locations.
2. Build and run the managed project
- Restore and build the bindings via
dotnet build dotnet/src/Vello. - Reference
Vello(and optionallyVello.Avalonia) in your application. - Ensure the native binaries accompany your executable (copy to output folder or use
NativeLibrary.SetDllImportResolverif you need custom probing).
3. Rendering workflow
- Configure
RenderSettingsto pin SIMD level, thread count, and quality mode. - Construct a
RenderContextsized for your output surface. - Prepare paints, gradients, glyph buffers, images, and masks—
Span<T>APIs avoid heap allocations. - Execute draw commands (fill/stroke, clips, masks) in your desired order.
- Resolve into a
Pixmap, copy bytes, or stream PNG data.
Example configuration:
var settings = new RenderSettings( level: SimdLevel.Avx2, numThreads: Environment.ProcessorCount, mode: RenderMode.OptimizeSpeed); using var context = new RenderContext(1920, 1080, settings);
4. Avalonia integration
The Vello.Avalonia package exposes VelloSurface, a control that manages the render-context lifecycle, handles resize events, and blits frames into Avalonia bitmaps. Reference the namespace and bind a renderer:
<Window xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vello="clr-namespace:Vello.Avalonia.Controls;assembly=Vello.Avalonia" x:Class="MyApp.MainWindow"> <vello:VelloSurface Width="800" Height="600" Renderer="{Binding Renderer}" UseMultithreadedRendering="True" /> </Window>
Renderer accepts any IVelloRenderer implementation. A minimal renderer might look like:
using Vello; using Vello.Avalonia.Rendering; using Vello.Geometry; public sealed class SimpleRenderer : IVelloRenderer { public void Render(RenderContext context, int pixelWidth, int pixelHeight) { context.Clear(); context.SetPaint(Color.FromRgba(0.15f, 0.18f, 0.24f, 1f)); context.FillRect(Rect.FromXYWH(0, 0, pixelWidth, pixelHeight)); Span<ColorStop> stops = stackalloc ColorStop[2]; stops[0] = new ColorStop(0f, Color.DeepSkyBlue); stops[1] = new ColorStop(1f, Color.MediumPurple); context.SetPaintLinearGradient(0, 0, pixelWidth, pixelHeight, stops); var rect = Rect.FromXYWH(pixelWidth / 4f, pixelHeight / 4f, pixelWidth / 2f, pixelHeight / 2f); context.FillRect(rect); } }
Expose an instance of SimpleRenderer (or a more advanced scene graph) through your view model and bind it to Renderer. See dotnet/samples/Vello.Samples/Avalonia for a full MVVM integration with live frame statistics.
Building From Source
-
Sync dependencies
git submodule update --init --recursive
-
Build native libraries
# Windows (PowerShell) .\scripts\build-windows.ps1
# Linux / macOS / WebAssembly ./scripts/build-linux.sh ./scripts/build-macos.sh ./scripts/build-wasm.sh # requires wasm-tools workload + Emscripten
-
Build managed artifacts
dotnet build dotnet/Vello.sln
The scripts focus on vello_cpu_ffi. Use dotnet publish to ship self-contained applications. Refer to docs/native-build.md for manual toolchain setup and troubleshooting.
Performance Profile
- Zero-allocation text/gradient/glyph rendering via aggressive
Span<T>usage and stackalloc heuristics. - Zero-copy PNG I/O – load from
ReadOnlySpan<byte>, export into caller-provided buffers, and expose raw pixel bytes. - SIMD-aware rendering – runtime detection plus explicit overrides for SSE2 through AVX512 and NEON.
- Multi-threaded pipelines – configurable worker pool for large surfaces.
Span<ColorStop> stops = stackalloc ColorStop[3]; stops[0] = new ColorStop(0.0f, Color.Red); stops[1] = new ColorStop(0.5f, Color.Green); stops[2] = new ColorStop(1.0f, Color.Blue); context.SetPaintLinearGradient(0, 0, 400, 300, stops); // zero allocations Span<Glyph> glyphs = stackalloc Glyph[text.Length]; int count = font.TextToGlyphs(text, glyphs); context.FillGlyphs(font, 48.0f, glyphs.Slice(0, count)); // zero allocations
More details live in docs/perf/ and docs/IMPLEMENTATION_PLAN.md.
Platform Support
| Platform | x64 | ARM64 | Status |
|---|---|---|---|
| Windows | ✅ | ✅ | Supported |
| Linux | ✅ | ✅ | Supported |
| macOS | ✅ | ✅ | Supported |
| WebAssembly | ⚙️ | ⚙️ | Experimental |
Quality & Testing
dotnet/tests/Vello.Tests– 85 unit tests (95%+ pass rate; remaining experiments tracked indocs/tests).dotnet/tests/Vello.DiagnosticTests– deep validation harness covering corner cases, threading, and disposal.dotnet/tests/Vello.Benchmarks– BenchmarkDotNet suites for frame time, glyph throughput, and PNG I/O.dotnet/tests/Vello.IntegrationTest– package validation and smoke tests executed before publishing.- Native benchmarks in
rust_api_benchanddocs/perf/ensure parity with upstream Vello performance.
Run the full suite via:
dotnet test dotnet/Vello.slnSamples & Tooling
dotnet/samples/Vello.Samples– 15 showcase scenarios (images, gradients, typography, masking).dotnet/samples/Vello.Examples– CLI-first examples suitable for CI or scripting.dotnet/samples/MTTest– multithreading exploration harness.BENCHMARKS.md– summary of recent perf investigations.
Documentation Hub
docs/API_COVERAGE.md– coverage matrix vs. upstream Vello APIs.docs/FFI_DESIGN.mdanddocs/ffi-interop-guidelines.md– FFI architecture, safety rules, and calling conventions.docs/native-build.md– native toolchain setup and artifact layout per platform.docs/IMPLEMENTATION_PLAN.md&docs/implementation-plan-missing-apis.md– roadmap and completed milestones.docs/STATUS.md– up-to-date delivery status, outstanding work, and risk log.docs/tests/– test plans and diagnostic methodologies.docs/vello-hybrid-bindings-plan.md&docs/vello_cpu_recording_api_plan.md– exploratory work for future bindings.
Project Status
Feature complete. All implementation phases (FFI, .NET bindings, advanced features, and docs) are complete, with 34/34 RenderContext methods exposed. See docs/STATUS.md for the authoritative state and docs/API_COVERAGE.md for the line-by-line checklist.
Contributing
Contributions are welcome—whether bug fixes, feature work, documentation, or performance experiments. Please open an issue to discuss significant changes, keep commits scoped, and ensure dotnet format + dotnet test pass locally. Native and managed guidelines live in docs/FFI_DESIGN.md and docs/tests/.
License
Dual-licensed under Apache-2.0 OR MIT, matching upstream Vello.
- Apache License, Version 2.0 – see
LICENSE-APACHEor http://www.apache.org/licenses/LICENSE-2.0 - MIT License – see
LICENSE-MITor http://opensource.org/licenses/MIT
Acknowledgments
Built on top of Vello Sparse Strips by the Linebender community and the contributors who created the original renderer. Thank you!