Browse Source

Merge pull request #656 from SixLabors/feature/add-allocation-options

Changed clean boolean for allocation into an enumeration.
af/merge-core
James Jackson-South 8 years ago
committed by GitHub
parent
commit
939086e228
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs
  2. 4
      src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
  3. 6
      src/ImageSharp/Formats/Gif/GifDecoderCore.cs
  4. 6
      src/ImageSharp/Formats/Gif/LzwDecoder.cs
  5. 4
      src/ImageSharp/Formats/Gif/LzwEncoder.cs
  6. 2
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangComponent.cs
  7. 2
      src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/DoubleBufferedStreamReader.cs
  8. 2
      src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/FastACTables.cs
  9. 2
      src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs
  10. 6
      src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs
  11. 8
      src/ImageSharp/Formats/Png/PngDecoderCore.cs
  12. 22
      src/ImageSharp/Formats/Png/PngEncoderCore.cs
  13. 2
      src/ImageSharp/ImageFrame{TPixel}.cs
  14. 2
      src/ImageSharp/ImageSharp.csproj
  15. 21
      src/ImageSharp/Memory/AllocationOptions.cs
  16. 8
      src/ImageSharp/Memory/ArrayPoolMemoryAllocator.cs
  17. 13
      src/ImageSharp/Memory/MemoryAllocator.cs
  18. 47
      src/ImageSharp/Memory/MemoryAllocatorExtensions.cs
  19. 4
      src/ImageSharp/Memory/SimpleGcMemoryAllocator.cs
  20. 42
      src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs
  21. 4
      src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.tt
  22. 4
      src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor.cs
  23. 2
      src/ImageSharp/Processing/Processors/Quantization/QuantizedFrame{TPixel}.cs
  24. 14
      src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs
  25. 2
      src/ImageSharp/Processing/Processors/Transforms/WeightsBuffer.cs
  26. 10
      tests/ImageSharp.Tests/Memory/ArrayPoolMemoryManagerTests.cs
  27. 8
      tests/ImageSharp.Tests/Memory/Buffer2DTests.cs
  28. 14
      tests/ImageSharp.Tests/Memory/BufferTestSuite.cs

2
src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs

@ -334,7 +334,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Text
} }
// take the path inside the path builder, scan thing and generate a Buffer2d representing the glyph and cache it. // take the path inside the path builder, scan thing and generate a Buffer2d representing the glyph and cache it.
Buffer2D<float> fullBuffer = this.MemoryAllocator.Allocate2D<float>(size.Width + 1, size.Height + 1, true); Buffer2D<float> fullBuffer = this.MemoryAllocator.Allocate2D<float>(size.Width + 1, size.Height + 1, AllocationOptions.Clean);
using (IBuffer<float> bufferBacking = this.MemoryAllocator.Allocate<float>(path.MaxIntersections)) using (IBuffer<float> bufferBacking = this.MemoryAllocator.Allocate<float>(path.MaxIntersections))
using (IBuffer<PointF> rowIntersectionBuffer = this.MemoryAllocator.Allocate<PointF>(size.Width)) using (IBuffer<PointF> rowIntersectionBuffer = this.MemoryAllocator.Allocate<PointF>(size.Width))

4
src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs

