CodeBrix.WebGpu.Skia.MitLicenseForever 1.0.291.34

dotnet add package CodeBrix.WebGpu.Skia.MitLicenseForever --version 1.0.291.34
                    
NuGet\Install-Package CodeBrix.WebGpu.Skia.MitLicenseForever -Version 1.0.291.34
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CodeBrix.WebGpu.Skia.MitLicenseForever" Version="1.0.291.34" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CodeBrix.WebGpu.Skia.MitLicenseForever" Version="1.0.291.34" />
                    
Directory.Packages.props
<PackageReference Include="CodeBrix.WebGpu.Skia.MitLicenseForever" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CodeBrix.WebGpu.Skia.MitLicenseForever --version 1.0.291.34
                    
#r "nuget: CodeBrix.WebGpu.Skia.MitLicenseForever, 1.0.291.34"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CodeBrix.WebGpu.Skia.MitLicenseForever@1.0.291.34
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CodeBrix.WebGpu.Skia.MitLicenseForever&version=1.0.291.34
                    
Install as a Cake Addin
#tool nuget:?package=CodeBrix.WebGpu.Skia.MitLicenseForever&version=1.0.291.34
                    
Install as a Cake Tool

CodeBrix.WebGpu.Skia

WebGPU rendering straight into SkiaSharp surfaces: give it an SKSurface, an SKCanvas, a GRContext or nothing at all, and WebGPU draws into it the fastest way the inputs allow - with no copy at all when the surface lives on the same GPU device - and tells you which way it took. CodeBrix.WebGpu.Skia is provided as a .NET library and associated CodeBrix.WebGpu.Skia.MitLicenseForever NuGet package.

CodeBrix.WebGpu.Skia supports applications and assemblies that target Microsoft .NET version 10.0 and later. Microsoft .NET version 10.0 is a Long-Term Supported (LTS) version of .NET, and was released on Nov 11, 2025; and will be actively supported by Microsoft until Nov 14, 2028. Please update your C#/.NET code and projects to the latest LTS version of Microsoft .NET.

Installation

dotnet add package CodeBrix.WebGpu.Skia.MitLicenseForever

Note that the NuGet package ID and the namespace are different - there is no package named plain CodeBrix.WebGpu.Skia:

  • NuGet package ID: CodeBrix.WebGpu.Skia.MitLicenseForever
  • Assembly and primary namespace: CodeBrix.WebGpu.Skia - i.e. using CodeBrix.WebGpu.Skia;

XML documentation (IntelliSense) ships alongside the assembly.

CodeBrix.WebGpu.Skia depends on SkiaSharp and on CodeBrix.WebGpu.Native (CodeBrix.WebGpu.Native.MitLicenseForever, the WebGPU binding with its native libraries for every supported platform); both are installed automatically. It does not bring SkiaSharp's native libraries for Linux: add the SkiaSharp native-assets package for each platform your application runs on (for example SkiaSharp.NativeAssets.Linux), as every SkiaSharp application does. Code that records WebGPU commands must allow unsafe code (<AllowUnsafeBlocks>true</AllowUnsafeBlocks>).

