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 /> /// <inheritdoc />
public bool RunsInBackground => _timer.RunsInBackground; public bool RunsInBackground => _timer.RunsInBackground;
internal IRenderTimer Timer => _timer;
/// <inheritdoc /> /// <inheritdoc />
public void Wakeup() public void Wakeup()
{ {

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

@ -44,7 +44,7 @@ namespace Avalonia.Win32
private static Win32PlatformOptions? s_options; private static Win32PlatformOptions? s_options;
private static Compositor? s_compositor; private static Compositor? s_compositor;
internal const int TIMERID_DISPATCHER = 1; internal const int TIMERID_DISPATCHER = 1;
private const int DefaultFramesPerSecond = 60;
private WndProc? _wndProcDelegate; private WndProc? _wndProcDelegate;
private IntPtr _hwnd; private IntPtr _hwnd;
private Win32DispatcherImpl _dispatcher; private Win32DispatcherImpl _dispatcher;
@ -87,7 +87,7 @@ namespace Avalonia.Win32
Dispatcher.InitializeUIThreadDispatcher(s_instance._dispatcher); 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 clipboardImpl = new ClipboardImpl();
var clipboard = new Clipboard(clipboardImpl); var clipboard = new Clipboard(clipboardImpl);
@ -133,7 +133,9 @@ namespace Avalonia.Win32
if (OleContext.Current != null) if (OleContext.Current != null)
AvaloniaLocator.CurrentMutable.Bind<IPlatformDragSource>().ToSingleton<DragSource>(); AvaloniaLocator.CurrentMutable.Bind<IPlatformDragSource>().ToSingleton<DragSource>();
UpdateTimerFps();
s_compositor = new Compositor( platformGraphics); s_compositor = new Compositor( platformGraphics);
AvaloniaLocator.CurrentMutable.Bind<Compositor>().ToConstant(s_compositor); AvaloniaLocator.CurrentMutable.Bind<Compositor>().ToConstant(s_compositor);
} }
@ -196,6 +198,16 @@ namespace Avalonia.Win32
return DefWindowProc(hWnd, msg, wParam, lParam); 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() private void CreateMessageWindow()
{ {
// Ensure that the delegate doesn't get garbage collected by storing it as a field. // 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;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Avalonia.Automation.Peers; using Avalonia.Automation.Peers;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Input.Raw; using Avalonia.Input.Raw;
using Avalonia.Rendering;
using Avalonia.Threading; using Avalonia.Threading;
using Avalonia.Win32.Automation; using Avalonia.Win32.Automation;
using Avalonia.Win32.Automation.Interop; using Avalonia.Win32.Automation.Interop;
@ -873,6 +875,9 @@ namespace Avalonia.Win32
case WindowsMessage.WM_DISPLAYCHANGE: case WindowsMessage.WM_DISPLAYCHANGE:
{ {
Screen?.OnChanged(); Screen?.OnChanged();
Win32Platform.UpdateTimerFps();
return IntPtr.Zero; return IntPtr.Zero;
} }

Loading…
Cancel
Save