diff --git a/src/ImageSharp/ImageSharp.csproj.DotSettings b/src/ImageSharp/ImageSharp.csproj.DotSettings
index 018ca75cd..6896e069c 100644
--- a/src/ImageSharp/ImageSharp.csproj.DotSettings
+++ b/src/ImageSharp/ImageSharp.csproj.DotSettings
@@ -2,6 +2,8 @@
True
True
True
+ True
+ True
True
True
True
diff --git a/src/ImageSharp/Memory/Allocators/ArrayPoolMemoryAllocator.cs b/src/ImageSharp/Memory/Allocators/ArrayPoolMemoryAllocator.cs
index 57a5b77bc..e53929c5c 100644
--- a/src/ImageSharp/Memory/Allocators/ArrayPoolMemoryAllocator.cs
+++ b/src/ImageSharp/Memory/Allocators/ArrayPoolMemoryAllocator.cs
@@ -95,7 +95,7 @@ namespace SixLabors.ImageSharp.Memory
public int MaximumContiguousBufferLength { get; set; } = Int32.MaxValue;
///
- protected internal override int GetMaximumContiguousBufferLength() => this.MaximumContiguousBufferLength;
+ protected internal override int GetBlockCapacity() => this.MaximumContiguousBufferLength;
///
public override IMemoryOwner Allocate(int length, AllocationOptions options = AllocationOptions.None)
diff --git a/src/ImageSharp/Memory/Allocators/MemoryAllocator.cs b/src/ImageSharp/Memory/Allocators/MemoryAllocator.cs
index 1e1f69784..ccb5bf2e8 100644
--- a/src/ImageSharp/Memory/Allocators/MemoryAllocator.cs
+++ b/src/ImageSharp/Memory/Allocators/MemoryAllocator.cs
@@ -11,9 +11,10 @@ namespace SixLabors.ImageSharp.Memory
public abstract class MemoryAllocator
{
///
- /// Gets the length of the largest contiguous buffer that can be handled by this allocator instance.
+ /// Gets the length of the largest contiguous buffer that can be handled by this allocator instance in bytes.
///
- protected internal abstract int GetMaximumContiguousBufferLength();
+ /// The length of the largest contiguous buffer that can be handled by this allocator instance.
+ protected internal abstract int GetBlockCapacity();
///
/// Allocates an , holding a of length .
diff --git a/src/ImageSharp/Memory/Allocators/SimpleGcMemoryAllocator.cs b/src/ImageSharp/Memory/Allocators/SimpleGcMemoryAllocator.cs
index ee9afbac5..88830c551 100644
--- a/src/ImageSharp/Memory/Allocators/SimpleGcMemoryAllocator.cs
+++ b/src/ImageSharp/Memory/Allocators/SimpleGcMemoryAllocator.cs
@@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.Memory
public sealed class SimpleGcMemoryAllocator : MemoryAllocator
{
///
- protected internal override int GetMaximumContiguousBufferLength() => int.MaxValue;
+ protected internal override int GetBlockCapacity() => int.MaxValue;
///
public override IMemoryOwner Allocate(int length, AllocationOptions options = AllocationOptions.None)
diff --git a/src/ImageSharp/Memory/DiscontiguousBuffers/IMemoryGroup{T}.cs b/src/ImageSharp/Memory/DiscontiguousBuffers/IMemoryGroup{T}.cs
new file mode 100644
index 000000000..eaacef713
--- /dev/null
+++ b/src/ImageSharp/Memory/DiscontiguousBuffers/IMemoryGroup{T}.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+
+namespace SixLabors.ImageSharp.Memory
+{
+ ///
+ /// Represents discontiguous group of multiple uniformly-sized memory segments.
+ /// The last segment can be smaller than the preceding ones.
+ ///
+ /// The element type.
+ public interface IMemoryGroup : IReadOnlyList>
+ where T : struct
+ {
+ ///
+ /// Gets the number of elements per contiguous sub-block.
+ ///
+ public int BlockSize { get; }
+
+ bool IsValid { get; }
+ }
+}
diff --git a/src/ImageSharp/Memory/DiscontinuousProto/InvalidMemoryOperationException.cs b/src/ImageSharp/Memory/DiscontiguousBuffers/InvalidMemoryOperationException.cs
similarity index 65%
rename from src/ImageSharp/Memory/DiscontinuousProto/InvalidMemoryOperationException.cs
rename to src/ImageSharp/Memory/DiscontiguousBuffers/InvalidMemoryOperationException.cs
index f756a1246..b211a13f3 100644
--- a/src/ImageSharp/Memory/DiscontinuousProto/InvalidMemoryOperationException.cs
+++ b/src/ImageSharp/Memory/DiscontiguousBuffers/InvalidMemoryOperationException.cs
@@ -1,6 +1,6 @@
using System;
-namespace SixLabors.ImageSharp.Memory.DiscontinuousProto
+namespace SixLabors.ImageSharp.Memory
{
public class InvalidMemoryOperationException : InvalidOperationException
{
diff --git a/src/ImageSharp/Memory/DiscontinuousProto/UniformMemoryGroupView{T}.cs b/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroupView{T}.cs
similarity index 77%
rename from src/ImageSharp/Memory/DiscontinuousProto/UniformMemoryGroupView{T}.cs
rename to src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroupView{T}.cs
index 4e5b04dfd..a2d5c0579 100644
--- a/src/ImageSharp/Memory/DiscontinuousProto/UniformMemoryGroupView{T}.cs
+++ b/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroupView{T}.cs
@@ -3,24 +3,24 @@ using System.Buffers;
using System.Collections;
using System.Collections.Generic;
-namespace SixLabors.ImageSharp.Memory.DiscontinuousProto
+namespace SixLabors.ImageSharp.Memory
{
///
- /// Implements , defining a view for
+ /// Implements , defining a view for
/// rather than owning the segments.
///
///
/// This type provides an indirection, protecting the users of publicly exposed memory API-s
- /// from internal memory-swaps. Whenever an internal swap happens, the
+ /// from internal memory-swaps. Whenever an internal swap happens, the
/// instance becomes invalid, throwing an exception on all operations.
///
/// The element type.
- internal class UniformMemoryGroupView : IUniformMemoryGroup where T : struct
+ internal class MemoryGroupView : IMemoryGroup where T : struct
{
- private readonly UniformMemoryGroup owner;
+ private readonly Memory.MemoryGroup owner;
private readonly MemoryOwnerWrapper[] memoryWrappers;
- public UniformMemoryGroupView(UniformMemoryGroup owner)
+ public MemoryGroupView(Memory.MemoryGroup owner)
{
this.IsValid = true;
this.owner = owner;
@@ -40,15 +40,17 @@ namespace SixLabors.ImageSharp.Memory.DiscontinuousProto
public Memory this[int index] => throw new NotImplementedException();
+ public int BlockSize => this.owner.BlockSize;
+
public bool IsValid { get; internal set; }
class MemoryOwnerWrapper : MemoryManager
{
- private UniformMemoryGroupView view;
+ private MemoryGroupView view;
private int index;
- public MemoryOwnerWrapper(UniformMemoryGroupView view, int index)
+ public MemoryOwnerWrapper(MemoryGroupView view, int index)
{
this.view = view;
this.index = index;
diff --git a/src/ImageSharp/Memory/DiscontinuousProto/UniformMemoryGroup{T}.Consumed.cs b/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.Consumed.cs
similarity index 84%
rename from src/ImageSharp/Memory/DiscontinuousProto/UniformMemoryGroup{T}.Consumed.cs
rename to src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.Consumed.cs
index 17410e900..03f61b75b 100644
--- a/src/ImageSharp/Memory/DiscontinuousProto/UniformMemoryGroup{T}.Consumed.cs
+++ b/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.Consumed.cs
@@ -1,12 +1,12 @@
using System;
using System.Collections.Generic;
-namespace SixLabors.ImageSharp.Memory.DiscontinuousProto
+namespace SixLabors.ImageSharp.Memory
{
- internal abstract partial class UniformMemoryGroup
+ internal abstract partial class MemoryGroup
{
// Analogous to the "consumed" variant of MemorySource
- private class Consumed : UniformMemoryGroup
+ private class Consumed : MemoryGroup
{
private readonly ReadOnlyMemory> source;
diff --git a/src/ImageSharp/Memory/DiscontinuousProto/UniformMemoryGroup{T}.Owned.cs b/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.Owned.cs
similarity index 86%
rename from src/ImageSharp/Memory/DiscontinuousProto/UniformMemoryGroup{T}.Owned.cs
rename to src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.Owned.cs
index d02975cbc..b15d7d676 100644
--- a/src/ImageSharp/Memory/DiscontinuousProto/UniformMemoryGroup{T}.Owned.cs
+++ b/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.Owned.cs
@@ -3,12 +3,12 @@ using System.Buffers;
using System.Collections.Generic;
using System.Linq;
-namespace SixLabors.ImageSharp.Memory.DiscontinuousProto
+namespace SixLabors.ImageSharp.Memory
{
// Analogous to the "owned" variant of MemorySource
- internal abstract partial class UniformMemoryGroup
+ internal abstract partial class MemoryGroup
{
- private class Owned : UniformMemoryGroup
+ private class Owned : MemoryGroup
{
private IMemoryOwner[] memoryOwners;
@@ -62,7 +62,7 @@ namespace SixLabors.ImageSharp.Memory.DiscontinuousProto
{
if (this.memoryOwners == null)
{
- throw new ObjectDisposedException(nameof(UniformMemoryGroup));
+ throw new ObjectDisposedException(nameof(MemoryGroup));
}
}
}
diff --git a/src/ImageSharp/Memory/DiscontinuousProto/UniformMemoryGroup{T}.cs b/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.cs
similarity index 65%
rename from src/ImageSharp/Memory/DiscontinuousProto/UniformMemoryGroup{T}.cs
rename to src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.cs
index 794239377..670a0aaf6 100644
--- a/src/ImageSharp/Memory/DiscontinuousProto/UniformMemoryGroup{T}.cs
+++ b/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.cs
@@ -2,7 +2,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
-namespace SixLabors.ImageSharp.Memory.DiscontinuousProto
+namespace SixLabors.ImageSharp.Memory
{
///
/// Represents discontinuous group of multiple uniformly-sized memory segments.
@@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.Memory.DiscontinuousProto
/// and .
///
/// The element type.
- internal abstract partial class UniformMemoryGroup : IUniformMemoryGroup, IDisposable where T : struct
+ internal abstract partial class MemoryGroup : IMemoryGroup, IDisposable where T : struct
{
public abstract IEnumerator> GetEnumerator();
@@ -22,26 +22,28 @@ namespace SixLabors.ImageSharp.Memory.DiscontinuousProto
public abstract void Dispose();
+ public int BlockSize { get; }
+
public bool IsValid { get; protected set; }
// bufferLengthAlignment == image.Width in row-major images
- public static UniformMemoryGroup Allocate(MemoryAllocator allocator, long length, int bufferLengthAlignment)
+ public static MemoryGroup Allocate(MemoryAllocator allocator, long totalLength, int blockAlignment)
{
- long bufferCount = length / allocator.GetMaximumContiguousBufferLength();
+ long bufferCount = totalLength / allocator.GetBlockCapacity();
// TODO: Adjust bufferCount, and calculate the uniform buffer length with respect to bufferLengthAlignment, and allocate bufferCount buffers
throw new NotImplementedException();
}
- public static UniformMemoryGroup Wrap(params Memory[] source) => Wrap(source.AsMemory());
+ public static MemoryGroup Wrap(params Memory[] source) => Wrap(source.AsMemory());
- public static UniformMemoryGroup Wrap(ReadOnlyMemory> source)
+ public static MemoryGroup Wrap(ReadOnlyMemory> source)
{
return new Consumed(source);
}
// Analogous to current MemorySource.SwapOrCopyContent()
- public static void SwapOrCopyContent(UniformMemoryGroup destination, UniformMemoryGroup source)
+ public static void SwapOrCopyContent(MemoryGroup destination, MemoryGroup source)
{
throw new NotImplementedException();
}
diff --git a/src/ImageSharp/Memory/DiscontinuousProto/IUniformMemoryGroup{T}.cs b/src/ImageSharp/Memory/DiscontinuousProto/IUniformMemoryGroup{T}.cs
deleted file mode 100644
index d0ec69bea..000000000
--- a/src/ImageSharp/Memory/DiscontinuousProto/IUniformMemoryGroup{T}.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace SixLabors.ImageSharp.Memory.DiscontinuousProto
-{
- ///
- /// Represents discontinuous group of multiple uniformly-sized memory segments.
- /// The last segment can be smaller than the preceding ones.
- ///
- /// The element type.
- public interface IUniformMemoryGroup : IReadOnlyList> where T : struct
- {
- bool IsValid { get; }
- }
-}
diff --git a/tests/ImageSharp.Tests/Memory/DiscontiguousBuffers/MemoryGroupTests.cs b/tests/ImageSharp.Tests/Memory/DiscontiguousBuffers/MemoryGroupTests.cs
new file mode 100644
index 000000000..adb398ee6
--- /dev/null
+++ b/tests/ImageSharp.Tests/Memory/DiscontiguousBuffers/MemoryGroupTests.cs
@@ -0,0 +1,96 @@
+using System.Linq;
+using System.Runtime.InteropServices;
+using SixLabors.ImageSharp.Memory;
+using Xunit;
+
+namespace SixLabors.ImageSharp.Tests.Memory.DiscontiguousBuffers
+{
+ public class MemoryGroupTests
+ {
+ public class Allocate
+ {
+ private readonly TestMemoryAllocator memoryAllocator = new TestMemoryAllocator();
+
+#pragma warning disable SA1509
+ public static TheoryData
public byte DirtyValue { get; }
+ public int BlockCapacity { get; set; } = int.MaxValue;
+
public IList AllocationLog => this.allocationLog;
- protected internal override int GetMaximumContiguousBufferLength() => int.MaxValue;
+ protected internal override int GetBlockCapacity() => this.BlockCapacity;
public override IMemoryOwner Allocate(int length, AllocationOptions options = AllocationOptions.None)
{