55using System . Buffers ;
66using System . Numerics ;
77using System . Threading ;
8+ using SixLabors . ImageSharp . Drawing . Utilities ;
89using SixLabors . ImageSharp . Memory ;
910using SixLabors . ImageSharp . PixelFormats ;
1011
@@ -59,7 +60,7 @@ internal abstract class GradientBrushApplicator<TPixel> : BrushApplicator<TPixel
5960
6061 private readonly int scalineWidth ;
6162
62- private readonly ThreadLocal < ThreadContextData > threadContextData ;
63+ private readonly ThreadLocalBlenderBuffers < TPixel > blenderBuffers ;
6364
6465 private bool isDisposed ;
6566
@@ -85,9 +86,7 @@ protected GradientBrushApplicator(
8586 this . repetitionMode = repetitionMode ;
8687 this . scalineWidth = target . Width ;
8788 this . allocator = configuration . MemoryAllocator ;
88- this . threadContextData = new ThreadLocal < ThreadContextData > (
89- ( ) => new ThreadContextData ( this . allocator , this . scalineWidth ) ,
90- true ) ;
89+ this . blenderBuffers = new ThreadLocalBlenderBuffers < TPixel > ( this . allocator , this . scalineWidth ) ;
9190 }
9291
9392 internal TPixel this [ int x , int y ]
@@ -140,9 +139,8 @@ protected GradientBrushApplicator(
140139 /// <inheritdoc />
141140 public override void Apply ( Span < float > scanline , int x , int y )
142141 {
143- ThreadContextData contextData = this . threadContextData . Value ;
144- Span < float > amounts = contextData . AmountSpan . Slice ( 0 , scanline . Length ) ;
145- Span < TPixel > overlays = contextData . OverlaySpan . Slice ( 0 , scanline . Length ) ;
142+ Span < float > amounts = this . blenderBuffers . AmountSpan . Slice ( 0 , scanline . Length ) ;
143+ Span < TPixel > overlays = this . blenderBuffers . OverlaySpan . Slice ( 0 , scanline . Length ) ;
146144 float blendPercentage = this . Options . BlendPercentage ;
147145
148146 // TODO: Remove bounds checks.
@@ -193,12 +191,7 @@ protected override void Dispose(bool disposing)
193191
194192 if ( disposing )
195193 {
196- foreach ( ThreadContextData data in this . threadContextData . Values )
197- {
198- data . Dispose ( ) ;
199- }
200-
201- this . threadContextData . Dispose ( ) ;
194+ this . blenderBuffers . Dispose ( ) ;
202195 }
203196
204197 this . isDisposed = true ;
@@ -225,33 +218,6 @@ protected override void Dispose(bool disposing)
225218
226219 return ( localGradientFrom , localGradientTo ) ;
227220 }
228-
229- private sealed class ThreadContextData : IDisposable
230- {
231- private bool isDisposed ;
232- private readonly IMemoryOwner < float > amountBuffer ;
233- private readonly IMemoryOwner < TPixel > overlayBuffer ;
234-
235- public ThreadContextData ( MemoryAllocator allocator , int scanlineLength )
236- {
237- this . amountBuffer = allocator . Allocate < float > ( scanlineLength ) ;
238- this . overlayBuffer = allocator . Allocate < TPixel > ( scanlineLength ) ;
239- }
240-
241- public Span < float > AmountSpan => this . amountBuffer . Memory . Span ;
242-
243- public Span < TPixel > OverlaySpan => this . overlayBuffer . Memory . Span ;
244-
245- public void Dispose ( )
246- {
247- if ( ! this . isDisposed )
248- {
249- this . isDisposed = true ;
250- this . amountBuffer . Dispose ( ) ;
251- this . overlayBuffer . Dispose ( ) ;
252- }
253- }
254- }
255221 }
256222 }
257223}
0 commit comments