Browse Source

drop parallelism in ResizeProcessor for simplicity

af/merge-core
Anton Firszov 7 years ago
parent
commit
1f12fd8104
  1. 72
      src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs

72
src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor.cs

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0.
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
@ -244,63 +245,48 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
// First process the columns. Since we are not using multiple threads startY and endY
// are the upper and lower bounds of the source rectangle.
using (Buffer2D<Vector4> firstPassPixelsTransposed = source.MemoryAllocator.Allocate2D<Vector4>(sourceHeight, width))
using (IMemoryOwner<Vector4> tempBuffer = source.MemoryAllocator.Allocate<Vector4>(Math.Max(source.Width, width)))
{
firstPassPixelsTransposed.MemorySource.Clear();
var processColsRect = new Rectangle(0, 0, source.Width, sourceRectangle.Bottom);
for (int y = 0; y < sourceRectangle.Bottom; y++)
{
Span<TPixel> sourceRow = source.GetPixelRowSpan(y).Slice(sourceX);
Span<Vector4> tempRowSpan = tempBuffer.GetSpan().Slice(sourceX, source.Width - sourceX);
ParallelHelper.IterateRowsWithTempBuffer<Vector4>(
processColsRect,
configuration,
(rows, tempRowBuffer) =>
{
for (int y = rows.Min; y < rows.Max; y++)
{
Span<TPixel> sourceRow = source.GetPixelRowSpan(y).Slice(sourceX);
Span<Vector4> tempRowSpan = tempRowBuffer.Span.Slice(sourceX);
PixelOperations<TPixel>.Instance.ToVector4(configuration, sourceRow, tempRowSpan, conversionModifiers);
ref Vector4 firstPassBaseRef = ref firstPassPixelsTransposed.Span[y];
PixelOperations<TPixel>.Instance.ToVector4(configuration, sourceRow, tempRowSpan, conversionModifiers);
for (int x = minX; x < maxX; x++)
{
ResizeKernel kernel = this.horizontalKernelMap.GetKernel(x - startX);
Unsafe.Add(ref firstPassBaseRef, x * sourceHeight) = kernel.Convolve(tempRowSpan);
}
}
});
ref Vector4 firstPassBaseRef = ref firstPassPixelsTransposed.Span[y];
var processRowsRect = Rectangle.FromLTRB(0, minY, width, maxY);
for (int x = minX; x < maxX; x++)
{
ResizeKernel kernel = this.horizontalKernelMap.GetKernel(x - startX);
Unsafe.Add(ref firstPassBaseRef, x * sourceHeight) = kernel.Convolve(tempRowSpan);
}
}
// Now process the rows.
ParallelHelper.IterateRowsWithTempBuffer<Vector4>(
processRowsRect,
configuration,
(rows, tempRowBuffer) =>
{
Span<Vector4> tempRowSpan = tempRowBuffer.Span;
Span<Vector4> tempColSpan = tempBuffer.GetSpan().Slice(0, width);
for (int y = rows.Min; y < rows.Max; y++)
{
// Ensure offsets are normalized for cropping and padding.
ResizeKernel kernel = this.verticalKernelMap.GetKernel(y - startY);
for (int y = minY; y < maxY; y++)
{
// Ensure offsets are normalized for cropping and padding.
ResizeKernel kernel = this.verticalKernelMap.GetKernel(y - startY);
ref Vector4 tempRowBase = ref MemoryMarshal.GetReference(tempRowSpan);
ref Vector4 tempRowBase = ref MemoryMarshal.GetReference(tempColSpan);
for (int x = 0; x < width; x++)
{
Span<Vector4> firstPassColumn = firstPassPixelsTransposed.GetRowSpan(x).Slice(sourceY);
for (int x = 0; x < width; x++)
{
Span<Vector4> firstPassColumn = firstPassPixelsTransposed.GetRowSpan(x).Slice(sourceY);
// Destination color components
Unsafe.Add(ref tempRowBase, x) = kernel.Convolve(firstPassColumn);
}
// Destination color components
Unsafe.Add(ref tempRowBase, x) = kernel.Convolve(firstPassColumn);
}
Span<TPixel> targetRowSpan = destination.GetPixelRowSpan(y);
Span<TPixel> targetRowSpan = destination.GetPixelRowSpan(y);
PixelOperations<TPixel>.Instance.FromVector4Destructive(configuration, tempRowSpan, targetRowSpan, conversionModifiers);
}
});
PixelOperations<TPixel>.Instance.FromVector4Destructive(configuration, tempColSpan, targetRowSpan, conversionModifiers);
}
}
}

Loading…
Cancel
Save