CodeBrix.WebGpu.Skia supports:

  • Three ways to get WebGPU pixels onto a Skia surface, chosen automatically and reported (WebGpuSkiaTarget.Tier and TierReason):
    • Zero copy - WebGPU renders directly into the texture behind the SKSurface; nothing is copied
    • GPU copy - the surface is on the same GPU device but its own texture cannot be shared: WebGPU renders into its own texture and SkiaSharp draws it onto the surface with one GPU-side draw, with no CPU readback
    • Readback - raster surfaces, surfaces on another device or on OpenGL, and canvases without a surface: the frame is copied to CPU memory and drawn onto the canvas
  • Owning the GPU device: the library creates the WebGPU device on the platform's own GPU API - Vulkan on Linux and Android, Direct3D 12 (with Vulkan as an option) on Windows, Metal on macOS - and creates the SkiaSharp GRContext on that same device, so every surface the library creates on it is zero copy
  • Adopting the application's device: an application that already has a Vulkan or Metal GRContext hands its backend context to the library, which wraps that native device for WebGPU - surfaces on the application's own context then reach the zero-copy and GPU-copy tiers
  • Zero copy for surfaces the application created over its own GPU texture, when it tells the library which native texture backs the surface
  • A small, explicit frame protocol - BeginWebGpuPass / EndWebGpuPass - that orders WebGPU and SkiaSharp work on the GPU and moves the texture between the two in both directions
  • Headless rendering with no surface at all, read back as an SKImage, an SKBitmap or raw bytes (tight rows or rows of your own stride) - for tests, servers and screenshots
  • Asynchronous, double-buffered read-back: BeginReadPixels issues a frame's copy and returns at once, EndReadPixels copies the pixels out later, so the next frame renders while the previous one is mapped; the number of staging buffers is configurable
  • Fast copies out of mapped GPU memory, including on mobile GPUs whose read-back memory the CPU reads uncached
  • Required device features, native engine features and limits for the owned device; a requirement the adapter cannot meet is never dropped - device creation reports each unmet feature or limit by name, with the adapter's value, so the caller can fall back
  • The adapter's available features and limits next to the device's enabled ones, for owned and adopted devices, and device-loss reporting
  • A readback counter, so an application (or a test) can prove a render loop never touches CPU memory
  • Optional preservation of the surface's content in the copy tiers, so a WebGPU pass that loads instead of clearing sees what SkiaSharp drew
  • Sharing through CodeBrix.WebGpu.Native's contracts: WebGpuSkiaDevice is an IWebGpuDeviceSource and WebGpuSkiaTarget an IWebGpuTextureTarget, so any library built on CodeBrix.WebGpu.Native that accepts them - for example CodeBrix.WebGpu.Graphics - shares the device and renders into the target in one call each, without either package referencing the other
  • Reporting instead of crashing: a missing GPU API, adapter, device or format - or a format and usage the device rejects - makes the device or target unavailable with a reason string; a frame whose WebGPU commands fail validation is never submitted: EndWebGpuPass throws WebGpuSkiaValidationException with WebGPU's message and the target stays ready for the next frame

Sample Code

Zero copy: WebGPU and SkiaSharp drawing into the same pixels

using CodeBrix.WebGpu.Native;
using CodeBrix.WebGpu.Skia;
using SkiaSharp;

using WebGpuSkiaDevice gpu = WebGpuSkiaDevice.Create();
if (!gpu.IsAvailable) { Console.WriteLine(gpu.Reason); return; }

GRContext grContext = gpu.CreateGrContext();            // owned by gpu; do not dispose
using WebGpuSkiaTarget target = WebGpuSkiaTarget.Create(gpu, grContext, 512, 512);
Console.WriteLine(target);                              // "ZeroCopy 512x512 RGBA8Unorm on Vulkan"

unsafe
{
    CommandEncoder encoder = target.BeginWebGpuPass();   // SkiaSharp's work is submitted first
    RenderPassColorAttachment attachment = new RenderPassColorAttachment
    {
        View = target.TextureView,
        DepthSlice = Constants.DepthSliceUndefined,
        LoadOp = LoadOp.Clear,
        StoreOp = StoreOp.Store,
        ClearValue = new Color { R = 0.1, G = 0.2, B = 0.4, A = 1 },
    };
    RenderPassDescriptor pass = new RenderPassDescriptor { ColorAttachmentCount = 1, ColorAttachments = &attachment };
    RenderPassEncoder renderPass = WebGpu.CommandEncoderBeginRenderPass(encoder, &pass);
    // ... set your pipeline and draw ...
    WebGpu.RenderPassEncoderEnd(renderPass);
    WebGpu.RenderPassEncoderRelease(renderPass);
    target.EndWebGpuPass();                              // submitted; the texture is SkiaSharp's again
}

using SKPaint paint = new SKPaint { Color = SKColors.White, IsAntialias = true };
using SKFont font = new SKFont { Size = 24 };
target.Surface.Canvas.DrawText("drawn by SkiaSharp", 20, 40, SKTextAlign.Left, font, paint);

Any surface you already have

using WebGpuSkiaTarget target = WebGpuSkiaTarget.Create(gpu, mySurface);   // or mySurface.Canvas
Console.WriteLine(target.Tier + ": " + target.TierReason);                  // why not a faster tier

CommandEncoder encoder = target.BeginWebGpuPass();
// ... record passes that render into target.TextureView ...
target.EndWebGpuPass();                                                    // the frame is on mySurface now

Headless

