Skip to content

Commit c71f248

Browse files
Remove TPixel generics from WebGPU API
1 parent f53fd52 commit c71f248

33 files changed

Lines changed: 443 additions & 373 deletions

src/ImageSharp.Drawing.WebGPU/WEBGPU_BACKEND.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ The public WebGPU surface area around this backend is small and target-first. Mo
2121
**Recommended types** — the entry points most applications should use:
2222

2323
- `WebGPUEnvironment` exposes explicit support probes for the library-managed WebGPU environment
24-
- `WebGPUWindow<TPixel>` owns a native window and either runs a render loop or returns `WebGPUSurfaceFrame<TPixel>` instances through `TryAcquireFrame(...)`
25-
- `WebGPUExternalSurface<TPixel>` attaches to a caller-owned native host via `WebGPUSurfaceHost`; the host application owns the UI object and tells the external surface when the drawable framebuffer resizes
26-
- `WebGPURenderTarget<TPixel>` owns an offscreen native target for GPU rendering, hybrid CPU plus GPU canvases, and readback
24+
- `WebGPUWindow` owns a native window and either runs a render loop or returns `WebGPUSurfaceFrame` instances through `TryAcquireFrame(...)`
25+
- `WebGPUExternalSurface` attaches to a caller-owned native host via `WebGPUSurfaceHost`; the host application owns the UI object and tells the external surface when the drawable framebuffer resizes
26+
- `WebGPURenderTarget` owns an offscreen native target for GPU rendering, hybrid CPU plus GPU canvases, and readback
2727

2828
**Advanced types** — interop escape hatches for applications that already own a WebGPU device, queue, or native surface:
2929

30-
- `WebGPUDeviceContext<TPixel>` wraps a shared or caller-owned device and queue and creates native-only or hybrid frames and canvases over external textures
30+
- `WebGPUDeviceContext` is the internal device/queue binding used by targets and surfaces
3131
- `WebGPUNativeSurfaceFactory` is the low-level escape hatch for caller-owned native targets
3232

3333
Those types all exist to get a `DrawingCanvas` over a native WebGPU target. Once the canvas flushes, `WebGPUDrawingBackend` becomes the execution boundary.
@@ -52,7 +52,7 @@ The backend still has to decide:
5252

5353
That is why the backend layer exists separately from the staged scene pipeline itself.
5454

55-
The raster pipeline solves "how to rasterize this encoded scene on the GPU".
55+
The raster pipeline solves "how to rasterize this encoded scene on the GPU".
5656
`WebGPUDrawingBackend` solves "should this flush go there, and how does the system manage that decision cleanly".
5757

5858
## The Core Idea
@@ -156,7 +156,7 @@ The expensive staged work is delegated:
156156
The public object graph around those responsibilities is also separate:
157157

158158
- `WebGPUEnvironment` handles explicit support probes
159-
- `WebGPUWindow<TPixel>`, `WebGPUExternalSurface<TPixel>`, and `WebGPURenderTarget<TPixel>` are the recommended target constructors; `WebGPUDeviceContext<TPixel>` and `WebGPUNativeSurfaceFactory` are advanced interop escape hatches for caller-owned devices or surfaces
159+
- `WebGPUWindow`, `WebGPUExternalSurface`, and `WebGPURenderTarget` are the public target constructors; `WebGPUNativeSurfaceFactory` remains the low-level interop escape hatch for caller-owned textures
160160
- `DrawingCanvas` hands a prepared `CompositionScene` to the backend
161161

