Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
82b07ab
Renamed ParallelRowIterator.IterateRows to IterateRowIntervals
Sergio0694 Feb 27, 2020
1cadad4
Removed unnecessary using directives
Sergio0694 Feb 27, 2020
6baa109
Added single row value delegate interfaces
Sergio0694 Feb 27, 2020
0d990e0
Added single row value delegate wrappers
Sergio0694 Feb 27, 2020
7fd93e8
Renamed new APIs
Sergio0694 Feb 27, 2020
96a0893
Introduced single row parallel helpers
Sergio0694 Feb 27, 2020
db68d7d
Removed IterationParameters type
Sergio0694 Feb 27, 2020
3d31033
Refactored BinaryThresholdProcessor<TPixel>
Sergio0694 Feb 27, 2020
ec4a56b
Micro-optimization in BinaryThresholdProcessor<TPixel>
Sergio0694 Feb 27, 2020
cf625a0
Refactored BokehBlurProcessor<TPixel>
Sergio0694 Feb 27, 2020
e302f35
Refactored Convolution2DProcessor<TPixel>
Sergio0694 Feb 27, 2020
badd5bf
Refactored Convolution2PassProcessor<TPixel>
Sergio0694 Feb 27, 2020
247cc6d
Refactored ConvolutionProcessor<TPixel>
Sergio0694 Feb 27, 2020
ee6f7f3
Refactored EdgeDetectorCompassProcessor<TPixel>
Sergio0694 Feb 27, 2020
c4cdc77
Refactored DrawImageProcessor<TPixelBg,TPixelFg>
Sergio0694 Feb 27, 2020
d152b14
Refactored PixelRowDelegateProcessor<TPixel,TDelegate>
Sergio0694 Feb 27, 2020
c8b69f1
Refactored FilterProcessor<TPixel>
Sergio0694 Feb 27, 2020
d5a98fc
Refactored GlobalHistogramEqualizationProcessor<TPixel>
Sergio0694 Feb 27, 2020
7c1d297
Refactored BackgroundColorProcessor<TPixel>
Sergio0694 Feb 27, 2020
41af0b5
Refactored GlowProcessor<TPixel>
Sergio0694 Feb 27, 2020
0f684e6
Refactored VignetteProcessor<TPixel>
Sergio0694 Feb 27, 2020
3feccec
Refactored AffineTransformProcessor<TPixel>
Sergio0694 Feb 27, 2020
4c0acaf
Refactored FlipProcessor<TPixel>
Sergio0694 Feb 27, 2020
1c49cea
Refactored ProjectiveTransformProcessor<TPixel>
Sergio0694 Feb 27, 2020
91e8353
Refactored RotateProcessor<TPixel>
Sergio0694 Feb 27, 2020
ba596b2
Refactored ResizeProcessor<TPixel>
Sergio0694 Feb 27, 2020
8811994
Refactored CropProcessor<TPixel>
Sergio0694 Feb 27, 2020
1cee460
Merge branch 'master' into feature/single-row-value-delegate-optin
Sergio0694 Feb 27, 2020
5626260
Merge branch 'master' into feature/single-row-value-delegate-optin
Sergio0694 Mar 3, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/ImageSharp/Advanced/IRowIntervalOperation.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.

using System;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Memory;

namespace SixLabors.ImageSharp.Advanced
Expand Down
2 changes: 0 additions & 2 deletions src/ImageSharp/Advanced/IRowIntervalOperation{TBuffer}.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// Licensed under the Apache License, Version 2.0.

using System;
using System.Buffers;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Memory;

namespace SixLabors.ImageSharp.Advanced
Expand Down
17 changes: 17 additions & 0 deletions src/ImageSharp/Advanced/IRowOperation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.

namespace SixLabors.ImageSharp.Advanced
{
/// <summary>
/// Defines the contract for an action that operates on a row.
/// </summary>
public interface IRowOperation
{
/// <summary>
/// Invokes the method passing the row y coordinate.
/// </summary>
/// <param name="y">The row y coordinate.</param>
void Invoke(int y);
}
}
22 changes: 22 additions & 0 deletions src/ImageSharp/Advanced/IRowOperation{TBuffer}.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.

using System;

