Skip to content

Commit 108bf55

Browse files
Support per-draw blend mode and alpha in WebGPU
1 parent 403b4fb commit 108bf55

92 files changed

Lines changed: 691 additions & 317 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/ImageSharp.Drawing.WebGPU.ShaderGen/WgslSourceGenerator.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,9 @@ private static void Execute(SourceProductionContext context, ImmutableArray<Shad
102102
// property exposes both the expanded WGSL text and a null-terminated UTF-8 payload.
103103
private static string GenerateSource(SourceProductionContext context, Dictionary<string, string> fileMap)
104104
{
105-
IReadOnlyList<string> rootFiles = fileMap.Keys
105+
IEnumerable<string> rootFiles = fileMap.Keys
106106
.Where(static path => !path.StartsWith("Shared/", StringComparison.Ordinal))
107-
.OrderBy(static path => path, StringComparer.Ordinal)
108-
.ToArray();
107+
.OrderBy(static path => path, StringComparer.Ordinal);
109108

110109
StringBuilder builder = new();
111110
_ = builder.AppendLine("// <auto-generated/>");

src/ImageSharp.Drawing.WebGPU/Shaders/Shared/blend.wgsl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ const MIX_SCREEN = 2u;
99
const MIX_OVERLAY = 3u;
1010
const MIX_DARKEN = 4u;
1111
const MIX_LIGHTEN = 5u;
12+
const MIX_ADD = 16u;
13+
const MIX_SUBTRACT = 17u;
1214
const MIX_COLOR_DODGE = 6u;
1315
const MIX_COLOR_BURN = 7u;
1416
const MIX_HARD_LIGHT = 8u;
@@ -162,6 +164,12 @@ fn blend_mix(cb: vec3<f32>, cs: vec3<f32>, mode: u32) -> vec3<f32> {
162164
case MIX_LIGHTEN: {
163165
b = max(cb, cs);
164166
}
167+
case MIX_ADD: {
168+
b = min(vec3(1.0), cb + cs);
169+
}
170+
case MIX_SUBTRACT: {
171+
b = max(vec3(0.0), cb - cs);
172+
}
165173
case MIX_COLOR_DODGE: {
166174
b = vec3(color_dodge(cb.x, cs.x), color_dodge(cb.y, cs.y), color_dodge(cb.z, cs.z));
167175
}

src/ImageSharp.Drawing.WebGPU/Shaders/Shared/drawtag.wgsl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ const DRAWTAG_END_CLIP = 0x21u;
3232
/// draw object stream but get used after the draw objects have been reduced on the GPU.
3333
/// 0 represents a non-zero fill. 1 represents an even-odd fill.
3434
const DRAW_INFO_FLAGS_FILL_RULE_BIT = 1u;
35+
const DRAW_FLAGS_BLEND_MODE_SHIFT = 1u;
36+
const DRAW_FLAGS_BLEND_MODE_MASK = 0x3ffeu;
37+
const DRAW_FLAGS_BLEND_ALPHA_SHIFT = 14u;
38+
const DRAW_FLAGS_BLEND_ALPHA_MASK = 0x3fffc000u;
3539

3640
fn draw_monoid_identity() -> DrawMonoid {
3741
return DrawMonoid();

src/ImageSharp.Drawing.WebGPU/Shaders/Shared/ptcl.wgsl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,14 @@ struct CmdJump {
4646

4747
struct CmdColor {
4848
rgba_color: u32,
49+
draw_flags: u32,
4950
}
5051

5152
struct CmdRecolor {
5253
source_color: u32,
5354
target_color: u32,
5455
threshold: f32,
56+
draw_flags: u32,
5557
}
5658

5759
struct CmdBlurRect {

src/ImageSharp.Drawing.WebGPU/Shaders/coarse.wgsl

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,19 +110,21 @@ fn write_path(tile: Tile, tile_ix: u32, draw_flags: u32) {
110110
}
111111

112112
fn write_color(color: CmdColor) {
113-
alloc_cmd(2u);
113+
alloc_cmd(3u);
114114
ptcl[cmd_offset] = CMD_COLOR;
115115
ptcl[cmd_offset + 1u] = color.rgba_color;
116-
cmd_offset += 2u;
116+
ptcl[cmd_offset + 2u] = color.draw_flags;
117+
cmd_offset += 3u;
117118
}
118119

119-
fn write_recolor(source_color: u32, target_color: u32, threshold: u32) {
120-
alloc_cmd(4u);
120+
fn write_recolor(source_color: u32, target_color: u32, threshold: u32, draw_flags: u32) {
121+
alloc_cmd(5u);
121122
ptcl[cmd_offset] = CMD_RECOLOR;
122123
ptcl[cmd_offset + 1u] = source_color;
123124
ptcl[cmd_offset + 2u] = target_color;
124125
ptcl[cmd_offset + 3u] = threshold;
125-
cmd_offset += 4u;
126+
ptcl[cmd_offset + 4u] = draw_flags;
127+
cmd_offset += 5u;
126128
}
127129

128130
fn write_grad(ty: u32, index: u32, info_offset: u32) {
@@ -388,17 +390,17 @@ fn main(
388390
case DRAWTAG_FILL_COLOR: {
389391
write_path(tile, tile_ix, draw_flags);
390392
let rgba_color = scene[dd];
391-
write_color(CmdColor(rgba_color));
393+
write_color(CmdColor(rgba_color, draw_flags));
392394
}
393395
case DRAWTAG_FILL_RECOLOR: {
394396
write_path(tile, tile_ix, draw_flags);
395-
write_recolor(scene[dd], scene[dd + 1u], scene[dd + 2u]);
397+
write_recolor(scene[dd], scene[dd + 1u], scene[dd + 2u], draw_flags);
396398
}
397399
case DRAWTAG_BLURRED_ROUNDED_RECT: {
398400
write_path(tile, tile_ix, draw_flags);
399401
let rgba_color = scene[dd];
400402
let info_offset = di + 1u;
401-
write_blurred_rounded_rect(CmdColor(rgba_color), info_offset);
403+
write_blurred_rounded_rect(CmdColor(rgba_color, draw_flags), info_offset);
402404
}
403405
case DRAWTAG_FILL_LIN_GRADIENT: {
404406
write_path(tile, tile_ix, draw_flags);

0 commit comments

Comments
 (0)