mirror of https://github.com/SixLabors/ImageSharp
committed by
GitHub
123 changed files with 523 additions and 1639 deletions
@ -0,0 +1,22 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Contains extension methods for <see cref="Configuration"/>
|
||||
|
/// </summary>
|
||||
|
internal static class ConfigurationExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Creates a <see cref="ParallelOptions"/> object based on <paramref name="configuration"/>,
|
||||
|
/// having <see cref="ParallelOptions.MaxDegreeOfParallelism"/> set to <see cref="Configuration.MaxDegreeOfParallelism"/>
|
||||
|
/// </summary>
|
||||
|
public static ParallelOptions GetParallelOptions(this Configuration configuration) |
||||
|
{ |
||||
|
return new ParallelOptions() { MaxDegreeOfParallelism = configuration.MaxDegreeOfParallelism }; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,21 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
namespace SixLabors.Memory |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Options for allocating buffers.
|
|
||||
/// </summary>
|
|
||||
public enum AllocationOptions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Indicates that the buffer should just be allocated.
|
|
||||
/// </summary>
|
|
||||
None, |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Indicates that the allocated buffer should be cleaned following allocation.
|
|
||||
/// </summary>
|
|
||||
Clean |
|
||||
} |
|
||||
} |
|
||||
@ -1,82 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using System.Buffers; |
|
||||
using System.Runtime.InteropServices; |
|
||||
|
|
||||
namespace SixLabors.Memory |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Contains <see cref="Buffer{T}"/> and <see cref="ManagedByteBuffer"/>
|
|
||||
/// </summary>
|
|
||||
public partial class ArrayPoolMemoryAllocator |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The buffer implementation of <see cref="ArrayPoolMemoryAllocator"/>.
|
|
||||
/// </summary>
|
|
||||
private class Buffer<T> : ManagedBufferBase<T> |
|
||||
where T : struct |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The length of the buffer
|
|
||||
/// </summary>
|
|
||||
private readonly int length; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// A weak reference to the source pool.
|
|
||||
/// </summary>
|
|
||||
/// <remarks>
|
|
||||
/// By using a weak reference here, we are making sure that array pools and their retained arrays are always GC-ed
|
|
||||
/// after a call to <see cref="ArrayPoolMemoryAllocator.ReleaseRetainedResources"/>, regardless of having buffer instances still being in use.
|
|
||||
/// </remarks>
|
|
||||
private WeakReference<ArrayPool<byte>> sourcePoolReference; |
|
||||
|
|
||||
public Buffer(byte[] data, int length, ArrayPool<byte> sourcePool) |
|
||||
{ |
|
||||
this.Data = data; |
|
||||
this.length = length; |
|
||||
this.sourcePoolReference = new WeakReference<ArrayPool<byte>>(sourcePool); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the buffer as a byte array.
|
|
||||
/// </summary>
|
|
||||
protected byte[] Data { get; private set; } |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
protected override void Dispose(bool disposing) |
|
||||
{ |
|
||||
if (!disposing || this.Data == null || this.sourcePoolReference == null) |
|
||||
{ |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
if (this.sourcePoolReference.TryGetTarget(out ArrayPool<byte> pool)) |
|
||||
{ |
|
||||
pool.Return(this.Data); |
|
||||
} |
|
||||
|
|
||||
this.sourcePoolReference = null; |
|
||||
this.Data = null; |
|
||||
} |
|
||||
|
|
||||
public override Span<T> GetSpan() => MemoryMarshal.Cast<byte, T>(this.Data.AsSpan()).Slice(0, this.length); |
|
||||
|
|
||||
protected override object GetPinnableObject() => this.Data; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The <see cref="IManagedByteBuffer"/> implementation of <see cref="ArrayPoolMemoryAllocator"/>.
|
|
||||
/// </summary>
|
|
||||
private class ManagedByteBuffer : Buffer<byte>, IManagedByteBuffer |
|
||||
{ |
|
||||
public ManagedByteBuffer(byte[] data, int length, ArrayPool<byte> sourcePool) |
|
||||
: base(data, length, sourcePool) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public byte[] Array => this.Data; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,71 +0,0 @@ |
|||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
|
|
||||
namespace SixLabors.Memory |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Contains common factory methods and configuration constants.
|
|
||||
/// </summary>
|
|
||||
public partial class ArrayPoolMemoryAllocator |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The default value for: maximum size of pooled arrays in bytes.
|
|
||||
/// Currently set to 24MB, which is equivalent to 8 megapixels of raw <see cref="Rgba32"/> data.
|
|
||||
/// </summary>
|
|
||||
internal const int DefaultMaxPooledBufferSizeInBytes = 24 * 1024 * 1024; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The value for: The threshold to pool arrays in <see cref="largeArrayPool"/> which has less buckets for memory safety.
|
|
||||
/// </summary>
|
|
||||
private const int DefaultBufferSelectorThresholdInBytes = 8 * 1024 * 1024; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The default bucket count for <see cref="largeArrayPool"/>.
|
|
||||
/// </summary>
|
|
||||
private const int DefaultLargePoolBucketCount = 6; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The default bucket count for <see cref="normalArrayPool"/>.
|
|
||||
/// </summary>
|
|
||||
private const int DefaultNormalPoolBucketCount = 16; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// This is the default. Should be good for most use cases.
|
|
||||
/// </summary>
|
|
||||
/// <returns>The memory manager</returns>
|
|
||||
public static ArrayPoolMemoryAllocator CreateDefault() |
|
||||
{ |
|
||||
return new ArrayPoolMemoryAllocator( |
|
||||
DefaultMaxPooledBufferSizeInBytes, |
|
||||
DefaultBufferSelectorThresholdInBytes, |
|
||||
DefaultLargePoolBucketCount, |
|
||||
DefaultNormalPoolBucketCount); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// For environments with limited memory capabilities. Only small images are pooled, which can result in reduced througput.
|
|
||||
/// </summary>
|
|
||||
/// <returns>The memory manager</returns>
|
|
||||
public static ArrayPoolMemoryAllocator CreateWithModeratePooling() |
|
||||
{ |
|
||||
return new ArrayPoolMemoryAllocator(1024 * 1024, 32 * 1024, 16, 24); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Only pool small buffers like image rows.
|
|
||||
/// </summary>
|
|
||||
/// <returns>The memory manager</returns>
|
|
||||
public static ArrayPoolMemoryAllocator CreateWithMinimalPooling() |
|
||||
{ |
|
||||
return new ArrayPoolMemoryAllocator(64 * 1024, 32 * 1024, 8, 24); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// RAM is not an issue for me, gimme maximum througput!
|
|
||||
/// </summary>
|
|
||||
/// <returns>The memory manager</returns>
|
|
||||
public static ArrayPoolMemoryAllocator CreateWithAggressivePooling() |
|
||||
{ |
|
||||
return new ArrayPoolMemoryAllocator(128 * 1024 * 1024, 32 * 1024 * 1024, 16, 32); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,140 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System.Buffers; |
|
||||
using System.Runtime.CompilerServices; |
|
||||
|
|
||||
namespace SixLabors.Memory |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Implements <see cref="MemoryAllocator"/> by allocating memory from <see cref="ArrayPool{T}"/>.
|
|
||||
/// </summary>
|
|
||||
public sealed partial class ArrayPoolMemoryAllocator : MemoryAllocator |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The <see cref="ArrayPool{T}"/> for small-to-medium buffers which is not kept clean.
|
|
||||
/// </summary>
|
|
||||
private ArrayPool<byte> normalArrayPool; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The <see cref="ArrayPool{T}"/> for huge buffers, which is not kept clean.
|
|
||||
/// </summary>
|
|
||||
private ArrayPool<byte> largeArrayPool; |
|
||||
|
|
||||
private readonly int maxArraysPerBucketNormalPool; |
|
||||
|
|
||||
private readonly int maxArraysPerBucketLargePool; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="ArrayPoolMemoryAllocator"/> class.
|
|
||||
/// </summary>
|
|
||||
public ArrayPoolMemoryAllocator() |
|
||||
: this(DefaultMaxPooledBufferSizeInBytes, DefaultBufferSelectorThresholdInBytes) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="ArrayPoolMemoryAllocator"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="maxPoolSizeInBytes">The maximum size of pooled arrays. Arrays over the thershold are gonna be always allocated.</param>
|
|
||||
public ArrayPoolMemoryAllocator(int maxPoolSizeInBytes) |
|
||||
: this(maxPoolSizeInBytes, GetLargeBufferThresholdInBytes(maxPoolSizeInBytes)) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="ArrayPoolMemoryAllocator"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="maxPoolSizeInBytes">The maximum size of pooled arrays. Arrays over the thershold are gonna be always allocated.</param>
|
|
||||
/// <param name="poolSelectorThresholdInBytes">Arrays over this threshold will be pooled in <see cref="largeArrayPool"/> which has less buckets for memory safety.</param>
|
|
||||
public ArrayPoolMemoryAllocator(int maxPoolSizeInBytes, int poolSelectorThresholdInBytes) |
|
||||
: this(maxPoolSizeInBytes, poolSelectorThresholdInBytes, DefaultLargePoolBucketCount, DefaultNormalPoolBucketCount) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="ArrayPoolMemoryAllocator"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="maxPoolSizeInBytes">The maximum size of pooled arrays. Arrays over the thershold are gonna be always allocated.</param>
|
|
||||
/// <param name="poolSelectorThresholdInBytes">The threshold to pool arrays in <see cref="largeArrayPool"/> which has less buckets for memory safety.</param>
|
|
||||
/// <param name="maxArraysPerBucketLargePool">Max arrays per bucket for the large array pool</param>
|
|
||||
/// <param name="maxArraysPerBucketNormalPool">Max arrays per bucket for the normal array pool</param>
|
|
||||
public ArrayPoolMemoryAllocator(int maxPoolSizeInBytes, int poolSelectorThresholdInBytes, int maxArraysPerBucketLargePool, int maxArraysPerBucketNormalPool) |
|
||||
{ |
|
||||
ImageSharp.Guard.MustBeGreaterThan(maxPoolSizeInBytes, 0, nameof(maxPoolSizeInBytes)); |
|
||||
Guard.MustBeLessThanOrEqualTo(poolSelectorThresholdInBytes, maxPoolSizeInBytes, nameof(poolSelectorThresholdInBytes)); |
|
||||
|
|
||||
this.MaxPoolSizeInBytes = maxPoolSizeInBytes; |
|
||||
this.PoolSelectorThresholdInBytes = poolSelectorThresholdInBytes; |
|
||||
this.maxArraysPerBucketLargePool = maxArraysPerBucketLargePool; |
|
||||
this.maxArraysPerBucketNormalPool = maxArraysPerBucketNormalPool; |
|
||||
|
|
||||
this.InitArrayPools(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the maximum size of pooled arrays in bytes.
|
|
||||
/// </summary>
|
|
||||
public int MaxPoolSizeInBytes { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the threshold to pool arrays in <see cref="largeArrayPool"/> which has less buckets for memory safety.
|
|
||||
/// </summary>
|
|
||||
public int PoolSelectorThresholdInBytes { get; } |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
public override void ReleaseRetainedResources() |
|
||||
{ |
|
||||
this.InitArrayPools(); |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
internal override IMemoryOwner<T> Allocate<T>(int length, AllocationOptions options = AllocationOptions.None) |
|
||||
{ |
|
||||
int itemSizeBytes = Unsafe.SizeOf<T>(); |
|
||||
int bufferSizeInBytes = length * itemSizeBytes; |
|
||||
|
|
||||
ArrayPool<byte> pool = this.GetArrayPool(bufferSizeInBytes); |
|
||||
byte[] byteArray = pool.Rent(bufferSizeInBytes); |
|
||||
|
|
||||
var buffer = new Buffer<T>(byteArray, length, pool); |
|
||||
if (options == AllocationOptions.Clean) |
|
||||
{ |
|
||||
buffer.Clear(); |
|
||||
} |
|
||||
|
|
||||
return buffer; |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
internal override IManagedByteBuffer AllocateManagedByteBuffer(int length, AllocationOptions options) |
|
||||
{ |
|
||||
ArrayPool<byte> pool = this.GetArrayPool(length); |
|
||||
byte[] byteArray = pool.Rent(length); |
|
||||
|
|
||||
var buffer = new ManagedByteBuffer(byteArray, length, pool); |
|
||||
if (options == AllocationOptions.Clean) |
|
||||
{ |
|
||||
buffer.Clear(); |
|
||||
} |
|
||||
|
|
||||
return buffer; |
|
||||
} |
|
||||
|
|
||||
private static int GetLargeBufferThresholdInBytes(int maxPoolSizeInBytes) |
|
||||
{ |
|
||||
return maxPoolSizeInBytes / 4; |
|
||||
} |
|
||||
|
|
||||
private ArrayPool<byte> GetArrayPool(int bufferSizeInBytes) |
|
||||
{ |
|
||||
return bufferSizeInBytes <= this.PoolSelectorThresholdInBytes ? this.normalArrayPool : this.largeArrayPool; |
|
||||
} |
|
||||
|
|
||||
private void InitArrayPools() |
|
||||
{ |
|
||||
this.largeArrayPool = ArrayPool<byte>.Create(this.MaxPoolSizeInBytes, this.maxArraysPerBucketLargePool); |
|
||||
this.normalArrayPool = ArrayPool<byte>.Create(this.PoolSelectorThresholdInBytes, this.maxArraysPerBucketNormalPool); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,59 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using System.Runtime.CompilerServices; |
|
||||
|
|
||||
namespace SixLabors.Memory |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Wraps an array as an <see cref="IManagedByteBuffer"/> instance.
|
|
||||
/// </summary>
|
|
||||
internal class BasicArrayBuffer<T> : ManagedBufferBase<T> |
|
||||
where T : struct |
|
||||
{ |
|
||||
public BasicArrayBuffer(T[] array, int length) |
|
||||
{ |
|
||||
ImageSharp.DebugGuard.MustBeLessThanOrEqualTo(length, array.Length, nameof(length)); |
|
||||
this.Array = array; |
|
||||
this.Length = length; |
|
||||
} |
|
||||
|
|
||||
public BasicArrayBuffer(T[] array) |
|
||||
: this(array, array.Length) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public T[] Array { get; } |
|
||||
|
|
||||
public int Length { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Returns a reference to specified element of the buffer.
|
|
||||
/// </summary>
|
|
||||
/// <param name="index">The index</param>
|
|
||||
/// <returns>The reference to the specified element</returns>
|
|
||||
public ref T this[int index] |
|
||||
{ |
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
||||
get |
|
||||
{ |
|
||||
DebugGuard.MustBeLessThan(index, this.Length, nameof(index)); |
|
||||
|
|
||||
Span<T> span = this.GetSpan(); |
|
||||
return ref span[index]; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
protected override void Dispose(bool disposing) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public override Span<T> GetSpan() => this.Array.AsSpan(0, this.Length); |
|
||||
|
|
||||
protected override object GetPinnableObject() |
|
||||
{ |
|
||||
return this.Array; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,13 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
namespace SixLabors.Memory |
|
||||
{ |
|
||||
internal sealed class BasicByteBuffer : BasicArrayBuffer<byte>, IManagedByteBuffer |
|
||||
{ |
|
||||
internal BasicByteBuffer(byte[] array) |
|
||||
: base(array) |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,18 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System.Buffers; |
|
||||
|
|
||||
namespace SixLabors.Memory |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Represents a byte buffer backed by a managed array. Useful for interop with classic .NET API-s.
|
|
||||
/// </summary>
|
|
||||
internal interface IManagedByteBuffer : IMemoryOwner<byte> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Gets the managed array backing this buffer instance.
|
|
||||
/// </summary>
|
|
||||
byte[] Array { get; } |
|
||||
} |
|
||||
} |
|
||||
@ -1,43 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System.Buffers; |
|
||||
using System.Runtime.InteropServices; |
|
||||
|
|
||||
namespace SixLabors.Memory |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Provides a base class for <see cref="IMemoryOwner{T}"/> implementations by implementing pinning logic for <see cref="MemoryManager{T}"/> adaption.
|
|
||||
/// </summary>
|
|
||||
internal abstract class ManagedBufferBase<T> : MemoryManager<T> |
|
||||
where T : struct |
|
||||
{ |
|
||||
private GCHandle pinHandle; |
|
||||
|
|
||||
public bool IsMemoryOwner => true; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the object that should be pinned.
|
|
||||
/// </summary>
|
|
||||
protected abstract object GetPinnableObject(); |
|
||||
|
|
||||
public override unsafe MemoryHandle Pin(int elementIndex = 0) |
|
||||
{ |
|
||||
if (!this.pinHandle.IsAllocated) |
|
||||
{ |
|
||||
this.pinHandle = GCHandle.Alloc(this.GetPinnableObject(), GCHandleType.Pinned); |
|
||||
} |
|
||||
|
|
||||
void* ptr = (void*)this.pinHandle.AddrOfPinnedObject(); |
|
||||
return new MemoryHandle(ptr, this.pinHandle); |
|
||||
} |
|
||||
|
|
||||
public override void Unpin() |
|
||||
{ |
|
||||
if (this.pinHandle.IsAllocated) |
|
||||
{ |
|
||||
this.pinHandle.Free(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,39 +0,0 @@ |
|||||
// Copyright (c) Six Labors and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System.Buffers; |
|
||||
|
|
||||
namespace SixLabors.Memory |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Memory managers are used to allocate memory for image processing operations.
|
|
||||
/// </summary>
|
|
||||
public abstract class MemoryAllocator |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Allocates an <see cref="IMemoryOwner{T}" />, holding a <see cref="System.Memory{T}"/> of length <paramref name="length"/>.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="T">Type of the data stored in the buffer</typeparam>
|
|
||||
/// <param name="length">Size of the buffer to allocate</param>
|
|
||||
/// <param name="options">The allocation options.</param>
|
|
||||
/// <returns>A buffer of values of type <typeparamref name="T"/>.</returns>
|
|
||||
internal abstract IMemoryOwner<T> Allocate<T>(int length, AllocationOptions options = AllocationOptions.None) |
|
||||
where T : struct; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Allocates an <see cref="IManagedByteBuffer"/>.
|
|
||||
/// </summary>
|
|
||||
/// <param name="length">The requested buffer length</param>
|
|
||||
/// <param name="options">The allocation options.</param>
|
|
||||
/// <returns>The <see cref="IManagedByteBuffer"/></returns>
|
|
||||
internal abstract IManagedByteBuffer AllocateManagedByteBuffer(int length, AllocationOptions options = AllocationOptions.None); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Releases all retained resources not being in use.
|
|
||||
/// Eg: by resetting array pools and letting GC to free the arrays.
|
|
||||
/// </summary>
|
|
||||
public virtual void ReleaseRetainedResources() |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,21 +0,0 @@ |
|||||
using System.Buffers; |
|
||||
|
|
||||
namespace SixLabors.Memory |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Implements <see cref="MemoryAllocator"/> by newing up arrays by the GC on every allocation requests.
|
|
||||
/// </summary>
|
|
||||
public sealed class SimpleGcMemoryAllocator : MemoryAllocator |
|
||||
{ |
|
||||
/// <inheritdoc />
|
|
||||
internal override IMemoryOwner<T> Allocate<T>(int length, AllocationOptions options = AllocationOptions.None) |
|
||||
{ |
|
||||
return new BasicArrayBuffer<T>(new T[length]); |
|
||||
} |
|
||||
|
|
||||
internal override IManagedByteBuffer AllocateManagedByteBuffer(int length, AllocationOptions options) |
|
||||
{ |
|
||||
return new BasicByteBuffer(new byte[length]); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue