@@ -17,51 +17,130 @@ namespace SixLabors.ImageSharp.Advanced
1717 /// </content>
1818 public static partial class ParallelRowIterator
1919 {
20- private readonly struct IterationParameters
20+ private readonly struct RowOperationWrapper < T >
21+ where T : struct , IRowOperation
2122 {
22- public readonly int MinY ;
23- public readonly int MaxY ;
24- public readonly int StepY ;
25- public readonly int Width ;
23+ private readonly int minY ;
24+ private readonly int maxY ;
25+ private readonly int stepY ;
26+ private readonly T action ;
2627
27- public IterationParameters ( int minY , int maxY , int stepY )
28- : this ( minY , maxY , stepY , 0 )
28+ [ MethodImpl ( InliningOptions . ShortMethod ) ]
29+ public RowOperationWrapper (
30+ int minY ,
31+ int maxY ,
32+ int stepY ,
33+ in T action )
2934 {
35+ this . minY = minY ;
36+ this . maxY = maxY ;
37+ this . stepY = stepY ;
38+ this . action = action ;
3039 }
3140
32- public IterationParameters ( int minY , int maxY , int stepY , int width )
41+ [ MethodImpl ( InliningOptions . ShortMethod ) ]
42+ public void Invoke ( int i )
3343 {
34- this . MinY = minY ;
35- this . MaxY = maxY ;
36- this . StepY = stepY ;
37- this . Width = width ;
44+ int yMin = this . minY + ( i * this . stepY ) ;
45+
46+ if ( yMin >= this . maxY )
47+ {
48+ return ;
49+ }
50+
51+ int yMax = Math . Min ( yMin + this . stepY , this . maxY ) ;
52+
53+ for ( int y = yMin ; y < yMax ; y ++ )
54+ {
55+ // Skip the safety copy when invoking a potentially impure method on a readonly field
56+ Unsafe . AsRef ( this . action ) . Invoke ( y ) ;
57+ }
58+ }
59+ }
60+
61+ private readonly struct RowOperationWrapper < T , TBuffer >
62+ where T : struct , IRowOperation < TBuffer >
63+ where TBuffer : unmanaged
64+ {
65+ private readonly int minY ;
66+ private readonly int maxY ;
67+ private readonly int stepY ;
68+ private readonly int width ;
69+ private readonly MemoryAllocator allocator ;
70+ private readonly T action ;
71+
72+ [ MethodImpl ( InliningOptions . ShortMethod ) ]
73+ public RowOperationWrapper (
74+ int minY ,
75+ int maxY ,
76+ int stepY ,
77+ int width ,
78+ MemoryAllocator allocator ,
79+ in T action )
80+ {
81+ this . minY = minY ;
82+ this . maxY = maxY ;
83+ this . stepY = stepY ;
84+ this . width = width ;
85+ this . allocator = allocator ;
86+ this . action = action ;
87+ }
88+
89+ [ MethodImpl ( InliningOptions . ShortMethod ) ]
90+ public void Invoke ( int i )
91+ {
92+ int yMin = this . minY + ( i * this . stepY ) ;
93+
94+ if ( yMin >= this . maxY )
95+ {
96+ return ;
97+ }
98+
99+ int yMax = Math . Min ( yMin + this . stepY , this . maxY ) ;
100+
101+ using IMemoryOwner < TBuffer > buffer = this . allocator . Allocate < TBuffer > ( this . width ) ;
102+
103+ Span < TBuffer > span = buffer . Memory . Span ;
104+
105+ for ( int y = yMin ; y < yMax ; y ++ )
106+ {
107+ Unsafe . AsRef ( this . action ) . Invoke ( y , span ) ;
108+ }
38109 }
39110 }
40111
41112 private readonly struct RowIntervalOperationWrapper < T >
42113 where T : struct , IRowIntervalOperation
43114 {
44- private readonly IterationParameters info ;
115+ private readonly int minY ;
116+ private readonly int maxY ;
117+ private readonly int stepY ;
45118 private readonly T operation ;
46119
47120 [ MethodImpl ( InliningOptions . ShortMethod ) ]
48- public RowIntervalOperationWrapper ( in IterationParameters info , in T operation )
121+ public RowIntervalOperationWrapper (
122+ int minY ,
123+ int maxY ,
124+ int stepY ,
125+ in T operation )
49126 {
50- this . info = info ;
127+ this . minY = minY ;
128+ this . maxY = maxY ;
129+ this . stepY = stepY ;
51130 this . operation = operation ;
52131 }
53132
54133 [ MethodImpl ( InliningOptions . ShortMethod ) ]
55134 public void Invoke ( int i )
56135 {
57- int yMin = this . info . MinY + ( i * this . info . StepY ) ;
136+ int yMin = this . minY + ( i * this . stepY ) ;
58137
59- if ( yMin >= this . info . MaxY )
138+ if ( yMin >= this . maxY )
60139 {
61140 return ;
62141 }
63142
64- int yMax = Math . Min ( yMin + this . info . StepY , this . info . MaxY ) ;
143+ int yMax = Math . Min ( yMin + this . stepY , this . maxY ) ;
65144 var rows = new RowInterval ( yMin , yMax ) ;
66145
67146 // Skip the safety copy when invoking a potentially impure method on a readonly field
@@ -73,35 +152,44 @@ private readonly struct RowIntervalOperationWrapper<T, TBuffer>
73152 where T : struct , IRowIntervalOperation < TBuffer >
74153 where TBuffer : unmanaged
75154 {
76- private readonly IterationParameters info ;
155+ private readonly int minY ;
156+ private readonly int maxY ;
157+ private readonly int stepY ;
158+ private readonly int width ;
77159 private readonly MemoryAllocator allocator ;
78160 private readonly T operation ;
79161
80162 [ MethodImpl ( InliningOptions . ShortMethod ) ]
81163 public RowIntervalOperationWrapper (
82- in IterationParameters info ,
164+ int minY ,
165+ int maxY ,
166+ int stepY ,
167+ int width ,
83168 MemoryAllocator allocator ,
84169 in T operation )
85170 {
86- this . info = info ;
171+ this . minY = minY ;
172+ this . maxY = maxY ;
173+ this . stepY = stepY ;
174+ this . width = width ;
87175 this . allocator = allocator ;
88176 this . operation = operation ;
89177 }
90178
91179 [ MethodImpl ( InliningOptions . ShortMethod ) ]
92180 public void Invoke ( int i )
93181 {
94- int yMin = this . info . MinY + ( i * this . info . StepY ) ;
182+ int yMin = this . minY + ( i * this . stepY ) ;
95183
96- if ( yMin >= this . info . MaxY )
184+ if ( yMin >= this . maxY )
97185 {
98186 return ;
99187 }
100188
101- int yMax = Math . Min ( yMin + this . info . StepY , this . info . MaxY ) ;
189+ int yMax = Math . Min ( yMin + this . stepY , this . maxY ) ;
102190 var rows = new RowInterval ( yMin , yMax ) ;
103191
104- using IMemoryOwner < TBuffer > buffer = this . allocator . Allocate < TBuffer > ( this . info . Width ) ;
192+ using IMemoryOwner < TBuffer > buffer = this . allocator . Allocate < TBuffer > ( this . width ) ;
105193
106194 Unsafe . AsRef ( in this . operation ) . Invoke ( in rows , buffer . Memory . Span ) ;
107195 }
0 commit comments