162162
## The Flush Boundary
@@ -267,7 +267,7 @@ The staged scene pipeline itself is described in [`WEBGPU_RASTERIZER.md`](d:/Git
267267
If you want to understand the backend first, read the code in this order:
268268

269269
1. `WebGPUEnvironment.cs`
270-
2. `WebGPUWindow{TPixel}.cs`, `WebGPUSurfaceFrame{TPixel}.cs`, `WebGPUExternalSurface{TPixel}.cs`, `WebGPUSurfaceHost.cs`, `WebGPURenderTarget{TPixel}.cs`, and `WebGPUDeviceContext{TPixel}.cs`
270+
2. `WebGPUWindow.cs`, `WebGPUSurfaceFrame.cs`, `WebGPUExternalSurface.cs`, `WebGPUSurfaceHost.cs`, `WebGPURenderTarget.cs`, and `WebGPUDeviceContext.cs`
271271
3. `WebGPUDrawingBackend.cs`
272272
4. `WebGPUFlushContext.cs`
273273
5. `WebGPURuntime.cs`
@@ -285,7 +285,7 @@ The easiest way to keep this backend straight is to remember that it is not the
285285
If that model is clear, the major types fall into place:
286286

287287
- `WebGPUEnvironment` exposes explicit support probes
288-
- `WebGPUWindow<TPixel>`, `WebGPUExternalSurface<TPixel>`, and `WebGPURenderTarget<TPixel>` are the recommended target types; `WebGPUDeviceContext<TPixel>` and `WebGPUNativeSurfaceFactory` are advanced interop escape hatches
288+
- `WebGPUWindow`, `WebGPUExternalSurface`, and `WebGPURenderTarget` are the recommended target types; `WebGPUNativeSurfaceFactory` is the advanced interop escape hatch
289289
- `WebGPUDrawingBackend` orchestrates and decides policy
290290
- `WebGPUFlushContext` owns one flush's execution state
291291
- `WebGPURuntime` owns longer-lived device state

src/ImageSharp.Drawing.WebGPU/WEBGPU_RASTERIZER.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Together, these types turn one prepared flush into a staged GPU scene, schedule
1414

1515
This document starts after two earlier boundaries have already been crossed:
1616

17-
- public WebGPU setup has already selected or created a native target through `WebGPUWindow<TPixel>`, `WebGPURenderTarget<TPixel>`, `WebGPUDeviceContext<TPixel>`, or `WebGPUNativeSurfaceFactory`
17+
- public WebGPU setup has already selected or created a native target through `WebGPUWindow`, `WebGPUExternalSurface`, `WebGPURenderTarget`, or `WebGPUNativeSurfaceFactory`
1818
- `WebGPUDrawingBackend` has already decided that the flush should stay on the GPU path
1919

2020
Support probing through `WebGPUEnvironment` also sits outside this document. The rasterizer describes execution of one staged scene, not environment detection or object construction.
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Six Labors Split License.
3+
4+
using SixLabors.ImageSharp.PixelFormats;
5+
6+
namespace SixLabors.ImageSharp.Drawing.Processing.Backends;
7+
8+
/// <summary>
9+
/// Creates typed canvas objects for the fixed set of WebGPU texture formats.
10+
/// </summary>
11+
internal static class WebGPUCanvasFactory
12+
{
13+
/// <summary>
14+
/// Creates a typed canvas over a WebGPU native surface.
15+
/// </summary>
16+
internal static DrawingCanvas CreateCanvas(
17+
Configuration configuration,
18+
DrawingOptions options,
19+
IDrawingBackend backend,
20+
Rectangle bounds,
21+
NativeSurface surface,
22+
WebGPUTextureFormat format)
23+
=> format switch
24+
{
25+
WebGPUTextureFormat.Rgba8Unorm => CreateCanvas<Rgba32>(
26+
configuration,
27+
options,
28+
backend,
29+
bounds,
30+
surface),
31+
32+
WebGPUTextureFormat.Bgra8Unorm => CreateCanvas<Bgra32>(
33+
configuration,
34+
options,
35+
backend,
36+
bounds,
37+
surface),
38+
39+
WebGPUTextureFormat.Rgba8Snorm => CreateCanvas<NormalizedByte4>(
40+
configuration,
41+
options,
42+
backend,
43+
bounds,
44+
surface),
45+
46+
WebGPUTextureFormat.Rgba16Float => CreateCanvas<HalfVector4>(
47+
configuration,
48+
options,
49+
backend,
50+
bounds,
51+
surface),
52+
53+
_ => throw new NotSupportedException($"Texture format '{format}' is not supported by the WebGPU backend.")
54+
};
55+
56+
/// <summary>
57+
/// Creates a typed frame over a WebGPU native surface.
58+
/// </summary>
59+
internal static NativeCanvasFrame<TPixel> CreateFrame<TPixel>(
60+
Rectangle bounds,
61+
NativeSurface surface)
62+
where TPixel : unmanaged, IPixel<TPixel>
63+
=> new(bounds, surface);
64+
65+
/// <summary>
66+
/// Creates a typed drawing canvas over an already selected WebGPU frame format.
67+
/// </summary>
68+
private static DrawingCanvas<TPixel> CreateCanvas<TPixel>(
69+
Configuration configuration,
70+
DrawingOptions options,
71+
IDrawingBackend backend,
72+
Rectangle bounds,
73+
NativeSurface surface)
74+
where TPixel : unmanaged, IPixel<TPixel>
75+
=> new(configuration, options, backend, CreateFrame<TPixel>(bounds, surface));
76+
}

0 commit comments

Comments
 (0)