@ -226,7 +226,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
TPixel color = default; TPixel color = default;
var rgba = new Rgba32(0, 0, 0, 255); var rgba = new Rgba32(0, 0, 0, 255);
using (Buffer2D<byte> buffer = this.memoryAllocator.AllocateClean2D<byte>(width, height)) using (Buffer2D<byte> buffer = this.memoryAllocator.Allocate2D<byte>(width, height, AllocationOptions.Clean))
{ {
this.UncompressRle8(width, buffer.GetSpan()); this.UncompressRle8(width, buffer.GetSpan());
@ -354,7 +354,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
padding = 4 - padding; padding = 4 - padding;
} }
using (IManagedByteBuffer row = this.memoryAllocator.AllocateCleanManagedByteBuffer(arrayWidth + padding)) using (IManagedByteBuffer row = this.memoryAllocator.AllocateManagedByteBuffer(arrayWidth + padding, AllocationOptions.Clean))
{ {
TPixel color = default; TPixel color = default;
var rgba = new Rgba32(0, 0, 0, 255); var rgba = new Rgba32(0, 0, 0, 255);

6
src/ImageSharp/Formats/Gif/GifDecoderCore.cs

@ -321,11 +321,11 @@ namespace SixLabors.ImageSharp.Formats.Gif
if (imageDescriptor.LocalColorTableFlag) if (imageDescriptor.LocalColorTableFlag)
{ {
int length = imageDescriptor.LocalColorTableSize * 3; int length = imageDescriptor.LocalColorTableSize * 3;
localColorTable = this.configuration.MemoryAllocator.AllocateManagedByteBuffer(length, true); localColorTable = this.configuration.MemoryAllocator.AllocateManagedByteBuffer(length, AllocationOptions.Clean);
this.stream.Read(localColorTable.Array, 0, length); this.stream.Read(localColorTable.Array, 0, length);
} }
indices = this.configuration.MemoryAllocator.AllocateManagedByteBuffer(imageDescriptor.Width * imageDescriptor.Height, true); indices = this.configuration.MemoryAllocator.AllocateManagedByteBuffer(imageDescriptor.Width * imageDescriptor.Height, AllocationOptions.Clean);
this.ReadFrameIndices(imageDescriptor, indices.GetSpan()); this.ReadFrameIndices(imageDescriptor, indices.GetSpan());
ReadOnlySpan<Rgb24> colorTable = MemoryMarshal.Cast<byte, Rgb24>((localColorTable ?? this.globalColorTable).GetSpan()); ReadOnlySpan<Rgb24> colorTable = MemoryMarshal.Cast<byte, Rgb24>((localColorTable ?? this.globalColorTable).GetSpan());
@ -556,7 +556,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
{ {
int globalColorTableLength = this.logicalScreenDescriptor.GlobalColorTableSize * 3; int globalColorTableLength = this.logicalScreenDescriptor.GlobalColorTableSize * 3;
this.globalColorTable = this.MemoryAllocator.AllocateManagedByteBuffer(globalColorTableLength, true); this.globalColorTable = this.MemoryAllocator.AllocateManagedByteBuffer(globalColorTableLength, AllocationOptions.Clean);
// Read the global color table data from the stream // Read the global color table data from the stream
stream.Read(this.globalColorTable.Array, 0, globalColorTableLength); stream.Read(this.globalColorTable.Array, 0, globalColorTableLength);

6
src/ImageSharp/Formats/Gif/LzwDecoder.cs

@ -57,9 +57,9 @@ namespace SixLabors.ImageSharp.Formats.Gif
this.stream = stream; this.stream = stream;
this.prefix = memoryAllocator.Allocate<int>(MaxStackSize, true); this.prefix = memoryAllocator.Allocate<int>(MaxStackSize, AllocationOptions.Clean);
this.suffix = memoryAllocator.Allocate<int>(MaxStackSize, true); this.suffix = memoryAllocator.Allocate<int>(MaxStackSize, AllocationOptions.Clean);
this.pixelStack = memoryAllocator.Allocate<int>(MaxStackSize + 1, true); this.pixelStack = memoryAllocator.Allocate<int>(MaxStackSize + 1, AllocationOptions.Clean);
} }
/// <summary> /// <summary>

4
src/ImageSharp/Formats/Gif/LzwEncoder.cs

@ -168,8 +168,8 @@ namespace SixLabors.ImageSharp.Formats.Gif
public LzwEncoder(MemoryAllocator memoryAllocator, int colorDepth) public LzwEncoder(MemoryAllocator memoryAllocator, int colorDepth)
{ {
this.initialCodeSize = Math.Max(2, colorDepth); this.initialCodeSize = Math.Max(2, colorDepth);
this.hashTable = memoryAllocator.Allocate<int>(HashSize, true); this.hashTable = memoryAllocator.Allocate<int>(HashSize, AllocationOptions.Clean);
this.codeTable = memoryAllocator.Allocate<int>(HashSize, true); this.codeTable = memoryAllocator.Allocate<int>(HashSize, AllocationOptions.Clean);
} }
/// <summary> /// <summary>

2
src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangComponent.cs

@ -81,7 +81,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
this.SubSamplingDivisors = c0.SamplingFactors.DivideBy(this.SamplingFactors); this.SubSamplingDivisors = c0.SamplingFactors.DivideBy(this.SamplingFactors);
} }
this.SpectralBlocks = memoryAllocator.Allocate2D<Block8x8>(this.SizeInBlocks.Width, this.SizeInBlocks.Height, true); this.SpectralBlocks = memoryAllocator.Allocate2D<Block8x8>(this.SizeInBlocks.Width, this.SizeInBlocks.Height, AllocationOptions.Clean);
} }
/// <summary> /// <summary>

2
src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/DoubleBufferedStreamReader.cs

@ -44,7 +44,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
{ {
this.stream = stream; this.stream = stream;
this.length = (int)stream.Length; this.length = (int)stream.Length;
this.managedBuffer = memoryAllocator.AllocateCleanManagedByteBuffer(ChunkLength); this.managedBuffer = memoryAllocator.AllocateManagedByteBuffer(ChunkLength, AllocationOptions.Clean);
this.bufferChunk = this.managedBuffer.Array; this.bufferChunk = this.managedBuffer.Array;
} }

2
src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/FastACTables.cs

@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
/// <param name="memoryAllocator">The memory allocator used to allocate memory for image processing operations.</param> /// <param name="memoryAllocator">The memory allocator used to allocate memory for image processing operations.</param>
public FastACTables(MemoryAllocator memoryAllocator) public FastACTables(MemoryAllocator memoryAllocator)
{ {
this.tables = memoryAllocator.AllocateClean2D<short>(512, 4); this.tables = memoryAllocator.Allocate2D<short>(512, 4, AllocationOptions.Clean);
} }
/// <summary> /// <summary>

2
src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs

