diff --git a/src/Perspex.Base/Threading/DispatcherTimer.cs b/src/Perspex.Base/Threading/DispatcherTimer.cs
index 159151dc79..d84bcf519e 100644
--- a/src/Perspex.Base/Threading/DispatcherTimer.cs
+++ b/src/Perspex.Base/Threading/DispatcherTimer.cs
@@ -18,12 +18,13 @@ namespace Perspex.Threading
private TimeSpan _interval;
+ private readonly Action _raiseTickAction;
+
///
/// Initializes a new instance of the class.
///
- public DispatcherTimer()
+ public DispatcherTimer() : this(DispatcherPriority.Normal)
{
- _priority = DispatcherPriority.Normal;
}
///
@@ -34,6 +35,7 @@ namespace Perspex.Threading
public DispatcherTimer(DispatcherPriority priority)
{
_priority = priority;
+ _raiseTickAction = RaiseTick;
}
///
@@ -43,7 +45,7 @@ namespace Perspex.Threading
/// The priority to use.
/// The dispatcher to use.
/// The event to call when the timer ticks.
- public DispatcherTimer(TimeSpan interval, DispatcherPriority priority, EventHandler callback)
+ public DispatcherTimer(TimeSpan interval, DispatcherPriority priority, EventHandler callback) : this(priority)
{
_priority = priority;
Interval = interval;
@@ -172,12 +174,14 @@ namespace Perspex.Threading
}
}
+
+
///
/// Raises the event on the dispatcher thread.
///
private void InternalTick()
{
- Dispatcher.UIThread.InvokeAsync(RaiseTick, _priority);
+ Dispatcher.UIThread.InvokeAsync(_raiseTickAction, _priority);
}
///
diff --git a/src/Perspex.SceneGraph/Media/DrawingContext.cs b/src/Perspex.SceneGraph/Media/DrawingContext.cs
index bd5b11a19f..28cfeb77a7 100644
--- a/src/Perspex.SceneGraph/Media/DrawingContext.cs
+++ b/src/Perspex.SceneGraph/Media/DrawingContext.cs
@@ -13,8 +13,17 @@ namespace Perspex.Media
private readonly IDrawingContextImpl _impl;
private int _currentLevel;
- private Stack _transformContainers = new Stack();
- private Stack _states = new Stack();
+
+
+ static readonly Stack> StateStackPool = new Stack>();
+ static readonly Stack> TransformStackPool = new Stack>();
+
+ private Stack _states = StateStackPool.Count == 0 ? new Stack() : StateStackPool.Pop();
+
+ private Stack _transformContainers = TransformStackPool.Count == 0
+ ? new Stack()
+ : TransformStackPool.Pop();
+
struct TransformContainer
{
public Matrix LocalTransform;
@@ -206,6 +215,10 @@ namespace Perspex.Media
{
while (_states.Count != 0)
_states.Peek().Dispose();
+ StateStackPool.Push(_states);
+ _states = null;
+ TransformStackPool.Push(_transformContainers);
+ _transformContainers = null;
_impl.Dispose();
}
}
diff --git a/src/Perspex.SceneGraph/Rendering/RendererBase.cs b/src/Perspex.SceneGraph/Rendering/RendererBase.cs
index 7a7db8f842..9ebe830f90 100644
--- a/src/Perspex.SceneGraph/Rendering/RendererBase.cs
+++ b/src/Perspex.SceneGraph/Rendering/RendererBase.cs
@@ -2,6 +2,8 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Perspex.Media;
using Perspex.Platform;
@@ -14,6 +16,8 @@ namespace Perspex.Rendering
///
/// This class provides implements the platform-independent parts of .
///
+ [SuppressMessage("ReSharper", "LoopCanBeConvertedToQuery")]
+ [SuppressMessage("ReSharper", "ForCanBeConvertedToForeach")]
public static class RendererMixin
{
///
@@ -58,12 +62,39 @@ namespace Perspex.Rendering
using (context.PushTransformContainer())
{
visual.Render(context);
- foreach (var child in visual.VisualChildren.OrderBy(x => x.ZIndex))
+ var lst = GetSortedVisualList(visual.VisualChildren);
+ foreach (var child in lst)
{
context.Render(child);
}
+ ReturnListToPool(lst);
}
}
}
+
+ static readonly Stack> ListPool = new Stack>();
+ static readonly ZIndexComparer VisualComparer = new ZIndexComparer();
+ class ZIndexComparer : IComparer
+ {
+ public int Compare(IVisual x, IVisual y) => x.ZIndex.CompareTo(y.ZIndex);
+ }
+
+ static void ReturnListToPool(List lst)
+ {
+ lst.Clear();
+ ListPool.Push(lst);
+ }
+
+ static List GetSortedVisualList(IReadOnlyList source)
+ {
+ var lst = ListPool.Count == 0 ? new List() : ListPool.Pop();
+ for (var c = 0; c < source.Count; c++)
+ lst.Add(source[c]);
+ lst.Sort(VisualComparer);
+ return lst;
+ }
+
+
+
}
}
diff --git a/src/Skia/Perspex.Skia/FormattedTextImpl.cs b/src/Skia/Perspex.Skia/FormattedTextImpl.cs
index 211da7bbc1..5e267099b5 100644
--- a/src/Skia/Perspex.Skia/FormattedTextImpl.cs
+++ b/src/Skia/Perspex.Skia/FormattedTextImpl.cs
@@ -114,6 +114,8 @@ namespace Perspex.Skia
get { return _constraint; }
set
{
+ if(_constraint == value)
+ return;
_constraint = value;
_shared->WidthConstraint = (_constraint.Width != double.PositiveInfinity)