/// <summary> /// Allocates a buffer of value type objects interpreted as a 2D region /// of <paramref name="width"/> x <paramref name="height"/> elements. /// </summary> /// <typeparam name="T">The type of buffer items to allocate.</typeparam> /// <param name="memoryAllocator">The memory allocator.</param> /// <param name="width">The buffer width.</param> /// <param name="height">The buffer height.</param> /// <param name="preferContiguosImageBuffers">A value indicating whether the allocated buffer should be contiguous, unless bigger than <see cref="int.MaxValue"/>.</param> /// <param name="options">The allocation options.</param> /// <returns>The <see cref="Buffer2D{T}"/>.</returns> public static Buffer2D <T> Allocate2D <T>( this MemoryAllocator memoryAllocator, int width, int height, bool preferContiguosImageBuffers, AllocationOptions options = AllocationOptions.None) where T : struct { long groupLength = (long)width * height; MemoryGroup <T> memoryGroup; if (preferContiguosImageBuffers && groupLength < int.MaxValue) { IMemoryOwner <T> buffer = memoryAllocator.Allocate <T>((int)groupLength, options); memoryGroup = MemoryGroup <T> .CreateContiguous(buffer, false); } else { memoryGroup = memoryAllocator.AllocateGroup <T>(groupLength, width, options); } return(new Buffer2D <T>(memoryGroup, width, height)); }
public static Buffer2D <T> Allocate2D <T>( this MemoryAllocator memoryAllocator, Size size, AllocationOptions options = AllocationOptions.None) where T : struct => Allocate2D <T>(memoryAllocator, size.Width, size.Height, options);
/// <summary> /// Creates a new memory group, allocating it's buffers with the provided allocator. /// </summary> /// <param name="allocator">The <see cref="MemoryAllocator"/> to use.</param> /// <param name="totalLengthInElements">The total length of the buffer.</param> /// <param name="bufferAlignmentInElements">The expected alignment (eg. to make sure image rows fit into single buffers).</param> /// <param name="options">The <see cref="AllocationOptions"/>.</param> /// <returns>A new <see cref="MemoryGroup{T}"/>.</returns> /// <exception cref="InvalidMemoryOperationException">Thrown when 'blockAlignment' converted to bytes is greater than the buffer capacity of the allocator.</exception> public static MemoryGroup <T> Allocate( MemoryAllocator allocator, long totalLengthInElements, int bufferAlignmentInElements, AllocationOptions options = AllocationOptions.None) { int bufferCapacityInBytes = allocator.GetBufferCapacityInBytes(); Guard.NotNull(allocator, nameof(allocator)); Guard.MustBeGreaterThanOrEqualTo(totalLengthInElements, 0, nameof(totalLengthInElements)); Guard.MustBeGreaterThanOrEqualTo(bufferAlignmentInElements, 0, nameof(bufferAlignmentInElements)); int blockCapacityInElements = bufferCapacityInBytes / ElementSize; if (bufferAlignmentInElements > blockCapacityInElements) { throw new InvalidMemoryOperationException( $"The buffer capacity of the provided MemoryAllocator is insufficient for the requested buffer alignment: {bufferAlignmentInElements}."); } if (totalLengthInElements == 0) { var buffers0 = new IMemoryOwner <T>[1] { allocator.Allocate <T>(0, options) }; return(new Owned(buffers0, 0, 0, true)); } int numberOfAlignedSegments = blockCapacityInElements / bufferAlignmentInElements; int bufferLength = numberOfAlignedSegments * bufferAlignmentInElements; if (totalLengthInElements > 0 && totalLengthInElements < bufferLength) { bufferLength = (int)totalLengthInElements; } int sizeOfLastBuffer = (int)(totalLengthInElements % bufferLength); long bufferCount = totalLengthInElements / bufferLength; if (sizeOfLastBuffer == 0) { sizeOfLastBuffer = bufferLength; } else { bufferCount++; } var buffers = new IMemoryOwner <T> [bufferCount]; for (int i = 0; i < buffers.Length - 1; i++) { buffers[i] = allocator.Allocate <T>(bufferLength, options); } if (bufferCount > 0) { buffers[buffers.Length - 1] = allocator.Allocate <T>(sizeOfLastBuffer, options); } return(new Owned(buffers, bufferLength, totalLengthInElements, true)); }
internal static MemoryStream AllocateFixedCapacityMemoryStream(this MemoryAllocator allocator, long length) => new FixedCapacityPooledMemoryStream(length, allocator);