Skip to content

Commit 17b1c49

Browse files
Add WebGPU surface alpha mode option
Expose a configurable composite alpha mode for WebGPU windows and external surfaces, and pass it through to native surface configuration. This adds a public enum and option properties so callers can request automatic handling or force opaque presentation.
1 parent a7db60a commit 17b1c49

7 files changed

Lines changed: 60 additions & 2 deletions
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Six Labors Split License.
3+
4+
namespace SixLabors.ImageSharp.Drawing.Processing.Backends;
5+
6+
/// <summary>
7+
/// Specifies how the native compositor interprets alpha in a WebGPU surface.
8+
/// </summary>
9+
public enum WebGPUCompositeAlphaMode
10+
{
11+
/// <summary>
12+
/// Allows WebGPU to select the surface composition mode.
13+
/// </summary>
14+
Auto,
15+
16+
/// <summary>
17+
/// Ignores the surface alpha channel and presents every pixel as opaque.
18+
/// </summary>
19+
Opaque,
20+
}

src/ImageSharp.Drawing.WebGPU/WebGPUDrawingBackend.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
using System.Runtime.CompilerServices;
55
using Silk.NET.WebGPU;
66
using Silk.NET.WebGPU.Extensions.WGPU;
7-
using SixLabors.ImageSharp.Memory;
87
using SixLabors.ImageSharp.PixelFormats;
9-
using SixLabors.ImageSharp.Processing;
108

119
namespace SixLabors.ImageSharp.Drawing.Processing.Backends;
1210

src/ImageSharp.Drawing.WebGPU/WebGPUExternalSurface.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ public WebGPUExternalSurface(
6868
configuration,
6969
new SilkNativeSurfaceAdapter(host),
7070
options.Format,
71+
options.AlphaMode,
7172
this.presentMode,
7273
this.framebufferSize);
7374
}

src/ImageSharp.Drawing.WebGPU/WebGPUExternalSurfaceOptions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,9 @@ public sealed class WebGPUExternalSurfaceOptions
2727
/// adapter reports it.
2828
/// </remarks>
2929
public WebGPUTextureFormat Format { get; set; } = WebGPUTextureFormat.Rgba8Unorm;
30+
31+
/// <summary>
32+
/// Gets or sets how the native compositor interprets the surface alpha channel.
33+
/// </summary>
34+
public WebGPUCompositeAlphaMode AlphaMode { get; set; } = WebGPUCompositeAlphaMode.Auto;
3035
}

src/ImageSharp.Drawing.WebGPU/WebGPUSurfaceResources.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ internal sealed unsafe class WebGPUSurfaceResources : IDisposable
4848
private FramePacingSignal? previousFrameWorkDone;
4949
private readonly FeatureName requiredFeature;
5050
private readonly Configuration configuration;
51+
private readonly WebGPUCompositeAlphaMode alphaMode;
5152

