Browse Source

fixed copy

af/merge-core
Anton Firszov 9 years ago
parent
commit
587bf1efa3
  1. 65
      src/ImageSharp/Common/Memory/BufferSpan.cs

65
src/ImageSharp/Common/Memory/BufferSpan.cs

@ -64,26 +64,34 @@ namespace ImageSharp
if (PerTypeValues<TDest>.IsPrimitiveType) if (PerTypeValues<TDest>.IsPrimitiveType)
{ {
Buffer.BlockCopy(source.Array, source.ByteOffset, destination.Array, destination.ByteOffset, byteCount); Buffer.BlockCopy(source.Array, source.ByteOffset, destination.Array, destination.ByteOffset, byteCount);
return;
} }
else if (byteCount > ByteCountThreshold)
{
ref byte destRef = ref Unsafe.As<TDest, byte>(ref destination.DangerousGetPinnableReference());
fixed (void* pinnedPtr = &destRef) ref byte destRef = ref Unsafe.As<TDest, byte>(ref destination.DangerousGetPinnableReference());
fixed (void* pinnedDest = &destRef)
{
#if !NETSTANDARD1_1
ref byte srcRef = ref source.DangerousGetPinnableReference();
fixed (void* pinnedSrc = &srcRef)
{ {
Marshal.Copy(source.Array, source.Start, (IntPtr)pinnedPtr, byteCount); Buffer.MemoryCopy(pinnedSrc, pinnedDest, byteCount, byteCount);
return;
} }
} #else
else if (byteCount > ByteCountThreshold)
{ {
IntPtr ptr = (IntPtr)pinnedDest;
Marshal.Copy(source.Array, source.Start, ptr, byteCount);
}
ref byte srcRef = ref source.DangerousGetPinnableReference(); ref byte srcRef = ref source.DangerousGetPinnableReference();
ref byte destRef = ref Unsafe.As<TDest, byte>(ref destination.DangerousGetPinnableReference());
fixed (void* pinnedSrc = &srcRef) fixed (void* pinnedSrc = &srcRef)
fixed (void* pinnedDest = &destRef)
{ {
Unsafe.CopyBlock(pinnedDest, pinnedSrc, (uint)byteCount); Unsafe.CopyBlock(pinnedSrc, pinnedDest, (uint)byteCount);
} }
#endif
} }
} }
@ -113,48 +121,59 @@ namespace ImageSharp
where T : struct where T : struct
where TDest : struct where TDest : struct
{ {
// TODO: Refactor this method when Unsafe.CopyBlock(ref T, ref T) gets available! // TODO: Use Unsafe.CopyBlock(ref T, ref T) for small buffers when it gets available!
int byteCount = SizeOf<T>(countInSource); int byteCount = SizeOf<T>(countInSource);
if (PerTypeValues<T>.IsPrimitiveType && PerTypeValues<TDest>.IsPrimitiveType) if (PerTypeValues<T>.IsPrimitiveType && PerTypeValues<TDest>.IsPrimitiveType)
{ {
Buffer.BlockCopy(source.Array, source.ByteOffset, destination.Array, destination.ByteOffset, byteCount); Buffer.BlockCopy(source.Array, source.ByteOffset, destination.Array, destination.ByteOffset, byteCount);
return;
} }
else if (byteCount > ByteCountThreshold)
{
ref byte destRef = ref Unsafe.As<TDest, byte>(ref destination.DangerousGetPinnableReference());
fixed (void* pinnedPtr = &destRef) ref byte destRef = ref Unsafe.As<TDest, byte>(ref destination.DangerousGetPinnableReference());
fixed (void* pinnedDest = &destRef)
{
#if !NETSTANDARD1_1
ref byte srcRef = ref Unsafe.As<T, byte>(ref source.DangerousGetPinnableReference());
fixed (void* pinnedSrc = &srcRef)
{ {
IntPtr ptr = (IntPtr)pinnedPtr; Buffer.MemoryCopy(pinnedSrc, pinnedDest, byteCount, byteCount);
return;
}
#else
if (byteCount > ByteCountThreshold)
{
IntPtr ptr = (IntPtr)pinnedDest;
if (Unsafe.SizeOf<T>() == sizeof(long)) if (Unsafe.SizeOf<T>() == sizeof(long))
{ {
Marshal.Copy(Unsafe.As<long[]>(source.Array), source.Start, ptr, countInSource); Marshal.Copy(Unsafe.As<long[]>(source.Array), source.Start, ptr, countInSource);
return;
} }
else if (Unsafe.SizeOf<T>() == sizeof(int)) else if (Unsafe.SizeOf<T>() == sizeof(int))
{ {
Marshal.Copy(Unsafe.As<int[]>(source.Array), source.Start, ptr, countInSource); Marshal.Copy(Unsafe.As<int[]>(source.Array), source.Start, ptr, countInSource);
return;
} }
else if (Unsafe.SizeOf<T>() == sizeof(short)) else if (Unsafe.SizeOf<T>() == sizeof(short))
{ {
Marshal.Copy(Unsafe.As<short[]>(source.Array), source.Start, ptr, countInSource); Marshal.Copy(Unsafe.As<short[]>(source.Array), source.Start, ptr, countInSource);
return;
} }
else if (Unsafe.SizeOf<T>() == sizeof(byte)) else if (Unsafe.SizeOf<T>() == sizeof(byte))
{ {
Marshal.Copy(Unsafe.As<byte[]>(source.Array), source.Start, ptr, countInSource); Marshal.Copy(Unsafe.As<byte[]>(source.Array), source.Start, ptr, countInSource);
return;
} }
} }
}
else
{
ref byte srcRef = ref Unsafe.As<T, byte>(ref source.DangerousGetPinnableReference()); ref byte srcRef = ref Unsafe.As<T, byte>(ref source.DangerousGetPinnableReference());
ref byte destRef = ref Unsafe.As<TDest, byte>(ref destination.DangerousGetPinnableReference());
fixed (void* pinnedSrc = &srcRef) fixed (void* pinnedSrc = &srcRef)
fixed (void* pinnedDest = &destRef)
{ {
Unsafe.CopyBlock(pinnedDest, pinnedSrc, (uint)byteCount); Unsafe.CopyBlock(pinnedSrc, pinnedDest, (uint)byteCount);
} }
#endif
} }
} }

Loading…
Cancel
Save