//
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
//
namespace ImageSharp.Benchmarks
{
using System;
using BenchmarkDotNet.Attributes;
using ImageSharp.PixelFormats;
using CoreSize = ImageSharp.Size;
using System.Numerics;
using ImageSharp.Memory;
using ImageSharp.PixelFormats.PixelBlenders;
public class PorterDuffBulkVsPixel : BenchmarkBase
{
private void BulkVectorConvert(Span destination, Span background, Span source, Span amount)
where TPixel : struct, IPixel
{
Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
using (Buffer buffer = new Buffer(destination.Length * 3))
{
Span destinationSpan = buffer.Slice(0, destination.Length);
Span backgroundSpan = buffer.Slice(destination.Length, destination.Length);
Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
PixelOperations.Instance.ToVector4(background, backgroundSpan, destination.Length);
PixelOperations.Instance.ToVector4(source, sourceSpan, destination.Length);
for (int i = 0; i < destination.Length; i++)
{
destinationSpan[i] = PorterDuffFunctions.NormalBlendFunction(backgroundSpan[i], sourceSpan[i], amount[i]);
}
PixelOperations.Instance.PackFromVector4(destinationSpan, destination, destination.Length);
}
}
private void BulkPixelConvert(Span destination, Span background, Span source, Span amount)
where TPixel : struct, IPixel
{
Guard.MustBeGreaterThanOrEqualTo(destination.Length, background.Length, nameof(destination));
Guard.MustBeGreaterThanOrEqualTo(source.Length, background.Length, nameof(destination));
Guard.MustBeGreaterThanOrEqualTo(amount.Length, background.Length, nameof(destination));
for (int i = 0; i < destination.Length; i++)
{
destination[i] = PorterDuffFunctions.NormalBlendFunction(destination[i], source[i], amount[i]);
}
}
[Benchmark(Description = "ImageSharp BulkVectorConvert")]
public CoreSize BulkVectorConvert()
{
using (Image image = new Image(800, 800))
{
Buffer amounts = new Buffer(image.Width);
for (int x = 0; x < image.Width; x++)
{
amounts[x] = 1;
}
using (PixelAccessor pixels = image.Lock())
{
for (int y = 0; y < image.Height; y++)
{
Span span = pixels.GetRowSpan(y);
BulkVectorConvert(span, span, span, amounts);
}
}
return new CoreSize(image.Width, image.Height);
}
}
[Benchmark(Description = "ImageSharp BulkPixelConvert")]
public CoreSize BulkPixelConvert()
{
using (Image image = new Image(800, 800))
{
Buffer amounts = new Buffer(image.Width);
for (int x = 0; x < image.Width; x++)
{
amounts[x] = 1;
}
using (PixelAccessor pixels = image.Lock())
{
for (int y = 0; y < image.Height; y++)
{
Span span = pixels.GetRowSpan(y);
BulkPixelConvert(span, span, span, amounts);
}
}
return new CoreSize(image.Width, image.Height);
}
}
}
}