@ -129,7 +129,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
this.SubSamplingDivisors = c0.SamplingFactors.DivideBy(this.SamplingFactors); this.SubSamplingDivisors = c0.SamplingFactors.DivideBy(this.SamplingFactors);
} }
this.SpectralBlocks = this.memoryAllocator.AllocateClean2D<Block8x8>(blocksPerColumnForMcu, blocksPerLineForMcu + 1); this.SpectralBlocks = this.memoryAllocator.Allocate2D<Block8x8>(blocksPerColumnForMcu, blocksPerLineForMcu + 1, AllocationOptions.Clean);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]

6
src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs

@ -709,7 +709,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
/// <param name="remaining">The remaining bytes in the segment block.</param> /// <param name="remaining">The remaining bytes in the segment block.</param>
private void ProcessDefineHuffmanTablesMarker(int remaining) private void ProcessDefineHuffmanTablesMarker(int remaining)
{ {
using (IManagedByteBuffer huffmanData = this.configuration.MemoryAllocator.AllocateCleanManagedByteBuffer(256)) using (IManagedByteBuffer huffmanData = this.configuration.MemoryAllocator.AllocateManagedByteBuffer(256, AllocationOptions.Clean))
{ {
ref byte huffmanDataRef = ref MemoryMarshal.GetReference(huffmanData.GetSpan()); ref byte huffmanDataRef = ref MemoryMarshal.GetReference(huffmanData.GetSpan());
for (int i = 2; i < remaining;) for (int i = 2; i < remaining;)
@ -717,7 +717,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
byte huffmanTableSpec = (byte)this.InputStream.ReadByte(); byte huffmanTableSpec = (byte)this.InputStream.ReadByte();
this.InputStream.Read(huffmanData.Array, 0, 16); this.InputStream.Read(huffmanData.Array, 0, 16);
using (IManagedByteBuffer codeLengths = this.configuration.MemoryAllocator.AllocateCleanManagedByteBuffer(17)) using (IManagedByteBuffer codeLengths = this.configuration.MemoryAllocator.AllocateManagedByteBuffer(17, AllocationOptions.Clean))
{ {
ref byte codeLengthsRef = ref MemoryMarshal.GetReference(codeLengths.GetSpan()); ref byte codeLengthsRef = ref MemoryMarshal.GetReference(codeLengths.GetSpan());
int codeLengthSum = 0; int codeLengthSum = 0;
@ -727,7 +727,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
codeLengthSum += Unsafe.Add(ref codeLengthsRef, j) = Unsafe.Add(ref huffmanDataRef, j - 1); codeLengthSum += Unsafe.Add(ref codeLengthsRef, j) = Unsafe.Add(ref huffmanDataRef, j - 1);
} }
using (IManagedByteBuffer huffmanValues = this.configuration.MemoryAllocator.AllocateCleanManagedByteBuffer(256)) using (IManagedByteBuffer huffmanValues = this.configuration.MemoryAllocator.AllocateManagedByteBuffer(256, AllocationOptions.Clean))
{ {
this.InputStream.Read(huffmanValues.Array, 0, codeLengthSum); this.InputStream.Read(huffmanValues.Array, 0, codeLengthSum);

8
src/ImageSharp/Formats/Png/PngDecoderCore.cs

@ -370,7 +370,7 @@ namespace SixLabors.ImageSharp.Formats.Png
return false; return false;
} }
buffer = this.MemoryAllocator.AllocateCleanManagedByteBuffer(bytesPerScanline * 8 / bits); buffer = this.MemoryAllocator.AllocateManagedByteBuffer(bytesPerScanline * 8 / bits, AllocationOptions.Clean);
byte[] result = buffer.Array; byte[] result = buffer.Array;
int mask = 0xFF >> (8 - bits); int mask = 0xFF >> (8 - bits);
int resultOffset = 0; int resultOffset = 0;
@ -437,8 +437,8 @@ namespace SixLabors.ImageSharp.Formats.Png
this.bytesPerSample = this.header.BitDepth / 8; this.bytesPerSample = this.header.BitDepth / 8;
} }
this.previousScanline = this.MemoryAllocator.AllocateCleanManagedByteBuffer(this.bytesPerScanline); this.previousScanline = this.MemoryAllocator.AllocateManagedByteBuffer(this.bytesPerScanline, AllocationOptions.Clean);
this.scanline = this.configuration.MemoryAllocator.AllocateCleanManagedByteBuffer(this.bytesPerScanline); this.scanline = this.configuration.MemoryAllocator.AllocateManagedByteBuffer(this.bytesPerScanline, AllocationOptions.Clean);
} }
/// <summary> /// <summary>
@ -1445,7 +1445,7 @@ namespace SixLabors.ImageSharp.Formats.Png
private IManagedByteBuffer ReadChunkData(int length) private IManagedByteBuffer ReadChunkData(int length)
{ {
// We rent the buffer here to return it afterwards in Decode() // We rent the buffer here to return it afterwards in Decode()
IManagedByteBuffer buffer = this.configuration.MemoryAllocator.AllocateCleanManagedByteBuffer(length); IManagedByteBuffer buffer = this.configuration.MemoryAllocator.AllocateManagedByteBuffer(length, AllocationOptions.Clean);
this.currentStream.Read(buffer.Array, 0, length); this.currentStream.Read(buffer.Array, 0, length);

22
src/ImageSharp/Formats/Png/PngEncoderCore.cs

@ -678,9 +678,9 @@ namespace SixLabors.ImageSharp.Formats.Png
this.bytesPerScanline = this.width * this.bytesPerPixel; this.bytesPerScanline = this.width * this.bytesPerPixel;
int resultLength = this.bytesPerScanline + 1; int resultLength = this.bytesPerScanline + 1;
this.previousScanline = this.memoryAllocator.AllocateCleanManagedByteBuffer(this.bytesPerScanline); this.previousScanline = this.memoryAllocator.AllocateManagedByteBuffer(this.bytesPerScanline, AllocationOptions.Clean);
this.rawScanline = this.memoryAllocator.AllocateCleanManagedByteBuffer(this.bytesPerScanline); this.rawScanline = this.memoryAllocator.AllocateManagedByteBuffer(this.bytesPerScanline, AllocationOptions.Clean);
this.result = this.memoryAllocator.AllocateCleanManagedByteBuffer(resultLength); this.result = this.memoryAllocator.AllocateManagedByteBuffer(resultLength, AllocationOptions.Clean);
switch (this.pngFilterMethod) switch (this.pngFilterMethod)
{ {
@ -689,29 +689,29 @@ namespace SixLabors.ImageSharp.Formats.Png
case PngFilterMethod.Sub: case PngFilterMethod.Sub:
this.sub = this.memoryAllocator.AllocateCleanManagedByteBuffer(resultLength); this.sub = this.memoryAllocator.AllocateManagedByteBuffer(resultLength, AllocationOptions.Clean);
break; break;
case PngFilterMethod.Up: case PngFilterMethod.Up:
this.up = this.memoryAllocator.AllocateCleanManagedByteBuffer(resultLength); this.up = this.memoryAllocator.AllocateManagedByteBuffer(resultLength, AllocationOptions.Clean);
break; break;
case PngFilterMethod.Average: case PngFilterMethod.Average:
this.average = this.memoryAllocator.AllocateCleanManagedByteBuffer(resultLength); this.average = this.memoryAllocator.AllocateManagedByteBuffer(resultLength, AllocationOptions.Clean);
break; break;
case PngFilterMethod.Paeth: case PngFilterMethod.Paeth:
this.paeth = this.memoryAllocator.AllocateCleanManagedByteBuffer(resultLength); this.paeth = this.memoryAllocator.AllocateManagedByteBuffer(resultLength, AllocationOptions.Clean);
break; break;
case PngFilterMethod.Adaptive: case PngFilterMethod.Adaptive:
this.sub = this.memoryAllocator.AllocateCleanManagedByteBuffer(resultLength); this.sub = this.memoryAllocator.AllocateManagedByteBuffer(resultLength, AllocationOptions.Clean);
this.up = this.memoryAllocator.AllocateCleanManagedByteBuffer(resultLength); this.up = this.memoryAllocator.AllocateManagedByteBuffer(resultLength, AllocationOptions.Clean);
this.average = this.memoryAllocator.AllocateCleanManagedByteBuffer(resultLength); this.average = this.memoryAllocator.AllocateManagedByteBuffer(resultLength, AllocationOptions.Clean);
this.paeth = this.memoryAllocator.AllocateCleanManagedByteBuffer(resultLength); this.paeth = this.memoryAllocator.AllocateManagedByteBuffer(resultLength, AllocationOptions.Clean);
break; break;
} }

2
src/ImageSharp/ImageFrame{TPixel}.cs

@ -86,7 +86,7 @@ namespace SixLabors.ImageSharp
this.configuration = configuration; this.configuration = configuration;
this.MemoryAllocator = configuration.MemoryAllocator; this.MemoryAllocator = configuration.MemoryAllocator;
this.PixelBuffer = this.MemoryAllocator.Allocate2D<TPixel>(width, height, false); this.PixelBuffer = this.MemoryAllocator.Allocate2D<TPixel>(width, height);
this.MetaData = metaData; this.MetaData = metaData;
this.Clear(configuration.ParallelOptions, backgroundColor); this.Clear(configuration.ParallelOptions, backgroundColor);
} }

