mirror of https://github.com/SixLabors/ImageSharp
16 changed files with 175 additions and 244 deletions
@ -0,0 +1,110 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
using System.Buffers; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
using System.Threading.Tasks; |
||||
|
using SixLabors.ImageSharp.Memory; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Advanced |
||||
|
{ |
||||
|
/// <content>
|
||||
|
/// Utility methods for batched processing of pixel row intervals.
|
||||
|
/// Parallel execution is optimized for image processing based on values defined
|
||||
|
/// <see cref="ParallelExecutionSettings"/> or <see cref="Configuration"/>.
|
||||
|
/// Using this class is preferred over direct usage of <see cref="Parallel"/> utility methods.
|
||||
|
/// </content>
|
||||
|
public static partial class ParallelRowIterator |
||||
|
{ |
||||
|
private readonly struct WrappingRowIntervalInfo |
||||
|
{ |
||||
|
public readonly int MinY; |
||||
|
public readonly int MaxY; |
||||
|
public readonly int StepY; |
||||
|
public readonly int MaxX; |
||||
|
|
||||
|
public WrappingRowIntervalInfo(int minY, int maxY, int stepY) |
||||
|
: this(minY, maxY, stepY, 0) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public WrappingRowIntervalInfo(int minY, int maxY, int stepY, int maxX) |
||||
|
{ |
||||
|
this.MinY = minY; |
||||
|
this.MaxY = maxY; |
||||
|
this.StepY = stepY; |
||||
|
this.MaxX = maxX; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private readonly struct WrappingRowIntervalOperation<T> |
||||
|
where T : struct, IRowIntervalOperation |
||||
|
{ |
||||
|
private readonly WrappingRowIntervalInfo info; |
||||
|
private readonly T operation; |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public WrappingRowIntervalOperation(in WrappingRowIntervalInfo info, in T operation) |
||||
|
{ |
||||
|
this.info = info; |
||||
|
this.operation = operation; |
||||
|
} |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void Invoke(int i) |
||||
|
{ |
||||
|
int yMin = this.info.MinY + (i * this.info.StepY); |
||||
|
|
||||
|
if (yMin >= this.info.MaxY) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
int yMax = Math.Min(yMin + this.info.StepY, this.info.MaxY); |
||||
|
var rows = new RowInterval(yMin, yMax); |
||||
|
|
||||
|
// Skip the safety copy when invoking a potentially impure method on a readonly field
|
||||
|
Unsafe.AsRef(this.operation).Invoke(in rows); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private readonly struct WrappingRowIntervalBufferOperation<T, TBuffer> |
||||
|
where T : struct, IRowIntervalOperation<TBuffer> |
||||
|
where TBuffer : unmanaged |
||||
|
{ |
||||
|
private readonly WrappingRowIntervalInfo info; |
||||
|
private readonly MemoryAllocator allocator; |
||||
|
private readonly T operation; |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public WrappingRowIntervalBufferOperation( |
||||
|
in WrappingRowIntervalInfo info, |
||||
|
MemoryAllocator allocator, |
||||
|
in T operation) |
||||
|
{ |
||||
|
this.info = info; |
||||
|
this.allocator = allocator; |
||||
|
this.operation = operation; |
||||
|
} |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void Invoke(int i) |
||||
|
{ |
||||
|
int yMin = this.info.MinY + (i * this.info.StepY); |
||||
|
|
||||
|
if (yMin >= this.info.MaxY) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
int yMax = Math.Min(yMin + this.info.StepY, this.info.MaxY); |
||||
|
var rows = new RowInterval(yMin, yMax); |
||||
|
|
||||
|
using IMemoryOwner<TBuffer> buffer = this.allocator.Allocate<TBuffer>(this.info.MaxX); |
||||
|
|
||||
|
Unsafe.AsRef(this.operation).Invoke(in rows, buffer.Memory.Span); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue