diff --git a/src/Android/Avalonia.Android/ChoreographerTimer.cs b/src/Android/Avalonia.Android/ChoreographerTimer.cs index 4dbc57a22e..af16ad4e7b 100644 --- a/src/Android/Avalonia.Android/ChoreographerTimer.cs +++ b/src/Android/Avalonia.Android/ChoreographerTimer.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using Android.OS; @@ -7,16 +8,16 @@ using Android.Views; using Avalonia.Reactive; using Avalonia.Rendering; - -using Java.Lang; +using ThreadPriority = System.Threading.ThreadPriority; namespace Avalonia.Android { internal sealed class ChoreographerTimer : Java.Lang.Object, IRenderTimer, Choreographer.IFrameCallback { private readonly object _lock = new(); - - private readonly Thread _thread; + + private AutoResetEvent _event = new(false); + private long _lastTime; private readonly TaskCompletionSource _choreographer = new(); private readonly ISet _views = new HashSet(); @@ -26,10 +27,16 @@ namespace Avalonia.Android public ChoreographerTimer() { - _thread = new Thread(Loop); - _thread.Start(); + new Thread(Loop) + { + Priority = ThreadPriority.AboveNormal + }.Start(); + new Thread(RenderLoop) + { + Priority = ThreadPriority.AboveNormal + }.Start(); } - + public bool RunsInBackground => true; public event Action Tick @@ -82,10 +89,27 @@ namespace Avalonia.Android private void Loop() { + Console.WriteLine("Entering Chroreographer loop"); Looper.Prepare(); _choreographer.SetResult(Choreographer.Instance!); Looper.Loop(); } + + private void RenderLoop() + { + Console.WriteLine("Entering RenderThread loop"); + while (true) + { + _event.WaitOne(); + long time; + lock (_lock) + { + time = _lastTime; + } + _tick?.Invoke(TimeSpan.FromTicks(time / 100)); + } + } + public void DoFrame(long frameTimeNanos) { @@ -95,9 +119,9 @@ namespace Avalonia.Android { Choreographer.Instance!.PostFrameCallback(this); } + _lastTime = frameTimeNanos; + _event.Set(); } - - _tick?.Invoke(TimeSpan.FromTicks(frameTimeNanos / 100)); } } }