Skip to content

Commit f427d04

Browse files
Remove rasterizer config
1 parent 2ec6284 commit f427d04

11 files changed

Lines changed: 43 additions & 275 deletions

File tree

src/ImageSharp.Drawing/Processing/Backends/DefaultDrawingBackend.cs

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -36,36 +36,10 @@ namespace SixLabors.ImageSharp.Drawing.Processing.Backends;
3636
/// </remarks>
3737
internal sealed class DefaultDrawingBackend : IDrawingBackend
3838
{
39-
/// <summary>
40-
/// Initializes a new instance of the <see cref="DefaultDrawingBackend"/> class.
41-
/// </summary>
42-
/// <param name="primaryRasterizer">Rasterizer used for coverage generation.</param>
43-
private DefaultDrawingBackend(IRasterizer primaryRasterizer)
44-
{
45-
Guard.NotNull(primaryRasterizer, nameof(primaryRasterizer));
46-
this.PrimaryRasterizer = primaryRasterizer;
47-
}
48-
4939
/// <summary>
5040
/// Gets the default backend instance.
5141
/// </summary>
52-
public static DefaultDrawingBackend Instance { get; } = new(DefaultRasterizer.Instance);
53-
54-
/// <summary>
55-
/// Gets the primary rasterizer used by this backend.
56-
/// </summary>
57-
public IRasterizer PrimaryRasterizer { get; }
58-
59-
/// <summary>
60-
/// Creates a backend that uses the given rasterizer as the primary implementation.
61-
/// </summary>
62-
/// <param name="rasterizer">Primary rasterizer.</param>
63-
/// <returns>A backend instance.</returns>
64-
public static DefaultDrawingBackend Create(IRasterizer rasterizer)
65-
{
66-
Guard.NotNull(rasterizer, nameof(rasterizer));
67-
return ReferenceEquals(rasterizer, DefaultRasterizer.Instance) ? Instance : new DefaultDrawingBackend(rasterizer);
68-
}
42+
public static DefaultDrawingBackend Instance { get; } = new();
6943

7044
/// <inheritdoc />
7145
public bool IsCompositionBrushSupported<TPixel>(Brush brush)
@@ -201,7 +175,7 @@ internal void FlushPreparedBatch<TPixel>(
201175
applicators,
202176
destinationBounds,
203177
definition.RasterizerOptions.Interest.Top);
204-
this.PrimaryRasterizer.Rasterize(
178+
DefaultRasterizer.Instance.Rasterize(
205179
definition.Path,
206180
definition.RasterizerOptions,
207181
configuration.MemoryAllocator,

src/ImageSharp.Drawing/Processing/RasterizerDefaultsExtensions.cs

Lines changed: 1 addition & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22
// Licensed under the Six Labors Split License.
33

44
using SixLabors.ImageSharp.Drawing.Processing.Backends;
5-
using SixLabors.ImageSharp.Drawing.Shapes.Rasterization;
65

76
namespace SixLabors.ImageSharp.Drawing.Processing;
87

98
/// <summary>
10-
/// Adds extensions that allow configuring the path rasterizer implementation.
9+
/// Adds extensions that allow configuring the drawing backend implementation.
1110
/// </summary>
1211
internal static class RasterizerDefaultsExtensions
1312
{
@@ -22,11 +21,6 @@ internal static IImageProcessingContext SetDrawingBackend(this IImageProcessingC
2221
Guard.NotNull(backend, nameof(backend));
2322
context.Properties[typeof(IDrawingBackend)] = backend;
2423

25-
if (backend is DefaultDrawingBackend defaultBackend)
26-
{
27-
context.Properties[typeof(IRasterizer)] = defaultBackend.PrimaryRasterizer;
28-
}
29-
3024
return context;
3125
}
3226

@@ -39,11 +33,6 @@ internal static void SetDrawingBackend(this Configuration configuration, IDrawin
3933
{
4034
Guard.NotNull(backend, nameof(backend));
4135
configuration.Properties[typeof(IDrawingBackend)] = backend;
42-
43-
if (backend is DefaultDrawingBackend defaultBackend)
44-
{
45-
configuration.Properties[typeof(IRasterizer)] = defaultBackend.PrimaryRasterizer;
46-
}
4736
}
4837

4938
/// <summary>
@@ -59,12 +48,6 @@ internal static IDrawingBackend GetDrawingBackend(this IImageProcessingContext c
5948
return configured;
6049
}
6150

62-
if (context.Properties.TryGetValue(typeof(IRasterizer), out object? rasterizer) &&
63-
rasterizer is IRasterizer configuredRasterizer)
64-
{
65-
return DefaultDrawingBackend.Create(configuredRasterizer);
66-
}
67-
6851
return context.Configuration.GetDrawingBackend();
6952
}
7053

@@ -81,90 +64,8 @@ internal static IDrawingBackend GetDrawingBackend(this Configuration configurati
8164
return configured;
8265
}
8366

84-
if (configuration.Properties.TryGetValue(typeof(IRasterizer), out object? rasterizer) &&
85-
rasterizer is IRasterizer configuredRasterizer)
86-
{
87-
IDrawingBackend rasterizerBackend = DefaultDrawingBackend.Create(configuredRasterizer);
88-
configuration.Properties[typeof(IDrawingBackend)] = rasterizerBackend;
89-
return rasterizerBackend;
90-
}
91-
9267
IDrawingBackend defaultBackend = DefaultDrawingBackend.Instance;
9368
configuration.Properties[typeof(IDrawingBackend)] = defaultBackend;
9469
return defaultBackend;
9570
}
96-
97-
/// <summary>
98-
/// Sets the rasterizer against the source image processing context.
99-
/// </summary>
100-
/// <param name="context">The image processing context to store the rasterizer against.</param>
101-
/// <param name="rasterizer">The rasterizer to use.</param>
102-
/// <returns>The passed in <paramref name="context"/> to allow chaining.</returns>
103-
internal static IImageProcessingContext SetRasterizer(this IImageProcessingContext context, IRasterizer rasterizer)
104-
{
105-
Guard.NotNull(rasterizer, nameof(rasterizer));
106-
context.Properties[typeof(IRasterizer)] = rasterizer;
107-
context.Properties[typeof(IDrawingBackend)] = DefaultDrawingBackend.Create(rasterizer);
108-
return context;
109-
}
110-
111-
/// <summary>
112-
/// Sets the default rasterizer against the configuration.
113-
/// </summary>
114-
/// <param name="configuration">The configuration to store the rasterizer against.</param>
115-
/// <param name="rasterizer">The rasterizer to use.</param>
116-
internal static void SetRasterizer(this Configuration configuration, IRasterizer rasterizer)
117-
{
118-
Guard.NotNull(rasterizer, nameof(rasterizer));
119-
configuration.Properties[typeof(IRasterizer)] = rasterizer;
120-
configuration.Properties[typeof(IDrawingBackend)] = DefaultDrawingBackend.Create(rasterizer);
121-
}
122-
123-
/// <summary>
124-
/// Gets the rasterizer from the source image processing context.
125-
/// </summary>
126-
/// <param name="context">The image processing context to retrieve the rasterizer from.</param>
127-
/// <returns>The configured rasterizer.</returns>
128-
internal static IRasterizer GetRasterizer(this IImageProcessingContext context)
129-
{
130-
if (context.Properties.TryGetValue(typeof(IRasterizer), out object? rasterizer) &&
131-
rasterizer is IRasterizer configured)
132-
{
133-
return configured;
134-
}
135-
136-
if (context.Properties.TryGetValue(typeof(IDrawingBackend), out object? backend) &&
137-
backend is DefaultDrawingBackend defaultBackend)
138-
{
139-
return defaultBackend.PrimaryRasterizer;
140-
}
141-
142-
// Do not cache config fallback in the context so changes on configuration reflow.
143-
return context.Configuration.GetRasterizer();
144-
}
145-
146-
/// <summary>
147-
/// Gets the default rasterizer from the configuration.
148-
/// </summary>
149-
/// <param name="configuration">The configuration to retrieve the rasterizer from.</param>
150-
/// <returns>The configured rasterizer.</returns>
151-
internal static IRasterizer GetRasterizer(this Configuration configuration)
152-
{
153-
if (configuration.Properties.TryGetValue(typeof(IRasterizer), out object? rasterizer) &&
154-
rasterizer is IRasterizer configured)
155-
{
156-
return configured;
157-
}
158-
159-
if (configuration.Properties.TryGetValue(typeof(IDrawingBackend), out object? backend) &&
160-
backend is DefaultDrawingBackend defaultBackend)
161-
{
162-
return defaultBackend.PrimaryRasterizer;
163-
}
164-
165-
IRasterizer defaultRasterizer = DefaultRasterizer.Instance;
166-
configuration.Properties[typeof(IRasterizer)] = defaultRasterizer;
167-
configuration.Properties[typeof(IDrawingBackend)] = DefaultDrawingBackend.Instance;
168-
return defaultRasterizer;
169-
}
17071
}

src/ImageSharp.Drawing/Shapes/Rasterization/DefaultRasterizer.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@ namespace SixLabors.ImageSharp.Drawing.Shapes.Rasterization;
1313
/// area/cover scanning and chooses an internal execution strategy (parallel row-tiles when
1414
/// profitable, sequential fallback otherwise).
1515
/// </remarks>
16-
internal sealed class DefaultRasterizer : IRasterizer
16+
internal sealed class DefaultRasterizer
1717
{
1818
/// <summary>
1919
/// Gets the singleton default rasterizer instance.
2020
/// </summary>
2121
public static DefaultRasterizer Instance { get; } = new();
2222

23-
/// <inheritdoc />
23+
/// <summary>
24+
/// Rasterizes the path into scanline coverage.
25+
/// </summary>
2426
public void Rasterize<TState>(
2527
IPath path,
2628
in RasterizerOptions options,

src/ImageSharp.Drawing/Shapes/Rasterization/IRasterizer.cs

Lines changed: 0 additions & 43 deletions
This file was deleted.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Six Labors Split License.
3+
4+
namespace SixLabors.ImageSharp.Drawing.Shapes.Rasterization;
5+
6+
/// <summary>
7+
/// Delegate invoked for each rasterized scanline.
8+
/// </summary>
9+
/// <typeparam name="TState">The caller-provided state type.</typeparam>
10+
/// <param name="y">The destination y coordinate.</param>
11+
/// <param name="scanline">Coverage values for the scanline.</param>
12+
/// <param name="state">Caller-provided mutable state.</param>
13+
internal delegate void RasterizerScanlineHandler<TState>(int y, Span<float> scanline, ref TState state)
14+
where TState : struct;

src/ImageSharp.Drawing/Shapes/Rasterization/ScanlineRasterizer.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@ namespace SixLabors.ImageSharp.Drawing.Shapes.Rasterization;
1313
/// It is retained as a compact fallback/reference implementation and as an explicit
1414
/// non-tiled option for profiling and comparison.
1515
/// </remarks>
16-
internal sealed class ScanlineRasterizer : IRasterizer
16+
internal sealed class ScanlineRasterizer
1717
{
1818
/// <summary>
1919
/// Gets the singleton scanline rasterizer instance.
2020
/// </summary>
2121
public static ScanlineRasterizer Instance { get; } = new();
2222

23-
/// <inheritdoc />
23+
/// <summary>
24+
/// Rasterizes the path into scanline coverage using the sequential scanner path.
25+
/// </summary>
2426
public void Rasterize<TState>(
2527
IPath path,
2628
in RasterizerOptions options,

tests/ImageSharp.Drawing.Benchmarks/Drawing/DrawPolygon.cs

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
using Newtonsoft.Json;
1010
using SixLabors.ImageSharp.Drawing.Processing;
1111
using SixLabors.ImageSharp.Drawing.Processing.Backends;
12-
using SixLabors.ImageSharp.Drawing.Shapes.Rasterization;
1312
using SixLabors.ImageSharp.Drawing.Tests;
1413
using SixLabors.ImageSharp.PixelFormats;
1514
using SixLabors.ImageSharp.Processing;
@@ -164,42 +163,16 @@ public void Cleanup()
164163
public void SystemDrawing()
165164
=> this.sdGraphics.DrawPath(this.sdPen, this.sdPath);
166165

167-
// Keep explicit scanline rasterizer path for side-by-side comparison now that tiled is default.
168166
[Benchmark]
169-
public void ImageSharpCombinedPathsScanlineRasterizer()
170-
=> this.image.Mutate(c =>
171-
{
172-
c.SetRasterizer(ScanlineRasterizer.Instance);
173-
c.ProcessWithCanvas(canvas => canvas.Draw(this.isPen, this.imageSharpPath));
174-
});
175-
176-
[Benchmark]
177-
public void ImageSharpSeparatePathsScanlineRasterizer()
178-
=> this.image.Mutate(
179-
c =>
180-
{
181-
// Keep explicit scanline rasterizer path for side-by-side comparison now that tiled is default.
182-
c.SetRasterizer(ScanlineRasterizer.Instance);
183-
c.ProcessWithCanvas(canvas =>
184-
{
185-
foreach (PointF[] loop in this.points)
186-
{
187-
canvas.Draw(Processing.Pens.Solid(Color.White, this.Thickness), new Polygon(loop));
188-
}
189-
});
190-
});
191-
192-
// Tiled is now the framework default rasterizer path.
193-
[Benchmark]
194-
public void ImageSharpCombinedPathsTiled()
167+
public void ImageSharpCombinedPaths()
195168
=> this.image.Mutate(c => c.ProcessWithCanvas(canvas => canvas.Draw(this.isPen, this.imageSharpPath)));
196169

197170
[Benchmark(Description = "ImageSharp Combined Paths WebGPU Backend")]
198171
public void ImageSharpCombinedPathsWebGPUBackend()
199172
=> this.webGpuImage.Mutate(c => c.ProcessWithCanvas(canvas => canvas.Draw(this.isPen, this.imageSharpPath)));
200173

201174
[Benchmark]
202-
public void ImageSharpSeparatePathsTiled()
175+
public void ImageSharpSeparatePaths()
203176
=> this.image.Mutate(
204177
c => c.ProcessWithCanvas(canvas =>
205178
{

tests/ImageSharp.Drawing.Tests/Processing/ProcessWithDrawingCanvasTests.Robustness.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
using GeoJSON.Net.Feature;
99
using Newtonsoft.Json;
1010
using SixLabors.ImageSharp.Drawing.Processing;
11-
using SixLabors.ImageSharp.Drawing.Shapes.Rasterization;
1211
using SixLabors.ImageSharp.Drawing.Tests.TestUtilities.ImageComparison;
1312
using SixLabors.ImageSharp.PixelFormats;
1413
using SixLabors.ImageSharp.Processing;
@@ -327,11 +326,7 @@ public void LargeGeoJson_States_All_Benchmark(TestImageProvider<Rgba32> provider
327326

328327
using Image<Rgba32> image = provider.GetImage();
329328

330-
image.Mutate(c =>
331-
{
332-
c.SetRasterizer(DefaultRasterizer.Instance);
333-
c.ProcessWithCanvas(canvas => canvas.Draw(Pens.Solid(Color.White, thickness), path));
334-
});
329+
image.Mutate(c => c.ProcessWithCanvas(canvas => canvas.Draw(Pens.Solid(Color.White, thickness), path)));
335330

336331
image.DebugSave(provider, $"Benchmark_{thickness}", appendPixelTypeToFileName: false, appendSourceFileOrDescription: false);
337332
}

0 commit comments

Comments
 (0)