/// <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);
Пример #3
0
        /// <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));
        }
Пример #4
0
 internal static MemoryStream AllocateFixedCapacityMemoryStream(this MemoryAllocator allocator, long length) =>
 new FixedCapacityPooledMemoryStream(length, allocator);