|
|
@ -10,7 +10,6 @@ using System.Threading; |
|
|
using SixLabors.ImageSharp.Advanced; |
|
|
using SixLabors.ImageSharp.Advanced; |
|
|
using SixLabors.ImageSharp.Memory; |
|
|
using SixLabors.ImageSharp.Memory; |
|
|
using SixLabors.ImageSharp.PixelFormats; |
|
|
using SixLabors.ImageSharp.PixelFormats; |
|
|
|
|
|
|
|
|
using Xunit; |
|
|
using Xunit; |
|
|
using Xunit.Abstractions; |
|
|
using Xunit.Abstractions; |
|
|
|
|
|
|
|
|
@ -64,10 +63,7 @@ namespace SixLabors.ImageSharp.Tests.Helpers |
|
|
|
|
|
|
|
|
int actualNumberOfSteps = 0; |
|
|
int actualNumberOfSteps = 0; |
|
|
|
|
|
|
|
|
ParallelRowIterator.IterateRows( |
|
|
void RowAction(RowInterval rows) |
|
|
rectangle, |
|
|
|
|
|
parallelSettings, |
|
|
|
|
|
rows => |
|
|
|
|
|
{ |
|
|
{ |
|
|
Assert.True(rows.Min >= minY); |
|
|
Assert.True(rows.Min >= minY); |
|
|
Assert.True(rows.Max <= maxY); |
|
|
Assert.True(rows.Max <= maxY); |
|
|
@ -77,7 +73,14 @@ namespace SixLabors.ImageSharp.Tests.Helpers |
|
|
|
|
|
|
|
|
Interlocked.Increment(ref actualNumberOfSteps); |
|
|
Interlocked.Increment(ref actualNumberOfSteps); |
|
|
Assert.Equal(expected, step); |
|
|
Assert.Equal(expected, step); |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var operation = new TestRowIntervalOperation(RowAction); |
|
|
|
|
|
|
|
|
|
|
|
ParallelRowIterator.IterateRows( |
|
|
|
|
|
rectangle, |
|
|
|
|
|
in parallelSettings, |
|
|
|
|
|
in operation); |
|
|
|
|
|
|
|
|
Assert.Equal(expectedNumberOfSteps, actualNumberOfSteps); |
|
|
Assert.Equal(expectedNumberOfSteps, actualNumberOfSteps); |
|
|
} |
|
|
} |
|
|
@ -102,16 +105,20 @@ namespace SixLabors.ImageSharp.Tests.Helpers |
|
|
int[] expectedData = Enumerable.Repeat(0, minY).Concat(Enumerable.Range(minY, maxY - minY)).ToArray(); |
|
|
int[] expectedData = Enumerable.Repeat(0, minY).Concat(Enumerable.Range(minY, maxY - minY)).ToArray(); |
|
|
var actualData = new int[maxY]; |
|
|
var actualData = new int[maxY]; |
|
|
|
|
|
|
|
|
ParallelRowIterator.IterateRows( |
|
|
void RowAction(RowInterval rows) |
|
|
rectangle, |
|
|
|
|
|
parallelSettings, |
|
|
|
|
|
rows => |
|
|
|
|
|
{ |
|
|
{ |
|
|
for (int y = rows.Min; y < rows.Max; y++) |
|
|
for (int y = rows.Min; y < rows.Max; y++) |
|
|
{ |
|
|
{ |
|
|
actualData[y] = y; |
|
|
actualData[y] = y; |
|
|
} |
|
|
} |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var operation = new TestRowIntervalOperation(RowAction); |
|
|
|
|
|
|
|
|
|
|
|
ParallelRowIterator.IterateRows( |
|
|
|
|
|
rectangle, |
|
|
|
|
|
in parallelSettings, |
|
|
|
|
|
in operation); |
|
|
|
|
|
|
|
|
Assert.Equal(expectedData, actualData); |
|
|
Assert.Equal(expectedData, actualData); |
|
|
} |
|
|
} |
|
|
@ -136,10 +143,8 @@ namespace SixLabors.ImageSharp.Tests.Helpers |
|
|
var bufferHashes = new ConcurrentBag<int>(); |
|
|
var bufferHashes = new ConcurrentBag<int>(); |
|
|
|
|
|
|
|
|
int actualNumberOfSteps = 0; |
|
|
int actualNumberOfSteps = 0; |
|
|
ParallelRowIterator.IterateRows( |
|
|
|
|
|
rectangle, |
|
|
void RowAction(RowInterval rows, Memory<Vector4> buffer) |
|
|
parallelSettings, |
|
|
|
|
|
(RowInterval rows, Memory<Vector4> buffer) => |
|
|
|
|
|
{ |
|
|
{ |
|
|
Assert.True(rows.Min >= minY); |
|
|
Assert.True(rows.Min >= minY); |
|
|
Assert.True(rows.Max <= maxY); |
|
|
Assert.True(rows.Max <= maxY); |
|
|
@ -151,7 +156,14 @@ namespace SixLabors.ImageSharp.Tests.Helpers |
|
|
|
|
|
|
|
|
Interlocked.Increment(ref actualNumberOfSteps); |
|
|
Interlocked.Increment(ref actualNumberOfSteps); |
|
|
Assert.Equal(expected, step); |
|
|
Assert.Equal(expected, step); |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var operation = new TestRowIntervalOperation<Vector4>(RowAction); |
|
|
|
|
|
|
|
|
|
|
|
ParallelRowIterator.IterateRows<TestRowIntervalOperation<Vector4>, Vector4>( |
|
|
|
|
|
rectangle, |
|
|
|
|
|
in parallelSettings, |
|
|
|
|
|
in operation); |
|
|
|
|
|
|
|
|
Assert.Equal(expectedNumberOfSteps, actualNumberOfSteps); |
|
|
Assert.Equal(expectedNumberOfSteps, actualNumberOfSteps); |
|
|
|
|
|
|
|
|
@ -179,16 +191,20 @@ namespace SixLabors.ImageSharp.Tests.Helpers |
|
|
int[] expectedData = Enumerable.Repeat(0, minY).Concat(Enumerable.Range(minY, maxY - minY)).ToArray(); |
|
|
int[] expectedData = Enumerable.Repeat(0, minY).Concat(Enumerable.Range(minY, maxY - minY)).ToArray(); |
|
|
var actualData = new int[maxY]; |
|
|
var actualData = new int[maxY]; |
|
|
|
|
|
|
|
|
ParallelRowIterator.IterateRows( |
|
|
void RowAction(RowInterval rows, Memory<Vector4> buffer) |
|
|
rectangle, |
|
|
|
|
|
parallelSettings, |
|
|
|
|
|
(RowInterval rows, Memory<Vector4> buffer) => |
|
|
|
|
|
{ |
|
|
{ |
|
|
for (int y = rows.Min; y < rows.Max; y++) |
|
|
for (int y = rows.Min; y < rows.Max; y++) |
|
|
{ |
|
|
{ |
|
|
actualData[y] = y; |
|
|
actualData[y] = y; |
|
|
} |
|
|
} |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var operation = new TestRowIntervalOperation<Vector4>(RowAction); |
|
|
|
|
|
|
|
|
|
|
|
ParallelRowIterator.IterateRows<TestRowIntervalOperation<Vector4>, Vector4>( |
|
|
|
|
|
rectangle, |
|
|
|
|
|
in parallelSettings, |
|
|
|
|
|
in operation); |
|
|
|
|
|
|
|
|
Assert.Equal(expectedData, actualData); |
|
|
Assert.Equal(expectedData, actualData); |
|
|
} |
|
|
} |
|
|
@ -225,10 +241,7 @@ namespace SixLabors.ImageSharp.Tests.Helpers |
|
|
|
|
|
|
|
|
int actualNumberOfSteps = 0; |
|
|
int actualNumberOfSteps = 0; |
|
|
|
|
|
|
|
|
ParallelRowIterator.IterateRows( |
|
|
void RowAction(RowInterval rows) |
|
|
rectangle, |
|
|
|
|
|
parallelSettings, |
|
|
|
|
|
rows => |
|
|
|
|
|
{ |
|
|
{ |
|
|
Assert.True(rows.Min >= 0); |
|
|
Assert.True(rows.Min >= 0); |
|
|
Assert.True(rows.Max <= height); |
|
|
Assert.True(rows.Max <= height); |
|
|
@ -238,7 +251,14 @@ namespace SixLabors.ImageSharp.Tests.Helpers |
|
|
|
|
|
|
|
|
Interlocked.Increment(ref actualNumberOfSteps); |
|
|
Interlocked.Increment(ref actualNumberOfSteps); |
|
|
Assert.Equal(expected, step); |
|
|
Assert.Equal(expected, step); |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var operation = new TestRowIntervalOperation(RowAction); |
|
|
|
|
|
|
|
|
|
|
|
ParallelRowIterator.IterateRows( |
|
|
|
|
|
rectangle, |
|
|
|
|
|
in parallelSettings, |
|
|
|
|
|
in operation); |
|
|
|
|
|
|
|
|
Assert.Equal(expectedNumberOfSteps, actualNumberOfSteps); |
|
|
Assert.Equal(expectedNumberOfSteps, actualNumberOfSteps); |
|
|
} |
|
|
} |
|
|
@ -262,10 +282,8 @@ namespace SixLabors.ImageSharp.Tests.Helpers |
|
|
var rectangle = new Rectangle(0, 0, width, height); |
|
|
var rectangle = new Rectangle(0, 0, width, height); |
|
|
|
|
|
|
|
|
int actualNumberOfSteps = 0; |
|
|
int actualNumberOfSteps = 0; |
|
|
ParallelRowIterator.IterateRows( |
|
|
|
|
|
rectangle, |
|
|
void RowAction(RowInterval rows, Memory<Vector4> buffer) |
|
|
parallelSettings, |
|
|
|
|
|
(RowInterval rows, Memory<Vector4> buffer) => |
|
|
|
|
|
{ |
|
|
{ |
|
|
Assert.True(rows.Min >= 0); |
|
|
Assert.True(rows.Min >= 0); |
|
|
Assert.True(rows.Max <= height); |
|
|
Assert.True(rows.Max <= height); |
|
|
@ -275,7 +293,14 @@ namespace SixLabors.ImageSharp.Tests.Helpers |
|
|
|
|
|
|
|
|
Interlocked.Increment(ref actualNumberOfSteps); |
|
|
Interlocked.Increment(ref actualNumberOfSteps); |
|
|
Assert.Equal(expected, step); |
|
|
Assert.Equal(expected, step); |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var operation = new TestRowIntervalOperation<Vector4>(RowAction); |
|
|
|
|
|
|
|
|
|
|
|
ParallelRowIterator.IterateRows<TestRowIntervalOperation<Vector4>, Vector4>( |
|
|
|
|
|
rectangle, |
|
|
|
|
|
in parallelSettings, |
|
|
|
|
|
in operation); |
|
|
|
|
|
|
|
|
Assert.Equal(expectedNumberOfSteps, actualNumberOfSteps); |
|
|
Assert.Equal(expectedNumberOfSteps, actualNumberOfSteps); |
|
|
} |
|
|
} |
|
|
@ -325,17 +350,21 @@ namespace SixLabors.ImageSharp.Tests.Helpers |
|
|
// Fill actual data using IterateRows:
|
|
|
// Fill actual data using IterateRows:
|
|
|
var settings = new ParallelExecutionSettings(maxDegreeOfParallelism, memoryAllocator); |
|
|
var settings = new ParallelExecutionSettings(maxDegreeOfParallelism, memoryAllocator); |
|
|
|
|
|
|
|
|
ParallelRowIterator.IterateRows( |
|
|
void RowAction(RowInterval rows) |
|
|
rect, |
|
|
|
|
|
settings, |
|
|
|
|
|
rows => |
|
|
|
|
|
{ |
|
|
{ |
|
|
this.output.WriteLine(rows.ToString()); |
|
|
this.output.WriteLine(rows.ToString()); |
|
|
for (int y = rows.Min; y < rows.Max; y++) |
|
|
for (int y = rows.Min; y < rows.Max; y++) |
|
|
{ |
|
|
{ |
|
|
FillRow(y, actual); |
|
|
FillRow(y, actual); |
|
|
} |
|
|
} |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var operation = new TestRowIntervalOperation(RowAction); |
|
|
|
|
|
|
|
|
|
|
|
ParallelRowIterator.IterateRows( |
|
|
|
|
|
rect, |
|
|
|
|
|
settings, |
|
|
|
|
|
in operation); |
|
|
|
|
|
|
|
|
// Assert:
|
|
|
// Assert:
|
|
|
TestImageExtensions.CompareBuffers(expected.GetSpan(), actual.GetSpan()); |
|
|
TestImageExtensions.CompareBuffers(expected.GetSpan(), actual.GetSpan()); |
|
|
@ -353,8 +382,14 @@ namespace SixLabors.ImageSharp.Tests.Helpers |
|
|
|
|
|
|
|
|
var rect = new Rectangle(0, 0, width, height); |
|
|
var rect = new Rectangle(0, 0, width, height); |
|
|
|
|
|
|
|
|
|
|
|
void RowAction(RowInterval rows) |
|
|
|
|
|
{ |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var operation = new TestRowIntervalOperation(RowAction); |
|
|
|
|
|
|
|
|
ArgumentOutOfRangeException ex = Assert.Throws<ArgumentOutOfRangeException>( |
|
|
ArgumentOutOfRangeException ex = Assert.Throws<ArgumentOutOfRangeException>( |
|
|
() => ParallelRowIterator.IterateRows(rect, parallelSettings, rows => { })); |
|
|
() => ParallelRowIterator.IterateRows(rect, in parallelSettings, in operation)); |
|
|
|
|
|
|
|
|
Assert.Contains(width <= 0 ? "Width" : "Height", ex.Message); |
|
|
Assert.Contains(width <= 0 ? "Width" : "Height", ex.Message); |
|
|
} |
|
|
} |
|
|
@ -370,10 +405,38 @@ namespace SixLabors.ImageSharp.Tests.Helpers |
|
|
|
|
|
|
|
|
var rect = new Rectangle(0, 0, width, height); |
|
|
var rect = new Rectangle(0, 0, width, height); |
|
|
|
|
|
|
|
|
|
|
|
void RowAction(RowInterval rows, Memory<Rgba32> memory) |
|
|
|
|
|
{ |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var operation = new TestRowIntervalOperation<Rgba32>(RowAction); |
|
|
|
|
|
|
|
|
ArgumentOutOfRangeException ex = Assert.Throws<ArgumentOutOfRangeException>( |
|
|
ArgumentOutOfRangeException ex = Assert.Throws<ArgumentOutOfRangeException>( |
|
|
() => ParallelRowIterator.IterateRows<Rgba32>(rect, parallelSettings, (rows, memory) => { })); |
|
|
() => ParallelRowIterator.IterateRows<TestRowIntervalOperation<Rgba32>, Rgba32>(rect, in parallelSettings, in operation)); |
|
|
|
|
|
|
|
|
Assert.Contains(width <= 0 ? "Width" : "Height", ex.Message); |
|
|
Assert.Contains(width <= 0 ? "Width" : "Height", ex.Message); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private readonly struct TestRowIntervalOperation : IRowIntervalOperation |
|
|
|
|
|
{ |
|
|
|
|
|
private readonly Action<RowInterval> action; |
|
|
|
|
|
|
|
|
|
|
|
public TestRowIntervalOperation(Action<RowInterval> action) |
|
|
|
|
|
=> this.action = action; |
|
|
|
|
|
|
|
|
|
|
|
public void Invoke(in RowInterval rows) => this.action(rows); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private readonly struct TestRowIntervalOperation<TBuffer> : IRowIntervalOperation<TBuffer> |
|
|
|
|
|
where TBuffer : unmanaged |
|
|
|
|
|
{ |
|
|
|
|
|
private readonly Action<RowInterval, Memory<TBuffer>> action; |
|
|
|
|
|
|
|
|
|
|
|
public TestRowIntervalOperation(Action<RowInterval, Memory<TBuffer>> action) |
|
|
|
|
|
=> this.action = action; |
|
|
|
|
|
|
|
|
|
|
|
public void Invoke(in RowInterval rows, Memory<TBuffer> memory) |
|
|
|
|
|
=> this.action(rows, memory); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|