Browse Source

Merge branch 'master' into managed-dialog-extras

pull/3885/head
Benedikt Stebner 6 years ago
committed by GitHub
parent
commit
d730326d4e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 18
      src/Avalonia.Visuals/Rendering/SceneGraph/Scene.cs
  2. 20
      src/Avalonia.Visuals/Rendering/SceneGraph/SceneLayers.cs
  3. 25
      src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs
  4. 4
      src/Avalonia.X11/X11Window.cs

18
src/Avalonia.Visuals/Rendering/SceneGraph/Scene.cs

@ -12,7 +12,7 @@ namespace Avalonia.Rendering.SceneGraph
/// </summary> /// </summary>
public class Scene : IDisposable public class Scene : IDisposable
{ {
private Dictionary<IVisual, IVisualNode> _index; private readonly Dictionary<IVisual, IVisualNode> _index;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Scene"/> class. /// Initializes a new instance of the <see cref="Scene"/> class.
@ -83,7 +83,7 @@ namespace Avalonia.Rendering.SceneGraph
/// <returns>The cloned scene.</returns> /// <returns>The cloned scene.</returns>
public Scene CloneScene() public Scene CloneScene()
{ {
var index = new Dictionary<IVisual, IVisualNode>(); var index = new Dictionary<IVisual, IVisualNode>(_index.Count);
var root = Clone((VisualNode)Root, null, index); var root = Clone((VisualNode)Root, null, index);
var result = new Scene(root, index, Layers.Clone(), Generation + 1) var result = new Scene(root, index, Layers.Clone(), Generation + 1)
@ -162,9 +162,19 @@ namespace Avalonia.Rendering.SceneGraph
index.Add(result.Visual, result); index.Add(result.Visual, result);
foreach (var child in source.Children) var children = source.Children;
var childrenCount = children.Count;
if (childrenCount > 0)
{ {
result.AddChild(Clone((VisualNode)child, result, index)); result.TryPreallocateChildren(childrenCount);
for (var i = 0; i < childrenCount; i++)
{
var child = children[i];
result.AddChild(Clone((VisualNode)child, result, index));
}
} }
return result; return result;

20
src/Avalonia.Visuals/Rendering/SceneGraph/SceneLayers.cs

@ -11,16 +11,28 @@ namespace Avalonia.Rendering.SceneGraph
public class SceneLayers : IEnumerable<SceneLayer> public class SceneLayers : IEnumerable<SceneLayer>
{ {
private readonly IVisual _root; private readonly IVisual _root;
private readonly List<SceneLayer> _inner = new List<SceneLayer>(); private readonly List<SceneLayer> _inner;
private readonly Dictionary<IVisual, SceneLayer> _index = new Dictionary<IVisual, SceneLayer>(); private readonly Dictionary<IVisual, SceneLayer> _index;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="SceneLayers"/> class. /// Initializes a new instance of the <see cref="SceneLayers"/> class.
/// </summary> /// </summary>
/// <param name="root">The scene's root visual.</param> /// <param name="root">The scene's root visual.</param>
public SceneLayers(IVisual root) public SceneLayers(IVisual root) : this(root, 0)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="SceneLayers"/> class.
/// </summary>
/// <param name="root">The scene's root visual.</param>
/// <param name="capacity">Initial layer capacity.</param>
public SceneLayers(IVisual root, int capacity)
{ {
_root = root; _root = root;
_inner = new List<SceneLayer>(capacity);
_index = new Dictionary<IVisual, SceneLayer>(capacity);
} }
/// <summary> /// <summary>
@ -84,7 +96,7 @@ namespace Avalonia.Rendering.SceneGraph
/// <returns>The cloned layers.</returns> /// <returns>The cloned layers.</returns>
public SceneLayers Clone() public SceneLayers Clone()
{ {
var result = new SceneLayers(_root); var result = new SceneLayers(_root, Count);
foreach (var src in _inner) foreach (var src in _inner)
{ {

25
src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using Avalonia.Collections;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Utilities; using Avalonia.Utilities;
@ -349,6 +349,11 @@ namespace Avalonia.Rendering.SceneGraph
context.Transform = transformRestore; context.Transform = transformRestore;
} }
internal void TryPreallocateChildren(int count)
{
EnsureChildrenCreated(count);
}
private Rect CalculateBounds() private Rect CalculateBounds()
{ {
var result = new Rect(); var result = new Rect();
@ -362,11 +367,11 @@ namespace Avalonia.Rendering.SceneGraph
return result; return result;
} }
private void EnsureChildrenCreated() private void EnsureChildrenCreated(int capacity = 0)
{ {
if (_children == null) if (_children == null)
{ {
_children = new List<IVisualNode>(); _children = new List<IVisualNode>(capacity);
} }
} }
@ -383,7 +388,15 @@ namespace Avalonia.Rendering.SceneGraph
} }
else if (_drawOperationsCloned) else if (_drawOperationsCloned)
{ {
_drawOperations = new List<IRef<IDrawOperation>>(_drawOperations.Select(op => op.Clone())); var oldDrawOperations = _drawOperations;
_drawOperations = new List<IRef<IDrawOperation>>(oldDrawOperations.Count);
foreach (var drawOperation in oldDrawOperations)
{
_drawOperations.Add(drawOperation.Clone());
}
_drawOperationsRefCounter.Dispose(); _drawOperationsRefCounter.Dispose();
_drawOperationsRefCounter = RefCountable.Create(CreateDisposeDrawOperations(_drawOperations)); _drawOperationsRefCounter = RefCountable.Create(CreateDisposeDrawOperations(_drawOperations));
_drawOperationsCloned = false; _drawOperationsCloned = false;
@ -399,9 +412,9 @@ namespace Avalonia.Rendering.SceneGraph
/// <returns>Disposable for given draw operations.</returns> /// <returns>Disposable for given draw operations.</returns>
private static IDisposable CreateDisposeDrawOperations(List<IRef<IDrawOperation>> drawOperations) private static IDisposable CreateDisposeDrawOperations(List<IRef<IDrawOperation>> drawOperations)
{ {
return Disposable.Create(() => return Disposable.Create(drawOperations, operations =>
{ {
foreach (var operation in drawOperations) foreach (var operation in operations)
{ {
operation.Dispose(); operation.Dispose();
} }

4
src/Avalonia.X11/X11Window.cs

@ -328,7 +328,9 @@ namespace Avalonia.X11
} }
else if (ev.type == XEventName.UnmapNotify) else if (ev.type == XEventName.UnmapNotify)
_mapped = false; _mapped = false;
else if (ev.type == XEventName.Expose) else if (ev.type == XEventName.Expose ||
(ev.type == XEventName.VisibilityNotify &&
ev.VisibilityEvent.state < 2))
{ {
if (!_triggeredExpose) if (!_triggeredExpose)
{ {

Loading…
Cancel
Save