11using System ;
22using System . Collections . Generic ;
33using System . Linq ;
4- using System . Runtime . InteropServices ;
4+ using System . Runtime . CompilerServices ;
55using System . Threading ;
66using SharpGen . Runtime ;
77using Vortice . Direct3D ;
@@ -184,13 +184,26 @@ private void UpdateZones()
184184 captureZone . Y + captureZone . UnscaledHeight , 1 ) ) ;
185185
186186 MappedSubresource mapSource = _context . Map ( stagingTexture , 0 , MapMode . Read , MapFlags . None ) ;
187- IntPtr sourcePtr = mapSource . DataPointer ;
188187 lock ( captureZone . Buffer )
189188 {
190- for ( int y = 0 ; y < captureZone . Height ; y ++ )
189+ Span < byte > source = mapSource . AsSpan ( captureZone . Stride * captureZone . Height ) ;
190+ switch ( Display . Rotation )
191191 {
192- Marshal . Copy ( sourcePtr , captureZone . Buffer , y * captureZone . Stride , captureZone . Stride ) ;
193- sourcePtr += mapSource . RowPitch ;
192+ case Rotation . Rotation90 :
193+ CopyRotate90 ( source , captureZone ) ;
194+ break ;
195+
196+ case Rotation . Rotation180 :
197+ CopyRotate180 ( source , captureZone ) ;
198+ break ;
199+
200+ case Rotation . Rotation270 :
201+ CopyRotate270 ( source , captureZone ) ;
202+ break ;
203+
204+ default :
205+ CopyRotate0 ( source , captureZone ) ;
206+ break ;
194207 }
195208 }
196209
@@ -200,11 +213,74 @@ private void UpdateZones()
200213 }
201214 }
202215
216+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
217+ private static void CopyRotate0 ( in Span < byte > source , in CaptureZone captureZone ) => source . CopyTo ( captureZone . Buffer . AsSpan ( ) ) ;
218+
219+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
220+ private static void CopyRotate90 ( in Span < byte > source , in CaptureZone captureZone )
221+ {
222+ int width = captureZone . Width ;
223+ int height = captureZone . Height ;
224+ Span < byte > destination = captureZone . Buffer . AsSpan ( ) ;
225+
226+ for ( int y = 0 ; y < height ; y ++ )
227+ for ( int x = 0 ; x < width ; x ++ )
228+ {
229+ int offset = ( ( y * width ) + x ) * BPP ;
230+ int destinationOffset = ( ( x * height ) + ( ( height - 1 ) - y ) ) * BPP ;
231+ destination [ destinationOffset ] = source [ offset ] ;
232+ destination [ destinationOffset + 1 ] = source [ offset + 1 ] ;
233+ destination [ destinationOffset + 2 ] = source [ offset + 2 ] ;
234+ destination [ destinationOffset + 3 ] = source [ offset + 3 ] ;
235+ }
236+ }
237+
238+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
239+ private static void CopyRotate180 ( in Span < byte > source , in CaptureZone captureZone )
240+ {
241+ int width = captureZone . Width ;
242+ int height = captureZone . Height ;
243+ Span < byte > destination = captureZone . Buffer . AsSpan ( ) ;
244+
245+ for ( int y = 0 ; y < height ; y ++ )
246+ for ( int x = 0 ; x < width ; x ++ )
247+ {
248+ int offset = ( ( y * width ) + x ) * BPP ;
249+ int destinationOffset = destination . Length - offset ;
250+ destination [ destinationOffset - 4 ] = source [ offset ] ;
251+ destination [ destinationOffset - 3 ] = source [ offset + 1 ] ;
252+ destination [ destinationOffset - 2 ] = source [ offset + 2 ] ;
253+ destination [ destinationOffset - 1 ] = source [ offset + 3 ] ;
254+ }
255+ }
256+
257+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
258+ private static void CopyRotate270 ( in Span < byte > source , in CaptureZone captureZone )
259+ {
260+ int width = captureZone . Width ;
261+ int height = captureZone . Height ;
262+ Span < byte > destination = captureZone . Buffer . AsSpan ( ) ;
263+
264+ for ( int y = 0 ; y < height ; y ++ )
265+ for ( int x = 0 ; x < width ; x ++ )
266+ {
267+ int offset = ( ( y * width ) + x ) * BPP ;
268+ int destinationOffset = ( ( ( ( width - 1 ) - x ) * height ) + y ) * BPP ;
269+ destination [ destinationOffset ] = source [ offset ] ;
270+ destination [ destinationOffset + 1 ] = source [ offset + 1 ] ;
271+ destination [ destinationOffset + 2 ] = source [ offset + 2 ] ;
272+ destination [ destinationOffset + 3 ] = source [ offset + 3 ] ;
273+ }
274+ }
275+
203276 /// <inheritdoc />
204277 public CaptureZone RegisterCaptureZone ( int x , int y , int width , int height , int downscaleLevel = 0 )
205278 {
206279 ValidateCaptureZoneAndThrow ( x , y , width , height ) ;
207280
281+ if ( Display . Rotation is Rotation . Rotation90 or Rotation . Rotation270 )
282+ ( x , y , width , height ) = ( y , x , height , width ) ;
283+
208284 int unscaledWidth = width ;
209285 int unscaledHeight = height ;
210286 ( width , height ) = CalculateScaledSize ( unscaledWidth , unscaledHeight , downscaleLevel ) ;
@@ -252,6 +328,9 @@ public void UpdateCaptureZone(CaptureZone captureZone, int? x = null, int? y = n
252328
253329 ValidateCaptureZoneAndThrow ( newX , newY , newUnscaledWidth , newUnscaledHeight ) ;
254330
331+ if ( Display . Rotation is Rotation . Rotation90 or Rotation . Rotation270 )
332+ ( newX , newY , newUnscaledWidth , newUnscaledHeight ) = ( newY , newX , newUnscaledHeight , newUnscaledWidth ) ;
333+
255334 captureZone . X = newX ;
256335 captureZone . Y = newY ;
257336
@@ -361,13 +440,18 @@ public void Restart()
361440 _output = adapter . GetOutput ( Display . Index ) ?? throw new ApplicationException ( "Couldn't get DirectX-Output." ) ;
362441 using IDXGIOutput5 output = _output . QueryInterface < IDXGIOutput5 > ( ) ;
363442
443+ int width = Display . Width ;
444+ int height = Display . Height ;
445+ if ( Display . Rotation is Rotation . Rotation90 or Rotation . Rotation270 )
446+ ( width , height ) = ( height , width ) ;
447+
364448 Texture2DDescription captureTextureDesc = new ( )
365449 {
366450 CPUAccessFlags = CpuAccessFlags . None ,
367451 BindFlags = BindFlags . RenderTarget | BindFlags . ShaderResource ,
368452 Format = Format . B8G8R8A8_UNorm ,
369- Width = Display . Width ,
370- Height = Display . Height ,
453+ Width = width ,
454+ Height = height ,
371455 MiscFlags = ResourceOptionFlags . None ,
372456 MipLevels = 1 ,
373457 ArraySize = 1 ,
0 commit comments