Browse Source

Notify tick count in IRenderTimer.Tick.

Steven Kirk 7 years ago
parent
commit
8ec2c8f661

+ 2 - 2
src/Avalonia.Controls/Platform/InternalPlatformThreadingInterface.cs

@@ -14,7 +14,7 @@ namespace Avalonia.Controls.Platform
         public InternalPlatformThreadingInterface()
         {
             TlsCurrentThreadIsLoopThread = true;
-            StartTimer(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 66), () => Tick?.Invoke(this, new EventArgs()));
+            StartTimer(DispatcherPriority.Render, new TimeSpan(0, 0, 0, 0, 66), () => Tick?.Invoke(Environment.TickCount));
         }
 
         private readonly AutoResetEvent _signaled = new AutoResetEvent(false);
@@ -105,7 +105,7 @@ namespace Avalonia.Controls.Platform
 
         public bool CurrentThreadIsLoopThread => TlsCurrentThreadIsLoopThread;
         public event Action<DispatcherPriority?> Signaled;
-        public event EventHandler<EventArgs> Tick;
+        public event Action<long> Tick;
 
     }
 }

+ 6 - 6
src/Avalonia.Visuals/Rendering/DefaultRenderTimer.cs

@@ -18,7 +18,7 @@ namespace Avalonia.Rendering
     {
         private IRuntimePlatform _runtime;
         private int _subscriberCount;
-        private EventHandler<EventArgs> _tick;
+        private Action<long> _tick;
         private IDisposable _subscription;
 
         /// <summary>
@@ -38,7 +38,7 @@ namespace Avalonia.Rendering
         public int FramesPerSecond { get; }
 
         /// <inheritdoc/>
-        public event EventHandler<EventArgs> Tick
+        public event Action<long> Tick
         {
             add
             {
@@ -77,14 +77,14 @@ namespace Avalonia.Rendering
         /// This can be overridden by platform implementations to use a specialized timer
         /// implementation.
         /// </remarks>
-        protected virtual IDisposable StartCore(Action tick)
+        protected virtual IDisposable StartCore(Action<long> tick)
         {
             if (_runtime == null)
             {
                 _runtime = AvaloniaLocator.Current.GetService<IRuntimePlatform>();
             }
 
-            return _runtime.StartSystemTimer(TimeSpan.FromSeconds(1.0 / FramesPerSecond), tick);
+            return _runtime.StartSystemTimer(TimeSpan.FromSeconds(1.0 / FramesPerSecond), () => tick(Environment.TickCount));
         }
 
         /// <summary>
@@ -96,9 +96,9 @@ namespace Avalonia.Rendering
             _subscription = null;
         }
 
-        private void InternalTick()
+        private void InternalTick(long tickCount)
         {
-            _tick(this, EventArgs.Empty);
+            _tick(tickCount);
         }
     }
 }

+ 1 - 1
src/Avalonia.Visuals/Rendering/IRenderTimer.cs

@@ -15,6 +15,6 @@ namespace Avalonia.Rendering
         /// This event can be raised on any thread; it is the responsibility of the subscriber to
         /// switch execution to the right thread.
         /// </remarks>
-        event EventHandler<EventArgs> Tick;
+        event Action<long> Tick;
     }
 }

+ 1 - 1
src/Avalonia.Visuals/Rendering/RenderLoop.cs

@@ -62,7 +62,7 @@ namespace Avalonia.Rendering
             }
         }
 
-        private async void TimerTick(object sender, EventArgs e)
+        private async void TimerTick(long tickCount)
         {
             if (!inTick)
             {

+ 2 - 2
src/OSX/Avalonia.MonoMac/RenderTimer.cs

@@ -20,12 +20,12 @@ namespace Avalonia.MonoMac
                     {
                         using (new NSAutoreleasePool())
                         {
-                            Tick?.Invoke(this, EventArgs.Empty);
+                            Tick?.Invoke(Environment.TickCount);
                         }
                     }
                 });
         }
 
-        public event EventHandler<EventArgs> Tick;
+        public event Action<long> Tick;
     }
 }

+ 3 - 0
src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs

@@ -972,6 +972,9 @@ namespace Avalonia.Win32.Interop
         [return: MarshalAs(UnmanagedType.Bool)]
         public static extern bool GetMonitorInfo([In] IntPtr hMonitor, [Out] MONITORINFO lpmi);
 
+        [DllImport("kernel32.dll", SetLastError = true)]
+        public static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
+
         [return: MarshalAs(UnmanagedType.Bool)]
         [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "PostMessageW")]
         public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

+ 6 - 2
src/Windows/Avalonia.Win32/RenderTimer.cs

@@ -14,9 +14,13 @@ namespace Avalonia.Win32
         {
         }
 
-        protected override IDisposable StartCore(Action tick)
+        protected override IDisposable StartCore(Action<long> tick)
         {
-            timerDelegate = (id, uMsg, user, dw1, dw2) => tick();
+            timerDelegate = (id, uMsg, user, dw1, dw2) =>
+            {
+                UnmanagedMethods.QueryPerformanceCounter(out long tickCount);
+                tick(tickCount);
+            };
 
             var handle = UnmanagedMethods.timeSetEvent(
                 (uint)(1000 / FramesPerSecond),