Browse Source

Win32 - Support rendering at max refresh rate of current displays (#21643)

* win32 - support rendering at max refresh rate for current displays

* win32 - set max framerate floor to 60
pull/21677/head
Emmanuel Hansen 3 months ago
committed by GitHub
parent
commit
4bd9909d0f
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      src/Avalonia.Base/Rendering/RenderLoop.cs
  2. 18
      src/Windows/Avalonia.Win32/Win32Platform.cs
  3. 5
      src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs

2
src/Avalonia.Base/Rendering/RenderLoop.cs

@ -101,6 +101,8 @@ namespace Avalonia.Rendering
/// <inheritdoc />
public bool RunsInBackground => _timer.RunsInBackground;
internal IRenderTimer Timer => _timer;
/// <inheritdoc />
public void Wakeup()
{

18
src/Windows/Avalonia.Win32/Win32Platform.cs

@ -44,7 +44,7 @@ namespace Avalonia.Win32
private static Win32PlatformOptions? s_options;
private static Compositor? s_compositor;
internal const int TIMERID_DISPATCHER = 1;
private const int DefaultFramesPerSecond = 60;
private WndProc? _wndProcDelegate;
private IntPtr _hwnd;
private Win32DispatcherImpl _dispatcher;
@ -87,7 +87,7 @@ namespace Avalonia.Win32
Dispatcher.InitializeUIThreadDispatcher(s_instance._dispatcher);
var renderTimer = options.ShouldRenderOnUIThread ? new UiThreadRenderTimer(60) : new DefaultRenderTimer(60);
IRenderTimer renderTimer = options.ShouldRenderOnUIThread ? new UiThreadRenderTimer(DefaultFramesPerSecond) : new SleepLoopRenderTimer(DefaultFramesPerSecond);
var clipboardImpl = new ClipboardImpl();
var clipboard = new Clipboard(clipboardImpl);
@ -133,7 +133,9 @@ namespace Avalonia.Win32
if (OleContext.Current != null)
AvaloniaLocator.CurrentMutable.Bind<IPlatformDragSource>().ToSingleton<DragSource>();
UpdateTimerFps();
s_compositor = new Compositor( platformGraphics);
AvaloniaLocator.CurrentMutable.Bind<Compositor>().ToConstant(s_compositor);
}
@ -196,6 +198,16 @@ namespace Avalonia.Win32
return DefWindowProc(hWnd, msg, wParam, lParam);
}
internal static void UpdateTimerFps()
{
var maxDisplayFrequency = Math.Max(60, Instance.Screen?.AllScreens?.Max(s => (s as WinScreen)?.Frequency) ?? 0);
if (AvaloniaLocator.Current.GetService<IRenderLoop>() is DefaultRenderLoop defaultRenderLoop &&
defaultRenderLoop.Timer is SleepLoopRenderTimer sleepLoopRenderTimer)
{
sleepLoopRenderTimer.DesiredFps = maxDisplayFrequency;
}
}
private void CreateMessageWindow()
{
// Ensure that the delegate doesn't get garbage collected by storing it as a field.

5
src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs

@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.InteropServices;
using Avalonia.Automation.Peers;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Input.Raw;
using Avalonia.Rendering;
using Avalonia.Threading;
using Avalonia.Win32.Automation;
using Avalonia.Win32.Automation.Interop;
@ -873,6 +875,9 @@ namespace Avalonia.Win32
case WindowsMessage.WM_DISPLAYCHANGE:
{
Screen?.OnChanged();
Win32Platform.UpdateTimerFps();
return IntPtr.Zero;
}

Loading…
Cancel
Save