2
src/ImageSharp/ImageSharp.csproj

@ -29,7 +29,7 @@
<DebugType Condition="$(codecov) == ''">portable</DebugType> <DebugType Condition="$(codecov) == ''">portable</DebugType>
<DebugSymbols>True</DebugSymbols> <DebugSymbols>True</DebugSymbols>
<Features>IOperation</Features> <Features>IOperation</Features>
<LangVersion>7.3</LangVersion> <LangVersion>Latest</LangVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\Shared\*.cs" Exclude="bin\**;obj\**;**\*.xproj;packages\**" /> <Compile Include="..\Shared\*.cs" Exclude="bin\**;obj\**;**\*.xproj;packages\**" />

21
src/ImageSharp/Memory/AllocationOptions.cs

@ -0,0 +1,21 @@
// 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
}
}

8
src/ImageSharp/Memory/ArrayPoolMemoryAllocator.cs

@ -89,7 +89,7 @@ namespace SixLabors.Memory
} }
/// <inheritdoc /> /// <inheritdoc />
internal override IBuffer<T> Allocate<T>(int length, bool clear) internal override IBuffer<T> Allocate<T>(int length, AllocationOptions options)
{ {
int itemSizeBytes = Unsafe.SizeOf<T>(); int itemSizeBytes = Unsafe.SizeOf<T>();
int bufferSizeInBytes = length * itemSizeBytes; int bufferSizeInBytes = length * itemSizeBytes;
@ -98,7 +98,7 @@ namespace SixLabors.Memory
byte[] byteArray = pool.Rent(bufferSizeInBytes); byte[] byteArray = pool.Rent(bufferSizeInBytes);
var buffer = new Buffer<T>(byteArray, length, pool); var buffer = new Buffer<T>(byteArray, length, pool);
if (clear) if (options == AllocationOptions.Clean)
{ {
buffer.Clear(); buffer.Clear();
} }
@ -107,13 +107,13 @@ namespace SixLabors.Memory
} }
/// <inheritdoc /> /// <inheritdoc />
internal override IManagedByteBuffer AllocateManagedByteBuffer(int length, bool clear) internal override IManagedByteBuffer AllocateManagedByteBuffer(int length, AllocationOptions options)
{ {
ArrayPool<byte> pool = this.GetArrayPool(length); ArrayPool<byte> pool = this.GetArrayPool(length);
byte[] byteArray = pool.Rent(length); byte[] byteArray = pool.Rent(length);
var buffer = new ManagedByteBuffer(byteArray, length, pool); var buffer = new ManagedByteBuffer(byteArray, length, pool);
if (clear) if (options == AllocationOptions.Clean)
{ {
buffer.Clear(); buffer.Clear();
} }

13
src/ImageSharp/Memory/MemoryAllocator.cs

@ -9,23 +9,22 @@ namespace SixLabors.Memory
public abstract class MemoryAllocator public abstract class MemoryAllocator
{ {
/// <summary> /// <summary>
/// Allocates an <see cref="IBuffer{T}"/> of size <paramref name="length"/>, optionally /// Allocates an <see cref="IBuffer{T}"/> of size <paramref name="length"/>.
/// clearing the buffer before it gets returned.
/// </summary> /// </summary>
/// <typeparam name="T">Type of the data stored in the buffer</typeparam> /// <typeparam name="T">Type of the data stored in the buffer</typeparam>
/// <param name="length">Size of the buffer to allocate</param> /// <param name="length">Size of the buffer to allocate</param>
/// <param name="clear">True to clear the backing memory of the buffer</param> /// <param name="options">The allocation options.</param>
/// <returns>A buffer of values of type <typeparamref name="T"/>.</returns> /// <returns>A buffer of values of type <typeparamref name="T"/>.</returns>
internal abstract IBuffer<T> Allocate<T>(int length, bool clear) internal abstract IBuffer<T> Allocate<T>(int length, AllocationOptions options = AllocationOptions.None)
where T : struct; where T : struct;
/// <summary> /// <summary>
/// Allocates an <see cref="IManagedByteBuffer"/> /// Allocates an <see cref="IManagedByteBuffer"/>.
/// </summary> /// </summary>
/// <param name="length">The requested buffer length</param> /// <param name="length">The requested buffer length</param>
/// <param name="clear">A value indicating whether to clean the buffer</param> /// <param name="options">The allocation options.</param>
/// <returns>The <see cref="IManagedByteBuffer"/></returns> /// <returns>The <see cref="IManagedByteBuffer"/></returns>
internal abstract IManagedByteBuffer AllocateManagedByteBuffer(int length, bool clear); internal abstract IManagedByteBuffer AllocateManagedByteBuffer(int length, AllocationOptions options = AllocationOptions.None);
/// <summary> /// <summary>
/// Releases all retained resources not being in use. /// Releases all retained resources not being in use.

47
src/ImageSharp/Memory/MemoryAllocatorExtensions.cs

@ -7,56 +7,17 @@ namespace SixLabors.Memory
/// </summary> /// </summary>
internal static class MemoryAllocatorExtensions internal static class MemoryAllocatorExtensions
{ {
/// <summary> public static Buffer2D<T> Allocate2D<T>(this MemoryAllocator memoryAllocator, int width, int height, AllocationOptions options = AllocationOptions.None)
/// Allocates a <see cref="IBuffer{T}"/> of size <paramref name="length"/>.
/// Note: Depending on the implementation, the buffer may not cleared before
/// returning, so it may contain data from an earlier use.
/// </summary>
/// <typeparam name="T">Type of the data stored in the buffer</typeparam>
/// <param name="memoryAllocator">The <see cref="MemoryAllocator"/></param>
/// <param name="length">Size of the buffer to allocate</param>
/// <returns>A buffer of values of type <typeparamref name="T"/>.</returns>
public static IBuffer<T> Allocate<T>(this MemoryAllocator memoryAllocator, int length)
where T : struct where T : struct
{ {
return memoryAllocator.Allocate<T>(length, false); IBuffer<T> buffer = memoryAllocator.Allocate<T>(width * height, options);
}
public static IBuffer<T> AllocateClean<T>(this MemoryAllocator memoryAllocator, int length)
where T : struct
{
return memoryAllocator.Allocate<T>(length, true);
}
public static IManagedByteBuffer AllocateManagedByteBuffer(this MemoryAllocator memoryAllocator, int length)
{
return memoryAllocator.AllocateManagedByteBuffer(length, false);
}
public static IManagedByteBuffer AllocateCleanManagedByteBuffer(this MemoryAllocator memoryAllocator, int length)
{
return memoryAllocator.AllocateManagedByteBuffer(length, true);
}
public static Buffer2D<T> Allocate2D<T>(this MemoryAllocator memoryAllocator, int width, int height, bool clear)
where T : struct
{
IBuffer<T> buffer = memoryAllocator.Allocate<T>(width * height, clear);
return new Buffer2D<T>(buffer, width, height); return new Buffer2D<T>(buffer, width, height);
} }
public static Buffer2D<T> Allocate2D<T>(this MemoryAllocator memoryAllocator, Size size) 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, false);
public static Buffer2D<T> Allocate2D<T>(this MemoryAllocator memoryAllocator, int width, int height)
where T : struct =>
Allocate2D<T>(memoryAllocator, width, height, false);
public static Buffer2D<T> AllocateClean2D<T>(this MemoryAllocator memoryAllocator, int width, int height)
where T : struct => where T : struct =>
Allocate2D<T>(memoryAllocator, width, height, true); Allocate2D<T>(memoryAllocator, size.Width, size.Height, options);
/// <summary> /// <summary>
/// Allocates padded buffers for BMP encoder/decoder. (Replacing old PixelRow/PixelArea) /// Allocates padded buffers for BMP encoder/decoder. (Replacing old PixelRow/PixelArea)

4
src/ImageSharp/Memory/SimpleGcMemoryAllocator.cs

@ -6,12 +6,12 @@
public sealed class SimpleGcMemoryAllocator : MemoryAllocator public sealed class SimpleGcMemoryAllocator : MemoryAllocator
{ {
/// <inheritdoc /> /// <inheritdoc />
internal override IBuffer<T> Allocate<T>(int length, bool clear) internal override IBuffer<T> Allocate<T>(int length, AllocationOptions options)
{ {
return new BasicArrayBuffer<T>(new T[length]); return new BasicArrayBuffer<T>(new T[length]);
} }
internal override IManagedByteBuffer AllocateManagedByteBuffer(int length, bool clear) internal override IManagedByteBuffer AllocateManagedByteBuffer(int length, AllocationOptions options)
{ {
return new BasicByteBuffer(new byte[length]); return new BasicByteBuffer(new byte[length]);
} }

42
src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs

@ -44,7 +44,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
@ -122,7 +122,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
@ -161,7 +161,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
@ -200,7 +200,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
@ -239,7 +239,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
@ -278,7 +278,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
@ -317,7 +317,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
@ -356,7 +356,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
@ -395,7 +395,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
@ -434,7 +434,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
@ -473,7 +473,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
@ -512,7 +512,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
@ -551,7 +551,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
@ -590,7 +590,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
@ -629,7 +629,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
@ -668,7 +668,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
@ -707,7 +707,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
@ -746,7 +746,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
@ -785,7 +785,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
@ -824,7 +824,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);

4
src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.tt

@ -16,7 +16,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
{ {
using System; using System;
using System.Numerics; using System.Numerics;
using SixLabors.ImageSharp.Memory; using SixLabors.Memory;
/// <summary> /// <summary>
@ -86,7 +86,7 @@ namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length)); Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length)); Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3, false)) using (IBuffer<Vector4> buffer = memoryManager.Allocate<Vector4>(destination.Length * 3))
{ {
Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length); Span<Vector4> destinationSpan = buffer.Slice(0, destination.Length);
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length); Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);

4
src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor.cs

@ -43,8 +43,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
Span<TPixel> pixels = source.GetPixelSpan(); Span<TPixel> pixels = source.GetPixelSpan();
// Build the histogram of the grayscale levels. // Build the histogram of the grayscale levels.
using (IBuffer<int> histogramBuffer = memoryAllocator.AllocateClean<int>(this.LuminanceLevels)) using (IBuffer<int> histogramBuffer = memoryAllocator.Allocate<int>(this.LuminanceLevels, AllocationOptions.Clean))
using (IBuffer<int> cdfBuffer = memoryAllocator.AllocateClean<int>(this.LuminanceLevels)) using (IBuffer<int> cdfBuffer = memoryAllocator.Allocate<int>(this.LuminanceLevels, AllocationOptions.Clean))
{ {
Span<int> histogram = histogramBuffer.GetSpan(); Span<int> histogram = histogramBuffer.GetSpan();
for (int i = 0; i < pixels.Length; i++) for (int i = 0; i < pixels.Length; i++)

2
src/ImageSharp/Processing/Processors/Quantization/QuantizedFrame{TPixel}.cs

@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
this.Width = width; this.Width = width;
this.Height = height; this.Height = height;
this.Palette = palette; this.Palette = palette;
this.pixels = memoryAllocator.AllocateCleanManagedByteBuffer(width * height); this.pixels = memoryAllocator.AllocateManagedByteBuffer(width * height, AllocationOptions.Clean);
} }
/// <summary> /// <summary>

14
src/ImageSharp/Processing/Processors/Quantization/WuFrameQuantizer{TPixel}.cs

@ -139,13 +139,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
try try
{ {
this.vwt = memoryAllocator.AllocateClean<long>(TableLength); this.vwt = memoryAllocator.Allocate<long>(TableLength, AllocationOptions.Clean);
this.vmr = memoryAllocator.AllocateClean<long>(TableLength); this.vmr = memoryAllocator.Allocate<long>(TableLength, AllocationOptions.Clean);
this.vmg = memoryAllocator.AllocateClean<long>(TableLength); this.vmg = memoryAllocator.Allocate<long>(TableLength, AllocationOptions.Clean);
this.vmb = memoryAllocator.AllocateClean<long>(TableLength); this.vmb = memoryAllocator.Allocate<long>(TableLength, AllocationOptions.Clean);
this.vma = memoryAllocator.AllocateClean<long>(TableLength); this.vma = memoryAllocator.Allocate<long>(TableLength, AllocationOptions.Clean);
this.m2 = memoryAllocator.AllocateClean<float>(TableLength); this.m2 = memoryAllocator.Allocate<float>(TableLength, AllocationOptions.Clean);
this.tag = memoryAllocator.AllocateClean<byte>(TableLength); this.tag = memoryAllocator.Allocate<byte>(TableLength, AllocationOptions.Clean);
return base.QuantizeFrame(image); return base.QuantizeFrame(image);
} }

2
src/ImageSharp/Processing/Processors/Transforms/WeightsBuffer.cs

@ -21,7 +21,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
/// <param name="destinationSize">The size of the destination window</param> /// <param name="destinationSize">The size of the destination window</param>
public WeightsBuffer(MemoryAllocator memoryAllocator, int sourceSize, int destinationSize) public WeightsBuffer(MemoryAllocator memoryAllocator, int sourceSize, int destinationSize)
{ {
this.dataBuffer = memoryAllocator.Allocate2D<float>(sourceSize, destinationSize, true); this.dataBuffer = memoryAllocator.Allocate2D<float>(sourceSize, destinationSize, AllocationOptions.Clean);
this.Weights = new WeightsWindow[destinationSize]; this.Weights = new WeightsWindow[destinationSize];
} }

10
tests/ImageSharp.Tests/Memory/ArrayPoolMemoryManagerTests.cs

@ -126,18 +126,18 @@ namespace SixLabors.ImageSharp.Tests.Memory
} }
[Theory] [Theory]
[InlineData(false)] [InlineData(AllocationOptions.None)]
[InlineData(true)] [InlineData(AllocationOptions.Clean)]
public void CleaningRequests_AreControlledByAllocationParameter_Clean(bool clean) public void CleaningRequests_AreControlledByAllocationParameter_Clean(AllocationOptions options)
{ {
using (IBuffer<int> firstAlloc = this.MemoryAllocator.Allocate<int>(42)) using (IBuffer<int> firstAlloc = this.MemoryAllocator.Allocate<int>(42))
{ {
firstAlloc.GetSpan().Fill(666); firstAlloc.GetSpan().Fill(666);
} }
using (IBuffer<int> secondAlloc = this.MemoryAllocator.Allocate<int>(42, clean)) using (IBuffer<int> secondAlloc = this.MemoryAllocator.Allocate<int>(42, options))
{ {
int expected = clean ? 0 : 666; int expected = options == AllocationOptions.Clean ? 0 : 666;
Assert.Equal(expected, secondAlloc.GetSpan()[0]); Assert.Equal(expected, secondAlloc.GetSpan()[0]);
} }
} }

