Browse Source

Reduced memory traffic

pull/328/head
Nikita Tsukanov 10 years ago
parent
commit
d1badd0dbb
  1. 12
      src/Perspex.Base/Threading/DispatcherTimer.cs
  2. 17
      src/Perspex.SceneGraph/Media/DrawingContext.cs
  3. 33
      src/Perspex.SceneGraph/Rendering/RendererBase.cs
  4. 2
      src/Skia/Perspex.Skia/FormattedTextImpl.cs

12
src/Perspex.Base/Threading/DispatcherTimer.cs

@ -18,12 +18,13 @@ namespace Perspex.Threading
private TimeSpan _interval;
private readonly Action _raiseTickAction;
/// <summary>
/// Initializes a new instance of the <see cref="DispatcherTimer"/> class.
/// </summary>
public DispatcherTimer()
public DispatcherTimer() : this(DispatcherPriority.Normal)
{
_priority = DispatcherPriority.Normal;
}
/// <summary>
@ -34,6 +35,7 @@ namespace Perspex.Threading
public DispatcherTimer(DispatcherPriority priority)
{
_priority = priority;
_raiseTickAction = RaiseTick;
}
/// <summary>
@ -43,7 +45,7 @@ namespace Perspex.Threading
/// <param name="priority">The priority to use.</param>
/// <param name="dispatcher">The dispatcher to use.</param>
/// <param name="callback">The event to call when the timer ticks.</param>
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
}
}
/// <summary>
/// Raises the <see cref="Tick"/> event on the dispatcher thread.
/// </summary>
private void InternalTick()
{
Dispatcher.UIThread.InvokeAsync(RaiseTick, _priority);
Dispatcher.UIThread.InvokeAsync(_raiseTickAction, _priority);
}
/// <summary>

17
src/Perspex.SceneGraph/Media/DrawingContext.cs

@ -13,8 +13,17 @@ namespace Perspex.Media
private readonly IDrawingContextImpl _impl;
private int _currentLevel;
private Stack<TransformContainer> _transformContainers = new Stack<TransformContainer>();
private Stack<PushedState> _states = new Stack<PushedState>();
static readonly Stack<Stack<PushedState>> StateStackPool = new Stack<Stack<PushedState>>();
static readonly Stack<Stack<TransformContainer>> TransformStackPool = new Stack<Stack<TransformContainer>>();
private Stack<PushedState> _states = StateStackPool.Count == 0 ? new Stack<PushedState>() : StateStackPool.Pop();
private Stack<TransformContainer> _transformContainers = TransformStackPool.Count == 0
? new Stack<TransformContainer>()
: 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();
}
}

33
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
/// <remarks>
/// This class provides implements the platform-independent parts of <see cref="IRenderTarget"/>.
/// </remarks>
[SuppressMessage("ReSharper", "LoopCanBeConvertedToQuery")]
[SuppressMessage("ReSharper", "ForCanBeConvertedToForeach")]
public static class RendererMixin
{
/// <summary>
@ -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<List<IVisual>> ListPool = new Stack<List<IVisual>>();
static readonly ZIndexComparer VisualComparer = new ZIndexComparer();
class ZIndexComparer : IComparer<IVisual>
{
public int Compare(IVisual x, IVisual y) => x.ZIndex.CompareTo(y.ZIndex);
}
static void ReturnListToPool(List<IVisual> lst)
{
lst.Clear();
ListPool.Push(lst);
}
static List<IVisual> GetSortedVisualList(IReadOnlyList<IVisual> source)
{
var lst = ListPool.Count == 0 ? new List<IVisual>() : ListPool.Pop();
for (var c = 0; c < source.Count; c++)
lst.Add(source[c]);
lst.Sort(VisualComparer);
return lst;
}
}
}

2
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)

Loading…
Cancel
Save