From f1cb97270e57a242e8f51ac292575b38fa193d50 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Tue, 24 Jul 2018 00:39:47 +0200 Subject: [PATCH] renamed BufferManager to MemorySource + enable consuming external IMemoryOwner --- .../Advanced/AdvancedImageExtensions.cs | 2 +- src/ImageSharp/Image.WrapMemory.cs | 5 +- src/ImageSharp/ImageFrameCollection.cs | 4 +- src/ImageSharp/ImageFrame{TPixel}.cs | 8 +-- src/ImageSharp/Image{TPixel}.cs | 15 +--- src/ImageSharp/Memory/Buffer2DExtensions.cs | 4 +- src/ImageSharp/Memory/Buffer2D{T}.cs | 28 +++----- .../Memory/MemoryAllocatorExtensions.cs | 3 +- .../{BufferManager.cs => MemorySource.cs} | 34 ++++++--- .../Processors/Transforms/ResizeProcessor.cs | 2 +- .../Processors/Transforms/WeightsWindow.cs | 4 +- .../Formats/Jpg/JpegColorConverterTests.cs | 3 +- .../Formats/Jpg/SpectralJpegTests.cs | 2 +- .../ImageSharp.Tests/Memory/Buffer2DTests.cs | 14 ++-- ...erManagerTests.cs => MemorySourceTests.cs} | 69 ++++++++++--------- 15 files changed, 101 insertions(+), 96 deletions(-) rename src/ImageSharp/Memory/{BufferManager.cs => MemorySource.cs} (57%) rename tests/ImageSharp.Tests/Memory/{BufferManagerTests.cs => MemorySourceTests.cs} (60%) diff --git a/src/ImageSharp/Advanced/AdvancedImageExtensions.cs b/src/ImageSharp/Advanced/AdvancedImageExtensions.cs index 18b1d994b3..1c73b5ed16 100644 --- a/src/ImageSharp/Advanced/AdvancedImageExtensions.cs +++ b/src/ImageSharp/Advanced/AdvancedImageExtensions.cs @@ -105,7 +105,7 @@ namespace SixLabors.ImageSharp.Advanced internal static Memory GetPixelMemory(this ImageFrame source) where TPixel : struct, IPixel { - return source.PixelBuffer.Buffer.Memory; + return source.PixelBuffer.MemorySource.Memory; } /// diff --git a/src/ImageSharp/Image.WrapMemory.cs b/src/ImageSharp/Image.WrapMemory.cs index 7f0c4ae2ee..c24a932e12 100644 --- a/src/ImageSharp/Image.WrapMemory.cs +++ b/src/ImageSharp/Image.WrapMemory.cs @@ -13,8 +13,6 @@ namespace SixLabors.ImageSharp /// public static partial class Image { - // TODO: This is a WIP API, should be public when finished. - /// /// Wraps an existing contigous memory area of 'width'x'height' pixels, /// allowing to view/manipulate it as an ImageSharp instance. @@ -34,7 +32,8 @@ namespace SixLabors.ImageSharp ImageMetaData metaData) where TPixel : struct, IPixel { - return new Image(config, pixelMemory, width, height, metaData); + var memorySource = new MemorySource(pixelMemory); + return new Image(config, memorySource, width, height, metaData); } /// diff --git a/src/ImageSharp/ImageFrameCollection.cs b/src/ImageSharp/ImageFrameCollection.cs index 3c1062df30..154ef5014b 100644 --- a/src/ImageSharp/ImageFrameCollection.cs +++ b/src/ImageSharp/ImageFrameCollection.cs @@ -30,14 +30,14 @@ namespace SixLabors.ImageSharp this.frames.Add(new ImageFrame(parent.GetConfiguration(), width, height, backgroundColor)); } - internal ImageFrameCollection(Image parent, int width, int height, Memory consumedMemory) + internal ImageFrameCollection(Image parent, int width, int height, MemorySource memorySource) { Guard.NotNull(parent, nameof(parent)); this.parent = parent; // Frames are already cloned within the caller - this.frames.Add(new ImageFrame(parent.GetConfiguration(), width, height, consumedMemory)); + this.frames.Add(new ImageFrame(parent.GetConfiguration(), width, height, memorySource)); } internal ImageFrameCollection(Image parent, IEnumerable> frames) diff --git a/src/ImageSharp/ImageFrame{TPixel}.cs b/src/ImageSharp/ImageFrame{TPixel}.cs index 370b3763c9..6c04d5aead 100644 --- a/src/ImageSharp/ImageFrame{TPixel}.cs +++ b/src/ImageSharp/ImageFrame{TPixel}.cs @@ -95,8 +95,8 @@ namespace SixLabors.ImageSharp /// /// Initializes a new instance of the class wrapping an existing buffer. /// - internal ImageFrame(Configuration configuration, int width, int height, Memory consumedMemory) - : this(configuration, width, height, consumedMemory, new ImageFrameMetaData()) + internal ImageFrame(Configuration configuration, int width, int height, MemorySource memorySource) + : this(configuration, width, height, memorySource, new ImageFrameMetaData()) { } @@ -107,7 +107,7 @@ namespace SixLabors.ImageSharp Configuration configuration, int width, int height, - Memory consumedMemory, + MemorySource memorySource, ImageFrameMetaData metaData) { Guard.NotNull(configuration, nameof(configuration)); @@ -117,7 +117,7 @@ namespace SixLabors.ImageSharp this.configuration = configuration; this.MemoryAllocator = configuration.MemoryAllocator; - this.PixelBuffer = new Buffer2D(consumedMemory, width, height); + this.PixelBuffer = new Buffer2D(memorySource, width, height); this.MetaData = metaData; } diff --git a/src/ImageSharp/Image{TPixel}.cs b/src/ImageSharp/Image{TPixel}.cs index 316c381c41..5a5928d6b5 100644 --- a/src/ImageSharp/Image{TPixel}.cs +++ b/src/ImageSharp/Image{TPixel}.cs @@ -84,23 +84,14 @@ namespace SixLabors.ImageSharp /// /// Initializes a new instance of the class - /// consuming an external buffer instance. + /// wrapping an external /// - internal Image(Configuration configuration, Memory consumedMemory, int width, int height) - : this(configuration, consumedMemory, width, height, new ImageMetaData()) - { - } - - /// - /// Initializes a new instance of the class - /// consuming an external buffer instance. - /// - internal Image(Configuration configuration, Memory consumedMemory, int width, int height, ImageMetaData metadata) + internal Image(Configuration configuration, MemorySource memorySource, int width, int height, ImageMetaData metadata) { this.configuration = configuration; this.PixelType = new PixelTypeInfo(Unsafe.SizeOf() * 8); this.MetaData = metadata; - this.frames = new ImageFrameCollection(this, width, height, consumedMemory); + this.frames = new ImageFrameCollection(this, width, height, memorySource); } /// diff --git a/src/ImageSharp/Memory/Buffer2DExtensions.cs b/src/ImageSharp/Memory/Buffer2DExtensions.cs index c277525703..be4f0ef153 100644 --- a/src/ImageSharp/Memory/Buffer2DExtensions.cs +++ b/src/ImageSharp/Memory/Buffer2DExtensions.cs @@ -18,7 +18,7 @@ namespace SixLabors.Memory internal static Span GetSpan(this Buffer2D buffer) where T : struct { - return buffer.Buffer.GetSpan(); + return buffer.MemorySource.GetSpan(); } /// @@ -61,7 +61,7 @@ namespace SixLabors.Memory public static Memory GetRowMemory(this Buffer2D buffer, int y) where T : struct { - return buffer.Buffer.Memory.Slice(y * buffer.Width, buffer.Width); + return buffer.MemorySource.Memory.Slice(y * buffer.Width, buffer.Width); } /// diff --git a/src/ImageSharp/Memory/Buffer2D{T}.cs b/src/ImageSharp/Memory/Buffer2D{T}.cs index 7d331b46d2..844ca1ad10 100644 --- a/src/ImageSharp/Memory/Buffer2D{T}.cs +++ b/src/ImageSharp/Memory/Buffer2D{T}.cs @@ -16,31 +16,21 @@ namespace SixLabors.Memory internal sealed class Buffer2D : IDisposable where T : struct { - private BufferManager buffer; + private MemorySource memorySource; /// /// Initializes a new instance of the class. /// - /// The buffer to wrap + /// The buffer to wrap /// The number of elements in a row /// The number of rows - public Buffer2D(BufferManager wrappedBuffer, int width, int height) + public Buffer2D(MemorySource memorySource, int width, int height) { - this.buffer = wrappedBuffer; + this.memorySource = memorySource; this.Width = width; this.Height = height; } - public Buffer2D(IMemoryOwner ownedMemory, int width, int height) - : this(new BufferManager(ownedMemory), width, height) - { - } - - public Buffer2D(Memory observedMemory, int width, int height) - : this(new BufferManager(observedMemory), width, height) - { - } - /// /// Gets the width. /// @@ -52,11 +42,11 @@ namespace SixLabors.Memory public int Height { get; private set; } /// - /// Gets the backing + /// Gets the backing /// - public BufferManager Buffer => this.buffer; + public MemorySource MemorySource => this.memorySource; - public Memory Memory => this.Buffer.Memory; + public Memory Memory => this.MemorySource.Memory; public Span Span => this.Memory.Span; @@ -83,7 +73,7 @@ namespace SixLabors.Memory /// public void Dispose() { - this.Buffer.Dispose(); + this.MemorySource.Dispose(); } /// @@ -92,7 +82,7 @@ namespace SixLabors.Memory /// public static void SwapOrCopyContent(Buffer2D destination, Buffer2D source) { - BufferManager.SwapOrCopyContent(ref destination.buffer, ref source.buffer); + MemorySource.SwapOrCopyContent(ref destination.memorySource, ref source.memorySource); SwapDimensionData(destination, source); } diff --git a/src/ImageSharp/Memory/MemoryAllocatorExtensions.cs b/src/ImageSharp/Memory/MemoryAllocatorExtensions.cs index 327bc8bbfc..d8c1f51f4f 100644 --- a/src/ImageSharp/Memory/MemoryAllocatorExtensions.cs +++ b/src/ImageSharp/Memory/MemoryAllocatorExtensions.cs @@ -17,8 +17,9 @@ namespace SixLabors.Memory where T : struct { IMemoryOwner buffer = memoryAllocator.Allocate(width * height, options); + var memorySource = new MemorySource(buffer, true); - return new Buffer2D(buffer, width, height); + return new Buffer2D(memorySource, width, height); } public static Buffer2D Allocate2D( diff --git a/src/ImageSharp/Memory/BufferManager.cs b/src/ImageSharp/Memory/MemorySource.cs similarity index 57% rename from src/ImageSharp/Memory/BufferManager.cs rename to src/ImageSharp/Memory/MemorySource.cs index 1a53890d40..27bca11c16 100644 --- a/src/ImageSharp/Memory/BufferManager.cs +++ b/src/ImageSharp/Memory/MemorySource.cs @@ -9,32 +9,50 @@ namespace SixLabors.Memory /// /// Holds a that is either OWNED or CONSUMED. /// Implements content transfer logic in that depends on the ownership status. - /// This is needed to transfer the contents of a temporary to a persistent + /// This is needed to transfer the contents of a temporary + /// to a persistent without copying the buffer. /// /// /// For a deeper understanding of the owner/consumer model, check out the following docs:
/// https://gist.github.com/GrabYourPitchforks/4c3e1935fd4d9fa2831dbfcab35dffc6 /// https://www.codemag.com/Article/1807051/Introducing-.NET-Core-2.1-Flagship-Types-Span-T-and-Memory-T ///
- internal struct BufferManager : IDisposable + internal struct MemorySource : IDisposable { - public BufferManager(IMemoryOwner memoryOwner) + /// + /// Initializes a new instance of the struct + /// by wrapping an existing . + /// + /// The to wrap + /// + /// A value indicating whether is an internal memory source managed by ImageSharp. + /// Eg. allocated by a . + /// + public MemorySource(IMemoryOwner memoryOwner, bool isInternalMemorySource) { this.MemoryOwner = memoryOwner; this.Memory = memoryOwner.Memory; + this.HasSwappableContents = isInternalMemorySource; } - public BufferManager(Memory memory) + public MemorySource(Memory memory) { this.Memory = memory; this.MemoryOwner = null; + this.HasSwappableContents = false; } public IMemoryOwner MemoryOwner { get; private set; } public Memory Memory { get; private set; } - public bool OwnsMemory => this.MemoryOwner != null; + /// + /// Gets a value indicating whether we are allowed to swap the contents of this buffer + /// with an other instance. + /// The value is true only and only if is present, + /// and it's coming from an internal source managed by ImageSharp (). + /// + public bool HasSwappableContents { get; } public Span GetSpan() => this.Memory.Span; @@ -44,9 +62,9 @@ namespace SixLabors.Memory /// Swaps the contents of 'destination' with 'source' if the buffers are owned (1), /// copies the contents of 'source' to 'destination' otherwise (2). Buffers should be of same size in case 2! ///
- public static void SwapOrCopyContent(ref BufferManager destination, ref BufferManager source) + public static void SwapOrCopyContent(ref MemorySource destination, ref MemorySource source) { - if (source.OwnsMemory && destination.OwnsMemory) + if (source.HasSwappableContents && destination.HasSwappableContents) { SwapContents(ref destination, ref source); } @@ -67,7 +85,7 @@ namespace SixLabors.Memory this.MemoryOwner?.Dispose(); } - private static void SwapContents(ref BufferManager a, ref BufferManager b) + private static void SwapContents(ref MemorySource a, ref MemorySource b) { IMemoryOwner tempOwner = a.MemoryOwner; Memory tempMemory = a.Memory; diff --git a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs index 7f18faec39..9c09b6a226 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ResizeProcessor.cs @@ -297,7 +297,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms // TODO: Using a transposed variant of 'firstPassPixels' could eliminate the need for the WeightsWindow.ComputeWeightedColumnSum() method, and improve speed! using (Buffer2D firstPassPixels = source.MemoryAllocator.Allocate2D(width, source.Height)) { - firstPassPixels.Buffer.Clear(); + firstPassPixels.MemorySource.Clear(); ParallelFor.WithTemporaryBuffer( 0, diff --git a/src/ImageSharp/Processing/Processors/Transforms/WeightsWindow.cs b/src/ImageSharp/Processing/Processors/Transforms/WeightsWindow.cs index 19909aaba2..6a2b6fbd14 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/WeightsWindow.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/WeightsWindow.cs @@ -33,7 +33,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// /// The buffer containing the weights values. /// - private readonly BufferManager buffer; + private readonly MemorySource buffer; /// /// Initializes a new instance of the struct. @@ -47,7 +47,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms { this.flatStartIndex = (index * buffer.Width) + left; this.Left = left; - this.buffer = buffer.Buffer; + this.buffer = buffer.MemorySource; this.Length = length; } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs index aed650b8e9..8048dd424e 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs @@ -290,7 +290,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } // no need to dispose when buffer is not array owner - buffers[i] = new Buffer2D(new BasicArrayBuffer(values), values.Length, 1); + var source = new MemorySource(new BasicArrayBuffer(values), true); + buffers[i] = new Buffer2D(source, values.Length, 1); } return new JpegColorConverter.ComponentValues(buffers, 0); } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs index 46a688b49c..9ffd42211f 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs @@ -107,7 +107,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg this.Output.WriteLine($"Component{i}: {diff}"); averageDifference += diff.average; totalDifference += diff.total; - tolerance += libJpegComponent.SpectralBlocks.Buffer.GetSpan().Length; + tolerance += libJpegComponent.SpectralBlocks.MemorySource.GetSpan().Length; } averageDifference /= componentCount; diff --git a/tests/ImageSharp.Tests/Memory/Buffer2DTests.cs b/tests/ImageSharp.Tests/Memory/Buffer2DTests.cs index 52d3929f6f..5753d92b3e 100644 --- a/tests/ImageSharp.Tests/Memory/Buffer2DTests.cs +++ b/tests/ImageSharp.Tests/Memory/Buffer2DTests.cs @@ -71,7 +71,7 @@ namespace SixLabors.ImageSharp.Tests.Memory // Assert.Equal(width * y, span.Start); Assert.Equal(width, span.Length); - Assert.SpanPointsTo(span, buffer.Buffer.MemoryOwner, width * y); + Assert.SpanPointsTo(span, buffer.MemorySource.MemoryOwner, width * y); } } @@ -87,7 +87,7 @@ namespace SixLabors.ImageSharp.Tests.Memory // Assert.Equal(width * y + x, span.Start); Assert.Equal(width - x, span.Length); - Assert.SpanPointsTo(span, buffer.Buffer.MemoryOwner, width * y + x); + Assert.SpanPointsTo(span, buffer.MemorySource.MemoryOwner, width * y + x); } } @@ -99,7 +99,7 @@ namespace SixLabors.ImageSharp.Tests.Memory { using (Buffer2D buffer = this.MemoryAllocator.Allocate2D(width, height)) { - Span span = buffer.Buffer.GetSpan(); + Span span = buffer.MemorySource.GetSpan(); ref TestStructs.Foo actual = ref buffer[x, y]; @@ -115,13 +115,13 @@ namespace SixLabors.ImageSharp.Tests.Memory using (Buffer2D a = this.MemoryAllocator.Allocate2D(10, 5)) using (Buffer2D b = this.MemoryAllocator.Allocate2D(3, 7)) { - IMemoryOwner aa = a.Buffer.MemoryOwner; - IMemoryOwner bb = b.Buffer.MemoryOwner; + IMemoryOwner aa = a.MemorySource.MemoryOwner; + IMemoryOwner bb = b.MemorySource.MemoryOwner; Buffer2D.SwapOrCopyContent(a, b); - Assert.Equal(bb, a.Buffer.MemoryOwner); - Assert.Equal(aa, b.Buffer.MemoryOwner); + Assert.Equal(bb, a.MemorySource.MemoryOwner); + Assert.Equal(aa, b.MemorySource.MemoryOwner); Assert.Equal(new Size(3, 7), a.Size()); Assert.Equal(new Size(10, 5), b.Size()); diff --git a/tests/ImageSharp.Tests/Memory/BufferManagerTests.cs b/tests/ImageSharp.Tests/Memory/MemorySourceTests.cs similarity index 60% rename from tests/ImageSharp.Tests/Memory/BufferManagerTests.cs rename to tests/ImageSharp.Tests/Memory/MemorySourceTests.cs index d08e734e82..9cdfb56353 100644 --- a/tests/ImageSharp.Tests/Memory/BufferManagerTests.cs +++ b/tests/ImageSharp.Tests/Memory/MemorySourceTests.cs @@ -12,21 +12,23 @@ using Xunit; namespace SixLabors.ImageSharp.Tests.Memory { - public class BufferManagerTests + public class MemorySourceTests { public class Construction { - [Fact] - public void InitializeAsOwner_MemoryOwner_IsPresent() + [Theory] + [InlineData(false)] + [InlineData(true)] + public void InitializeAsOwner(bool isInternalMemorySource) { var data = new Rgba32[21]; var mmg = new TestMemoryManager(data); - var a = new BufferManager(mmg); + var a = new MemorySource(mmg, isInternalMemorySource); Assert.Equal(mmg, a.MemoryOwner); Assert.Equal(mmg.Memory, a.Memory); - Assert.True(a.OwnsMemory); + Assert.Equal(isInternalMemorySource, a.HasSwappableContents); } [Fact] @@ -35,21 +37,23 @@ namespace SixLabors.ImageSharp.Tests.Memory var data = new Rgba32[21]; var mmg = new TestMemoryManager(data); - var a = new BufferManager(mmg.Memory); + var a = new MemorySource(mmg.Memory); Assert.Null(a.MemoryOwner); Assert.Equal(mmg.Memory, a.Memory); - Assert.False(a.OwnsMemory); + Assert.False(a.HasSwappableContents); } } public class Dispose { - [Fact] - public void WhenOwnershipIsTransfered_ShouldDisposeMemoryOwner() + [Theory] + [InlineData(false)] + [InlineData(true)] + public void WhenOwnershipIsTransfered_ShouldDisposeMemoryOwner(bool isInternalMemorySource) { var mmg = new TestMemoryManager(new int[10]); - var bmg = new BufferManager(mmg); + var bmg = new MemorySource(mmg, isInternalMemorySource); bmg.Dispose(); Assert.True(mmg.IsDisposed); @@ -59,7 +63,7 @@ namespace SixLabors.ImageSharp.Tests.Memory public void WhenMemoryObserver_ShouldNotDisposeAnything() { var mmg = new TestMemoryManager(new int[10]); - var bmg = new BufferManager(mmg.Memory); + var bmg = new MemorySource(mmg.Memory); bmg.Dispose(); Assert.False(mmg.IsDisposed); @@ -70,18 +74,18 @@ namespace SixLabors.ImageSharp.Tests.Memory { private MemoryAllocator MemoryAllocator { get; } = new TestMemoryAllocator(); - private BufferManager AllocateBufferManager(int length, AllocationOptions options = AllocationOptions.None) + private MemorySource AllocateMemorySource(int length, AllocationOptions options = AllocationOptions.None) where T : struct { - var owner = (IMemoryOwner)this.MemoryAllocator.Allocate(length, options); - return new BufferManager(owner); + IMemoryOwner owner = this.MemoryAllocator.Allocate(length, options); + return new MemorySource(owner, true); } [Fact] public void WhenBothAreMemoryOwners_ShouldSwap() { - BufferManager a = this.AllocateBufferManager(13); - BufferManager b = this.AllocateBufferManager(17); + MemorySource a = this.AllocateMemorySource(13); + MemorySource b = this.AllocateMemorySource(17); IMemoryOwner aa = a.MemoryOwner; IMemoryOwner bb = b.MemoryOwner; @@ -89,7 +93,7 @@ namespace SixLabors.ImageSharp.Tests.Memory Memory aaa = a.Memory; Memory bbb = b.Memory; - BufferManager.SwapOrCopyContent(ref a, ref b); + MemorySource.SwapOrCopyContent(ref a, ref b); Assert.Equal(bb, a.MemoryOwner); Assert.Equal(aa, b.MemoryOwner); @@ -100,26 +104,27 @@ namespace SixLabors.ImageSharp.Tests.Memory } [Theory] - [InlineData(false)] - [InlineData(true)] - public void WhenDestIsNotMemoryOwner_SameSize_ShouldCopy(bool sourceIsOwner) + [InlineData(false, false)] + [InlineData(true, true)] + [InlineData(true, false)] + public void WhenDestIsNotMemoryOwner_SameSize_ShouldCopy(bool sourceIsOwner, bool isInternalMemorySource) { var data = new Rgba32[21]; var color = new Rgba32(1, 2, 3, 4); var destOwner = new TestMemoryManager(data); - var dest = new BufferManager(destOwner.Memory); + var dest = new MemorySource(destOwner.Memory); - var sourceOwner = (IMemoryOwner)this.MemoryAllocator.Allocate(21); + IMemoryOwner sourceOwner = this.MemoryAllocator.Allocate(21); - BufferManager source = sourceIsOwner - ? new BufferManager(sourceOwner) - : new BufferManager(sourceOwner.Memory); + MemorySource source = sourceIsOwner + ? new MemorySource(sourceOwner, isInternalMemorySource) + : new MemorySource(sourceOwner.Memory); sourceOwner.Memory.Span[10] = color; // Act: - BufferManager.SwapOrCopyContent(ref dest, ref source); + MemorySource.SwapOrCopyContent(ref dest, ref source); // Assert: Assert.Equal(color, dest.Memory.Span[10]); @@ -136,18 +141,18 @@ namespace SixLabors.ImageSharp.Tests.Memory var color = new Rgba32(1, 2, 3, 4); var destOwner = new TestMemoryManager(data); - var dest = new BufferManager(destOwner.Memory); + var dest = new MemorySource(destOwner.Memory); - var sourceOwner = (IMemoryOwner)this.MemoryAllocator.Allocate(22); + IMemoryOwner sourceOwner = this.MemoryAllocator.Allocate(22); - BufferManager source = sourceIsOwner - ? new BufferManager(sourceOwner) - : new BufferManager(sourceOwner.Memory); + MemorySource source = sourceIsOwner + ? new MemorySource(sourceOwner, true) + : new MemorySource(sourceOwner.Memory); sourceOwner.Memory.Span[10] = color; // Act: Assert.ThrowsAny( - () => BufferManager.SwapOrCopyContent(ref dest, ref source) + () => MemorySource.SwapOrCopyContent(ref dest, ref source) ); Assert.Equal(color, source.Memory.Span[10]);