using WebGpuSkiaTarget target = WebGpuSkiaTarget.CreateHeadless(gpu, 256, 256);
CommandEncoder encoder = target.BeginWebGpuPass();
// ... render into target.TextureView ...
target.EndWebGpuPass();
using SKImage image = target.ReadImage();

Required features and limits

WebGpuSkiaDeviceOptions options = new WebGpuSkiaDeviceOptions();
options.RequiredFeatures.Add(FeatureName.TimestampQuery);
Limits limits = WebGpuSkiaLimits.Undefined();
limits.MaxTextureDimension2D = 16384;
options.RequiredLimits = limits;

using WebGpuSkiaDevice gpu = WebGpuSkiaDevice.Create(options);
if (!gpu.IsAvailable)
{
    foreach (WebGpuSkiaUnmetRequirement unmet in gpu.UnmetRequirements) Console.WriteLine(unmet.Message);
}
else
{
    Console.WriteLine(string.Join(", ", gpu.Features) + " enabled of " + string.Join(", ", gpu.AdapterFeatures));
}

Asynchronous read-back

byte[] pixels = new byte[target.Width * target.Height * 4];
WebGpuSkiaReadback previous = default;
for (int frame = 0; frame < frames; frame++)
{
    CommandEncoder encoder = target.BeginWebGpuPass();
    // ... render frame ...
    target.EndWebGpuPass();
    WebGpuSkiaReadback current = target.BeginReadPixels();        // returns at once
    if (previous.IsValid && target.EndReadPixels(previous, pixels)) Show(pixels);
    previous = current;
}

if (previous.IsValid) target.EndReadPixels(previous, pixels);

Another WebGPU library on the same device and target

WebGpuSkiaDevice implements IWebGpuDeviceSource and WebGpuSkiaTarget implements IWebGpuTextureTarget (both defined in CodeBrix.WebGpu.Native), whose pass protocol is this package's BeginWebGpuPass / EndWebGpuPass. A library that accepts those contracts needs no reference to this one - with CodeBrix.WebGpu.Graphics, for example:

using GraphicsContext graphics = GraphicsContext.Wrap(gpu);                 // the same device
using (GraphicsFrame frame = graphics.BeginFrame(target, depth))            // the target's WebGPU pass
{
    using (RenderPass pass = frame.BeginRenderPass(Color4.Black)) { /* draw */ }
    frame.Submit();                                                          // ends the pass
}

target.Surface.Canvas.DrawText(...);                                         // SkiaSharp on the same pixels

Documentation

The NuGet package includes AGENT-README.txt, a complete API reference and usage guide written for AI coding agents - point your agent at that file when it is writing code against this library.

Additional sample code and usage examples are available in the CodeBrix.WebGpu.Skia.Tests project: https://github.com/ellisnet/CodeBrix.WebGpu/tree/main/tests/CodeBrix.WebGpu.Skia.Tests

License

CodeBrix.WebGpu.Skia is licensed under the MIT License - see the LICENSE file.

For licensing and provenance information about the open source code included in this package, see THIRD-PARTY-NOTICES.txt.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on CodeBrix.WebGpu.Skia.MitLicenseForever:

Package Downloads
CodeBrix.Platform.WebGpu.ApacheLicenseForever

Adds a WebGPU render view to your app: put a WebGpuRenderView in a page, handle its Render event (or give it an IWebGpuRenderer), and record WebGPU commands into the frame it hands you. It works on every Skia head, owns its GPU device, and can run continuously at a target frame rate, render only when invalidated, or be driven frame by frame from any thread you choose. A SkiaSharp overlay draws HUD text and shapes over each frame, and the view shares its device and texture with other WebGPU libraries and with native (Rust, C, C++) modules through the CodeBrix.WebGpu hand-off contracts.

CodeBrix.Android.WebGpu.ApacheLicenseForever

The WebGpu add-in for CodeBrix.Android applications: the WebGpuRenderView element of the CodeBrix.Platform WebGpu add-in on Android, with the same public API and namespace - a XAML view that hands your code a WebGPU frame (command encoder and texture) on its own Vulkan device, under a continuous, on-demand or manual frame driver, with a SkiaSharp overlay and the CodeBrix.WebGpu sharing contracts and native-module hand-off. Frames reach the screen through the SkiaSharp.Views canvas (Readback, the default) or, with the experimental direct GPU rendering opt-in, through a SurfaceView with no read-back (DirectSurface).

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.291.34 107 10/18/2026
1.0.287.390 83 10/14/2026