Browse Source

adapt ParallelHelper in: FliterProcessor, GlowProcessor, VignetteProcessor

pull/710/head
Anton Firszov 8 years ago
parent
commit
d70fbc69d0
  1. 9
      src/ImageSharp/Common/ParallelUtils/ParallelHelper.cs
  2. 28
      src/ImageSharp/Processing/Processors/Filters/FilterProcessor.cs
  3. 60
      src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs
  4. 61
      src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs

9
src/ImageSharp/Common/ParallelUtils/ParallelHelper.cs

@ -127,6 +127,15 @@ namespace SixLabors.ImageSharp.ParallelUtils
}); });
} }
public static void IterateRowsWithTempBuffer<T>(
Rectangle rectangle,
Configuration configuration,
Action<RowInterval, Memory<T>> body)
where T : struct
{
IterateRowsWithTempBuffer(rectangle, configuration.GetParallelSettings(), body);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int DivideCeil(int dividend, int divisor) private static int DivideCeil(int dividend, int divisor)
{ {

28
src/ImageSharp/Processing/Processors/Filters/FilterProcessor.cs

@ -5,6 +5,7 @@ using System;
using System.Numerics; using System.Numerics;
using System.Threading.Tasks; using System.Threading.Tasks;
using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.ParallelUtils;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Primitives; using SixLabors.Primitives;
@ -35,25 +36,24 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters
protected override void OnFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration) protected override void OnFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration)
{ {
var interest = Rectangle.Intersect(sourceRectangle, source.Bounds()); var interest = Rectangle.Intersect(sourceRectangle, source.Bounds());
int startY = interest.Y;
int endY = interest.Bottom;
int startX = interest.X;
int endX = interest.Right;
Matrix4x4 matrix = this.Matrix; Matrix4x4 matrix = this.Matrix;
ParallelFor.WithConfiguration( ParallelHelper.IterateRows(
startY, interest,
endY,
configuration, configuration,
y => rows =>
{ {
Span<TPixel> row = source.GetPixelRowSpan(y); for (int y = rows.Min; y < rows.Max; y++)
for (int x = startX; x < endX; x++)
{ {
ref TPixel pixel = ref row[x]; Span<TPixel> row = source.GetPixelRowSpan(y);
var vector = Vector4.Transform(pixel.ToVector4(), matrix);
pixel.PackFromVector4(vector); for (int x = interest.X; x < interest.Right; x++)
{
ref TPixel pixel = ref row[x];
var vector = Vector4.Transform(pixel.ToVector4(), matrix);
pixel.PackFromVector4(vector);
}
} }
}); });
} }

60
src/ImageSharp/Processing/Processors/Overlays/GlowProcessor.cs

@ -7,6 +7,7 @@ using System.Numerics;
using System.Threading.Tasks; using System.Threading.Tasks;
using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.ParallelUtils;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Primitives; using SixLabors.ImageSharp.Primitives;
using SixLabors.Memory; using SixLabors.Memory;
@ -84,6 +85,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Overlays
/// <inheritdoc/> /// <inheritdoc/>
protected override void OnFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration) protected override void OnFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration)
{ {
// TODO: can we simplify the rectangle calculation?
int startY = sourceRectangle.Y; int startY = sourceRectangle.Y;
int endY = sourceRectangle.Bottom; int endY = sourceRectangle.Bottom;
int startX = sourceRectangle.X; int startX = sourceRectangle.X;
@ -113,36 +116,43 @@ namespace SixLabors.ImageSharp.Processing.Processors.Overlays
} }
int width = maxX - minX; int width = maxX - minX;
int offsetX = minX - startX;
var workingRect = Rectangle.FromLTRB(minX, minY, maxX, maxY);
using (IMemoryOwner<TPixel> rowColors = source.MemoryAllocator.Allocate<TPixel>(width)) using (IMemoryOwner<TPixel> rowColors = source.MemoryAllocator.Allocate<TPixel>(width))
{ {
// Be careful! Do not capture rowColorsSpan in the lambda below! rowColors.GetSpan().Fill(glowColor);
Span<TPixel> rowColorsSpan = rowColors.GetSpan();
for (int i = 0; i < width; i++) ParallelHelper.IterateRowsWithTempBuffer<float>(
{ workingRect,
rowColorsSpan[i] = glowColor;
}
ParallelFor.WithTemporaryBuffer<float>(
minY,
maxY,
configuration, configuration,
width, (rows, amounts) =>
(y, amounts) =>
{
Span<float> amountsSpan = amounts.GetSpan();
int offsetY = y - startY;
int offsetX = minX - startX;
for (int i = 0; i < width; i++)
{ {
float distance = Vector2.Distance(center, new Vector2(i + offsetX, offsetY)); Span<float> amountsSpan = amounts.Span;
amountsSpan[i] = (this.GraphicsOptions.BlendPercentage * (1 - (.95F * (distance / maxDistance)))).Clamp(0, 1);
} for (int y = rows.Min; y < rows.Max; y++)
{
Span<TPixel> destination = source.GetPixelRowSpan(offsetY).Slice(offsetX, width); int offsetY = y - startY;
this.blender.Blend(source.MemoryAllocator, destination, destination, rowColors.GetSpan(), amountsSpan); for (int i = 0; i < width; i++)
}); {
float distance = Vector2.Distance(center, new Vector2(i + offsetX, offsetY));
amountsSpan[i] =
(this.GraphicsOptions.BlendPercentage * (1 - (.95F * (distance / maxDistance))))
.Clamp(0, 1);
}
Span<TPixel> destination = source.GetPixelRowSpan(offsetY).Slice(offsetX, width);
this.blender.Blend(
source.MemoryAllocator,
destination,
destination,
rowColors.GetSpan(),
amountsSpan);
}
});
} }
} }
} }

