diff options
Diffstat (limited to 'Ryujinx.Ava/AppHost.cs')
-rw-r--r-- | Ryujinx.Ava/AppHost.cs | 92 |
1 files changed, 36 insertions, 56 deletions
diff --git a/Ryujinx.Ava/AppHost.cs b/Ryujinx.Ava/AppHost.cs index 7e3cddc8..7cf5934a 100644 --- a/Ryujinx.Ava/AppHost.cs +++ b/Ryujinx.Ava/AppHost.cs @@ -1,6 +1,5 @@ using ARMeilleure.Translation; using ARMeilleure.Translation.PTC; -using Avalonia; using Avalonia.Input; using Avalonia.Threading; using LibHac.Tools.FsSystem; @@ -12,10 +11,8 @@ using Ryujinx.Audio.Integration; using Ryujinx.Ava.Common; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Input; -using Ryujinx.Ava.Ui.Backend.Vulkan; using Ryujinx.Ava.Ui.Controls; using Ryujinx.Ava.Ui.Models; -using Ryujinx.Ava.Ui.Vulkan; using Ryujinx.Ava.Ui.Windows; using Ryujinx.Common; using Ryujinx.Common.Configuration; @@ -39,6 +36,7 @@ using SixLabors.ImageSharp; using SixLabors.ImageSharp.Formats.Png; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; +using SPB.Graphics.Vulkan; using System; using System.Diagnostics; using System.IO; @@ -58,24 +56,24 @@ namespace Ryujinx.Ava { private const int CursorHideIdleTime = 8; // Hide Cursor seconds private const float MaxResolutionScale = 4.0f; // Max resolution hotkeys can scale to before wrapping. + private const int TargetFps = 60; - private static readonly Cursor InvisibleCursor = new Cursor(StandardCursorType.None); + private static readonly Cursor InvisibleCursor = new Cursor(StandardCursorType.None); + private readonly long _ticksPerFrame; + private readonly Stopwatch _chrono; private readonly AccountManager _accountManager; private readonly UserChannelPersistence _userChannelPersistence; - private readonly InputManager _inputManager; - - private readonly IKeyboard _keyboardInterface; - private readonly MainWindow _parent; - + private readonly IKeyboard _keyboardInterface; private readonly GraphicsDebugLevel _glLogLevel; private bool _hideCursorOnIdle; private bool _isStopped; private bool _isActive; private long _lastCursorMoveTime; + private long _ticks = 0; private KeyboardHotkeyState _prevHotkeyState; @@ -93,7 +91,7 @@ namespace Ryujinx.Ava public event EventHandler AppExit; public event EventHandler<StatusUpdatedEventArgs> StatusUpdatedEvent; - public RendererControl Renderer { get; } + public RendererHost Renderer { get; } public VirtualFileSystem VirtualFileSystem { get; } public ContentManager ContentManager { get; } public Switch Device { get; set; } @@ -111,7 +109,7 @@ namespace Ryujinx.Ava private object _lockObject = new(); public AppHost( - RendererControl renderer, + RendererHost renderer, InputManager inputManager, string applicationPath, VirtualFileSystem virtualFileSystem, @@ -128,7 +126,7 @@ namespace Ryujinx.Ava _hideCursorOnIdle = ConfigurationState.Instance.HideCursorOnIdle; _lastCursorMoveTime = Stopwatch.GetTimestamp(); _glLogLevel = ConfigurationState.Instance.Logger.GraphicsDebugLevel; - _inputManager.SetMouseDriver(new AvaloniaMouseDriver(renderer)); + _inputManager.SetMouseDriver(new AvaloniaMouseDriver(_parent, renderer)); _keyboardInterface = (IKeyboard)_inputManager.KeyboardDriver.GetGamepad("0"); NpadManager = _inputManager.CreateNpadManager(); @@ -138,6 +136,9 @@ namespace Ryujinx.Ava VirtualFileSystem = virtualFileSystem; ContentManager = contentManager; + _chrono = new Stopwatch(); + _ticksPerFrame = Stopwatch.Frequency / TargetFps; + if (ApplicationPath.StartsWith("@SystemContent")) { ApplicationPath = _parent.VirtualFileSystem.SwitchPathToSystemPath(ApplicationPath); @@ -177,7 +178,7 @@ namespace Ryujinx.Ava if (_renderer != null) { double scale = _parent.PlatformImpl.RenderScaling; - _renderer.Window.SetSize((int)(size.Width * scale), (int)(size.Height * scale)); + _renderer.Window?.SetSize((int)(size.Width * scale), (int)(size.Height * scale)); } } @@ -335,8 +336,6 @@ namespace Ryujinx.Ava return; } - AvaloniaLocator.Current.GetService<VulkanPlatformInterface>()?.MainSurface.Display.ChangeVSyncMode(true); - _isStopped = true; _isActive = false; } @@ -376,6 +375,8 @@ namespace Ryujinx.Ava _gpuCancellationTokenSource.Cancel(); _gpuCancellationTokenSource.Dispose(); + + _chrono.Stop(); } public void DisposeGpu() @@ -389,8 +390,7 @@ namespace Ryujinx.Ava Renderer?.MakeCurrent(); Device.DisposeGpu(); - - Renderer?.DestroyBackgroundContext(); + Renderer?.MakeCurrent(null); } @@ -596,16 +596,11 @@ namespace Ryujinx.Ava IRenderer renderer; - if (Program.UseVulkan) + if (Renderer.IsVulkan) { - var vulkan = AvaloniaLocator.Current.GetService<VulkanPlatformInterface>(); + string preferredGpu = ConfigurationState.Instance.Graphics.PreferredGpu.Value; - renderer = new VulkanRenderer(vulkan.Instance.InternalHandle, - vulkan.MainSurface.Device.InternalHandle, - vulkan.PhysicalDevice.InternalHandle, - vulkan.MainSurface.Device.Queue.InternalHandle, - vulkan.PhysicalDevice.QueueFamilyIndex, - vulkan.MainSurface.Device.Lock); + renderer = new VulkanRenderer(Renderer.CreateVulkanSurface, VulkanHelper.GetRequiredInstanceExtensions, preferredGpu); } else { @@ -778,11 +773,7 @@ namespace Ryujinx.Ava { Width = (int)e.Width; Height = (int)e.Height; - - if (!Program.UseVulkan) - { - SetRendererWindowSize(e); - } + SetRendererWindowSize(e); } private void MainLoop() @@ -822,12 +813,10 @@ namespace Ryujinx.Ava _renderer.ScreenCaptured += Renderer_ScreenCaptured; - (_renderer as OpenGLRenderer)?.InitializeBackgroundContext(SPBOpenGLContext.CreateBackgroundContext((Renderer as OpenGLRendererControl).GameContext)); + (_renderer as OpenGLRenderer)?.InitializeBackgroundContext(SPBOpenGLContext.CreateBackgroundContext(Renderer.GetContext())); Renderer.MakeCurrent(); - AvaloniaLocator.Current.GetService<VulkanPlatformInterface>()?.MainSurface?.Display?.ChangeVSyncMode(Device.EnableDeviceVsync); - Device.Gpu.Renderer.Initialize(_glLogLevel); Width = (int)Renderer.Bounds.Width; @@ -835,16 +824,20 @@ namespace Ryujinx.Ava _renderer.Window.SetSize((int)(Width * _parent.PlatformImpl.RenderScaling), (int)(Height * _parent.PlatformImpl.RenderScaling)); + _chrono.Start(); + Device.Gpu.Renderer.RunLoop(() => { Device.Gpu.SetGpuThread(); Device.Gpu.InitializeShaderCache(_gpuCancellationTokenSource.Token); Translator.IsReadyForTranslation.Set(); - Renderer.Start(); - while (_isActive) { + _ticks += _chrono.ElapsedTicks; + + _chrono.Restart(); + if (Device.WaitFifo()) { Device.Statistics.RecordFifoStart(); @@ -860,19 +853,20 @@ namespace Ryujinx.Ava _parent.SwitchToGameControl(); } - Device.PresentFrame(Present); + Device.PresentFrame(() => Renderer?.SwapBuffers()); } - } - Renderer.Stop(); + if (_ticks >= _ticksPerFrame) + { + UpdateStatus(); + } + } }); Renderer?.MakeCurrent(null); - - Renderer.SizeChanged -= Window_SizeChanged; } - private void Present(object image) + public void UpdateStatus() { // Run a status update only when a frame is to be drawn. This prevents from updating the ui and wasting a render when no frame is queued string dockedMode = ConfigurationState.Instance.System.EnableDockedMode ? LocaleManager.Instance["Docked"] : LocaleManager.Instance["Handheld"]; @@ -886,24 +880,12 @@ namespace Ryujinx.Ava StatusUpdatedEvent?.Invoke(this, new StatusUpdatedEventArgs( Device.EnableDeviceVsync, Device.GetVolume(), - Program.UseVulkan ? "Vulkan" : "OpenGL", + Renderer.IsVulkan ? "Vulkan" : "OpenGL", dockedMode, ConfigurationState.Instance.Graphics.AspectRatio.Value.ToText(), LocaleManager.Instance["Game"] + $": {Device.Statistics.GetGameFrameRate():00.00} FPS ({Device.Statistics.GetGameFrameTime():00.00} ms)", $"FIFO: {Device.Statistics.GetFifoPercent():00.00} %", $"GPU: {_renderer.GetHardwareInfo().GpuVendor}")); - - if (Program.UseVulkan) - { - var platformInterface = AvaloniaLocator.Current.GetService<VulkanPlatformInterface>(); - if (platformInterface.MainSurface.Display.IsSurfaceChanged()) - { - SetRendererWindowSize(new Size(Width, Height)); - return; - } - } - - Renderer.Present(image); } public async Task ShowExitPrompt() @@ -985,8 +967,6 @@ namespace Ryujinx.Ava case KeyboardHotkeyState.ToggleVSync: Device.EnableDeviceVsync = !Device.EnableDeviceVsync; - AvaloniaLocator.Current.GetService<VulkanPlatformInterface>()?.MainSurface?.Display?.ChangeVSyncMode(Device.EnableDeviceVsync); - break; case KeyboardHotkeyState.Screenshot: ScreenshotRequested = true; |