Skip to content

Commit 1c5e3e1

Browse files
Modernize base PorterDuffFunctions
1 parent 66f21f7 commit 1c5e3e1

File tree

4 files changed

+59
-59
lines changed

4 files changed

+59
-59
lines changed

src/ImageSharp/Common/Helpers/Numerics.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,7 @@ public static Vector4 WithW(Vector4 value, Vector4 w)
690690
/// </summary>
691691
/// <param name="vectors">The span of vectors</param>
692692
[MethodImpl(MethodImplOptions.AggressiveInlining)]
693-
public static unsafe void CubePowOnXYZ(Span<Vector4> vectors)
693+
public static void CubePowOnXYZ(Span<Vector4> vectors)
694694
{
695695
ref Vector4 baseRef = ref MemoryMarshal.GetReference(vectors);
696696
ref Vector4 endRef = ref Unsafe.Add(ref baseRef, (uint)vectors.Length);

src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -602,48 +602,25 @@ private static void Shuffle4Slice3(
602602
}
603603

604604
/// <summary>
605-
/// Performs a multiplication and an addition of the <see cref="Vector256{Single}"/>.
606-
/// TODO: Fix. The arguments are in a different order to the FMA intrinsic.
605+
/// Performs a multiplication and a negated addition of the <see cref="Vector256{Single}"/>.
607606
/// </summary>
608-
/// <remarks>ret = (vm0 * vm1) + va</remarks>
609-
/// <param name="va">The vector to add to the intermediate result.</param>
607+
/// <remarks>ret = va - (vm0 * vm1)</remarks>
608+
/// <param name="va">The vector to add to the negated intermediate result.</param>
610609
/// <param name="vm0">The first vector to multiply.</param>
611610
/// <param name="vm1">The second vector to multiply.</param>
612611
/// <returns>The <see cref="Vector256{T}"/>.</returns>
613-
[MethodImpl(InliningOptions.AlwaysInline)]
614-
public static Vector256<float> MultiplyAdd(
612+
[MethodImpl(InliningOptions.ShortMethod)]
613+
public static Vector256<float> MultiplyAddNegated(
615614
Vector256<float> va,
616615
Vector256<float> vm0,
617616
Vector256<float> vm1)
618617
{
619618
if (Fma.IsSupported)
620619
{
621-
return Fma.MultiplyAdd(vm1, vm0, va);
622-
}
623-
624-
return va + (vm0 * vm1);
625-
}
626-
627-
/// <summary>
628-
/// Performs a multiplication and a negated addition of the <see cref="Vector256{Single}"/>.
629-
/// </summary>
630-
/// <remarks>ret = c - (a * b)</remarks>
631-
/// <param name="a">The first vector to multiply.</param>
632-
/// <param name="b">The second vector to multiply.</param>
633-
/// <param name="c">The vector to add negated to the intermediate result.</param>
634-
/// <returns>The <see cref="Vector256{T}"/>.</returns>
635-
[MethodImpl(InliningOptions.ShortMethod)]
636-
public static Vector256<float> MultiplyAddNegated(
637-
Vector256<float> a,
638-
Vector256<float> b,
639-
Vector256<float> c)
640-
{
641-
if (Fma.IsSupported)
642-
{
643-
return Fma.MultiplyAddNegated(a, b, c);
620+
return Fma.MultiplyAddNegated(vm0, vm1, va);
644621
}
645622

646-
return Avx.Subtract(c, Avx.Multiply(a, b));
623+
return Avx.Subtract(va, Avx.Multiply(vm0, vm1));
647624
}
648625

649626
/// <summary>

src/ImageSharp/Common/Helpers/Vector256Utilities.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,28 @@ public static Vector256<float> MultiplyAdd(
115115
return va + (vm0 * vm1);
116116
}
117117

118+
/// <summary>
119+
/// Performs a multiplication and a negated addition of the <see cref="Vector256{Single}"/>.
120+
/// </summary>
121+
/// <remarks>ret = va - (vm0 * vm1)</remarks>
122+
/// <param name="va">The vector to add to the negated intermediate result.</param>
123+
/// <param name="vm0">The first vector to multiply.</param>
124+
/// <param name="vm1">The second vector to multiply.</param>
125+
/// <returns>The <see cref="Vector256{T}"/>.</returns>
126+
[MethodImpl(InliningOptions.ShortMethod)]
127+
public static Vector256<float> MultiplyAddNegated(
128+
Vector256<float> va,
129+
Vector256<float> vm0,
130+
Vector256<float> vm1)
131+
{
132+
if (Fma.IsSupported)
133+
{
134+
return Fma.MultiplyAddNegated(vm0, vm1, va);
135+
}
136+
137+
return va - (vm0 * vm1);
138+
}
139+
118140
/// <summary>
119141
/// Performs a multiplication and a subtraction of the <see cref="Vector256{Single}"/>.
120142
/// </summary>

src/ImageSharp/PixelFormats/PixelBlenders/PorterDuffFunctions.cs

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Runtime.CompilerServices;
66
using System.Runtime.Intrinsics;
77
using System.Runtime.Intrinsics.X86;
8+
using SixLabors.ImageSharp.Common.Helpers;
89

910
namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders;
1011

@@ -62,7 +63,7 @@ public static Vector4 Multiply(Vector4 backdrop, Vector4 source)
6263
/// <returns>The <see cref="Vector256{Single}"/>.</returns>
6364
[MethodImpl(MethodImplOptions.AggressiveInlining)]
6465
public static Vector256<float> Multiply(Vector256<float> backdrop, Vector256<float> source)
65-
=> Avx.Multiply(backdrop, source);
66+
=> backdrop * source;
6667

6768
/// <summary>
6869
/// Returns the result of the "Add" compositing equation.
@@ -82,7 +83,7 @@ public static Vector4 Add(Vector4 backdrop, Vector4 source)
8283
/// <returns>The <see cref="Vector256{Single}"/>.</returns>
8384
[MethodImpl(MethodImplOptions.AggressiveInlining)]
8485
public static Vector256<float> Add(Vector256<float> backdrop, Vector256<float> source)
85-
=> Avx.Min(Vector256.Create(1F), Avx.Add(backdrop, source));
86+
=> Vector256.Min(Vector256.Create(1F), backdrop + source);
8687

8788
/// <summary>
8889
/// Returns the result of the "Subtract" compositing equation.
@@ -102,7 +103,7 @@ public static Vector4 Subtract(Vector4 backdrop, Vector4 source)
102103
/// <returns>The <see cref="Vector256{Single}"/>.</returns>
103104
[MethodImpl(MethodImplOptions.AggressiveInlining)]
104105
public static Vector256<float> Subtract(Vector256<float> backdrop, Vector256<float> source)
105-
=> Avx.Max(Vector256<float>.Zero, Avx.Subtract(backdrop, source));
106+
=> Vector256.Max(Vector256<float>.Zero, backdrop - source);
106107

107108
/// <summary>
108109
/// Returns the result of the "Screen" compositing equation.
@@ -124,7 +125,7 @@ public static Vector4 Screen(Vector4 backdrop, Vector4 source)
124125
public static Vector256<float> Screen(Vector256<float> backdrop, Vector256<float> source)
125126
{
126127
Vector256<float> vOne = Vector256.Create(1F);
127-
return SimdUtils.HwIntrinsics.MultiplyAddNegated(Avx.Subtract(vOne, backdrop), Avx.Subtract(vOne, source), vOne);
128+
return Vector256_.MultiplyAddNegated(vOne, vOne - backdrop, vOne - source);
128129
}
129130

130131
/// <summary>
@@ -145,7 +146,7 @@ public static Vector4 Darken(Vector4 backdrop, Vector4 source)
145146
/// <returns>The <see cref="Vector256{Single}"/>.</returns>
146147
[MethodImpl(MethodImplOptions.AggressiveInlining)]
147148
public static Vector256<float> Darken(Vector256<float> backdrop, Vector256<float> source)
148-
=> Avx.Min(backdrop, source);
149+
=> Vector256.Min(backdrop, source);
149150

150151
/// <summary>
151152
/// Returns the result of the "Lighten" compositing equation.
@@ -164,7 +165,7 @@ public static Vector256<float> Darken(Vector256<float> backdrop, Vector256<float
164165
/// <returns>The <see cref="Vector256{Single}"/>.</returns>
165166
[MethodImpl(MethodImplOptions.AggressiveInlining)]
166167
public static Vector256<float> Lighten(Vector256<float> backdrop, Vector256<float> source)
167-
=> Avx.Max(backdrop, source);
168+
=> Vector256.Max(backdrop, source);
168169

169170
/// <summary>
170171
/// Returns the result of the "Overlay" compositing equation.
@@ -192,7 +193,7 @@ public static Vector4 Overlay(Vector4 backdrop, Vector4 source)
192193
public static Vector256<float> Overlay(Vector256<float> backdrop, Vector256<float> source)
193194
{
194195
Vector256<float> color = OverlayValueFunction(backdrop, source);
195-
return Avx.Min(Vector256.Create(1F), Avx.Blend(color, Vector256<float>.Zero, BlendAlphaControl));
196+
return Vector256.Min(Vector256.Create(1F), Avx.Blend(color, Vector256<float>.Zero, BlendAlphaControl));
196197
}
197198

198199
/// <summary>
@@ -221,7 +222,7 @@ public static Vector4 HardLight(Vector4 backdrop, Vector4 source)
221222
public static Vector256<float> HardLight(Vector256<float> backdrop, Vector256<float> source)
222223
{
223224
Vector256<float> color = OverlayValueFunction(source, backdrop);
224-
return Avx.Min(Vector256.Create(1F), Avx.Blend(color, Vector256<float>.Zero, BlendAlphaControl));
225+
return Vector256.Min(Vector256.Create(1F), Avx.Blend(color, Vector256<float>.Zero, BlendAlphaControl));
225226
}
226227

227228
/// <summary>
@@ -244,10 +245,10 @@ private static float OverlayValueFunction(float backdrop, float source)
244245
public static Vector256<float> OverlayValueFunction(Vector256<float> backdrop, Vector256<float> source)
245246
{
246247
Vector256<float> vOne = Vector256.Create(1F);
247-
Vector256<float> left = Avx.Multiply(Avx.Add(backdrop, backdrop), source);
248+
Vector256<float> left = (backdrop + backdrop) * source;
248249

249250
Vector256<float> vOneMinusSource = Avx.Subtract(vOne, source);
250-
Vector256<float> right = SimdUtils.HwIntrinsics.MultiplyAddNegated(Avx.Add(vOneMinusSource, vOneMinusSource), Avx.Subtract(vOne, backdrop), vOne);
251+
Vector256<float> right = Vector256_.MultiplyAddNegated(vOne, vOneMinusSource + vOneMinusSource, vOne - backdrop);
251252
Vector256<float> cmp = Avx.CompareGreaterThan(backdrop, Vector256.Create(.5F));
252253
return Avx.BlendVariable(left, right, cmp);
253254
}
@@ -295,17 +296,17 @@ public static Vector256<float> Over(Vector256<float> destination, Vector256<floa
295296
Vector256<float> sW = Avx.Permute(source, ShuffleAlphaControl);
296297
Vector256<float> dW = Avx.Permute(destination, ShuffleAlphaControl);
297298

298-
Vector256<float> blendW = Avx.Multiply(sW, dW);
299-
Vector256<float> dstW = Avx.Subtract(dW, blendW);
300-
Vector256<float> srcW = Avx.Subtract(sW, blendW);
299+
Vector256<float> blendW = sW * dW;
300+
Vector256<float> dstW = dW - blendW;
301+
Vector256<float> srcW = sW - blendW;
301302

302303
// calculate final alpha
303-
Vector256<float> alpha = Avx.Add(dstW, sW);
304+
Vector256<float> alpha = dstW + sW;
304305

305306
// calculate final color
306-
Vector256<float> color = Avx.Multiply(destination, dstW);
307-
color = SimdUtils.HwIntrinsics.MultiplyAdd(color, source, srcW);
308-
color = SimdUtils.HwIntrinsics.MultiplyAdd(color, blend, blendW);
307+
Vector256<float> color = destination * dstW;
308+
color = Vector256_.MultiplyAdd(color, source, srcW);
309+
color = Vector256_.MultiplyAdd(color, blend, blendW);
309310

310311
// unpremultiply
311312
return Numerics.UnPremultiply(color, alpha);
@@ -354,11 +355,11 @@ public static Vector256<float> Atop(Vector256<float> destination, Vector256<floa
354355

355356
// calculate weights
356357
Vector256<float> sW = Avx.Permute(source, ShuffleAlphaControl);
357-
Vector256<float> blendW = Avx.Multiply(sW, alpha);
358-
Vector256<float> dstW = Avx.Subtract(alpha, blendW);
358+
Vector256<float> blendW = sW * alpha;
359+
Vector256<float> dstW = alpha - blendW;
359360

360361
// calculate final color
361-
Vector256<float> color = SimdUtils.HwIntrinsics.MultiplyAdd(Avx.Multiply(blend, blendW), destination, dstW);
362+
Vector256<float> color = Vector256_.MultiplyAdd(Avx.Multiply(blend, blendW), destination, dstW);
362363

363364
// unpremultiply
364365
return Numerics.UnPremultiply(color, alpha);
@@ -392,10 +393,10 @@ public static Vector4 In(Vector4 destination, Vector4 source)
392393
public static Vector256<float> In(Vector256<float> destination, Vector256<float> source)
393394
{
394395
// calculate alpha
395-
Vector256<float> alpha = Avx.Permute(Avx.Multiply(source, destination), ShuffleAlphaControl);
396+
Vector256<float> alpha = Avx.Permute(source * destination, ShuffleAlphaControl);
396397

397398
// premultiply
398-
Vector256<float> color = Avx.Multiply(source, alpha);
399+
Vector256<float> color = source * alpha;
399400

400401
// unpremultiply
401402
return Numerics.UnPremultiply(color, alpha);
@@ -429,10 +430,10 @@ public static Vector4 Out(Vector4 destination, Vector4 source)
429430
public static Vector256<float> Out(Vector256<float> destination, Vector256<float> source)
430431
{
431432
// calculate alpha
432-
Vector256<float> alpha = Avx.Permute(Avx.Multiply(source, Avx.Subtract(Vector256.Create(1F), destination)), ShuffleAlphaControl);
433+
Vector256<float> alpha = Avx.Permute(source * (Vector256.Create(1F) - destination), ShuffleAlphaControl);
433434

434435
// premultiply
435-
Vector256<float> color = Avx.Multiply(source, alpha);
436+
Vector256<float> color = source * alpha;
436437

437438
// unpremultiply
438439
return Numerics.UnPremultiply(color, alpha);
@@ -475,12 +476,12 @@ public static Vector256<float> Xor(Vector256<float> destination, Vector256<float
475476
Vector256<float> dW = Avx.Shuffle(destination, destination, ShuffleAlphaControl);
476477

477478
Vector256<float> vOne = Vector256.Create(1F);
478-
Vector256<float> srcW = Avx.Subtract(vOne, dW);
479-
Vector256<float> dstW = Avx.Subtract(vOne, sW);
479+
Vector256<float> srcW = vOne - dW;
480+
Vector256<float> dstW = vOne - sW;
480481

481482
// calculate alpha
482-
Vector256<float> alpha = SimdUtils.HwIntrinsics.MultiplyAdd(Avx.Multiply(dW, dstW), sW, srcW);
483-
Vector256<float> color = SimdUtils.HwIntrinsics.MultiplyAdd(Avx.Multiply(Avx.Multiply(dW, destination), dstW), Avx.Multiply(sW, source), srcW);
483+
Vector256<float> alpha = Vector256_.MultiplyAdd(Avx.Multiply(dW, dstW), sW, srcW);
484+
Vector256<float> color = Vector256_.MultiplyAdd(Avx.Multiply(Avx.Multiply(dW, destination), dstW), Avx.Multiply(sW, source), srcW);
484485

485486
// unpremultiply
486487
return Numerics.UnPremultiply(color, alpha);

0 commit comments

Comments
 (0)