using XFESystem.Desktop; using Xunit; namespace XFESystem.Core.Tests; public sealed class SceneMotionBufferTests { [Theory] [InlineData(2, 3)] [InlineData(-2, -1)] [InlineData(0, 0)] public void TranslationReadsThePointerFreeSceneEvenWhenRectanglesOverlap(int dx, int dy) { var scene = Enumerable.Range(0, 120).ToArray(); var pixels = Enumerable.Repeat(-1, 120).ToArray(); var buffer = new DesktopSceneMotionBuffer(pixels, scene, 12, 10); buffer.Preserve(new(3, 3, 5, 4), 3 + dx, 3 + dy); for (int y = 0; y < 10; y++) for (int x = 0; x < 12; x++) Assert.Equal(buffer.PreservedBounds.Contains(x, y) ? scene[(y - dy) * 12 + x - dx] : -1, pixels[y * 12 + x]); Assert.Equal(20, buffer.PixelsReused); Assert.Equal(1, buffer.ReuseCount); } [Fact] public void SourceAndDestinationClippingRetainTheSameTranslation() { var scene = Enumerable.Range(0, 80).ToArray(); var pixels = Enumerable.Repeat(-1, 80).ToArray(); var buffer = new DesktopSceneMotionBuffer(pixels, scene, 10, 8); buffer.Preserve(new(-2, -3, 8, 7), 6, 5); Assert.Equal(default, buffer.PreservedBounds); Assert.All(pixels, value => Assert.Equal(-1, value)); buffer.Preserve(new(-2, -1, 8, 7), 3, 0); Assert.Equal(new DesktopBounds(5, 1, 5, 6), buffer.PreservedBounds); for (int y = 1; y < 7; y++) for (int x = 5; x < 10; x++) Assert.Equal(scene[(y - 1) * 10 + x - 5], pixels[y * 10 + x]); } [Fact] public void RowExclusionSkipsOnlyTheCopiedOpaqueRectangle() { var buffer = new DesktopSceneMotionBuffer(new int[100], new int[100], 10, 10); buffer.Preserve(new(0, 0, 4, 3), 3, 4); for (int row = 0; row < 10; row++) for (int x = 0; x < 10; x++) { buffer.RowSegments(x, 10 - x, row, out int leftEnd, out int rightStart); for (int col = x; col < 10; col++) Assert.Equal(!buffer.PreservedBounds.Contains(col, row), col < leftEnd || col >= rightStart); } Assert.True(buffer.Contains(new(4, 4, 2, 2))); Assert.False(buffer.Contains(new(2, 4, 2, 2))); buffer.End(); Assert.False(buffer.Contains(new(4, 4, 2, 2))); buffer.RowSegments(1, 7, 5, out var end, out var start); Assert.Equal(8, end); Assert.Equal(8, start); } [Fact] public void OutOfBoundsOrEmptyTranslationDoesNotLeaveOldExclusionActive() { var buffer = new DesktopSceneMotionBuffer(new int[100], new int[100], 10, 10); buffer.Preserve(new(0, 0, 3, 3), 4, 4); buffer.Preserve(new(int.MinValue, 0, int.MaxValue, 3), int.MaxValue, 4); Assert.Equal(default, buffer.PreservedBounds); buffer.Preserve(new(0, 0, 0, 3), 4, 4); Assert.Equal(default, buffer.PreservedBounds); Assert.Throws(() => { var array = new int[100]; _ = new DesktopSceneMotionBuffer(array, array, 10, 10); }); } [Fact] public void SamePositionReuseCanAvoidAllPixelWritesAndRejectsAMovingRegion() { var pixels = Enumerable.Repeat(7, 100).ToArray(); var scene = Enumerable.Repeat(9, 100).ToArray(); var buffer = new DesktopSceneMotionBuffer(pixels, scene, 10, 10); buffer.Preserve(new(2, 2, 4, 4), 2, 2, pixelsAlreadyMatch: true); Assert.All(pixels, value => Assert.Equal(7, value)); Assert.Equal(new DesktopBounds(2, 2, 4, 4), buffer.PreservedBounds); Assert.Throws(() => buffer.Preserve(new(2, 2, 4, 4), 3, 2, pixelsAlreadyMatch: true)); Assert.Equal(default, buffer.PreservedBounds); } }