diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs index e6092574c5..3594cb59ee 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs @@ -408,9 +408,12 @@ namespace Avalonia.Rendering.SceneGraph var dirty = Owner.Layers.GetOrAdd(Owner._node.LayerRoot).Dirty; - foreach (var operation in Owner._node.DrawOperations) + var drawOperations = Owner._node.DrawOperations; + var drawOperationsCount = drawOperations.Count; + + for (var i = 0; i < drawOperationsCount; i++) { - dirty.Add(operation.Item.Bounds); + dirty.Add(drawOperations[i].Item.Bounds); } Owner._node = Node; diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs index d0c4566485..187c1da0a9 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/RectangleNode.cs @@ -84,7 +84,7 @@ namespace Avalonia.Rendering.SceneGraph return transform == Transform && Equals(brush, Brush) && Equals(Pen, pen) && - Media.BoxShadows.Equals(BoxShadows, boxShadows) && + BoxShadows.Equals(boxShadows) && rect.Equals(Rect); } diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs index 7d5d62a091..56f05db04e 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs @@ -1,5 +1,5 @@ using System; -using System.Linq; +using System.Collections.Generic; using Avalonia.Media; using Avalonia.Platform; using Avalonia.Threading; @@ -247,11 +247,26 @@ namespace Avalonia.Rendering.SceneGraph if (forceRecurse) { - foreach (var child in visual.VisualChildren.OrderBy(x => x, ZIndexComparer.Instance)) + var visualChildren = (IList) visual.VisualChildren; + + if (visualChildren.Count == 1) { - var childNode = GetOrCreateChildNode(scene, child, node); + var childNode = GetOrCreateChildNode(scene, visualChildren[0], node); Update(context, scene, (VisualNode)childNode, clip, forceRecurse); } + else if (visualChildren.Count > 1) + { + var sortedChildren = new IVisual[visualChildren.Count]; + visualChildren.CopyTo(sortedChildren, 0); + + Array.Sort(sortedChildren, ZIndexComparer.ComparisonInstance); + + foreach (var child in sortedChildren) + { + var childNode = GetOrCreateChildNode(scene, child, node); + Update(context, scene, (VisualNode)childNode, clip, forceRecurse); + } + } node.SubTreeUpdated = true; contextImpl.TrimChildren(); @@ -308,13 +323,17 @@ namespace Avalonia.Rendering.SceneGraph private static void Deindex(Scene scene, VisualNode node) { - foreach (VisualNode child in node.Children) + var nodeChildren = node.Children; + var nodeChildrenCount = nodeChildren.Count; + + for (var i = 0; i < nodeChildrenCount; i++) { - if (child is VisualNode visual) + if (nodeChildren[i] is VisualNode visual) { Deindex(scene, visual); } } + scene.Remove(node); node.SubTreeUpdated = true; @@ -323,7 +342,6 @@ namespace Avalonia.Rendering.SceneGraph node.Visual.TransformedBounds = null; - if (node.LayerRoot == node.Visual && node.Visual != scene.Root.Visual) { scene.Layers.Remove(node.LayerRoot); diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs index 8fb6b2542a..d0439feed2 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs @@ -365,9 +365,12 @@ namespace Avalonia.Rendering.SceneGraph { var result = new Rect(); - foreach (var operation in DrawOperations) + if (_drawOperations != null) { - result = result.Union(operation.Item.Bounds); + foreach (var operation in _drawOperations) + { + result = result.Union(operation.Item.Bounds); + } } _bounds = result; diff --git a/src/Avalonia.Visuals/Rendering/ZIndexComparer.cs b/src/Avalonia.Visuals/Rendering/ZIndexComparer.cs index 3ed076f22e..e9700c70a5 100644 --- a/src/Avalonia.Visuals/Rendering/ZIndexComparer.cs +++ b/src/Avalonia.Visuals/Rendering/ZIndexComparer.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Avalonia.VisualTree; namespace Avalonia.Rendering @@ -6,6 +7,7 @@ namespace Avalonia.Rendering public class ZIndexComparer : IComparer { public static readonly ZIndexComparer Instance = new ZIndexComparer(); + public static readonly Comparison ComparisonInstance = Instance.Compare; public int Compare(IVisual x, IVisual y) => (x?.ZIndex ?? 0).CompareTo(y?.ZIndex ?? 0); }