diff --git a/src/Uno.UI.Runtime.Skia.X11/Builder/X11HostBuilder.cs b/src/Uno.UI.Runtime.Skia.X11/Builder/X11HostBuilder.cs index 3bb2ed455bd2..d667df3df6fa 100644 --- a/src/Uno.UI.Runtime.Skia.X11/Builder/X11HostBuilder.cs +++ b/src/Uno.UI.Runtime.Skia.X11/Builder/X11HostBuilder.cs @@ -10,15 +10,26 @@ internal partial class X11HostBuilder : IPlatformHostBuilder [GeneratedRegex(@"^(?:(?[\w\.-]+))?:(?\d+)(?:\.(?\d+))?$")] private static partial Regex DisplayRegex(); + private int _renderFrameRate = 60; + public X11HostBuilder() { } + /// + /// Sets the FPS that the application should try to achieve. + /// + public X11HostBuilder RenderFrameRate(int renderFrameRate) + { + _renderFrameRate = renderFrameRate; + return this; + } + public bool IsSupported => OperatingSystem.IsLinux() && Environment.GetEnvironmentVariable("DISPLAY") is { } displayString && DisplayRegex().Match(displayString).Success; public SkiaHost Create(Func appBuilder) - => new X11ApplicationHost(appBuilder); + => new X11ApplicationHost(appBuilder, _renderFrameRate); } diff --git a/src/Uno.UI.Runtime.Skia.X11/X11ApplicationHost.cs b/src/Uno.UI.Runtime.Skia.X11/X11ApplicationHost.cs index f40b91496cd6..71376b4296f3 100644 --- a/src/Uno.UI.Runtime.Skia.X11/X11ApplicationHost.cs +++ b/src/Uno.UI.Runtime.Skia.X11/X11ApplicationHost.cs @@ -23,6 +23,7 @@ namespace Uno.WinUI.Runtime.Skia.X11; public partial class X11ApplicationHost : SkiaHost, ISkiaApplicationHost, IDisposable { [ThreadStatic] private static bool _isDispatcherThread; + [ThreadStatic] private static int _renderFrameRate; private readonly EventLoop _eventLoop; private readonly Func _appBuilder; @@ -70,18 +71,24 @@ static X11ApplicationHost() ApiExtensibility.Register(typeof(Uno.Graphics.INativeOpenGLWrapper), xamlRoot => new X11NativeOpenGLWrapper(xamlRoot)); } - public X11ApplicationHost(Func appBuilder) + public X11ApplicationHost(Func appBuilder, int renderFrameRate = 60) { _appBuilder = appBuilder; _eventLoop = new EventLoop(); _eventLoop.Schedule(() => { Thread.CurrentThread.Name = "Uno Event Loop"; }, UI.Dispatching.NativeDispatcherPriority.Normal); - _eventLoop.Schedule(() => _isDispatcherThread = true, UI.Dispatching.NativeDispatcherPriority.Normal); + _eventLoop.Schedule(() => + { + _isDispatcherThread = true; + _renderFrameRate = renderFrameRate; + }, UI.Dispatching.NativeDispatcherPriority.Normal); CoreDispatcher.DispatchOverride = _eventLoop.Schedule; CoreDispatcher.HasThreadAccessOverride = () => _isDispatcherThread; } + internal static int RenderFrameRate => _renderFrameRate; + [LibraryImport("libc", StringMarshallingCustomType = typeof(AnsiStringMarshaller))] private static partial void setlocale(int type, string s); diff --git a/src/Uno.UI.Runtime.Skia.X11/X11XamlRootHost.cs b/src/Uno.UI.Runtime.Skia.X11/X11XamlRootHost.cs index 194927936de8..e02190e9f70f 100644 --- a/src/Uno.UI.Runtime.Skia.X11/X11XamlRootHost.cs +++ b/src/Uno.UI.Runtime.Skia.X11/X11XamlRootHost.cs @@ -100,7 +100,7 @@ public X11XamlRootHost(X11WindowWrapper wrapper, Window winUIWindow, XamlRoot xa _configureCallback = configureCallback; _renderTimer = new DispatcherTimer(); - _renderTimer.Interval = new TimeSpan(1000 / 16); + _renderTimer.Interval = TimeSpan.FromSeconds(1.0 / X11ApplicationHost.RenderFrameRate); // we're on the UI thread _renderTimer.Tick += (sender, o) => { if (Interlocked.Exchange(ref _needsConfigureCallback, 0) == 1) @@ -110,8 +110,8 @@ public X11XamlRootHost(X11WindowWrapper wrapper, Window winUIWindow, XamlRoot xa if (_renderDirty) { - _renderer?.Render(); _renderDirty = false; + _renderer?.Render(); } }; _renderTimer.Start();