@@ -161,38 +161,6 @@ public void SetPixel(int x, int y, Color color)
161161 }
162162 }
163163
164- /// <summary>
165- /// Sets pixels from a collection of <see cref="PixelData" />.
166- /// Uses unsafe pointer arithmetic for speed.
167- /// </summary>
168- /// <param name="pixels">The pixels to set.</param>
169- public void SetPixelsUnsafe ( IEnumerable < PixelData > pixels )
170- {
171- _bitmap . Lock ( ) ;
172- unsafe
173- {
174- var buffer = ( byte * ) _bitmap . BackBuffer . ToPointer ( ) ;
175- var stride = _bitmap . BackBufferStride ;
176-
177- foreach ( var pixel in pixels )
178- {
179- if ( ( uint ) pixel . X >= Width || ( uint ) pixel . Y >= Height )
180- continue ;
181-
182- var offset = pixel . Y * stride + pixel . X * 4 ;
183- buffer [ offset + 0 ] = pixel . B ;
184- buffer [ offset + 1 ] = pixel . G ;
185- buffer [ offset + 2 ] = pixel . R ;
186- buffer [ offset + 3 ] = pixel . A ;
187-
188- // still update the shared Bits array
189- DirectBitmapCore . SetPixels ( Bits , Width , Height , new [ ] { pixel } ) ;
190- }
191- }
192- _bitmap . AddDirtyRect ( new Int32Rect ( 0 , 0 , Width , Height ) ) ;
193- _bitmap . Unlock ( ) ;
194- }
195-
196164 /// <summary>
197165 /// Fills the bitmap with a uniform color using SIMD.
198166 /// </summary>
@@ -251,14 +219,54 @@ public void ApplyColorMatrix(float[][] matrix)
251219 /// Sets pixels from PixelData collection efficiently.
252220 /// </summary>
253221 /// <param name="pixels">Collection of PixelData (x, y, RGBA).</param>
254- public void SetPixels ( IEnumerable < PixelData > pixels )
222+ public void SetPixels ( IEnumerable < PixelData > pixels , int threshold = 16 )
255223 {
256- lock ( _syncLock )
224+ if ( pixels == null ) return ;
225+
226+ IEnumerable < PixelData > pixelCollection = pixels ;
227+
228+ // Materialize if not ICollection to count
229+ int count ;
230+ if ( pixels is ICollection < PixelData > col )
231+ {
232+ count = col . Count ;
233+ }
234+ else
235+ {
236+ var list = pixels . ToList ( ) ;
237+ count = list . Count ;
238+ pixelCollection = list ;
239+ }
240+
241+ // Small batch -> unsafe direct write
242+ if ( count <= threshold )
257243 {
258- // Convert PixelData to (x, y, Pixel32)
259- var pixelData = pixels . Select ( p => ( p . X , p . Y , new Pixel32 ( p . R , p . G , p . B , p . A ) ) ) ;
244+ if ( _bitmap != null )
245+ {
246+ _bitmap . Lock ( ) ;
247+ unsafe
248+ {
249+ var buffer = ( byte * ) _bitmap . BackBuffer . ToPointer ( ) ;
250+ var stride = _bitmap . BackBufferStride ;
251+ DirectBitmapCore . SetPixelsUnsafe ( Bits , Width , Height , pixelCollection , buffer , stride ) ;
252+ }
253+ _bitmap . AddDirtyRect ( new Int32Rect ( 0 , 0 , Width , Height ) ) ;
254+ _bitmap . Unlock ( ) ;
255+ }
256+ else
257+ {
258+ unsafe
259+ {
260+ DirectBitmapCore . SetPixelsUnsafe ( Bits , Width , Height , pixelCollection ) ;
261+ }
262+ }
263+ return ;
264+ }
260265
261- // SIMD batch update
266+ // Large batch -> SIMD batch
267+ lock ( _syncLock )
268+ {
269+ var pixelData = pixelCollection . Select ( p => ( p . X , p . Y , new Pixel32 ( p . R , p . G , p . B , p . A ) ) ) ;
262270 DirectBitmapCore . SetPixelsSimd ( Bits , Width , Height , pixelData ) ;
263271 }
264272
0 commit comments