Browse Source

Merge branch 'master' into fixes/fix-missed-resources

pull/4411/head
danwalmsley 6 years ago
committed by GitHub
parent
commit
8bd24dfcf7
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 38
      src/Avalonia.Visuals/Rendering/RenderLoop.cs
  2. 72
      src/Avalonia.Visuals/Rendering/SleepLoopRenderTimer.cs
  3. 2
      src/Avalonia.X11/X11Platform.cs

38
src/Avalonia.Visuals/Rendering/RenderLoop.cs

@ -18,6 +18,7 @@ namespace Avalonia.Rendering
{
private readonly IDispatcher _dispatcher;
private List<IRenderLoopTask> _items = new List<IRenderLoopTask>();
private List<IRenderLoopTask> _itemsCopy = new List<IRenderLoopTask>();
private IRenderTimer _timer;
private int _inTick;
private int _inUpdate;
@ -63,11 +64,14 @@ namespace Avalonia.Rendering
Contract.Requires<ArgumentNullException>(i != null);
Dispatcher.UIThread.VerifyAccess();
_items.Add(i);
if (_items.Count == 1)
lock (_items)
{
Timer.Tick += TimerTick;
_items.Add(i);
if (_items.Count == 1)
{
Timer.Tick += TimerTick;
}
}
}
@ -76,12 +80,14 @@ namespace Avalonia.Rendering
{
Contract.Requires<ArgumentNullException>(i != null);
Dispatcher.UIThread.VerifyAccess();
_items.Remove(i);
if (_items.Count == 0)
lock (_items)
{
Timer.Tick -= TimerTick;
_items.Remove(i);
if (_items.Count == 0)
{
Timer.Tick -= TimerTick;
}
}
}
@ -129,10 +135,20 @@ namespace Avalonia.Rendering
}, DispatcherPriority.Render);
}
for(int i = 0; i < _items.Count; i++)
lock (_items)
{
_itemsCopy.Clear();
foreach (var i in _items)
_itemsCopy.Add(i);
}
for (int i = 0; i < _itemsCopy.Count; i++)
{
_items[i].Render();
_itemsCopy[i].Render();
}
_itemsCopy.Clear();
}
catch (Exception ex)
{

72
src/Avalonia.Visuals/Rendering/SleepLoopRenderTimer.cs

@ -0,0 +1,72 @@
using System;
using System.Diagnostics;
using System.Threading;
namespace Avalonia.Rendering
{
public class SleepLoopRenderTimer : IRenderTimer
{
private Action<TimeSpan> _tick;
private int _count;
private readonly object _lock = new object();
private bool _running;
private readonly Stopwatch _st = Stopwatch.StartNew();
private readonly TimeSpan _timeBetweenTicks;
public SleepLoopRenderTimer(int fps)
{
_timeBetweenTicks = TimeSpan.FromSeconds(1d / fps);
}
public event Action<TimeSpan> Tick
{
add
{
lock (_lock)
{
_tick += value;
_count++;
if (_running)
return;
_running = true;
new Thread(LoopProc) { IsBackground = true }.Start();
}
}
remove
{
lock (_lock)
{
_tick -= value;
_count--;
}
}
}
void LoopProc()
{
var now = _st.Elapsed;
var lastTick = now;
while (true)
{
var timeTillNextTick = lastTick + _timeBetweenTicks - now;
if (timeTillNextTick.TotalMilliseconds > 1) Thread.Sleep(timeTillNextTick);
lock (_lock)
{
if (_count == 0)
{
_running = false;
return;
}
}
_tick?.Invoke(now);
now = _st.Elapsed;
}
}
}
}

2
src/Avalonia.X11/X11Platform.cs

@ -47,7 +47,7 @@ namespace Avalonia.X11
AvaloniaLocator.CurrentMutable.BindToSelf(this)
.Bind<IWindowingPlatform>().ToConstant(this)
.Bind<IPlatformThreadingInterface>().ToConstant(new X11PlatformThreading(this))
.Bind<IRenderTimer>().ToConstant(new DefaultRenderTimer(60))
.Bind<IRenderTimer>().ToConstant(new SleepLoopRenderTimer(60))
.Bind<IRenderLoop>().ToConstant(new RenderLoop())
.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration(KeyModifiers.Control))
.Bind<IKeyboardDevice>().ToFunc(() => KeyboardDevice)

Loading…
Cancel
Save