From 607e452e2de800d96eb14e6e4b7e9c0b3acf141e Mon Sep 17 00:00:00 2001 From: Lauri Kotilainen Date: Thu, 11 Jan 2018 18:44:01 +0200 Subject: [PATCH] - Allocate Buffers from memory manager --- .../Brushes/ImageBrush{TPixel}.cs | 4 +- .../Brushes/PatternBrush{TPixel}.cs | 4 +- .../Brushes/Processors/BrushApplicator.cs | 4 +- .../Brushes/RecolorBrush{TPixel}.cs | 4 +- .../Brushes/SolidBrush{TPixel}.cs | 4 +- src/ImageSharp.Drawing/Paths/ShapeRegion.cs | 2 +- .../Processors/DrawImageProcessor.cs | 2 +- .../Processors/FillProcessor.cs | 2 +- .../Processors/FillRegionProcessor.cs | 2 +- src/ImageSharp/Configuration.cs | 1 + src/ImageSharp/Formats/Gif/GifDecoderCore.cs | 6 +-- .../Common/Decoder/JpegImagePostProcessor.cs | 2 +- .../Components/PdfJsFrameComponent.cs | 2 +- .../PdfJsPort/Components/PdfJsHuffmanTable.cs | 12 +++--- .../Components/PdfJsJpegPixelArea.cs | 4 +- .../Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs | 10 ++--- src/ImageSharp/Formats/Png/PngDecoderCore.cs | 14 +++--- src/ImageSharp/Formats/Png/PngEncoderCore.cs | 14 +++--- src/ImageSharp/Image/Image.Decode.cs | 2 +- src/ImageSharp/Image/PixelArea{TPixel}.cs | 2 +- .../Memory/ArrayPoolMemoryManager.cs | 28 ++++++++++++ src/ImageSharp/Memory/Buffer2D{T}.cs | 19 ++++---- src/ImageSharp/Memory/Buffer{T}.cs | 43 +++---------------- src/ImageSharp/Memory/MemoryManager.cs | 39 +++++++++++++++++ .../DefaultPixelBlenders.Generated.cs | 42 +++++++++--------- .../DefaultPixelBlenders.Generated.tt | 2 +- .../Effects/BackgroundColorProcessor.cs | 4 +- .../Processors/Overlays/GlowProcessor.cs | 4 +- .../Processors/Overlays/VignetteProcessor.cs | 4 +- .../Processors/Transforms/ResizeProcessor.cs | 2 +- .../Color/Bulk/PackFromVector4.cs | 4 +- .../Bulk/PackFromVector4ReferenceVsPointer.cs | 4 +- .../Color/Bulk/PackFromXyzw.cs | 4 +- .../Color/Bulk/ToVector4.cs | 4 +- .../ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs | 4 +- .../Color/Bulk/ToXyzw.cs | 4 +- .../General/ClearBuffer.cs | 2 +- .../General/IterateArray.cs | 2 +- .../PixelBlenders/PorterDuffBulkVsPixel.cs | 6 +-- tests/ImageSharp.Benchmarks/Samplers/Glow.cs | 2 +- tests/ImageSharp.Tests/Memory/BufferTests.cs | 22 +++++----- .../Memory/SpanUtilityTests.cs | 2 +- .../PixelFormats/PixelOperationsTests.cs | 6 +-- .../ReferenceCodecs/SystemDrawingBridge.cs | 12 +++--- 44 files changed, 200 insertions(+), 162 deletions(-) create mode 100644 src/ImageSharp/Memory/ArrayPoolMemoryManager.cs create mode 100644 src/ImageSharp/Memory/MemoryManager.cs diff --git a/src/ImageSharp.Drawing/Brushes/ImageBrush{TPixel}.cs b/src/ImageSharp.Drawing/Brushes/ImageBrush{TPixel}.cs index 2d29e23fe..d64225385 100644 --- a/src/ImageSharp.Drawing/Brushes/ImageBrush{TPixel}.cs +++ b/src/ImageSharp.Drawing/Brushes/ImageBrush{TPixel}.cs @@ -122,8 +122,8 @@ namespace SixLabors.ImageSharp.Drawing.Brushes internal override void Apply(Span scanline, int x, int y) { // Create a span for colors - using (var amountBuffer = new Buffer(scanline.Length)) - using (var overlay = new Buffer(scanline.Length)) + using (var amountBuffer = MemoryManager.Current.Allocate(scanline.Length)) + using (var overlay = MemoryManager.Current.Allocate(scanline.Length)) { int sourceY = (y - this.offsetY) % this.yLength; int offsetX = x - this.offsetX; diff --git a/src/ImageSharp.Drawing/Brushes/PatternBrush{TPixel}.cs b/src/ImageSharp.Drawing/Brushes/PatternBrush{TPixel}.cs index 844df0e0e..4b26c4edc 100644 --- a/src/ImageSharp.Drawing/Brushes/PatternBrush{TPixel}.cs +++ b/src/ImageSharp.Drawing/Brushes/PatternBrush{TPixel}.cs @@ -152,8 +152,8 @@ namespace SixLabors.ImageSharp.Drawing.Brushes internal override void Apply(Span scanline, int x, int y) { int patternY = y % this.pattern.Height; - using (var amountBuffer = new Buffer(scanline.Length)) - using (var overlay = new Buffer(scanline.Length)) + using (var amountBuffer = MemoryManager.Current.Allocate(scanline.Length)) + using (var overlay = MemoryManager.Current.Allocate(scanline.Length)) { for (int i = 0; i < scanline.Length; i++) { diff --git a/src/ImageSharp.Drawing/Brushes/Processors/BrushApplicator.cs b/src/ImageSharp.Drawing/Brushes/Processors/BrushApplicator.cs index ca6f7630d..5a50e12fb 100644 --- a/src/ImageSharp.Drawing/Brushes/Processors/BrushApplicator.cs +++ b/src/ImageSharp.Drawing/Brushes/Processors/BrushApplicator.cs @@ -65,8 +65,8 @@ namespace SixLabors.ImageSharp.Drawing.Brushes.Processors /// scanlineBuffer will be > scanlineWidth but provide and offset in case we want to share a larger buffer across runs. internal virtual void Apply(Span scanline, int x, int y) { - using (var amountBuffer = new Buffer(scanline.Length)) - using (var overlay = new Buffer(scanline.Length)) + using (var amountBuffer = MemoryManager.Current.Allocate(scanline.Length)) + using (var overlay = MemoryManager.Current.Allocate(scanline.Length)) { for (int i = 0; i < scanline.Length; i++) { diff --git a/src/ImageSharp.Drawing/Brushes/RecolorBrush{TPixel}.cs b/src/ImageSharp.Drawing/Brushes/RecolorBrush{TPixel}.cs index ba2fca4e4..1c02884f2 100644 --- a/src/ImageSharp.Drawing/Brushes/RecolorBrush{TPixel}.cs +++ b/src/ImageSharp.Drawing/Brushes/RecolorBrush{TPixel}.cs @@ -144,8 +144,8 @@ namespace SixLabors.ImageSharp.Drawing.Brushes /// internal override void Apply(Span scanline, int x, int y) { - using (var amountBuffer = new Buffer(scanline.Length)) - using (var overlay = new Buffer(scanline.Length)) + using (var amountBuffer = MemoryManager.Current.Allocate(scanline.Length)) + using (var overlay = MemoryManager.Current.Allocate(scanline.Length)) { for (int i = 0; i < scanline.Length; i++) { diff --git a/src/ImageSharp.Drawing/Brushes/SolidBrush{TPixel}.cs b/src/ImageSharp.Drawing/Brushes/SolidBrush{TPixel}.cs index 658164339..b935bbe36 100644 --- a/src/ImageSharp.Drawing/Brushes/SolidBrush{TPixel}.cs +++ b/src/ImageSharp.Drawing/Brushes/SolidBrush{TPixel}.cs @@ -61,7 +61,7 @@ namespace SixLabors.ImageSharp.Drawing.Brushes public SolidBrushApplicator(ImageFrame source, TPixel color, GraphicsOptions options) : base(source, options) { - this.Colors = new Buffer(source.Width); + this.Colors = MemoryManager.Current.Allocate(source.Width); for (int i = 0; i < this.Colors.Length; i++) { this.Colors[i] = color; @@ -96,7 +96,7 @@ namespace SixLabors.ImageSharp.Drawing.Brushes { Span destinationRow = this.Target.GetPixelRowSpan(y).Slice(x, scanline.Length); - using (var amountBuffer = new Buffer(scanline.Length)) + using (var amountBuffer = MemoryManager.Current.Allocate(scanline.Length)) { for (int i = 0; i < scanline.Length; i++) { diff --git a/src/ImageSharp.Drawing/Paths/ShapeRegion.cs b/src/ImageSharp.Drawing/Paths/ShapeRegion.cs index a96b03dd0..7851bac50 100644 --- a/src/ImageSharp.Drawing/Paths/ShapeRegion.cs +++ b/src/ImageSharp.Drawing/Paths/ShapeRegion.cs @@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp.Drawing { var start = new PointF(this.Bounds.Left - 1, y); var end = new PointF(this.Bounds.Right + 1, y); - using (var innerBuffer = new Buffer(buffer.Length)) + using (var innerBuffer = MemoryManager.Current.Allocate(buffer.Length)) { PointF[] array = innerBuffer.Array; int count = this.Shape.FindIntersections(start, end, array, 0); diff --git a/src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs b/src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs index 47763c0aa..2d411e0b6 100644 --- a/src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs +++ b/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); int width = maxX - minX; - using (var amount = new Buffer(width)) + using (var amount = MemoryManager.Current.Allocate(width)) { for (int i = 0; i < width; i++) { diff --git a/src/ImageSharp.Drawing/Processors/FillProcessor.cs b/src/ImageSharp.Drawing/Processors/FillProcessor.cs index 679ca6a22..f4763af1e 100644 --- a/src/ImageSharp.Drawing/Processors/FillProcessor.cs +++ b/src/ImageSharp.Drawing/Processors/FillProcessor.cs @@ -66,7 +66,7 @@ namespace SixLabors.ImageSharp.Drawing.Processors int width = maxX - minX; - using (var amount = new Buffer(width)) + using (var amount = MemoryManager.Current.Allocate(width)) using (BrushApplicator applicator = this.brush.CreateApplicator(source, sourceRectangle, this.options)) { for (int i = 0; i < width; i++) diff --git a/src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs b/src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs index b6ef4be21..82ffea08e 100644 --- a/src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs +++ b/src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs @@ -102,7 +102,7 @@ namespace SixLabors.ImageSharp.Drawing.Processors { float[] buffer = arrayPool.Rent(maxIntersections); int scanlineWidth = maxX - minX; - using (var scanline = new Buffer(scanlineWidth)) + using (var scanline = MemoryManager.Current.Allocate(scanlineWidth)) { try { diff --git a/src/ImageSharp/Configuration.cs b/src/ImageSharp/Configuration.cs index 740103533..8ea676d32 100644 --- a/src/ImageSharp/Configuration.cs +++ b/src/ImageSharp/Configuration.cs @@ -12,6 +12,7 @@ using SixLabors.ImageSharp.Formats.Gif; using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.Formats.Png; using SixLabors.ImageSharp.IO; +using SixLabors.ImageSharp.Memory; namespace SixLabors.ImageSharp { diff --git a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs index ae20be7d5..0003dbc82 100644 --- a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs +++ b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs @@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.Formats.Gif if (this.logicalScreenDescriptor.GlobalColorTableFlag) { this.globalColorTableLength = this.logicalScreenDescriptor.GlobalColorTableSize * 3; - this.globalColorTable = Buffer.CreateClean(this.globalColorTableLength); + this.globalColorTable = MemoryManager.Current.Allocate(this.globalColorTableLength, true); // Read the global color table from the stream stream.Read(this.globalColorTable.Array, 0, this.globalColorTableLength); @@ -320,11 +320,11 @@ namespace SixLabors.ImageSharp.Formats.Gif if (imageDescriptor.LocalColorTableFlag) { int length = imageDescriptor.LocalColorTableSize * 3; - localColorTable = Buffer.CreateClean(length); + localColorTable = MemoryManager.Current.Allocate(length, true); this.currentStream.Read(localColorTable.Array, 0, length); } - indices = Buffer.CreateClean(imageDescriptor.Width * imageDescriptor.Height); + indices = MemoryManager.Current.Allocate(imageDescriptor.Width * imageDescriptor.Height, true); this.ReadFrameIndices(imageDescriptor, indices); this.ReadFrameColors(indices, localColorTable ?? this.globalColorTable, imageDescriptor); diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegImagePostProcessor.cs b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegImagePostProcessor.cs index 125ec5272..44deb6722 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegImagePostProcessor.cs +++ b/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.ComponentProcessors = rawJpeg.Components.Select(c => new JpegComponentPostProcessor(this, c)).ToArray(); - this.rgbaBuffer = new Buffer(rawJpeg.ImageSizeInPixels.Width); + this.rgbaBuffer = MemoryManager.Current.Allocate(rawJpeg.ImageSizeInPixels.Width); this.colorConverter = ColorConverters.JpegColorConverter.GetConverter(rawJpeg.ColorSpace); } diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs index f60097dc9..5d51e2ad5 100644 --- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs +++ b/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); // Pooled. Disposed via frame disposal - this.BlockData = Buffer.CreateClean(blocksBufferSize); + this.BlockData = MemoryManager.Current.Allocate(blocksBufferSize, true); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsHuffmanTable.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsHuffmanTable.cs index 9dc831567..38f223dca 100644 --- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsHuffmanTable.cs +++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsHuffmanTable.cs @@ -24,12 +24,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components /// The huffman values public PdfJsHuffmanTable(byte[] lengths, byte[] values) { - this.lookahead = Buffer.CreateClean(256); - this.valOffset = Buffer.CreateClean(18); - this.maxcode = Buffer.CreateClean(18); + this.lookahead = MemoryManager.Current.Allocate(256, true); + this.valOffset = MemoryManager.Current.Allocate(18, true); + this.maxcode = MemoryManager.Current.Allocate(18, true); - using (var huffsize = Buffer.CreateClean(257)) - using (var huffcode = Buffer.CreateClean(257)) + using (var huffsize = MemoryManager.Current.Allocate(257, true)) + using (var huffcode = MemoryManager.Current.Allocate(257, true)) { GenerateSizeTable(lengths, huffsize); GenerateCodeTable(huffsize, huffcode); @@ -37,7 +37,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components GenerateLookaheadTables(lengths, values, this.lookahead); } - this.huffval = Buffer.CreateClean(values.Length); + this.huffval = MemoryManager.Current.Allocate(values.Length, true); Buffer.BlockCopy(values, 0, this.huffval.Array, 0, values.Length); this.MaxCode = this.maxcode.Array; diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsJpegPixelArea.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsJpegPixelArea.cs index 034986c2c..eb1680796 100644 --- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsJpegPixelArea.cs +++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsJpegPixelArea.cs @@ -69,11 +69,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components this.rowStride = width * numberOfComponents; var scale = new Vector2(this.imageWidth / (float)width, this.imageHeight / (float)height); - this.componentData = new Buffer(width * height * numberOfComponents); + this.componentData = MemoryManager.Current.Allocate(width * height * numberOfComponents); Span componentDataSpan = this.componentData; const uint Mask3Lsb = 0xFFFFFFF8; // Used to clear the 3 LSBs - using (var xScaleBlockOffset = new Buffer(width)) + using (var xScaleBlockOffset = MemoryManager.Current.Allocate(width)) { Span xScaleBlockOffsetSpan = xScaleBlockOffset; for (int i = 0; i < numberOfComponents; i++) diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs index 211c24d20..917e3c7e3 100644 --- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs +++ b/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}"); } - using (var huffmanData = Buffer.CreateClean(256)) + using (var huffmanData = MemoryManager.Current.Allocate(256, true)) { for (int i = 2; i < remaining;) { byte huffmanTableSpec = (byte)this.InputStream.ReadByte(); this.InputStream.Read(huffmanData.Array, 0, 16); - using (var codeLengths = Buffer.CreateClean(17)) + using (var codeLengths = MemoryManager.Current.Allocate(17, true)) { int codeLengthSum = 0; @@ -689,7 +689,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort codeLengthSum += codeLengths[j] = huffmanData[j - 1]; } - using (var huffmanValues = Buffer.CreateClean(256)) + using (var huffmanValues = MemoryManager.Current.Allocate(256, true)) { this.InputStream.Read(huffmanValues.Array, 0, codeLengthSum); @@ -784,8 +784,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort { int blocksPerLine = component.BlocksPerLine; int blocksPerColumn = component.BlocksPerColumn; - using (var computationBuffer = Buffer.CreateClean(64)) - using (var multiplicationBuffer = Buffer.CreateClean(64)) + using (var computationBuffer = MemoryManager.Current.Allocate(64, true)) + using (var multiplicationBuffer = MemoryManager.Current.Allocate(64, true)) { Span quantizationTable = this.quantizationTables.Tables.GetRowSpan(frameComponent.QuantizationTableIndex); Span computationBufferSpan = computationBuffer; diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs index 7149b74d8..ebda05a1e 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -375,8 +375,8 @@ namespace SixLabors.ImageSharp.Formats.Png this.bytesPerSample = this.header.BitDepth / 8; } - this.previousScanline = Buffer.CreateClean(this.bytesPerScanline); - this.scanline = Buffer.CreateClean(this.bytesPerScanline); + this.previousScanline = MemoryManager.Current.Allocate(this.bytesPerScanline, true); + this.scanline = MemoryManager.Current.Allocate(this.bytesPerScanline, true); } /// @@ -669,7 +669,7 @@ namespace SixLabors.ImageSharp.Formats.Png if (this.header.BitDepth == 16) { int length = this.header.Width * 3; - using (var compressed = new Buffer(length)) + using (var compressed = MemoryManager.Current.Allocate(length)) { // TODO: Should we use pack from vector here instead? this.From16BitTo8Bit(scanlineBuffer, compressed, length); @@ -686,7 +686,7 @@ namespace SixLabors.ImageSharp.Formats.Png if (this.header.BitDepth == 16) { int length = this.header.Width * 3; - using (var compressed = new Buffer(length)) + using (var compressed = MemoryManager.Current.Allocate(length)) { // TODO: Should we use pack from vector here instead? this.From16BitTo8Bit(scanlineBuffer, compressed, length); @@ -727,7 +727,7 @@ namespace SixLabors.ImageSharp.Formats.Png if (this.header.BitDepth == 16) { int length = this.header.Width * 4; - using (var compressed = new Buffer(length)) + using (var compressed = MemoryManager.Current.Allocate(length)) { // TODO: Should we use pack from vector here instead? this.From16BitTo8Bit(scanlineBuffer, compressed, length); @@ -930,7 +930,7 @@ namespace SixLabors.ImageSharp.Formats.Png if (this.header.BitDepth == 16) { int length = this.header.Width * 3; - using (var compressed = new Buffer(length)) + using (var compressed = MemoryManager.Current.Allocate(length)) { // TODO: Should we use pack from vector here instead? this.From16BitTo8Bit(scanlineBuffer, compressed, length); @@ -998,7 +998,7 @@ namespace SixLabors.ImageSharp.Formats.Png if (this.header.BitDepth == 16) { int length = this.header.Width * 4; - using (var compressed = new Buffer(length)) + using (var compressed = MemoryManager.Current.Allocate(length)) { // TODO: Should we use pack from vector here instead? this.From16BitTo8Bit(scanlineBuffer, compressed, length); diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index 0efd46ec7..9be0f5ee4 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -620,16 +620,16 @@ namespace SixLabors.ImageSharp.Formats.Png this.bytesPerScanline = this.width * this.bytesPerPixel; int resultLength = this.bytesPerScanline + 1; - this.previousScanline = Buffer.CreateClean(this.bytesPerScanline); - this.rawScanline = Buffer.CreateClean(this.bytesPerScanline); - this.result = Buffer.CreateClean(resultLength); + this.previousScanline = MemoryManager.Current.Allocate(this.bytesPerScanline, true); + this.rawScanline = MemoryManager.Current.Allocate(this.bytesPerScanline, true); + this.result = MemoryManager.Current.Allocate(resultLength, true); if (this.pngColorType != PngColorType.Palette) { - this.sub = Buffer.CreateClean(resultLength); - this.up = Buffer.CreateClean(resultLength); - this.average = Buffer.CreateClean(resultLength); - this.paeth = Buffer.CreateClean(resultLength); + this.sub = MemoryManager.Current.Allocate(resultLength, true); + this.up = MemoryManager.Current.Allocate(resultLength, true); + this.average = MemoryManager.Current.Allocate(resultLength, true); + this.paeth = MemoryManager.Current.Allocate(resultLength, true); } byte[] buffer; diff --git a/src/ImageSharp/Image/Image.Decode.cs b/src/ImageSharp/Image/Image.Decode.cs index b4ab712d0..1bce23cfc 100644 --- a/src/ImageSharp/Image/Image.Decode.cs +++ b/src/ImageSharp/Image/Image.Decode.cs @@ -29,7 +29,7 @@ namespace SixLabors.ImageSharp return null; } - using (var buffer = new Buffer(maxHeaderSize)) + using (var buffer = MemoryManager.Current.Allocate(maxHeaderSize)) { long startPosition = stream.Position; stream.Read(buffer.Array, 0, maxHeaderSize); diff --git a/src/ImageSharp/Image/PixelArea{TPixel}.cs b/src/ImageSharp/Image/PixelArea{TPixel}.cs index 1c7256455..e6ae556f7 100644 --- a/src/ImageSharp/Image/PixelArea{TPixel}.cs +++ b/src/ImageSharp/Image/PixelArea{TPixel}.cs @@ -116,7 +116,7 @@ namespace SixLabors.ImageSharp this.RowStride = (width * GetComponentCount(componentOrder)) + padding; this.Length = this.RowStride * height; - this.byteBuffer = Buffer.CreateClean(this.Length); + this.byteBuffer = MemoryManager.Current.Allocate(this.Length, true); } /// diff --git a/src/ImageSharp/Memory/ArrayPoolMemoryManager.cs b/src/ImageSharp/Memory/ArrayPoolMemoryManager.cs new file mode 100644 index 000000000..c4ce7d299 --- /dev/null +++ b/src/ImageSharp/Memory/ArrayPoolMemoryManager.cs @@ -0,0 +1,28 @@ +using System.Buffers; + +namespace SixLabors.ImageSharp.Memory +{ + /// + /// Implements by allocating memory from . + /// + public class ArrayPoolMemoryManager : MemoryManager + { + /// + internal override Buffer Allocate(int size, bool clear = false) + { + var buffer = new Buffer(PixelDataPool.Rent(size), size, this); + if (clear) + { + buffer.Clear(); + } + + return buffer; + } + + /// + internal override void Release(Buffer buffer) + { + PixelDataPool.Return(buffer.Array); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Memory/Buffer2D{T}.cs b/src/ImageSharp/Memory/Buffer2D{T}.cs index 6dd4c93a5..a7de343f9 100644 --- a/src/ImageSharp/Memory/Buffer2D{T}.cs +++ b/src/ImageSharp/Memory/Buffer2D{T}.cs @@ -1,20 +1,20 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; using System.Runtime.CompilerServices; using SixLabors.Primitives; namespace SixLabors.ImageSharp.Memory { - using System; - /// /// Represents a buffer of value type objects /// interpreted as a 2D region of x elements. /// /// The value type. internal class Buffer2D : IBuffer2D, IDisposable - where T : struct { + where T : struct + { public Buffer2D(Size size) : this(size.Width, size.Height) { @@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp.Memory /// The number of elements in a row /// The number of rows public Buffer2D(int width, int height) - : this(MemoryManager.Current.Allocate(width * height), width, height) + : this(MemoryManager.Current.Allocate(width * height), width, height) { this.Width = width; this.Height = height; @@ -38,7 +38,8 @@ namespace SixLabors.ImageSharp.Memory /// The array to pin /// The number of elements in a row /// The number of rows - public Buffer2D(T[] array, int width, int height) { + public Buffer2D(T[] array, int width, int height) + { this.Buffer = new Buffer(array, width * height); this.Width = width; this.Height = height; @@ -50,7 +51,8 @@ namespace SixLabors.ImageSharp.Memory /// The buffer to wrap /// The number of elements in a row /// The number of rows - public Buffer2D(Buffer wrappedBuffer, int width, int height) { + public Buffer2D(Buffer wrappedBuffer, int width, int height) + { this.Buffer = wrappedBuffer; this.Width = width; this.Height = height; @@ -92,7 +94,7 @@ namespace SixLabors.ImageSharp.Memory /// The instance public static Buffer2D CreateClean(int width, int height) { - return new Buffer2D(MemoryManager.Current.Allocate(width*height, true), width, height); + return new Buffer2D(MemoryManager.Current.Allocate(width * height, true), width, height); } /// @@ -102,7 +104,8 @@ namespace SixLabors.ImageSharp.Memory /// The instance public static Buffer2D CreateClean(Size size) => CreateClean(size.Width, size.Height); - public void Dispose() { + public void Dispose() + { this.Buffer?.Dispose(); } } diff --git a/src/ImageSharp/Memory/Buffer{T}.cs b/src/ImageSharp/Memory/Buffer{T}.cs index 186a2212c..16f4e8599 100644 --- a/src/ImageSharp/Memory/Buffer{T}.cs +++ b/src/ImageSharp/Memory/Buffer{T}.cs @@ -16,6 +16,8 @@ namespace SixLabors.ImageSharp.Memory internal class Buffer : IBuffer where T : struct { + private MemoryManager memoryManager; + /// /// A pointer to the first element of when pinned. /// @@ -26,23 +28,6 @@ namespace SixLabors.ImageSharp.Memory /// private GCHandle handle; - /// - /// A value indicating wheter should be returned to - /// when disposing this instance. - /// - private bool isPoolingOwner; - - /// - /// Initializes a new instance of the class. - /// - /// The desired count of elements. (Minimum size for ) - public Buffer(int length) - { - this.Length = length; - this.Array = PixelDataPool.Rent(length); - this.isPoolingOwner = true; - } - /// /// Initializes a new instance of the class. /// @@ -51,7 +36,6 @@ namespace SixLabors.ImageSharp.Memory { this.Length = array.Length; this.Array = array; - this.isPoolingOwner = false; } /// @@ -68,7 +52,6 @@ namespace SixLabors.ImageSharp.Memory this.Length = length; this.Array = array; - this.isPoolingOwner = false; } internal Buffer(T[] array, int length, MemoryManager memoryManager) @@ -140,19 +123,6 @@ namespace SixLabors.ImageSharp.Memory return new Span(buffer.Array, 0, buffer.Length); } - /// - /// Creates a clean instance of initializing it's elements with 'default(T)'. - /// - /// The desired count of elements. (Minimum size for ) - /// The instance - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Buffer CreateClean(int count) - { - Buffer buffer = new Buffer(count); - buffer.Clear(); - return buffer; - } - /// /// Gets a to an offseted position inside the buffer. /// @@ -190,12 +160,9 @@ namespace SixLabors.ImageSharp.Memory this.IsDisposedOrLostArrayOwnership = true; this.UnPin(); - if (this.isPoolingOwner) - { - PixelDataPool.Return(this.Array); - } + this.memoryManager?.Release(this); - this.isPoolingOwner = false; + this.memoryManager = null; this.Array = null; this.Length = 0; @@ -220,7 +187,7 @@ namespace SixLabors.ImageSharp.Memory this.UnPin(); T[] array = this.Array; this.Array = null; - this.isPoolingOwner = false; + this.memoryManager = null; return array; } diff --git a/src/ImageSharp/Memory/MemoryManager.cs b/src/ImageSharp/Memory/MemoryManager.cs new file mode 100644 index 000000000..54b727b60 --- /dev/null +++ b/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 +{ + /// + /// Memory managers are used to allocate memory for image processing operations. + /// + public abstract class MemoryManager + { + /// + /// Gets or sets the that is currently in use. + /// + public static MemoryManager Current { get; set; } = new ArrayPoolMemoryManager(); + + /// + /// Allocates a of size , optionally + /// clearing the buffer before it gets returned. + /// + /// Type of the data stored in the buffer + /// Size of the buffer to allocate + /// True to clear the backing memory of the buffer + /// A buffer of values of type . + internal abstract Buffer Allocate(int size, bool clear = false) + where T : struct; + + /// + /// Releases the memory allocated for . After this, the buffer + /// is no longer usable. + /// + /// Type of the data stored in the buffer + /// The buffer to release + internal abstract void Release(Buffer buffer) + where T : struct; + } +} diff --git a/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs b/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs index 99a20516d..477281673 100644 --- a/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs +++ b/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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span 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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span 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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span 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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span 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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span 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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span 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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span 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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span 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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span 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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span 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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span 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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span 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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span 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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span 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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span 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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span 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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span 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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span 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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span 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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span 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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); diff --git a/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.tt b/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.tt index 9d7d73db9..cb99237c4 100644 --- a/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.tt +++ b/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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); diff --git a/src/ImageSharp/Processing/Processors/Effects/BackgroundColorProcessor.cs b/src/ImageSharp/Processing/Processors/Effects/BackgroundColorProcessor.cs index 72e9b8f55..5f6fd4023 100644 --- a/src/ImageSharp/Processing/Processors/Effects/BackgroundColorProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Effects/BackgroundColorProcessor.cs @@ -67,8 +67,8 @@ namespace SixLabors.ImageSharp.Processing.Processors int width = maxX - minX; - using (var colors = new Buffer(width)) - using (var amount = new Buffer(width)) + using (var colors = MemoryManager.Current.Allocate(width)) + using (var amount = MemoryManager.Current.Allocate(width)) { for (int i = 0; i < width; i++) { diff --git a/src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs b/src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs index b02585d8f..0cee4c0b2 100644 --- a/src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs @@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.Processing.Processors } int width = maxX - minX; - using (var rowColors = new Buffer(width)) + using (var rowColors = MemoryManager.Current.Allocate(width)) { for (int i = 0; i < width; i++) { @@ -96,7 +96,7 @@ namespace SixLabors.ImageSharp.Processing.Processors configuration.ParallelOptions, y => { - using (var amounts = new Buffer(width)) + using (var amounts = MemoryManager.Current.Allocate(width)) { int offsetY = y - startY; int offsetX = minX - startX; diff --git a/src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs b/src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs index 7b592a6a4..60915e6db 100644 --- a/src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs @@ -104,7 +104,7 @@ namespace SixLabors.ImageSharp.Processing.Processors } int width = maxX - minX; - using (var rowColors = new Buffer(width)) + using (var rowColors = MemoryManager.Current.Allocate(width)) { for (int i = 0; i < width; i++) { @@ -117,7 +117,7 @@ namespace SixLabors.ImageSharp.Processing.Processors configuration.ParallelOptions, y => { - using (var amounts = new Buffer(width)) + using (var amounts = MemoryManager.Current.Allocate(width)) { int offsetY = y - startY; int offsetX = minX - startX; diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs index bb0845776..6dcffbbc0 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs @@ -132,7 +132,7 @@ namespace SixLabors.ImageSharp.Processing.Processors y => { // TODO: Without Parallel.For() this buffer object could be reused: - using (var tempRowBuffer = new Buffer(source.Width)) + using (var tempRowBuffer = MemoryManager.Current.Allocate(source.Width)) { Span firstPassRow = firstPassPixels.GetRowSpan(y); Span sourceRow = source.GetPixelRowSpan(y); diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs index 83c2a2ee8..e00b94a2e 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4.cs @@ -22,8 +22,8 @@ namespace SixLabors.ImageSharp.Benchmarks.Color.Bulk [GlobalSetup] public void Setup() { - this.destination = new Buffer(this.Count); - this.source = new Buffer(this.Count); + this.destination = MemoryManager.Current.Allocate(this.Count); + this.source = MemoryManager.Current.Allocate(this.Count); } [GlobalCleanup] diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4ReferenceVsPointer.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4ReferenceVsPointer.cs index b4f6ea9c0..593291ded 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4ReferenceVsPointer.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromVector4ReferenceVsPointer.cs @@ -25,8 +25,8 @@ [GlobalSetup] public void Setup() { - this.destination = new Buffer(this.Count); - this.source = new Buffer(this.Count * 4); + this.destination = MemoryManager.Current.Allocate(this.Count); + this.source = MemoryManager.Current.Allocate(this.Count * 4); this.source.Pin(); this.destination.Pin(); } diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs index 5c3648c2d..d273124b8 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs @@ -19,8 +19,8 @@ namespace SixLabors.ImageSharp.Benchmarks.Color.Bulk [GlobalSetup] public void Setup() { - this.destination = new Buffer(this.Count); - this.source = new Buffer(this.Count * 4); + this.destination = MemoryManager.Current.Allocate(this.Count); + this.source = MemoryManager.Current.Allocate(this.Count * 4); } [GlobalCleanup] diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs index 2bf4e0da6..7e29dfe3a 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4.cs @@ -21,8 +21,8 @@ namespace SixLabors.ImageSharp.Benchmarks.Color.Bulk [GlobalSetup] public void Setup() { - this.source = new Buffer(this.Count); - this.destination = new Buffer(this.Count); + this.source = MemoryManager.Current.Allocate(this.Count); + this.destination = MemoryManager.Current.Allocate(this.Count); } [GlobalCleanup] diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs index 2d624c19f..adc374c1f 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyz.cs @@ -19,8 +19,8 @@ namespace SixLabors.ImageSharp.Benchmarks.Color.Bulk [GlobalSetup] public void Setup() { - this.source = new Buffer(this.Count); - this.destination = new Buffer(this.Count * 3); + this.source = MemoryManager.Current.Allocate(this.Count); + this.destination = MemoryManager.Current.Allocate(this.Count * 3); } [GlobalCleanup] diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs index 150b55aed..bead1384b 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToXyzw.cs @@ -24,8 +24,8 @@ namespace SixLabors.ImageSharp.Benchmarks.Color.Bulk [GlobalSetup] public void Setup() { - this.source = new Buffer(this.Count); - this.destination = new Buffer(this.Count * 4); + this.source = MemoryManager.Current.Allocate(this.Count); + this.destination = MemoryManager.Current.Allocate(this.Count * 4); } [GlobalCleanup] diff --git a/tests/ImageSharp.Benchmarks/General/ClearBuffer.cs b/tests/ImageSharp.Benchmarks/General/ClearBuffer.cs index 0ac1413be..47c812554 100644 --- a/tests/ImageSharp.Benchmarks/General/ClearBuffer.cs +++ b/tests/ImageSharp.Benchmarks/General/ClearBuffer.cs @@ -18,7 +18,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General [GlobalSetup] public void Setup() { - this.buffer = new Buffer(this.Count); + this.buffer = MemoryManager.Current.Allocate(this.Count); } [GlobalCleanup] diff --git a/tests/ImageSharp.Benchmarks/General/IterateArray.cs b/tests/ImageSharp.Benchmarks/General/IterateArray.cs index 48ee266fe..383e7080c 100644 --- a/tests/ImageSharp.Benchmarks/General/IterateArray.cs +++ b/tests/ImageSharp.Benchmarks/General/IterateArray.cs @@ -21,7 +21,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General [GlobalSetup] public void Setup() { - this.buffer = new Buffer(this.Length); + this.buffer = MemoryManager.Current.Allocate(this.Length); this.buffer.Pin(); this.array = new Vector4[this.Length]; } diff --git a/tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs b/tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs index 5a3131f79..ef44d1e78 100644 --- a/tests/ImageSharp.Benchmarks/PixelBlenders/PorterDuffBulkVsPixel.cs +++ b/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(amount.Length, destination.Length, nameof(amount.Length)); - using (Buffer buffer = new Buffer(destination.Length * 3)) + using (Buffer buffer = MemoryManager.Current.Allocate(destination.Length * 3)) { Span destinationSpan = buffer.Slice(0, destination.Length); Span backgroundSpan = buffer.Slice(destination.Length, destination.Length); @@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.Benchmarks { using (Image image = new Image(800, 800)) { - Buffer amounts = new Buffer(image.Width); + Buffer amounts = MemoryManager.Current.Allocate(image.Width); for (int x = 0; x < image.Width; x++) { @@ -82,7 +82,7 @@ namespace SixLabors.ImageSharp.Benchmarks { using (Image image = new Image(800, 800)) { - Buffer amounts = new Buffer(image.Width); + Buffer amounts = MemoryManager.Current.Allocate(image.Width); for (int x = 0; x < image.Width; x++) { diff --git a/tests/ImageSharp.Benchmarks/Samplers/Glow.cs b/tests/ImageSharp.Benchmarks/Samplers/Glow.cs index 1f88c4fbf..0494db9b9 100644 --- a/tests/ImageSharp.Benchmarks/Samplers/Glow.cs +++ b/tests/ImageSharp.Benchmarks/Samplers/Glow.cs @@ -103,7 +103,7 @@ namespace SixLabors.ImageSharp.Benchmarks } int width = maxX - minX; - using (Buffer rowColors = new Buffer(width)) + using (Buffer rowColors = MemoryManager.Current.Allocate(width)) using (PixelAccessor sourcePixels = source.Lock()) { for (int i = 0; i < width; i++) diff --git a/tests/ImageSharp.Tests/Memory/BufferTests.cs b/tests/ImageSharp.Tests/Memory/BufferTests.cs index e1efeb24e..8669f2bb0 100644 --- a/tests/ImageSharp.Tests/Memory/BufferTests.cs +++ b/tests/ImageSharp.Tests/Memory/BufferTests.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Tests.Memory [InlineData(1111)] public void ConstructWithOwnArray(int count) { - using (Buffer buffer = new Buffer(count)) + using (Buffer buffer = MemoryManager.Current.Allocate(count)) { Assert.False(buffer.IsDisposedOrLostArrayOwnership); Assert.NotNull(buffer.Array); @@ -76,7 +76,7 @@ namespace SixLabors.ImageSharp.Tests.Memory { for (int i = 0; i < 100; i++) { - using (Buffer buffer = Buffer.CreateClean(42)) + using (Buffer buffer = MemoryManager.Current.Allocate(42, true)) { for (int j = 0; j < buffer.Length; j++) { @@ -129,7 +129,7 @@ namespace SixLabors.ImageSharp.Tests.Memory [Fact] public void Dispose() { - Buffer buffer = new Buffer(42); + Buffer buffer = MemoryManager.Current.Allocate(42); buffer.Dispose(); Assert.True(buffer.IsDisposedOrLostArrayOwnership); @@ -140,7 +140,7 @@ namespace SixLabors.ImageSharp.Tests.Memory [InlineData(123)] public void CastToSpan(int bufferLength) { - using (Buffer buffer = new Buffer(bufferLength)) + using (Buffer buffer = MemoryManager.Current.Allocate(bufferLength)) { Span span = buffer; @@ -154,7 +154,7 @@ namespace SixLabors.ImageSharp.Tests.Memory [Fact] public void Span() { - using (Buffer buffer = new Buffer(42)) + using (Buffer buffer = MemoryManager.Current.Allocate(42)) { Span span = buffer.Span; @@ -173,7 +173,7 @@ namespace SixLabors.ImageSharp.Tests.Memory [InlineData(123, 17)] public void WithStartOnly(int bufferLength, int start) { - using (Buffer buffer = new Buffer(bufferLength)) + using (Buffer buffer = MemoryManager.Current.Allocate(bufferLength)) { Span span = buffer.Slice(start); @@ -187,7 +187,7 @@ namespace SixLabors.ImageSharp.Tests.Memory [InlineData(123, 17, 42)] public void WithStartAndLength(int bufferLength, int start, int spanLength) { - using (Buffer buffer = new Buffer(bufferLength)) + using (Buffer buffer = MemoryManager.Current.Allocate(bufferLength)) { Span span = buffer.Slice(start, spanLength); @@ -201,7 +201,7 @@ namespace SixLabors.ImageSharp.Tests.Memory public void UnPinAndTakeArrayOwnership() { TestStructs.Foo[] data = null; - using (Buffer buffer = new Buffer(42)) + using (Buffer buffer = MemoryManager.Current.Allocate(42)) { data = buffer.TakeArrayOwnership(); Assert.True(buffer.IsDisposedOrLostArrayOwnership); @@ -216,7 +216,7 @@ namespace SixLabors.ImageSharp.Tests.Memory [Fact] public void ReturnsPinnedPointerToTheBeginningOfArray() { - using (Buffer buffer = new Buffer(42)) + using (Buffer buffer = MemoryManager.Current.Allocate(42)) { TestStructs.Foo* actual = (TestStructs.Foo*)buffer.Pin(); fixed (TestStructs.Foo* expected = buffer.Array) @@ -229,7 +229,7 @@ namespace SixLabors.ImageSharp.Tests.Memory [Fact] public void SecondCallReturnsTheSamePointer() { - using (Buffer buffer = new Buffer(42)) + using (Buffer buffer = MemoryManager.Current.Allocate(42)) { IntPtr ptr1 = buffer.Pin(); IntPtr ptr2 = buffer.Pin(); @@ -241,7 +241,7 @@ namespace SixLabors.ImageSharp.Tests.Memory [Fact] public void WhenCalledOnDisposedBuffer_ThrowsInvalidOperationException() { - Buffer buffer = new Buffer(42); + Buffer buffer = MemoryManager.Current.Allocate(42); buffer.Dispose(); Assert.Throws(() => buffer.Pin()); diff --git a/tests/ImageSharp.Tests/Memory/SpanUtilityTests.cs b/tests/ImageSharp.Tests/Memory/SpanUtilityTests.cs index 395c32546..8b90295ce 100644 --- a/tests/ImageSharp.Tests/Memory/SpanUtilityTests.cs +++ b/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), }; using (Buffer colorBuf = new Buffer(colors)) - using (Buffer byteBuf = new Buffer(colors.Length * 4)) + using (Buffer byteBuf = MemoryManager.Current.Allocate(colors.Length * 4)) { SpanHelper.Copy(colorBuf.Span.AsBytes(), byteBuf, colorBuf.Length * sizeof(Rgba32)); diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs index 0fde67d28..c7227eb8a 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs @@ -50,8 +50,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats int times = 200000; int count = 1024; - using (Buffer source = new Buffer(count)) - using (Buffer dest = new Buffer(count)) + using (Buffer source = MemoryManager.Current.Allocate(count)) + using (Buffer dest = MemoryManager.Current.Allocate(count)) { this.Measure( times, @@ -344,7 +344,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats { this.SourceBuffer = new Buffer(source); this.ExpectedDestBuffer = new Buffer(expectedDest); - this.ActualDestBuffer = new Buffer(expectedDest.Length); + this.ActualDestBuffer = MemoryManager.Current.Allocate(expectedDest.Length); } public void Dispose() diff --git a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs index a201b39bd..babe148c8 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs @@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs int length = source.Length; Guard.MustBeSizedAtLeast(dest, length, nameof(dest)); - using (var rgbaBuffer = new Buffer(length)) + using (var rgbaBuffer = MemoryManager.Current.Allocate(length)) { PixelOperations.Instance.ToRgba32(source, rgbaBuffer, length); @@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs int length = source.Length; Guard.MustBeSizedAtLeast(dest, length, nameof(dest)); - using (var rgbaBuffer = new Buffer(length)) + using (var rgbaBuffer = MemoryManager.Current.Allocate(length)) { PixelOperations.Instance.ToRgba32(source, rgbaBuffer, length); @@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs int length = source.Length; Guard.MustBeSizedAtLeast(dest, length, nameof(dest)); - using (var rgbaBuffer = new Buffer(length)) + using (var rgbaBuffer = MemoryManager.Current.Allocate(length)) { PixelOperations.Instance.ToRgb24(source, rgbaBuffer, length); @@ -96,7 +96,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs var image = new Image(w, h); - using (var workBuffer = new Buffer(w)) + using (var workBuffer = MemoryManager.Current.Allocate(w)) { var destPtr = (Argb32*)workBuffer.Pin(); for (int y = 0; y < h; y++) @@ -138,7 +138,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs var image = new Image(w, h); - using (var workBuffer = new Buffer(w)) + using (var workBuffer = MemoryManager.Current.Allocate(w)) { var destPtr = (Rgb24*)workBuffer.Pin(); for (int y = 0; y < h; y++) @@ -170,7 +170,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs long destRowByteCount = data.Stride; long sourceRowByteCount = w * sizeof(Argb32); - using (var workBuffer = new Buffer(w)) + using (var workBuffer = MemoryManager.Current.Allocate(w)) { var sourcePtr = (Argb32*)workBuffer.Pin();