Browse Source

- Allocate Buffers from memory manager

pull/431/head
Lauri Kotilainen 8 years ago
parent
commit
607e452e2d
  1. 4
      src/ImageSharp.Drawing/Brushes/ImageBrush{TPixel}.cs
  2. 4
      src/ImageSharp.Drawing/Brushes/PatternBrush{TPixel}.cs
  3. 4
      src/ImageSharp.Drawing/Brushes/Processors/BrushApplicator.cs
  4. 4
      src/ImageSharp.Drawing/Brushes/RecolorBrush{TPixel}.cs
  5. 4
      src/ImageSharp.Drawing/Brushes/SolidBrush{TPixel}.cs
  6. 2
      src/ImageSharp.Drawing/Paths/ShapeRegion.cs
  7. 2
      src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs
  8. 2
      src/ImageSharp.Drawing/Processors/FillProcessor.cs
  9. 2
      src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs
  10. 1
      src/ImageSharp/Configuration.cs
  11. 6
      src/ImageSharp/Formats/Gif/GifDecoderCore.cs
  12. 2
      src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegImagePostProcessor.cs
  13. 2
      src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs
  14. 12
      src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsHuffmanTable.cs
  15. 4
      src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsJpegPixelArea.cs
  16. 10
      src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs
  17. 14
      src/ImageSharp/Formats/Png/PngDecoderCore.cs
  18. 14
      src/ImageSharp/Formats/Png/PngEncoderCore.cs
  19. 2
      src/ImageSharp/Image/Image.Decode.cs
  20. 2
      src/ImageSharp/Image/PixelArea{TPixel}.cs
  21. 28
      src/ImageSharp/Memory/ArrayPoolMemoryManager.cs
  22. 19
      src/ImageSharp/Memory/Buffer2D{T}.cs
  23. 43
      src/ImageSharp/Memory/Buffer{T}.cs
  24. 39
      src/ImageSharp/Memory/MemoryManager.cs
  25. 42
      src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs
  26. 2
      src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.tt
  27. 4
      src/ImageSharp/Processing/Processors/Effects/BackgroundColorProcessor.cs
  28. 4
      src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs
  29. 4
      src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs
  30. 2
      src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs
  31. 4
      tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs
  32. 4
      tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4ReferenceVsPointer.cs
  33. 4
      tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs
  34. 4
      tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs
  35. 4
      tests/ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs
  36. 4
      tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs
  37. 2
      tests/ImageSharp.Benchmarks/General/ClearBuffer.cs
  38. 2
      tests/ImageSharp.Benchmarks/General/IterateArray.cs
  39. 6
      tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs
  40. 2
      tests/ImageSharp.Benchmarks/Samplers/Glow.cs
  41. 22
      tests/ImageSharp.Tests/Memory/BufferTests.cs
  42. 2
      tests/ImageSharp.Tests/Memory/SpanUtilityTests.cs
  43. 6
      tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs
  44. 12
      tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs

4
src/ImageSharp.Drawing/Brushes/ImageBrush{TPixel}.cs

