Skip to content

Commit b05b25b

Browse files
Use RemoteExecutor for composition tests
1 parent c06da8c commit b05b25b

File tree

2 files changed

+86
-33
lines changed

2 files changed

+86
-33
lines changed
Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,66 @@
11
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
33

4-
namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders;
5-
64
using SixLabors.ImageSharp.PixelFormats;
75
using SixLabors.ImageSharp.Processing;
6+
using SixLabors.ImageSharp.Tests.TestUtilities;
87

9-
using Xunit;
8+
namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelBlenders;
109

1110
public class PorterDuffCompositorTests
1211
{
1312
// TODO: Add other modes to compare.
1413
public static readonly TheoryData<PixelAlphaCompositionMode> CompositingOperators =
15-
new TheoryData<PixelAlphaCompositionMode>
16-
{
17-
PixelAlphaCompositionMode.Src,
18-
PixelAlphaCompositionMode.SrcAtop,
19-
PixelAlphaCompositionMode.SrcOver,
20-
PixelAlphaCompositionMode.SrcIn,
21-
PixelAlphaCompositionMode.SrcOut,
22-
PixelAlphaCompositionMode.Dest,
23-
PixelAlphaCompositionMode.DestAtop,
24-
PixelAlphaCompositionMode.DestOver,
25-
PixelAlphaCompositionMode.DestIn,
26-
PixelAlphaCompositionMode.DestOut,
27-
PixelAlphaCompositionMode.Clear,
28-
PixelAlphaCompositionMode.Xor
29-
};
14+
new()
15+
{
16+
PixelAlphaCompositionMode.Src,
17+
PixelAlphaCompositionMode.SrcAtop,
18+
PixelAlphaCompositionMode.SrcOver,
19+
PixelAlphaCompositionMode.SrcIn,
20+
PixelAlphaCompositionMode.SrcOut,
21+
PixelAlphaCompositionMode.Dest,
22+
PixelAlphaCompositionMode.DestAtop,
23+
PixelAlphaCompositionMode.DestOver,
24+
PixelAlphaCompositionMode.DestIn,
25+
PixelAlphaCompositionMode.DestOut,
26+
PixelAlphaCompositionMode.Clear,
27+
PixelAlphaCompositionMode.Xor
28+
};
3029

3130
[Theory]
3231
[WithFile(TestImages.Png.PDDest, nameof(CompositingOperators), PixelTypes.Rgba32)]
3332
public void PorterDuffOutputIsCorrect(TestImageProvider<Rgba32> provider, PixelAlphaCompositionMode mode)
3433
{
35-
var srcFile = TestFile.Create(TestImages.Png.PDSrc);
36-
using (Image<Rgba32> src = srcFile.CreateRgba32Image())
37-
using (Image<Rgba32> dest = provider.GetImage())
34+
static void RunTest(string providerDump, string alphaMode)
3835
{
39-
var options = new GraphicsOptions
36+
TestImageProvider<Rgba32> provider
37+
= BasicSerializer.Deserialize<TestImageProvider<Rgba32>>(providerDump);
38+
39+
TestFile srcFile = TestFile.Create(TestImages.Png.PDSrc);
40+
using Image<Rgba32> src = srcFile.CreateRgba32Image();
41+
using Image<Rgba32> dest = provider.GetImage();
42+
GraphicsOptions options = new()
4043
{
4144
Antialias = false,
42-
AlphaCompositionMode = mode
45+
AlphaCompositionMode = Enum.Parse<PixelAlphaCompositionMode>(alphaMode)
4346
};
4447

45-
using (Image<Rgba32> res = dest.Clone(x => x.DrawImage(src, options)))
46-
{
47-
string combinedMode = mode.ToString();
48-
49-
if (combinedMode != "Src" && combinedMode.StartsWith("Src"))
50-
{
51-
combinedMode = combinedMode.Substring(3);
52-
}
48+
using Image<Rgba32> res = dest.Clone(x => x.DrawImage(src, options));
49+
string combinedMode = alphaMode;
5350

54-
res.DebugSave(provider, combinedMode);
55-
res.CompareToReferenceOutput(provider, combinedMode);
51+
if (combinedMode != "Src" && combinedMode.StartsWith("Src", StringComparison.OrdinalIgnoreCase))
52+
{
53+
combinedMode = combinedMode[3..];
5654
}
55+
56+
res.DebugSave(provider, combinedMode);
57+
res.CompareToReferenceOutput(provider, combinedMode);
5758
}
59+
60+
FeatureTestRunner.RunWithHwIntrinsicsFeature(
61+
RunTest,
62+
HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX,
63+
provider,
64+
mode.ToString());
5865
}
5966
}

tests/ImageSharp.Tests/TestUtilities/FeatureTesting/FeatureTestRunner.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,52 @@ public static void RunWithHwIntrinsicsFeature<T, T2>(
257257
}
258258
}
259259

260+
/// <summary>
261+
/// Runs the given test <paramref name="action"/> within an environment
262+
/// where the given <paramref name="intrinsics"/> features.
263+
/// </summary>
264+
/// <param name="action">The test action to run.</param>
265+
/// <param name="intrinsics">The intrinsics features.</param>
266+
/// <param name="arg1">The value to pass as a parameter to the test action.</param>
267+
/// <param name="arg2">The second value to pass as a parameter to the test action.</param>
268+
public static void RunWithHwIntrinsicsFeature<T>(
269+
Action<string, string> action,
270+
HwIntrinsics intrinsics,
271+
T arg1,
272+
string arg2)
273+
where T : IXunitSerializable
274+
{
275+
if (!RemoteExecutor.IsSupported)
276+
{
277+
return;
278+
}
279+
280+
foreach (KeyValuePair<HwIntrinsics, string> intrinsic in intrinsics.ToFeatureKeyValueCollection())
281+
{
282+
ProcessStartInfo processStartInfo = new();
283+
if (intrinsic.Key != HwIntrinsics.AllowAll)
284+
{
285+
processStartInfo.Environment[$"COMPlus_{intrinsic.Value}"] = "0";
286+
287+
RemoteExecutor.Invoke(
288+
action,
289+
BasicSerializer.Serialize(arg1),
290+
arg2,
291+
new RemoteInvokeOptions
292+
{
293+
StartInfo = processStartInfo
294+
})
295+
.Dispose();
296+
}
297+
else
298+
{
299+
// Since we are running using the default architecture there is no
300+
// point creating the overhead of running the action in a separate process.
301+
action(BasicSerializer.Serialize(arg1), arg2);
302+
}
303+
}
304+
}
305+
260306
/// <summary>
261307
/// Runs the given test <paramref name="action"/> within an environment
262308
/// where the given <paramref name="intrinsics"/> features.

0 commit comments

Comments
 (0)