61
src/ImageSharp/Processing/Processors/Overlays/VignetteProcessor.cs

@ -7,6 +7,7 @@ using System.Numerics;
using System.Threading.Tasks; using System.Threading.Tasks;
using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.ParallelUtils;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Primitives; using SixLabors.ImageSharp.Primitives;
using SixLabors.Memory; using SixLabors.Memory;
@ -115,43 +116,43 @@ namespace SixLabors.ImageSharp.Processing.Processors.Overlays
} }
int width = maxX - minX; int width = maxX - minX;
int offsetX = minX - startX;
var workingRect = Rectangle.FromLTRB(minX, minY, maxX, maxY);
using (IMemoryOwner<TPixel> rowColors = source.MemoryAllocator.Allocate<TPixel>(width)) using (IMemoryOwner<TPixel> rowColors = source.MemoryAllocator.Allocate<TPixel>(width))
{ {
// Be careful! Do not capture rowColorsSpan in the lambda below! rowColors.GetSpan().Fill(vignetteColor);
Span<TPixel> rowColorsSpan = rowColors.GetSpan();
for (int i = 0; i < width; i++)
{
rowColorsSpan[i] = vignetteColor;
}
ParallelFor.WithTemporaryBuffer<float>( ParallelHelper.IterateRowsWithTempBuffer<float>(
minY, workingRect,
maxY,
configuration, configuration,
width, (rows, amounts) =>
(y, amounts) =>
{ {
Span<float> amountsSpan = amounts.GetSpan(); Span<float> amountsSpan = amounts.Span;
int offsetY = y - startY;
int offsetX = minX - startX; for (int y = rows.Min; y < rows.Max; y++)
for (int i = 0; i < width; i++)
{ {
float distance = Vector2.Distance(centre, new Vector2(i + offsetX, offsetY)); int offsetY = y - startY;
amountsSpan[i] =
(this.GraphicsOptions.BlendPercentage * (.9F * (distance / maxDistance))).Clamp( for (int i = 0; i < width; i++)
0, {
1); float distance = Vector2.Distance(centre, new Vector2(i + offsetX, offsetY));
amountsSpan[i] =
(this.GraphicsOptions.BlendPercentage * (.9F * (distance / maxDistance))).Clamp(
0,
1);
}
Span<TPixel> destination = source.GetPixelRowSpan(offsetY).Slice(offsetX, width);
this.blender.Blend(
source.MemoryAllocator,
destination,
destination,
rowColors.GetSpan(),
amountsSpan);
} }
Span<TPixel> destination = source.GetPixelRowSpan(offsetY).Slice(offsetX, width);
this.blender.Blend(
source.MemoryAllocator,
destination,
destination,
rowColors.GetSpan(),
amountsSpan);
}); });
} }
} }

Loading…
Cancel
Save