From 0d990e0b1fafcdd64dea08692487370f7822292c Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 27 Feb 2020 12:47:07 +0100 Subject: [PATCH] Added single row value delegate wrappers --- .../Advanced/ParallelRowIterator.Wrappers.cs | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/ImageSharp/Advanced/ParallelRowIterator.Wrappers.cs b/src/ImageSharp/Advanced/ParallelRowIterator.Wrappers.cs index adbad0d662..bd30d4ff4f 100644 --- a/src/ImageSharp/Advanced/ParallelRowIterator.Wrappers.cs +++ b/src/ImageSharp/Advanced/ParallelRowIterator.Wrappers.cs @@ -38,6 +38,81 @@ namespace SixLabors.ImageSharp.Advanced } } + private readonly struct WrappingRowAction + where T : struct, IRowAction + { + private readonly IterationParameters info; + private readonly T action; + + [MethodImpl(InliningOptions.ShortMethod)] + public WrappingRowAction(in IterationParameters info, in T action) + { + this.info = info; + this.action = action; + } + + [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); + + 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 WrappingRowAction + where T : struct, IRowAction + where TBuffer : unmanaged + { + private readonly IterationParameters info; + private readonly MemoryAllocator allocator; + private readonly T action; + + [MethodImpl(InliningOptions.ShortMethod)] + public WrappingRowAction( + in IterationParameters info, + MemoryAllocator allocator, + in T action) + { + this.info = info; + this.allocator = allocator; + this.action = action; + } + + [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); + + using IMemoryOwner buffer = this.allocator.Allocate(this.info.MaxX); + + Span span = buffer.Memory.Span; + + for (int y = yMin; y < yMax; y++) + { + Unsafe.AsRef(this.action).Invoke(y, span); + } + } + } + private readonly struct RowIntervalOperationWrapper where T : struct, IRowIntervalOperation {