namespace SixLabors.ImageSharp.Advanced
{
/// <summary>
/// Defines the contract for an action that operates on a row with a temporary buffer.
/// </summary>
/// <typeparam name="TBuffer">The type of buffer elements.</typeparam>
public interface IRowOperation<TBuffer>
where TBuffer : unmanaged
{
/// <summary>
/// Invokes the method passing the row and a buffer.
/// </summary>
/// <param name="y">The row y coordinate.</param>
/// <param name="span">The contiguous region of memory.</param>
void Invoke(int y, Span<TBuffer> span);
}
}
138 changes: 113 additions & 25 deletions src/ImageSharp/Advanced/ParallelRowIterator.Wrappers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,51 +17,130 @@ namespace SixLabors.ImageSharp.Advanced
/// </content>
public static partial class ParallelRowIterator
{
private readonly struct IterationParameters
private readonly struct RowOperationWrapper<T>
where T : struct, IRowOperation
{
public readonly int MinY;
public readonly int MaxY;
public readonly int StepY;
public readonly int Width;
private readonly int minY;
private readonly int maxY;
private readonly int stepY;
private readonly T action;

public IterationParameters(int minY, int maxY, int stepY)
: this(minY, maxY, stepY, 0)
[MethodImpl(InliningOptions.ShortMethod)]
public RowOperationWrapper(
int minY,
int maxY,
int stepY,
in T action)
{
this.minY = minY;
this.maxY = maxY;
this.stepY = stepY;
this.action = action;
}

public IterationParameters(int minY, int maxY, int stepY, int width)
[MethodImpl(InliningOptions.ShortMethod)]
public void Invoke(int i)
{
this.MinY = minY;
this.MaxY = maxY;
this.StepY = stepY;
this.Width = width;
int yMin = this.minY + (i * this.stepY);

if (yMin >= this.maxY)
{
return;
}

int yMax = Math.Min(yMin + this.stepY, this.maxY);

for (int y = yMin; y < yMax; y++)
{
// Skip the safety copy when invoking a potentially impure method on a readonly field
Unsafe.AsRef(this.action).Invoke(y);
}
}
}

private readonly struct RowOperationWrapper<T, TBuffer>
where T : struct, IRowOperation<TBuffer>
where TBuffer : unmanaged
{
private readonly int minY;
private readonly int maxY;
private readonly int stepY;
private readonly int width;
private readonly MemoryAllocator allocator;
private readonly T action;

[MethodImpl(InliningOptions.ShortMethod)]
public RowOperationWrapper(
int minY,
int maxY,
int stepY,
int width,
MemoryAllocator allocator,
in T action)
{
this.minY = minY;
this.maxY = maxY;
this.stepY = stepY;
this.width = width;
this.allocator = allocator;
this.action = action;
}

[MethodImpl(InliningOptions.ShortMethod)]
public void Invoke(int i)
{
int yMin = this.minY + (i * this.stepY);

if (yMin >= this.maxY)
{
return;
}

int yMax = Math.Min(yMin + this.stepY, this.maxY);

using IMemoryOwner<TBuffer> buffer = this.allocator.Allocate<TBuffer>(this.width);

Span<TBuffer> span = buffer.Memory.Span;

for (int y = yMin; y < yMax; y++)
{
Unsafe.AsRef(this.action).Invoke(y, span);
}
}
}

private readonly struct RowIntervalOperationWrapper<T>
where T : struct, IRowIntervalOperation
{
private readonly IterationParameters info;
private readonly int minY;
private readonly int maxY;
private readonly int stepY;
private readonly T operation;

[MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalOperationWrapper(in IterationParameters info, in T operation)
public RowIntervalOperationWrapper(
int minY,
int maxY,
int stepY,
in T operation)
{
this.info = info;
this.minY = minY;
this.maxY = maxY;
this.stepY = stepY;
this.operation = operation;
}

[MethodImpl(InliningOptions.ShortMethod)]
public void Invoke(int i)
{
int yMin = this.info.MinY + (i * this.info.StepY);
int yMin = this.minY + (i * this.stepY);

if (yMin >= this.info.MaxY)
if (yMin >= this.maxY)
{
return;
}

int yMax = Math.Min(yMin + this.info.StepY, this.info.MaxY);
int yMax = Math.Min(yMin + this.stepY, this.maxY);
var rows = new RowInterval(yMin, yMax);

// Skip the safety copy when invoking a potentially impure method on a readonly field
Expand All @@ -73,35 +152,44 @@ private readonly struct RowIntervalOperationWrapper<T, TBuffer>
where T : struct, IRowIntervalOperation<TBuffer>
where TBuffer : unmanaged
{
private readonly IterationParameters info;
private readonly int minY;
private readonly int maxY;
private readonly int stepY;
private readonly int width;
private readonly MemoryAllocator allocator;
private readonly T operation;

[MethodImpl(InliningOptions.ShortMethod)]
public RowIntervalOperationWrapper(
in IterationParameters info,
int minY,
int maxY,
int stepY,
int width,
MemoryAllocator allocator,
in T operation)
{
this.info = info;
this.minY = minY;
this.maxY = maxY;
this.stepY = stepY;
this.width = width;
this.allocator = allocator;
this.operation = operation;
}

[MethodImpl(InliningOptions.ShortMethod)]
public void Invoke(int i)
{
int yMin = this.info.MinY + (i * this.info.StepY);
int yMin = this.minY + (i * this.stepY);

if (yMin >= this.info.MaxY)
if (yMin >= this.maxY)
{
return;
}

int yMax = Math.Min(yMin + this.info.StepY, this.info.MaxY);
int yMax = Math.Min(yMin + this.stepY, this.maxY);
var rows = new RowInterval(yMin, yMax);

using IMemoryOwner<TBuffer> buffer = this.allocator.Allocate<TBuffer>(this.info.Width);
using IMemoryOwner<TBuffer> buffer = this.allocator.Allocate<TBuffer>(this.width);

Unsafe.AsRef(in this.operation).Invoke(in rows, buffer.Memory.Span);
}
Expand Down
Loading