diff --git a/tests/Avalonia.Benchmarks/Rendering/CompositionHitTesting.cs b/tests/Avalonia.Benchmarks/Rendering/CompositionHitTesting.cs index b8a162be82..f4b5c42abc 100644 --- a/tests/Avalonia.Benchmarks/Rendering/CompositionHitTesting.cs +++ b/tests/Avalonia.Benchmarks/Rendering/CompositionHitTesting.cs @@ -19,7 +19,6 @@ public class CompositionHitTesting private CompositorTestServices? _services; private CompositionVisual? _rootVisual; private Point _hitPoint; - private Point _globalHitPoint; private Border? _expectedHit; [Params(1024, 4096, 16384)] @@ -60,7 +59,6 @@ public class CompositionHitTesting _rootVisual = _services.TopLevel.CompositionVisual; _hitPoint = new Point(CellSize / 2d, CellSize / 2d); - _globalHitPoint = _hitPoint * _services.Renderer.CompositionTarget.Scaling; if (!ReferenceEquals(HitTestFirst_RTree(), _expectedHit)) throw new InvalidOperationException("R-tree hit test returned an unexpected visual."); @@ -81,10 +79,14 @@ public class CompositionHitTesting [Benchmark(Baseline = true)] public Visual? HitTestFirst_Linear() { - _services!.Renderer.CompositionTarget.Server.Readback.NextRead(); + _services!.Renderer.CompositionTarget.Server.Compositor.Readback.NextRead(); + + var rootReadback = _rootVisual!.TryGetValidReadback(); + if (rootReadback == null) + return null; using var results = new PooledList(); - LinearHitTestCore(_rootVisual!, _globalHitPoint, results); + LinearHitTestCore(_rootVisual, _hitPoint.Transform(rootReadback.Matrix), results); foreach (var visual in results) { @@ -101,14 +103,25 @@ public class CompositionHitTesting return _services!.Renderer.HitTestFirst(_hitPoint, _services.TopLevel, null); } - private static void LinearHitTestCore(CompositionVisual visual, Point globalPoint, PooledList result) + private static void LinearHitTestCore(CompositionVisual visual, Point parentPoint, PooledList result) { if (visual.Visible == false) return; - if (!TryTransformTo(visual, globalPoint, out var point)) + var readback = visual.TryGetValidReadback(); + if (readback == null) + return; + + if (!visual.DisableSubTreeBoundsHitTestOptimization && + (readback.TransformedSubtreeBounds == null || + !readback.TransformedSubtreeBounds.Value.Contains(parentPoint))) return; + if (!readback.Matrix.TryInvert(out var inverted)) + return; + + var point = parentPoint.Transform(inverted); + if (visual.ClipToBounds && (point.X < 0 || point.Y < 0 || point.X > visual.Size.X || point.Y > visual.Size.Y)) return; @@ -119,22 +132,10 @@ public class CompositionHitTesting if (visual is CompositionContainerVisual container) { for (var c = container.Children.Count - 1; c >= 0; c--) - LinearHitTestCore(container.Children[c], globalPoint, result); + LinearHitTestCore(container.Children[c], point, result); } if (visual.HitTest(point)) result.Add(visual); } - - private static bool TryTransformTo(CompositionVisual visual, Point globalPoint, out Point point) - { - point = default; - - var matrix = visual.TryGetServerGlobalTransform(); - if (matrix == null || !matrix.Value.TryInvert(out var inverted)) - return false; - - point = globalPoint * inverted; - return true; - } }