8
tests/ImageSharp.Tests/Memory/Buffer2DTests.cs

@ -34,11 +34,11 @@ namespace SixLabors.ImageSharp.Tests.Memory
private class MockMemoryAllocator : MemoryAllocator private class MockMemoryAllocator : MemoryAllocator
{ {
internal override IBuffer<T> Allocate<T>(int length, bool clear) internal override IBuffer<T> Allocate<T>(int length, AllocationOptions options)
{ {
var array = new T[length + 42]; var array = new T[length + 42];
if (!clear) if (options == AllocationOptions.None)
{ {
Span<byte> data = MemoryMarshal.Cast<T, byte>(array.AsSpan()); Span<byte> data = MemoryMarshal.Cast<T, byte>(array.AsSpan());
for (int i = 0; i < data.Length; i++) for (int i = 0; i < data.Length; i++)
@ -50,7 +50,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
return new BasicArrayBuffer<T>(array, length); return new BasicArrayBuffer<T>(array, length);
} }
internal override IManagedByteBuffer AllocateManagedByteBuffer(int length, bool clear) internal override IManagedByteBuffer AllocateManagedByteBuffer(int length, AllocationOptions options)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -72,7 +72,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
[Fact] [Fact]
public void CreateClean() public void CreateClean()
{ {
using (Buffer2D<int> buffer = this.MemoryAllocator.Allocate2D<int>(42, 42, true)) using (Buffer2D<int> buffer = this.MemoryAllocator.Allocate2D<int>(42, 42, AllocationOptions.Clean))
{ {
Span<int> span = buffer.GetSpan(); Span<int> span = buffer.GetSpan();
for (int j = 0; j < span.Length; j++) for (int j = 0; j < span.Length; j++)

14
tests/ImageSharp.Tests/Memory/BufferTestSuite.cs

@ -124,12 +124,12 @@ namespace SixLabors.ImageSharp.Tests.Memory
this.TestCanAllocateCleanBuffer<CustomStruct>(desiredLength); this.TestCanAllocateCleanBuffer<CustomStruct>(desiredLength);
} }
private IBuffer<T> Allocate<T>(int desiredLength, bool clean, bool managedByteBuffer) private IBuffer<T> Allocate<T>(int desiredLength, AllocationOptions options, bool managedByteBuffer)
where T : struct where T : struct
{ {
if (managedByteBuffer) if (managedByteBuffer)
{ {
if (!(this.MemoryAllocator.AllocateManagedByteBuffer(desiredLength, clean) is IBuffer<T> buffer)) if (!(this.MemoryAllocator.AllocateManagedByteBuffer(desiredLength, options) is IBuffer<T> buffer))
{ {
throw new InvalidOperationException("typeof(T) != typeof(byte)"); throw new InvalidOperationException("typeof(T) != typeof(byte)");
} }
@ -137,7 +137,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
return buffer; return buffer;
} }
return this.MemoryAllocator.Allocate<T>(desiredLength, clean); return this.MemoryAllocator.Allocate<T>(desiredLength, options);
} }
private void TestCanAllocateCleanBuffer<T>(int desiredLength, bool testManagedByteBuffer = false) private void TestCanAllocateCleanBuffer<T>(int desiredLength, bool testManagedByteBuffer = false)
@ -147,7 +147,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
{ {
using (IBuffer<T> buffer = this.Allocate<T>(desiredLength, true, testManagedByteBuffer)) using (IBuffer<T> buffer = this.Allocate<T>(desiredLength, AllocationOptions.Clean, testManagedByteBuffer))
{ {
Assert.True(buffer.GetSpan().SequenceEqual(expected)); Assert.True(buffer.GetSpan().SequenceEqual(expected));
} }
@ -172,7 +172,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
private void TestSpanPropertyIsAlwaysTheSame<T>(int desiredLength, bool testManagedByteBuffer = false) private void TestSpanPropertyIsAlwaysTheSame<T>(int desiredLength, bool testManagedByteBuffer = false)
where T : struct where T : struct
{ {
using (IBuffer<T> buffer = this.Allocate<T>(desiredLength, false, testManagedByteBuffer)) using (IBuffer<T> buffer = this.Allocate<T>(desiredLength, AllocationOptions.None, testManagedByteBuffer))
{ {
ref T a = ref MemoryMarshal.GetReference(buffer.GetSpan()); ref T a = ref MemoryMarshal.GetReference(buffer.GetSpan());
ref T b = ref MemoryMarshal.GetReference(buffer.GetSpan()); ref T b = ref MemoryMarshal.GetReference(buffer.GetSpan());
@ -201,7 +201,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
private void TestWriteAndReadElements<T>(int desiredLength, Func<int, T> getExpectedValue, bool testManagedByteBuffer = false) private void TestWriteAndReadElements<T>(int desiredLength, Func<int, T> getExpectedValue, bool testManagedByteBuffer = false)
where T : struct where T : struct
{ {
using (IBuffer<T> buffer = this.Allocate<T>(desiredLength, false, testManagedByteBuffer)) using (IBuffer<T> buffer = this.Allocate<T>(desiredLength, AllocationOptions.None, testManagedByteBuffer))
{ {
T[] expectedVals = new T[buffer.Length()]; T[] expectedVals = new T[buffer.Length()];
@ -247,7 +247,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
{ {
var dummy = default(T); var dummy = default(T);
using (IBuffer<T> buffer = this.Allocate<T>(desiredLength, false, testManagedByteBuffer)) using (IBuffer<T> buffer = this.Allocate<T>(desiredLength, AllocationOptions.None, testManagedByteBuffer))
{ {
Assert.ThrowsAny<Exception>( Assert.ThrowsAny<Exception>(
() => () =>

Loading…
Cancel
Save