Skip to content

Commit 3e512d5

Browse files
Refactor brush renderers and FlushScene parallel loop
1 parent d9e128e commit 3e512d5

5 files changed

Lines changed: 47 additions & 70 deletions

File tree

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

Lines changed: 41 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -670,61 +670,51 @@ private void ExecuteCore<TPixel>(
670670
}
671671
});
672672

673-
try
674-
{
675-
_ = Parallel.For(
676-
0,
677-
this.RowCount,
678-
options,
679-
() => new ExecuteWorkerState<TPixel>(
680-
allocator,
673+
_ = Parallel.For(
674+
0,
675+
this.RowCount,
676+
options,
677+
() => new ExecuteWorkerState<TPixel>(
678+
allocator,
679+
this.maxWordsPerRow,
680+
this.maxCoverStride,
681+
this.maxWidth,
682+
this.maxBandCapacity),
683+
(sceneRow, _, state) =>
684+
{
685+
DefaultRasterizer.WorkerScratch scratch = state.Scratch!;
686+
DefaultRasterizer.Context context = scratch.CreateContext(
687+
this.maxWidth,
681688
this.maxWordsPerRow,
682689
this.maxCoverStride,
683-
this.maxWidth,
684-
this.maxBandCapacity),
685-
(sceneRow, _, state) =>
690+
this.maxBandCapacity,
691+
IntersectionRule.NonZero,
692+
RasterizationMode.Antialiased,
693+
antialiasThreshold: 0F);
694+
695+
int rowStart = this.rowOffsets[sceneRow];
696+
int rowEnd = this.rowOffsets[sceneRow + 1];
697+
if (rowStart >= rowEnd)
686698
{
687-
DefaultRasterizer.WorkerScratch scratch = state.Scratch!;
688-
DefaultRasterizer.Context context = scratch.CreateContext(
689-
this.maxWidth,
690-
this.maxWordsPerRow,
691-
this.maxCoverStride,
692-
this.maxBandCapacity,
693-
IntersectionRule.NonZero,
694-
RasterizationMode.Antialiased,
695-
antialiasThreshold: 0F);
696-
697-
int rowStart = this.rowOffsets[sceneRow];
698-
int rowEnd = this.rowOffsets[sceneRow + 1];
699-
if (rowStart >= rowEnd)
700-
{
701-
return state;
702-
}
703-
704-
BandTarget<TPixel> rootTarget = BandTarget<TPixel>.CreateRoot(destinationFrame);
705-
this.ExecuteBand(
706-
configuration,
707-
sourceCommands,
708-
preparedBrushes,
709-
lineData.Span,
710-
startCovers.Span,
711-
sceneRow,
712-
rowStart,
713-
rowEnd,
714-
ref context,
715-
state,
716-
rootTarget);
717699
return state;
718-
},
719-
state => state.Dispose());
720-
}
721-
finally
722-
{
723-
for (int i = 0; i < preparedBrushes.Length; i++)
724-
{
725-
preparedBrushes[i].Dispose();
726-
}
727-
}
700+
}
701+
702+
BandTarget<TPixel> rootTarget = BandTarget<TPixel>.CreateRoot(destinationFrame);
703+
this.ExecuteBand(
704+
configuration,
705+
sourceCommands,
706+
preparedBrushes,
707+
lineData.Span,
708+
startCovers.Span,
709+
sceneRow,
710+
rowStart,
711+
rowEnd,
712+
ref context,
713+
state,
714+
rootTarget);
715+
return state;
716+
},
717+
state => state.Dispose());
728718
}
729719

730720
/// <summary>

src/ImageSharp.Drawing/Processing/BrushRenderer.cs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace SixLabors.ImageSharp.Drawing.Processing;
77
/// Renders a <see cref="Brush"/> against individual coverage scanlines.
88
/// </summary>
99
/// <typeparam name="TPixel">The pixel format.</typeparam>
10-
public abstract class BrushRenderer<TPixel> : IDisposable
10+
public abstract class BrushRenderer<TPixel>
1111
where TPixel : unmanaged, IPixel<TPixel>
1212
{
1313
/// <summary>
@@ -47,18 +47,6 @@ protected BrushRenderer(
4747
/// </summary>
4848
protected int CanvasWidth { get; }
4949

50-
/// <summary>
51-
/// Gets a value indicating whether this renderer owns disposable resources.
52-
/// </summary>
53-
internal virtual bool RequiresDispose => false;
54-
55-
/// <inheritdoc />
56-
public void Dispose()
57-
{
58-
this.Dispose(true);
59-
GC.SuppressFinalize(this);
60-
}
61-
6250
/// <summary>
6351
/// Applies the opacity weighting for each pixel in a scanline to the target based on the
6452
/// pattern contained in the brush.

src/ImageSharp.Drawing/Processing/ImageBrush.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ private static void ThrowIfInvalidImagePixelFormat()
169169
/// The image brush applicator.
170170
/// </summary>
171171
/// <typeparam name="TPixel">The pixel format.</typeparam>
172-
private class ImageBrushRenderer<TPixel> : BrushRenderer<TPixel>
172+
private sealed class ImageBrushRenderer<TPixel> : BrushRenderer<TPixel>
173173
where TPixel : unmanaged, IPixel<TPixel>
174174
{
175175
private readonly ImageFrame<TPixel> sourceFrame;

src/ImageSharp.Drawing/Processing/RecolorBrush.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public override int GetHashCode()
7474
/// The recolor brush applicator.
7575
/// </summary>
7676
/// <typeparam name="TPixel">The pixel format.</typeparam>
77-
private class RecolorBrushRenderer<TPixel> : BrushRenderer<TPixel>
77+
private sealed class RecolorBrushRenderer<TPixel> : BrushRenderer<TPixel>
7878
where TPixel : unmanaged, IPixel<TPixel>
7979
{
8080
private readonly Vector4 sourceColor;

src/ImageSharp.Drawing/Processing/SweepGradientBrush.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,17 +226,16 @@ public override BrushRenderer<TPixel> CreateRenderer<TPixel>(
226226
Configuration configuration,
227227
GraphicsOptions options,
228228
int canvasWidth,
229-
RectangleF region)
230-
{
229+
RectangleF region) =>
230+
231231
// The renderer precomputes the angular interval once and then samples it per pixel.
232-
return new SweepGradientBrushRenderer<TPixel>(
232+
new SweepGradientBrushRenderer<TPixel>(
233233
configuration,
234234
options,
235235
canvasWidth,
236236
this,
237237
this.ColorStopsArray,
238238
this.RepetitionMode);
239-
}
240239

241240
/// <summary>
242241
/// The sweep (conic) gradient brush applicator.

0 commit comments

Comments
 (0)