@ -122,8 +122,8 @@ namespace SixLabors.ImageSharp.Drawing.Brushes
internal override void Apply(Span<float> scanline, int x, int y) internal override void Apply(Span<float> scanline, int x, int y)
{ {
// Create a span for colors // Create a span for colors
using (var amountBuffer = new Buffer<float>(scanline.Length)) using (var amountBuffer = MemoryManager.Current.Allocate<float>(scanline.Length))
using (var overlay = new Buffer<TPixel>(scanline.Length)) using (var overlay = MemoryManager.Current.Allocate<TPixel>(scanline.Length))
{ {
int sourceY = (y - this.offsetY) % this.yLength; int sourceY = (y - this.offsetY) % this.yLength;
int offsetX = x - this.offsetX; int offsetX = x - this.offsetX;

4
src/ImageSharp.Drawing/Brushes/PatternBrush{TPixel}.cs

@ -152,8 +152,8 @@ namespace SixLabors.ImageSharp.Drawing.Brushes
internal override void Apply(Span<float> scanline, int x, int y) internal override void Apply(Span<float> scanline, int x, int y)
{ {
int patternY = y % this.pattern.Height; int patternY = y % this.pattern.Height;
using (var amountBuffer = new Buffer<float>(scanline.Length)) using (var amountBuffer = MemoryManager.Current.Allocate<float>(scanline.Length))
using (var overlay = new Buffer<TPixel>(scanline.Length)) using (var overlay = MemoryManager.Current.Allocate<TPixel>(scanline.Length))
{ {
for (int i = 0; i < scanline.Length; i++) for (int i = 0; i < scanline.Length; i++)
{ {

4
src/ImageSharp.Drawing/Brushes/Processors/BrushApplicator.cs

@ -65,8 +65,8 @@ namespace SixLabors.ImageSharp.Drawing.Brushes.Processors
/// <remarks>scanlineBuffer will be > scanlineWidth but provide and offset in case we want to share a larger buffer across runs.</remarks> /// <remarks>scanlineBuffer will be > scanlineWidth but provide and offset in case we want to share a larger buffer across runs.</remarks>
internal virtual void Apply(Span<float> scanline, int x, int y) internal virtual void Apply(Span<float> scanline, int x, int y)
{ {
using (var amountBuffer = new Buffer<float>(scanline.Length)) using (var amountBuffer = MemoryManager.Current.Allocate<float>(scanline.Length))
using (var overlay = new Buffer<TPixel>(scanline.Length)) using (var overlay = MemoryManager.Current.Allocate<TPixel>(scanline.Length))
{ {
for (int i = 0; i < scanline.Length; i++) for (int i = 0; i < scanline.Length; i++)
{ {

4
src/ImageSharp.Drawing/Brushes/RecolorBrush{TPixel}.cs

@ -144,8 +144,8 @@ namespace SixLabors.ImageSharp.Drawing.Brushes
/// <inheritdoc /> /// <inheritdoc />
internal override void Apply(Span<float> scanline, int x, int y) internal override void Apply(Span<float> scanline, int x, int y)
{ {
using (var amountBuffer = new Buffer<float>(scanline.Length)) using (var amountBuffer = MemoryManager.Current.Allocate<float>(scanline.Length))
using (var overlay = new Buffer<TPixel>(scanline.Length)) using (var overlay = MemoryManager.Current.Allocate<TPixel>(scanline.Length))
{ {
for (int i = 0; i < scanline.Length; i++) for (int i = 0; i < scanline.Length; i++)
{ {

4
src/ImageSharp.Drawing/Brushes/SolidBrush{TPixel}.cs

@ -61,7 +61,7 @@ namespace SixLabors.ImageSharp.Drawing.Brushes
public SolidBrushApplicator(ImageFrame<TPixel> source, TPixel color, GraphicsOptions options) public SolidBrushApplicator(ImageFrame<TPixel> source, TPixel color, GraphicsOptions options)
: base(source, options) : base(source, options)
{ {
this.Colors = new Buffer<TPixel>(source.Width); this.Colors = MemoryManager.Current.Allocate<TPixel>(source.Width);
for (int i = 0; i < this.Colors.Length; i++) for (int i = 0; i < this.Colors.Length; i++)
{ {
this.Colors[i] = color; this.Colors[i] = color;
@ -96,7 +96,7 @@ namespace SixLabors.ImageSharp.Drawing.Brushes
{ {
Span<TPixel> destinationRow = this.Target.GetPixelRowSpan(y).Slice(x, scanline.Length); Span<TPixel> destinationRow = this.Target.GetPixelRowSpan(y).Slice(x, scanline.Length);
using (var amountBuffer = new Buffer<float>(scanline.Length)) using (var amountBuffer = MemoryManager.Current.Allocate<float>(scanline.Length))
{ {
for (int i = 0; i < scanline.Length; i++) for (int i = 0; i < scanline.Length; i++)
{ {

2
src/ImageSharp.Drawing/Paths/ShapeRegion.cs

@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp.Drawing
{ {
var start = new PointF(this.Bounds.Left - 1, y); var start = new PointF(this.Bounds.Left - 1, y);
var end = new PointF(this.Bounds.Right + 1, y); var end = new PointF(this.Bounds.Right + 1, y);
using (var innerBuffer = new Buffer<PointF>(buffer.Length)) using (var innerBuffer = MemoryManager.Current.Allocate<PointF>(buffer.Length))
{ {
PointF[] array = innerBuffer.Array; PointF[] array = innerBuffer.Array;
int count = this.Shape.FindIntersections(start, end, array, 0); int count = this.Shape.FindIntersections(start, end, array, 0);

2
src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs

@ -84,7 +84,7 @@ namespace SixLabors.ImageSharp.Drawing.Processors
maxY = Math.Min(this.Location.Y + this.Size.Height, maxY); maxY = Math.Min(this.Location.Y + this.Size.Height, maxY);
int width = maxX - minX; int width = maxX - minX;
using (var amount = new Buffer<float>(width)) using (var amount = MemoryManager.Current.Allocate<float>(width))
{ {
for (int i = 0; i < width; i++) for (int i = 0; i < width; i++)
{ {

2
src/ImageSharp.Drawing/Processors/FillProcessor.cs

@ -66,7 +66,7 @@ namespace SixLabors.ImageSharp.Drawing.Processors
int width = maxX - minX; int width = maxX - minX;
using (var amount = new Buffer<float>(width)) using (var amount = MemoryManager.Current.Allocate<float>(width))
using (BrushApplicator<TPixel> applicator = this.brush.CreateApplicator(source, sourceRectangle, this.options)) using (BrushApplicator<TPixel> applicator = this.brush.CreateApplicator(source, sourceRectangle, this.options))
{ {
for (int i = 0; i < width; i++) for (int i = 0; i < width; i++)

2
src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs

@ -102,7 +102,7 @@ namespace SixLabors.ImageSharp.Drawing.Processors
{ {
float[] buffer = arrayPool.Rent(maxIntersections); float[] buffer = arrayPool.Rent(maxIntersections);
int scanlineWidth = maxX - minX; int scanlineWidth = maxX - minX;
using (var scanline = new Buffer<float>(scanlineWidth)) using (var scanline = MemoryManager.Current.Allocate<float>(scanlineWidth))
{ {
try try
{ {

1
src/ImageSharp/Configuration.cs

@ -12,6 +12,7 @@ using SixLabors.ImageSharp.Formats.Gif;
using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Png; using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp namespace SixLabors.ImageSharp
{ {

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

@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
if (this.logicalScreenDescriptor.GlobalColorTableFlag) if (this.logicalScreenDescriptor.GlobalColorTableFlag)
{ {
this.globalColorTableLength = this.logicalScreenDescriptor.GlobalColorTableSize * 3; this.globalColorTableLength = this.logicalScreenDescriptor.GlobalColorTableSize * 3;
this.globalColorTable = Buffer<byte>.CreateClean(this.globalColorTableLength); this.globalColorTable = MemoryManager.Current.Allocate<byte>(this.globalColorTableLength, true);
// Read the global color table from the stream // Read the global color table from the stream
stream.Read(this.globalColorTable.Array, 0, this.globalColorTableLength); stream.Read(this.globalColorTable.Array, 0, this.globalColorTableLength);
@ -320,11 +320,11 @@ namespace SixLabors.ImageSharp.Formats.Gif
if (imageDescriptor.LocalColorTableFlag) if (imageDescriptor.LocalColorTableFlag)
{ {
int length = imageDescriptor.LocalColorTableSize * 3; int length = imageDescriptor.LocalColorTableSize * 3;
localColorTable = Buffer<byte>.CreateClean(length); localColorTable = MemoryManager.Current.Allocate<byte>(length, true);
this.currentStream.Read(localColorTable.Array, 0, length); this.currentStream.Read(localColorTable.Array, 0, length);
} }
indices = Buffer<byte>.CreateClean(imageDescriptor.Width * imageDescriptor.Height); indices = MemoryManager.Current.Allocate<byte>(imageDescriptor.Width * imageDescriptor.Height, true);
this.ReadFrameIndices(imageDescriptor, indices); this.ReadFrameIndices(imageDescriptor, indices);
this.ReadFrameColors(indices, localColorTable ?? this.globalColorTable, imageDescriptor); this.ReadFrameColors(indices, localColorTable ?? this.globalColorTable, imageDescriptor);

2
src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegImagePostProcessor.cs

@ -53,7 +53,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder
this.PostProcessorBufferSize = new Size(c0.SizeInBlocks.Width * 8, PixelRowsPerStep); this.PostProcessorBufferSize = new Size(c0.SizeInBlocks.Width * 8, PixelRowsPerStep);
this.ComponentProcessors = rawJpeg.Components.Select(c => new JpegComponentPostProcessor(this, c)).ToArray(); this.ComponentProcessors = rawJpeg.Components.Select(c => new JpegComponentPostProcessor(this, c)).ToArray();
this.rgbaBuffer = new Buffer<Vector4>(rawJpeg.ImageSizeInPixels.Width); this.rgbaBuffer = MemoryManager.Current.Allocate<Vector4>(rawJpeg.ImageSizeInPixels.Width);
this.colorConverter = ColorConverters.JpegColorConverter.GetConverter(rawJpeg.ColorSpace); this.colorConverter = ColorConverters.JpegColorConverter.GetConverter(rawJpeg.ColorSpace);
} }

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

@ -114,7 +114,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
int blocksBufferSize = 64 * this.BlocksPerColumnForMcu * (this.BlocksPerLineForMcu + 1); int blocksBufferSize = 64 * this.BlocksPerColumnForMcu * (this.BlocksPerLineForMcu + 1);
// Pooled. Disposed via frame disposal // Pooled. Disposed via frame disposal
this.BlockData = Buffer<short>.CreateClean(blocksBufferSize); this.BlockData = MemoryManager.Current.Allocate<short>(blocksBufferSize, true);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]

12
src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsHuffmanTable.cs

@ -24,12 +24,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
/// <param name="values">The huffman values</param> /// <param name="values">The huffman values</param>
public PdfJsHuffmanTable(byte[] lengths, byte[] values) public PdfJsHuffmanTable(byte[] lengths, byte[] values)
{ {
this.lookahead = Buffer<short>.CreateClean(256); this.lookahead = MemoryManager.Current.Allocate<short>(256, true);
this.valOffset = Buffer<short>.CreateClean(18); this.valOffset = MemoryManager.Current.Allocate<short>(18, true);
this.maxcode = Buffer<long>.CreateClean(18); this.maxcode = MemoryManager.Current.Allocate<long>(18, true);
using (var huffsize = Buffer<short>.CreateClean(257)) using (var huffsize = MemoryManager.Current.Allocate<short>(257, true))
using (var huffcode = Buffer<short>.CreateClean(257)) using (var huffcode = MemoryManager.Current.Allocate<short>(257, true))
{ {
GenerateSizeTable(lengths, huffsize); GenerateSizeTable(lengths, huffsize);
GenerateCodeTable(huffsize, huffcode); GenerateCodeTable(huffsize, huffcode);
@ -37,7 +37,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
GenerateLookaheadTables(lengths, values, this.lookahead); GenerateLookaheadTables(lengths, values, this.lookahead);
} }
this.huffval = Buffer<byte>.CreateClean(values.Length); this.huffval = MemoryManager.Current.Allocate<byte>(values.Length, true);
Buffer.BlockCopy(values, 0, this.huffval.Array, 0, values.Length); Buffer.BlockCopy(values, 0, this.huffval.Array, 0, values.Length);
this.MaxCode = this.maxcode.Array; this.MaxCode = this.maxcode.Array;

4
src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsJpegPixelArea.cs

@ -69,11 +69,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
this.rowStride = width * numberOfComponents; this.rowStride = width * numberOfComponents;
var scale = new Vector2(this.imageWidth / (float)width, this.imageHeight / (float)height); var scale = new Vector2(this.imageWidth / (float)width, this.imageHeight / (float)height);
this.componentData = new Buffer<byte>(width * height * numberOfComponents); this.componentData = MemoryManager.Current.Allocate<byte>(width * height * numberOfComponents);
Span<byte> componentDataSpan = this.componentData; Span<byte> componentDataSpan = this.componentData;
const uint Mask3Lsb = 0xFFFFFFF8; // Used to clear the 3 LSBs const uint Mask3Lsb = 0xFFFFFFF8; // Used to clear the 3 LSBs
using (var xScaleBlockOffset = new Buffer<int>(width)) using (var xScaleBlockOffset = MemoryManager.Current.Allocate<int>(width))
{ {
Span<int> xScaleBlockOffsetSpan = xScaleBlockOffset; Span<int> xScaleBlockOffsetSpan = xScaleBlockOffset;
for (int i = 0; i < numberOfComponents; i++) for (int i = 0; i < numberOfComponents; i++)

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

@ -673,14 +673,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
throw new ImageFormatException($"DHT has wrong length: {remaining}"); throw new ImageFormatException($"DHT has wrong length: {remaining}");
} }
using (var huffmanData = Buffer<byte>.CreateClean(256)) using (var huffmanData = MemoryManager.Current.Allocate<byte>(256, true))
{ {
for (int i = 2; i < remaining;) for (int i = 2; i < remaining;)
{ {
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 (var codeLengths = Buffer<byte>.CreateClean(17)) using (var codeLengths = MemoryManager.Current.Allocate<byte>(17, true))
{ {
int codeLengthSum = 0; int codeLengthSum = 0;
@ -689,7 +689,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
codeLengthSum += codeLengths[j] = huffmanData[j - 1]; codeLengthSum += codeLengths[j] = huffmanData[j - 1];
} }
using (var huffmanValues = Buffer<byte>.CreateClean(256)) using (var huffmanValues = MemoryManager.Current.Allocate<byte>(256, true))
{ {
this.InputStream.Read(huffmanValues.Array, 0, codeLengthSum); this.InputStream.Read(huffmanValues.Array, 0, codeLengthSum);
@ -784,8 +784,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
{ {
int blocksPerLine = component.BlocksPerLine; int blocksPerLine = component.BlocksPerLine;
int blocksPerColumn = component.BlocksPerColumn; int blocksPerColumn = component.BlocksPerColumn;
using (var computationBuffer = Buffer<short>.CreateClean(64)) using (var computationBuffer = MemoryManager.Current.Allocate<short>(64, true))
using (var multiplicationBuffer = Buffer<short>.CreateClean(64)) using (var multiplicationBuffer = MemoryManager.Current.Allocate<short>(64, true))
{ {
Span<short> quantizationTable = this.quantizationTables.Tables.GetRowSpan(frameComponent.QuantizationTableIndex); Span<short> quantizationTable = this.quantizationTables.Tables.GetRowSpan(frameComponent.QuantizationTableIndex);
Span<short> computationBufferSpan = computationBuffer; Span<short> computationBufferSpan = computationBuffer;

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

@ -375,8 +375,8 @@ namespace SixLabors.ImageSharp.Formats.Png
this.bytesPerSample = this.header.BitDepth / 8; this.bytesPerSample = this.header.BitDepth / 8;
} }
this.previousScanline = Buffer<byte>.CreateClean(this.bytesPerScanline); this.previousScanline = MemoryManager.Current.Allocate<byte>(this.bytesPerScanline, true);
this.scanline = Buffer<byte>.CreateClean(this.bytesPerScanline); this.scanline = MemoryManager.Current.Allocate<byte>(this.bytesPerScanline, true);
} }
/// <summary> /// <summary>
@ -669,7 +669,7 @@ namespace SixLabors.ImageSharp.Formats.Png
if (this.header.BitDepth == 16) if (this.header.BitDepth == 16)
{ {
int length = this.header.Width * 3; int length = this.header.Width * 3;
using (var compressed = new Buffer<byte>(length)) using (var compressed = MemoryManager.Current.Allocate<byte>(length))
{ {
// TODO: Should we use pack from vector here instead? // TODO: Should we use pack from vector here instead?
this.From16BitTo8Bit(scanlineBuffer, compressed, length); this.From16BitTo8Bit(scanlineBuffer, compressed, length);
@ -686,7 +686,7 @@ namespace SixLabors.ImageSharp.Formats.Png
if (this.header.BitDepth == 16) if (this.header.BitDepth == 16)
{ {
int length = this.header.Width * 3; int length = this.header.Width * 3;
using (var compressed = new Buffer<byte>(length)) using (var compressed = MemoryManager.Current.Allocate<byte>(length))
{ {
// TODO: Should we use pack from vector here instead? // TODO: Should we use pack from vector here instead?
this.From16BitTo8Bit(scanlineBuffer, compressed, length); this.From16BitTo8Bit(scanlineBuffer, compressed, length);
@ -727,7 +727,7 @@ namespace SixLabors.ImageSharp.Formats.Png
if (this.header.BitDepth == 16) if (this.header.BitDepth == 16)
{ {
int length = this.header.Width * 4; int length = this.header.Width * 4;
using (var compressed = new Buffer<byte>(length)) using (var compressed = MemoryManager.Current.Allocate<byte>(length))
{ {
// TODO: Should we use pack from vector here instead? // TODO: Should we use pack from vector here instead?
this.From16BitTo8Bit(scanlineBuffer, compressed, length); this.From16BitTo8Bit(scanlineBuffer, compressed, length);
@ -930,7 +930,7 @@ namespace SixLabors.ImageSharp.Formats.Png
if (this.header.BitDepth == 16) if (this.header.BitDepth == 16)
{ {
int length = this.header.Width * 3; int length = this.header.Width * 3;
using (var compressed = new Buffer<byte>(length)) using (var compressed = MemoryManager.Current.Allocate<byte>(length))
{ {
// TODO: Should we use pack from vector here instead? // TODO: Should we use pack from vector here instead?
this.From16BitTo8Bit(scanlineBuffer, compressed, length); this.From16BitTo8Bit(scanlineBuffer, compressed, length);
@ -998,7 +998,7 @@ namespace SixLabors.ImageSharp.Formats.Png
if (this.header.BitDepth == 16) if (this.header.BitDepth == 16)
{ {
int length = this.header.Width * 4; int length = this.header.Width * 4;
using (var compressed = new Buffer<byte>(length)) using (var compressed = MemoryManager.Current.Allocate<byte>(length))
{ {
// TODO: Should we use pack from vector here instead? // TODO: Should we use pack from vector here instead?
this.From16BitTo8Bit(scanlineBuffer, compressed, length); this.From16BitTo8Bit(scanlineBuffer, compressed, length);

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

@ -620,16 +620,16 @@ 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 = Buffer<byte>.CreateClean(this.bytesPerScanline); this.previousScanline = MemoryManager.Current.Allocate<byte>(this.bytesPerScanline, true);
this.rawScanline = Buffer<byte>.CreateClean(this.bytesPerScanline); this.rawScanline = MemoryManager.Current.Allocate<byte>(this.bytesPerScanline, true);
this.result = Buffer<byte>.CreateClean(resultLength); this.result = MemoryManager.Current.Allocate<byte>(resultLength, true);
if (this.pngColorType != PngColorType.Palette) if (this.pngColorType != PngColorType.Palette)
{ {
this.sub = Buffer<byte>.CreateClean(resultLength); this.sub = MemoryManager.Current.Allocate<byte>(resultLength, true);
this.up = Buffer<byte>.CreateClean(resultLength); this.up = MemoryManager.Current.Allocate<byte>(resultLength, true);
this.average = Buffer<byte>.CreateClean(resultLength); this.average = MemoryManager.Current.Allocate<byte>(resultLength, true);
this.paeth = Buffer<byte>.CreateClean(resultLength); this.paeth = MemoryManager.Current.Allocate<byte>(resultLength, true);
} }
byte[] buffer; byte[] buffer;

2
src/ImageSharp/Image/Image.Decode.cs

@ -29,7 +29,7 @@ namespace SixLabors.ImageSharp
return null; return null;
} }
using (var buffer = new Buffer<byte>(maxHeaderSize)) using (var buffer = MemoryManager.Current.Allocate<byte>(maxHeaderSize))
{ {
long startPosition = stream.Position; long startPosition = stream.Position;
stream.Read(buffer.Array, 0, maxHeaderSize); stream.Read(buffer.Array, 0, maxHeaderSize);

2
src/ImageSharp/Image/PixelArea{TPixel}.cs

@ -116,7 +116,7 @@ namespace SixLabors.ImageSharp
this.RowStride = (width * GetComponentCount(componentOrder)) + padding; this.RowStride = (width * GetComponentCount(componentOrder)) + padding;
this.Length = this.RowStride * height; this.Length = this.RowStride * height;
this.byteBuffer = Buffer<byte>.CreateClean(this.Length); this.byteBuffer = MemoryManager.Current.Allocate<byte>(this.Length, true);
} }
/// <summary> /// <summary>

28
src/ImageSharp/Memory/ArrayPoolMemoryManager.cs

@ -0,0 +1,28 @@
using System.Buffers;
namespace SixLabors.ImageSharp.Memory
{
/// <summary>
/// Implements <see cref="MemoryManager"/> by allocating memory from <see cref="ArrayPool{T}"/>.
/// </summary>
public class ArrayPoolMemoryManager : MemoryManager
{
/// <inheritdoc />
internal override Buffer<T> Allocate<T>(int size, bool clear = false)
{
var buffer = new Buffer<T>(PixelDataPool<T>.Rent(size), size, this);
if (clear)
{
buffer.Clear();
}
return buffer;
}
/// <inheritdoc />
internal override void Release<T>(Buffer<T> buffer)
{
PixelDataPool<T>.Return(buffer.Array);
}
}
}

19
src/ImageSharp/Memory/Buffer2D{T}.cs

@ -1,20 +1,20 @@
// Copyright (c) Six Labors and contributors. // Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using SixLabors.Primitives; using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Memory namespace SixLabors.ImageSharp.Memory
{ {
using System;
/// <summary> /// <summary>
/// Represents a buffer of value type objects /// Represents a buffer of value type objects
/// interpreted as a 2D region of <see cref="Width"/> x <see cref="Height"/> elements. /// interpreted as a 2D region of <see cref="Width"/> x <see cref="Height"/> elements.
/// </summary> /// </summary>
/// <typeparam name="T">The value type.</typeparam> /// <typeparam name="T">The value type.</typeparam>
internal class Buffer2D<T> : IBuffer2D<T>, IDisposable internal class Buffer2D<T> : IBuffer2D<T>, IDisposable
where T : struct { where T : struct
{
public Buffer2D(Size size) public Buffer2D(Size size)
: this(size.Width, size.Height) : this(size.Width, size.Height)
{ {
@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp.Memory
/// <param name="width">The number of elements in a row</param> /// <param name="width">The number of elements in a row</param>
/// <param name="height">The number of rows</param> /// <param name="height">The number of rows</param>
public Buffer2D(int width, int height) public Buffer2D(int width, int height)
: this(MemoryManager.Current.Allocate<T>(width * height), width, height) : this(MemoryManager.Current.Allocate<T>(width * height), width, height)
{ {
this.Width = width; this.Width = width;
this.Height = height; this.Height = height;
@ -38,7 +38,8 @@ namespace SixLabors.ImageSharp.Memory
/// <param name="array">The array to pin</param> /// <param name="array">The array to pin</param>
/// <param name="width">The number of elements in a row</param> /// <param name="width">The number of elements in a row</param>
/// <param name="height">The number of rows</param> /// <param name="height">The number of rows</param>
public Buffer2D(T[] array, int width, int height) { public Buffer2D(T[] array, int width, int height)
{
this.Buffer = new Buffer<T>(array, width * height); this.Buffer = new Buffer<T>(array, width * height);
this.Width = width; this.Width = width;
this.Height = height; this.Height = height;
@ -50,7 +51,8 @@ namespace SixLabors.ImageSharp.Memory
/// <param name="wrappedBuffer">The buffer to wrap</param> /// <param name="wrappedBuffer">The buffer to wrap</param>
/// <param name="width">The number of elements in a row</param> /// <param name="width">The number of elements in a row</param>
/// <param name="height">The number of rows</param> /// <param name="height">The number of rows</param>
public Buffer2D(Buffer<T> wrappedBuffer, int width, int height) { public Buffer2D(Buffer<T> wrappedBuffer, int width, int height)
{
this.Buffer = wrappedBuffer; this.Buffer = wrappedBuffer;
this.Width = width; this.Width = width;
this.Height = height; this.Height = height;
@ -92,7 +94,7 @@ namespace SixLabors.ImageSharp.Memory
/// <returns>The <see cref="Buffer{T}"/> instance</returns> /// <returns>The <see cref="Buffer{T}"/> instance</returns>
public static Buffer2D<T> CreateClean(int width, int height) public static Buffer2D<T> CreateClean(int width, int height)
{ {
return new Buffer2D<T>(MemoryManager.Current.Allocate<T>(width*height, true), width, height); return new Buffer2D<T>(MemoryManager.Current.Allocate<T>(width * height, true), width, height);
} }
/// <summary> /// <summary>
@ -102,7 +104,8 @@ namespace SixLabors.ImageSharp.Memory
/// <returns>The <see cref="Buffer2D{T}"/> instance</returns> /// <returns>The <see cref="Buffer2D{T}"/> instance</returns>
public static Buffer2D<T> CreateClean(Size size) => CreateClean(size.Width, size.Height); public static Buffer2D<T> CreateClean(Size size) => CreateClean(size.Width, size.Height);
public void Dispose() { public void Dispose()
{
this.Buffer?.Dispose(); this.Buffer?.Dispose();
} }
} }

43
src/ImageSharp/Memory/Buffer{T}.cs

@ -16,6 +16,8 @@ namespace SixLabors.ImageSharp.Memory
internal class Buffer<T> : IBuffer<T> internal class Buffer<T> : IBuffer<T>
where T : struct where T : struct
{ {
private MemoryManager memoryManager;
/// <summary> /// <summary>
/// A pointer to the first element of <see cref="Array"/> when pinned. /// A pointer to the first element of <see cref="Array"/> when pinned.
/// </summary> /// </summary>
@ -26,23 +28,6 @@ namespace SixLabors.ImageSharp.Memory
/// </summary> /// </summary>
private GCHandle handle; private GCHandle handle;
/// <summary>
/// A value indicating wheter <see cref="Array"/> should be returned to <see cref="PixelDataPool{T}"/>
/// when disposing this <see cref="Buffer{T}"/> instance.
/// </summary>
private bool isPoolingOwner;
/// <summary>
/// Initializes a new instance of the <see cref="Buffer{T}"/> class.
/// </summary>
/// <param name="length">The desired count of elements. (Minimum size for <see cref="Array"/>)</param>
public Buffer(int length)
{
this.Length = length;
this.Array = PixelDataPool<T>.Rent(length);
this.isPoolingOwner = true;
}
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Buffer{T}"/> class. /// Initializes a new instance of the <see cref="Buffer{T}"/> class.
/// </summary> /// </summary>
@ -51,7 +36,6 @@ namespace SixLabors.ImageSharp.Memory
{ {
this.Length = array.Length; this.Length = array.Length;
this.Array = array; this.Array = array;
this.isPoolingOwner = false;
} }
/// <summary> /// <summary>
@ -68,7 +52,6 @@ namespace SixLabors.ImageSharp.Memory
this.Length = length; this.Length = length;
this.Array = array; this.Array = array;
this.isPoolingOwner = false;
} }
internal Buffer(T[] array, int length, MemoryManager memoryManager) internal Buffer(T[] array, int length, MemoryManager memoryManager)
@ -140,19 +123,6 @@ namespace SixLabors.ImageSharp.Memory
return new Span<T>(buffer.Array, 0, buffer.Length); return new Span<T>(buffer.Array, 0, buffer.Length);
} }
/// <summary>
/// Creates a clean instance of <see cref="Buffer{T}"/> initializing it's elements with 'default(T)'.
/// </summary>
/// <param name="count">The desired count of elements. (Minimum size for <see cref="Array"/>)</param>
/// <returns>The <see cref="Buffer{T}"/> instance</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Buffer<T> CreateClean(int count)
{
Buffer<T> buffer = new Buffer<T>(count);
buffer.Clear();
return buffer;
}
/// <summary> /// <summary>
/// Gets a <see cref="Span{T}"/> to an offseted position inside the buffer. /// Gets a <see cref="Span{T}"/> to an offseted position inside the buffer.
/// </summary> /// </summary>
@ -190,12 +160,9 @@ namespace SixLabors.ImageSharp.Memory
this.IsDisposedOrLostArrayOwnership = true; this.IsDisposedOrLostArrayOwnership = true;
this.UnPin(); this.UnPin();
if (this.isPoolingOwner) this.memoryManager?.Release(this);
{
PixelDataPool<T>.Return(this.Array);
}
this.isPoolingOwner = false; this.memoryManager = null;
this.Array = null; this.Array = null;
this.Length = 0; this.Length = 0;
@ -220,7 +187,7 @@ namespace SixLabors.ImageSharp.Memory
this.UnPin(); this.UnPin();
T[] array = this.Array; T[] array = this.Array;
this.Array = null; this.Array = null;
this.isPoolingOwner = false; this.memoryManager = null;
return array; return array;
} }

39
src/ImageSharp/Memory/MemoryManager.cs

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SixLabors.ImageSharp.Memory
{
/// <summary>
/// Memory managers are used to allocate memory for image processing operations.
/// </summary>
public abstract class MemoryManager
{
/// <summary>
/// Gets or sets the <see cref="MemoryManager"/> that is currently in use.
/// </summary>
public static MemoryManager Current { get; set; } = new ArrayPoolMemoryManager();
/// <summary>
/// Allocates a <see cref="Buffer{T}"/> of size <paramref name="size"/>, optionally
/// clearing the buffer before it gets returned.
/// </summary>
/// <typeparam name="T">Type of the data stored in the buffer</typeparam>
/// <param name="size">Size of the buffer to allocate</param>
/// <param name="clear">True to clear the backing memory of the buffer</param>
/// <returns>A buffer of values of type <typeparamref name="T"/>.</returns>
internal abstract Buffer<T> Allocate<T>(int size, bool clear = false)
where T : struct;
/// <summary>
/// Releases the memory allocated for <paramref name="buffer"/>. After this, the buffer
/// is no longer usable.
/// </summary>
/// <typeparam name="T">Type of the data stored in the buffer</typeparam>
/// <param name="buffer">The buffer to release</param>
internal abstract void Release<T>(Buffer<T> buffer)
where T : struct;
}
}

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

@ -45,7 +45,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);
@ -84,7 +84,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);
@ -123,7 +123,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);
@ -162,7 +162,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);
@ -201,7 +201,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);
@ -240,7 +240,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);
@ -279,7 +279,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);
@ -318,7 +318,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);
@ -357,7 +357,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);
@ -396,7 +396,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);
@ -435,7 +435,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);
@ -474,7 +474,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);
@ -513,7 +513,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);
@ -552,7 +552,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);
@ -591,7 +591,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);
@ -630,7 +630,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);
@ -669,7 +669,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);
@ -708,7 +708,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);
@ -747,7 +747,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);
@ -786,7 +786,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);
@ -825,7 +825,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);

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

@ -87,7 +87,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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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/Effects/BackgroundColorProcessor.cs

@ -67,8 +67,8 @@ namespace SixLabors.ImageSharp.Processing.Processors
int width = maxX - minX; int width = maxX - minX;
using (var colors = new Buffer<TPixel>(width)) using (var colors = MemoryManager.Current.Allocate<TPixel>(width))
using (var amount = new Buffer<float>(width)) using (var amount = MemoryManager.Current.Allocate<float>(width))
{ {
for (int i = 0; i < width; i++) for (int i = 0; i < width; i++)
{ {

4
src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs

@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.Processing.Processors
} }
int width = maxX - minX; int width = maxX - minX;
using (var rowColors = new Buffer<TPixel>(width)) using (var rowColors = MemoryManager.Current.Allocate<TPixel>(width))
{ {
for (int i = 0; i < width; i++) for (int i = 0; i < width; i++)
{ {
@ -96,7 +96,7 @@ namespace SixLabors.ImageSharp.Processing.Processors
configuration.ParallelOptions, configuration.ParallelOptions,
y => y =>
{ {
using (var amounts = new Buffer<float>(width)) using (var amounts = MemoryManager.Current.Allocate<float>(width))
{ {
int offsetY = y - startY; int offsetY = y - startY;
int offsetX = minX - startX; int offsetX = minX - startX;

4
src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs

@ -104,7 +104,7 @@ namespace SixLabors.ImageSharp.Processing.Processors
} }
int width = maxX - minX; int width = maxX - minX;
using (var rowColors = new Buffer<TPixel>(width)) using (var rowColors = MemoryManager.Current.Allocate<TPixel>(width))
{ {
for (int i = 0; i < width; i++) for (int i = 0; i < width; i++)
{ {
@ -117,7 +117,7 @@ namespace SixLabors.ImageSharp.Processing.Processors
configuration.ParallelOptions, configuration.ParallelOptions,
y => y =>
{ {
using (var amounts = new Buffer<float>(width)) using (var amounts = MemoryManager.Current.Allocate<float>(width))
{ {
int offsetY = y - startY; int offsetY = y - startY;
int offsetX = minX - startX; int offsetX = minX - startX;

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

@ -132,7 +132,7 @@ namespace SixLabors.ImageSharp.Processing.Processors
y => y =>
{ {
// TODO: Without Parallel.For() this buffer object could be reused: // TODO: Without Parallel.For() this buffer object could be reused:
using (var tempRowBuffer = new Buffer<Vector4>(source.Width)) using (var tempRowBuffer = MemoryManager.Current.Allocate<Vector4>(source.Width))
{ {
Span<Vector4> firstPassRow = firstPassPixels.GetRowSpan(y); Span<Vector4> firstPassRow = firstPassPixels.GetRowSpan(y);
Span<TPixel> sourceRow = source.GetPixelRowSpan(y); Span<TPixel> sourceRow = source.GetPixelRowSpan(y);

4
tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs

@ -22,8 +22,8 @@ namespace SixLabors.ImageSharp.Benchmarks.Color.Bulk
[GlobalSetup] [GlobalSetup]
public void Setup() public void Setup()
{ {
this.destination = new Buffer<TPixel>(this.Count); this.destination = MemoryManager.Current.Allocate<TPixel>(this.Count);
this.source = new Buffer<Vector4>(this.Count); this.source = MemoryManager.Current.Allocate<Vector4>(this.Count);
} }
[GlobalCleanup] [GlobalCleanup]

4
tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4ReferenceVsPointer.cs

@ -25,8 +25,8 @@
[GlobalSetup] [GlobalSetup]
public void Setup() public void Setup()
{ {
this.destination = new Buffer<Rgba32>(this.Count); this.destination = MemoryManager.Current.Allocate<Rgba32>(this.Count);
this.source = new Buffer<Vector4>(this.Count * 4); this.source = MemoryManager.Current.Allocate<Vector4>(this.Count * 4);
this.source.Pin(); this.source.Pin();
this.destination.Pin(); this.destination.Pin();
} }

4
tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs

@ -19,8 +19,8 @@ namespace SixLabors.ImageSharp.Benchmarks.Color.Bulk
[GlobalSetup] [GlobalSetup]
public void Setup() public void Setup()
{ {
this.destination = new Buffer<TPixel>(this.Count); this.destination = MemoryManager.Current.Allocate<TPixel>(this.Count);
this.source = new Buffer<byte>(this.Count * 4); this.source = MemoryManager.Current.Allocate<byte>(this.Count * 4);
} }
[GlobalCleanup] [GlobalCleanup]

4
tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs

@ -21,8 +21,8 @@ namespace SixLabors.ImageSharp.Benchmarks.Color.Bulk
[GlobalSetup] [GlobalSetup]
public void Setup() public void Setup()
{ {
this.source = new Buffer<TPixel>(this.Count); this.source = MemoryManager.Current.Allocate<TPixel>(this.Count);
this.destination = new Buffer<Vector4>(this.Count); this.destination = MemoryManager.Current.Allocate<Vector4>(this.Count);
} }
[GlobalCleanup] [GlobalCleanup]

4
tests/ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs

@ -19,8 +19,8 @@ namespace SixLabors.ImageSharp.Benchmarks.Color.Bulk
[GlobalSetup] [GlobalSetup]
public void Setup() public void Setup()
{ {
this.source = new Buffer<TPixel>(this.Count); this.source = MemoryManager.Current.Allocate<TPixel>(this.Count);
this.destination = new Buffer<byte>(this.Count * 3); this.destination = MemoryManager.Current.Allocate<byte>(this.Count * 3);
} }
[GlobalCleanup] [GlobalCleanup]

4
tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs

@ -24,8 +24,8 @@ namespace SixLabors.ImageSharp.Benchmarks.Color.Bulk
[GlobalSetup] [GlobalSetup]
public void Setup() public void Setup()
{ {
this.source = new Buffer<TPixel>(this.Count); this.source = MemoryManager.Current.Allocate<TPixel>(this.Count);
this.destination = new Buffer<byte>(this.Count * 4); this.destination = MemoryManager.Current.Allocate<byte>(this.Count * 4);
} }
[GlobalCleanup] [GlobalCleanup]

2
tests/ImageSharp.Benchmarks/General/ClearBuffer.cs

@ -18,7 +18,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General
[GlobalSetup] [GlobalSetup]
public void Setup() public void Setup()
{ {
this.buffer = new Buffer<Rgba32>(this.Count); this.buffer = MemoryManager.Current.Allocate<Rgba32>(this.Count);
} }
[GlobalCleanup] [GlobalCleanup]

2
tests/ImageSharp.Benchmarks/General/IterateArray.cs

@ -21,7 +21,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General
[GlobalSetup] [GlobalSetup]
public void Setup() public void Setup()
{ {
this.buffer = new Buffer<Vector4>(this.Length); this.buffer = MemoryManager.Current.Allocate<Vector4>(this.Length);
this.buffer.Pin(); this.buffer.Pin();
this.array = new Vector4[this.Length]; this.array = new Vector4[this.Length];
} }

6
tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs

@ -24,7 +24,7 @@ namespace SixLabors.ImageSharp.Benchmarks
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 (Buffer<Vector4> buffer = new Buffer<Vector4>(destination.Length * 3)) using (Buffer<Vector4> buffer = MemoryManager.Current.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);
@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.Benchmarks
{ {
using (Image<Rgba32> image = new Image<Rgba32>(800, 800)) using (Image<Rgba32> image = new Image<Rgba32>(800, 800))
{ {
Buffer<float> amounts = new Buffer<float>(image.Width); Buffer<float> amounts = MemoryManager.Current.Allocate<float>(image.Width);
for (int x = 0; x < image.Width; x++) for (int x = 0; x < image.Width; x++)
{ {
@ -82,7 +82,7 @@ namespace SixLabors.ImageSharp.Benchmarks
{ {
using (Image<Rgba32> image = new Image<Rgba32>(800, 800)) using (Image<Rgba32> image = new Image<Rgba32>(800, 800))
{ {
Buffer<float> amounts = new Buffer<float>(image.Width); Buffer<float> amounts = MemoryManager.Current.Allocate<float>(image.Width);
for (int x = 0; x < image.Width; x++) for (int x = 0; x < image.Width; x++)
{ {

2
tests/ImageSharp.Benchmarks/Samplers/Glow.cs

@ -103,7 +103,7 @@ namespace SixLabors.ImageSharp.Benchmarks
} }
int width = maxX - minX; int width = maxX - minX;
using (Buffer<TPixel> rowColors = new Buffer<TPixel>(width)) using (Buffer<TPixel> rowColors = MemoryManager.Current.Allocate<TPixel>(width))
using (PixelAccessor<TPixel> sourcePixels = source.Lock()) using (PixelAccessor<TPixel> sourcePixels = source.Lock())
{ {
for (int i = 0; i < width; i++) for (int i = 0; i < width; i++)

22
tests/ImageSharp.Tests/Memory/BufferTests.cs

@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
[InlineData(1111)] [InlineData(1111)]
public void ConstructWithOwnArray(int count) public void ConstructWithOwnArray(int count)
{ {
using (Buffer<TestStructs.Foo> buffer = new Buffer<TestStructs.Foo>(count)) using (Buffer<TestStructs.Foo> buffer = MemoryManager.Current.Allocate<TestStructs.Foo>(count))
{ {
Assert.False(buffer.IsDisposedOrLostArrayOwnership); Assert.False(buffer.IsDisposedOrLostArrayOwnership);
Assert.NotNull(buffer.Array); Assert.NotNull(buffer.Array);
@ -76,7 +76,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
{ {
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
{ {
using (Buffer<int> buffer = Buffer<int>.CreateClean(42)) using (Buffer<int> buffer = MemoryManager.Current.Allocate<int>(42, true))
{ {
for (int j = 0; j < buffer.Length; j++) for (int j = 0; j < buffer.Length; j++)
{ {
@ -129,7 +129,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
[Fact] [Fact]
public void Dispose() public void Dispose()
{ {
Buffer<TestStructs.Foo> buffer = new Buffer<TestStructs.Foo>(42); Buffer<TestStructs.Foo> buffer = MemoryManager.Current.Allocate<TestStructs.Foo>(42);
buffer.Dispose(); buffer.Dispose();
Assert.True(buffer.IsDisposedOrLostArrayOwnership); Assert.True(buffer.IsDisposedOrLostArrayOwnership);
@ -140,7 +140,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
[InlineData(123)] [InlineData(123)]
public void CastToSpan(int bufferLength) public void CastToSpan(int bufferLength)
{ {
using (Buffer<TestStructs.Foo> buffer = new Buffer<TestStructs.Foo>(bufferLength)) using (Buffer<TestStructs.Foo> buffer = MemoryManager.Current.Allocate<TestStructs.Foo>(bufferLength))
{ {
Span<TestStructs.Foo> span = buffer; Span<TestStructs.Foo> span = buffer;
@ -154,7 +154,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
[Fact] [Fact]
public void Span() public void Span()
{ {
using (Buffer<TestStructs.Foo> buffer = new Buffer<TestStructs.Foo>(42)) using (Buffer<TestStructs.Foo> buffer = MemoryManager.Current.Allocate<TestStructs.Foo>(42))
{ {
Span<TestStructs.Foo> span = buffer.Span; Span<TestStructs.Foo> span = buffer.Span;
@ -173,7 +173,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
[InlineData(123, 17)] [InlineData(123, 17)]
public void WithStartOnly(int bufferLength, int start) public void WithStartOnly(int bufferLength, int start)
{ {
using (Buffer<TestStructs.Foo> buffer = new Buffer<TestStructs.Foo>(bufferLength)) using (Buffer<TestStructs.Foo> buffer = MemoryManager.Current.Allocate<TestStructs.Foo>(bufferLength))
{ {
Span<TestStructs.Foo> span = buffer.Slice(start); Span<TestStructs.Foo> span = buffer.Slice(start);
@ -187,7 +187,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
[InlineData(123, 17, 42)] [InlineData(123, 17, 42)]
public void WithStartAndLength(int bufferLength, int start, int spanLength) public void WithStartAndLength(int bufferLength, int start, int spanLength)
{ {
using (Buffer<TestStructs.Foo> buffer = new Buffer<TestStructs.Foo>(bufferLength)) using (Buffer<TestStructs.Foo> buffer = MemoryManager.Current.Allocate<TestStructs.Foo>(bufferLength))
{ {
Span<TestStructs.Foo> span = buffer.Slice(start, spanLength); Span<TestStructs.Foo> span = buffer.Slice(start, spanLength);
@ -201,7 +201,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
public void UnPinAndTakeArrayOwnership() public void UnPinAndTakeArrayOwnership()
{ {
TestStructs.Foo[] data = null; TestStructs.Foo[] data = null;
using (Buffer<TestStructs.Foo> buffer = new Buffer<TestStructs.Foo>(42)) using (Buffer<TestStructs.Foo> buffer = MemoryManager.Current.Allocate<TestStructs.Foo>(42))
{ {
data = buffer.TakeArrayOwnership(); data = buffer.TakeArrayOwnership();
Assert.True(buffer.IsDisposedOrLostArrayOwnership); Assert.True(buffer.IsDisposedOrLostArrayOwnership);
@ -216,7 +216,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
[Fact] [Fact]
public void ReturnsPinnedPointerToTheBeginningOfArray() public void ReturnsPinnedPointerToTheBeginningOfArray()
{ {
using (Buffer<TestStructs.Foo> buffer = new Buffer<TestStructs.Foo>(42)) using (Buffer<TestStructs.Foo> buffer = MemoryManager.Current.Allocate<TestStructs.Foo>(42))
{ {
TestStructs.Foo* actual = (TestStructs.Foo*)buffer.Pin(); TestStructs.Foo* actual = (TestStructs.Foo*)buffer.Pin();
fixed (TestStructs.Foo* expected = buffer.Array) fixed (TestStructs.Foo* expected = buffer.Array)
@ -229,7 +229,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
[Fact] [Fact]
public void SecondCallReturnsTheSamePointer() public void SecondCallReturnsTheSamePointer()
{ {
using (Buffer<TestStructs.Foo> buffer = new Buffer<TestStructs.Foo>(42)) using (Buffer<TestStructs.Foo> buffer = MemoryManager.Current.Allocate<TestStructs.Foo>(42))
{ {
IntPtr ptr1 = buffer.Pin(); IntPtr ptr1 = buffer.Pin();
IntPtr ptr2 = buffer.Pin(); IntPtr ptr2 = buffer.Pin();
@ -241,7 +241,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
[Fact] [Fact]
public void WhenCalledOnDisposedBuffer_ThrowsInvalidOperationException() public void WhenCalledOnDisposedBuffer_ThrowsInvalidOperationException()
{ {
Buffer<TestStructs.Foo> buffer = new Buffer<TestStructs.Foo>(42); Buffer<TestStructs.Foo> buffer = MemoryManager.Current.Allocate<TestStructs.Foo>(42);
buffer.Dispose(); buffer.Dispose();
Assert.Throws<InvalidOperationException>(() => buffer.Pin()); Assert.Throws<InvalidOperationException>(() => buffer.Pin());

2
tests/ImageSharp.Tests/Memory/SpanUtilityTests.cs

@ -424,7 +424,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
Rgba32[] colors = { new Rgba32(0, 1, 2, 3), new Rgba32(4, 5, 6, 7), new Rgba32(8, 9, 10, 11), }; Rgba32[] colors = { new Rgba32(0, 1, 2, 3), new Rgba32(4, 5, 6, 7), new Rgba32(8, 9, 10, 11), };
using (Buffer<Rgba32> colorBuf = new Buffer<Rgba32>(colors)) using (Buffer<Rgba32> colorBuf = new Buffer<Rgba32>(colors))
using (Buffer<byte> byteBuf = new Buffer<byte>(colors.Length * 4)) using (Buffer<byte> byteBuf = MemoryManager.Current.Allocate<byte>(colors.Length * 4))
{ {
SpanHelper.Copy(colorBuf.Span.AsBytes(), byteBuf, colorBuf.Length * sizeof(Rgba32)); SpanHelper.Copy(colorBuf.Span.AsBytes(), byteBuf, colorBuf.Length * sizeof(Rgba32));

6
tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs

@ -50,8 +50,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
int times = 200000; int times = 200000;
int count = 1024; int count = 1024;
using (Buffer<ImageSharp.Rgba32> source = new Buffer<ImageSharp.Rgba32>(count)) using (Buffer<ImageSharp.Rgba32> source = MemoryManager.Current.Allocate<ImageSharp.Rgba32>(count))
using (Buffer<Vector4> dest = new Buffer<Vector4>(count)) using (Buffer<Vector4> dest = MemoryManager.Current.Allocate<Vector4>(count))
{ {
this.Measure( this.Measure(
times, times,
@ -344,7 +344,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
{ {
this.SourceBuffer = new Buffer<TSource>(source); this.SourceBuffer = new Buffer<TSource>(source);
this.ExpectedDestBuffer = new Buffer<TDest>(expectedDest); this.ExpectedDestBuffer = new Buffer<TDest>(expectedDest);
this.ActualDestBuffer = new Buffer<TDest>(expectedDest.Length); this.ActualDestBuffer = MemoryManager.Current.Allocate<TDest>(expectedDest.Length);
} }
public void Dispose() public void Dispose()

12
tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs

@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
int length = source.Length; int length = source.Length;
Guard.MustBeSizedAtLeast(dest, length, nameof(dest)); Guard.MustBeSizedAtLeast(dest, length, nameof(dest));
using (var rgbaBuffer = new Buffer<Rgba32>(length)) using (var rgbaBuffer = MemoryManager.Current.Allocate<Rgba32>(length))
{ {
PixelOperations<TPixel>.Instance.ToRgba32(source, rgbaBuffer, length); PixelOperations<TPixel>.Instance.ToRgba32(source, rgbaBuffer, length);
@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
int length = source.Length; int length = source.Length;
Guard.MustBeSizedAtLeast(dest, length, nameof(dest)); Guard.MustBeSizedAtLeast(dest, length, nameof(dest));
using (var rgbaBuffer = new Buffer<Rgba32>(length)) using (var rgbaBuffer = MemoryManager.Current.Allocate<Rgba32>(length))
{ {
PixelOperations<Argb32>.Instance.ToRgba32(source, rgbaBuffer, length); PixelOperations<Argb32>.Instance.ToRgba32(source, rgbaBuffer, length);
@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
int length = source.Length; int length = source.Length;
Guard.MustBeSizedAtLeast(dest, length, nameof(dest)); Guard.MustBeSizedAtLeast(dest, length, nameof(dest));
using (var rgbaBuffer = new Buffer<Rgb24>(length)) using (var rgbaBuffer = MemoryManager.Current.Allocate<Rgb24>(length))
{ {
PixelOperations<Rgb24>.Instance.ToRgb24(source, rgbaBuffer, length); PixelOperations<Rgb24>.Instance.ToRgb24(source, rgbaBuffer, length);
@ -96,7 +96,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
var image = new Image<TPixel>(w, h); var image = new Image<TPixel>(w, h);
using (var workBuffer = new Buffer<Argb32>(w)) using (var workBuffer = MemoryManager.Current.Allocate<Argb32>(w))
{ {
var destPtr = (Argb32*)workBuffer.Pin(); var destPtr = (Argb32*)workBuffer.Pin();
for (int y = 0; y < h; y++) for (int y = 0; y < h; y++)
@ -138,7 +138,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
var image = new Image<TPixel>(w, h); var image = new Image<TPixel>(w, h);
using (var workBuffer = new Buffer<Rgb24>(w)) using (var workBuffer = MemoryManager.Current.Allocate<Rgb24>(w))
{ {
var destPtr = (Rgb24*)workBuffer.Pin(); var destPtr = (Rgb24*)workBuffer.Pin();
for (int y = 0; y < h; y++) for (int y = 0; y < h; y++)
@ -170,7 +170,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
long destRowByteCount = data.Stride; long destRowByteCount = data.Stride;
long sourceRowByteCount = w * sizeof(Argb32); long sourceRowByteCount = w * sizeof(Argb32);
using (var workBuffer = new Buffer<Argb32>(w)) using (var workBuffer = MemoryManager.Current.Allocate<Argb32>(w))
{ {
var sourcePtr = (Argb32*)workBuffer.Pin(); var sourcePtr = (Argb32*)workBuffer.Pin();

Loading…
Cancel
Save