5253
// Mutable because the device-owned portion of the stack is replaced on device-loss recovery.
5354
private WebGPUDeviceContext deviceContext;
@@ -69,6 +70,7 @@ internal sealed unsafe class WebGPUSurfaceResources : IDisposable
6970
/// <param name="queueHandle">The owned default queue handle paired with <paramref name="deviceHandle"/>.</param>
7071
/// <param name="deviceContext">The device context bound to <paramref name="deviceHandle"/> and <paramref name="queueHandle"/>.</param>
7172
/// <param name="format">The negotiated swapchain texture format.</param>
73+
/// <param name="alphaMode">How the native compositor interprets the swapchain alpha channel.</param>
7274
/// <param name="requiredFeature">The optional WebGPU feature required by the selected texture format.</param>
7375
private WebGPUSurfaceResources(
7476
WebGPU api,
@@ -80,6 +82,7 @@ private WebGPUSurfaceResources(
8082
WebGPUQueueHandle queueHandle,
8183
WebGPUDeviceContext deviceContext,
8284
WebGPUTextureFormat format,
85+
WebGPUCompositeAlphaMode alphaMode,
8386
FeatureName requiredFeature)
8487
{
8588
this.Api = api;
@@ -91,6 +94,7 @@ private WebGPUSurfaceResources(
9194
this.QueueHandle = queueHandle;
9295
this.deviceContext = deviceContext;
9396
this.Format = format;
97+
this.alphaMode = alphaMode;
9498
this.requiredFeature = requiredFeature;
9599
}
96100

@@ -138,6 +142,7 @@ private WebGPUSurfaceResources(
138142
/// <param name="configuration">The ImageSharp configuration the device context will use for its rendering backend.</param>
139143
/// <param name="nativeSource">The native surface source that provides the platform handles for surface creation.</param>
140144
/// <param name="format">The swapchain texture format.</param>
145+
/// <param name="alphaMode">How the native compositor interprets the swapchain alpha channel.</param>
141146
/// <param name="initialPresentMode">The present mode to apply to the first surface configuration.</param>
142147
/// <param name="initialFramebufferSize">The framebuffer size to apply to the first surface configuration. Zero-area
143148
/// sizes are permitted and leave the surface unconfigured until the caller invokes <see cref="ConfigureSurface"/>
@@ -152,6 +157,7 @@ public static WebGPUSurfaceResources Create(
152157
Configuration configuration,
153158
INativeWindowSource nativeSource,
154159
WebGPUTextureFormat format,
160+
WebGPUCompositeAlphaMode alphaMode,
155161
WebGPUPresentMode initialPresentMode,
156162
Size initialFramebufferSize)
157163
{
@@ -191,6 +197,7 @@ public static WebGPUSurfaceResources Create(
191197
deviceResources.QueueHandle,
192198
deviceResources.DeviceContext,
193199
format,
200+
alphaMode,
194201
requiredFeature);
195202

196203
resources.ConfigureSurface(initialPresentMode, initialFramebufferSize);
@@ -250,6 +257,7 @@ private void ConfigureSurfaceCore(WebGPUPresentMode presentMode, Size framebuffe
250257
{
251258
Usage = TextureUsage.RenderAttachment | TextureUsage.CopySrc | TextureUsage.CopyDst | TextureUsage.TextureBinding,
252259
Format = WebGPUTextureFormatMapper.ToNative(this.Format),
260+
AlphaMode = ToNative(this.alphaMode),
253261
PresentMode = ToNative(presentMode),
254262
Width = (uint)framebufferSize.Width,
255263
Height = (uint)framebufferSize.Height,
@@ -275,6 +283,19 @@ private static SilkPresentMode ToNative(WebGPUPresentMode presentMode)
275283
_ => throw new InvalidOperationException("The WebGPU present mode mapping is incomplete.")
276284
};
277285

286+
/// <summary>
287+
/// Maps the public composite-alpha enumeration to the native Silk.NET value.
288+
/// </summary>
289+
/// <param name="alphaMode">The composite-alpha mode to map.</param>
290+
/// <returns>The native composite-alpha mode.</returns>
291+
private static CompositeAlphaMode ToNative(WebGPUCompositeAlphaMode alphaMode)
292+
=> alphaMode switch
293+
{
294+
WebGPUCompositeAlphaMode.Auto => CompositeAlphaMode.Auto,
295+
WebGPUCompositeAlphaMode.Opaque => CompositeAlphaMode.Opaque,
296+
_ => throw new InvalidOperationException("The WebGPU composite alpha mode mapping is incomplete.")
297+
};
298+
278299
/// <summary>
279300
/// Acquires the next presentable frame from <see cref="SurfaceHandle"/> and wraps it as a
280301
/// <see cref="WebGPUSurfaceFrame"/> with a ready-to-use <see cref="DrawingCanvas"/>.

src/ImageSharp.Drawing.WebGPU/WebGPUWindow.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public WebGPUWindow(Configuration configuration, WebGPUWindowOptions options)
5353
this.window = Window.Create(CreateSilkOptions(options));
5454
this.Configuration = configuration;
5555
this.Format = options.Format;
56+
this.AlphaMode = options.AlphaMode;
5657
this.presentMode = options.PresentMode;
5758

5859
try
@@ -62,6 +63,7 @@ public WebGPUWindow(Configuration configuration, WebGPUWindowOptions options)
6263
configuration,
6364
this.window,
6465
this.Format,
66+
this.AlphaMode,
6567
this.presentMode,
6668
ToSize(this.window.FramebufferSize));
6769
}
@@ -272,6 +274,11 @@ public WebGPUPresentMode PresentMode
272274
/// </summary>
273275
public WebGPUTextureFormat Format { get; }
274276

277+
/// <summary>
278+
/// Gets how the native compositor interprets the window surface alpha channel.
279+
/// </summary>
280+
public WebGPUCompositeAlphaMode AlphaMode { get; }
281+
275282
/// <summary>
276283
/// Tries to acquire the next drawable frame using default drawing options.
277284
/// </summary>
@@ -558,6 +565,7 @@ private static WindowOptions CreateSilkOptions(WebGPUWindowOptions options)
558565
silkOptions.WindowState = ToNative(options.WindowState);
559566
silkOptions.WindowBorder = ToNative(options.WindowBorder);
560567
silkOptions.TopMost = options.IsTopMost;
568+
561569
return silkOptions;
562570
}
563571

src/ImageSharp.Drawing.WebGPU/WebGPUWindowOptions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,9 @@ public sealed class WebGPUWindowOptions
8787
/// Gets or sets the swapchain texture format used by acquired frames.
8888
/// </summary>
8989
public WebGPUTextureFormat Format { get; set; } = WebGPUTextureFormat.Rgba8Unorm;
90+
91+
/// <summary>
92+
/// Gets or sets how the native compositor interprets the window surface alpha channel.
93+
/// </summary>
94+
public WebGPUCompositeAlphaMode AlphaMode { get; set; } = WebGPUCompositeAlphaMode.Auto;
9095
}

0 commit comments

Comments
 (0)