forked from Mirror/Ryujinx
Loop GLScreen with custom method (#244)
* Loop GLScreen with custom method * Fix deadlocks * Fix screen resizing * Change event to bool * Try to fix quitting error * Set title from main thread * Queue max 1 vsync, fix high FPS after a slowdown
This commit is contained in:
parent
37071285bc
commit
cd18ab29df
4 changed files with 113 additions and 11 deletions
|
@ -1,5 +1,6 @@
|
||||||
using Ryujinx.HLE.Gpu.Memory;
|
using Ryujinx.HLE.Gpu.Memory;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.Gpu.Engines
|
namespace Ryujinx.HLE.Gpu.Engines
|
||||||
{
|
{
|
||||||
|
@ -18,6 +19,8 @@ namespace Ryujinx.HLE.Gpu.Engines
|
||||||
|
|
||||||
private NvGpuEngine[] SubChannels;
|
private NvGpuEngine[] SubChannels;
|
||||||
|
|
||||||
|
public AutoResetEvent Event { get; private set; }
|
||||||
|
|
||||||
private struct CachedMacro
|
private struct CachedMacro
|
||||||
{
|
{
|
||||||
public int Position { get; private set; }
|
public int Position { get; private set; }
|
||||||
|
@ -60,6 +63,8 @@ namespace Ryujinx.HLE.Gpu.Engines
|
||||||
Macros = new CachedMacro[MacrosCount];
|
Macros = new CachedMacro[MacrosCount];
|
||||||
|
|
||||||
Mme = new int[MmeWords];
|
Mme = new int[MmeWords];
|
||||||
|
|
||||||
|
Event = new AutoResetEvent(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PushBuffer(NvGpuVmm Vmm, NvGpuPBEntry[] Buffer)
|
public void PushBuffer(NvGpuVmm Vmm, NvGpuPBEntry[] Buffer)
|
||||||
|
@ -68,6 +73,8 @@ namespace Ryujinx.HLE.Gpu.Engines
|
||||||
{
|
{
|
||||||
BufferQueue.Enqueue((Vmm, PBEntry));
|
BufferQueue.Enqueue((Vmm, PBEntry));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Event.Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DispatchCalls()
|
public void DispatchCalls()
|
||||||
|
|
|
@ -71,6 +71,11 @@ namespace Ryujinx.HLE
|
||||||
Os.LoadProgram(FileName);
|
Os.LoadProgram(FileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool WaitFifo()
|
||||||
|
{
|
||||||
|
return Gpu.Fifo.Event.WaitOne(8);
|
||||||
|
}
|
||||||
|
|
||||||
public void ProcessFrame()
|
public void ProcessFrame()
|
||||||
{
|
{
|
||||||
Gpu.Fifo.DispatchCalls();
|
Gpu.Fifo.DispatchCalls();
|
||||||
|
|
|
@ -5,6 +5,9 @@ using Ryujinx.Graphics.Gal;
|
||||||
using Ryujinx.HLE;
|
using Ryujinx.HLE;
|
||||||
using Ryujinx.HLE.Input;
|
using Ryujinx.HLE.Input;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
using Stopwatch = System.Diagnostics.Stopwatch;
|
||||||
|
|
||||||
namespace Ryujinx
|
namespace Ryujinx
|
||||||
{
|
{
|
||||||
|
@ -16,6 +19,8 @@ namespace Ryujinx
|
||||||
private const float TouchScreenRatioX = (float)TouchScreenWidth / TouchScreenHeight;
|
private const float TouchScreenRatioX = (float)TouchScreenWidth / TouchScreenHeight;
|
||||||
private const float TouchScreenRatioY = (float)TouchScreenHeight / TouchScreenWidth;
|
private const float TouchScreenRatioY = (float)TouchScreenHeight / TouchScreenWidth;
|
||||||
|
|
||||||
|
private const int TargetFPS = 60;
|
||||||
|
|
||||||
private Switch Ns;
|
private Switch Ns;
|
||||||
|
|
||||||
private IGalRenderer Renderer;
|
private IGalRenderer Renderer;
|
||||||
|
@ -24,6 +29,14 @@ namespace Ryujinx
|
||||||
|
|
||||||
private MouseState? Mouse = null;
|
private MouseState? Mouse = null;
|
||||||
|
|
||||||
|
private Thread RenderThread;
|
||||||
|
|
||||||
|
private bool ResizeEvent;
|
||||||
|
|
||||||
|
private bool TitleEvent;
|
||||||
|
|
||||||
|
private string NewTitle;
|
||||||
|
|
||||||
public GLScreen(Switch Ns, IGalRenderer Renderer)
|
public GLScreen(Switch Ns, IGalRenderer Renderer)
|
||||||
: base(1280, 720,
|
: base(1280, 720,
|
||||||
new GraphicsMode(), "Ryujinx", 0,
|
new GraphicsMode(), "Ryujinx", 0,
|
||||||
|
@ -36,13 +49,85 @@ namespace Ryujinx
|
||||||
Location = new Point(
|
Location = new Point(
|
||||||
(DisplayDevice.Default.Width / 2) - (Width / 2),
|
(DisplayDevice.Default.Width / 2) - (Width / 2),
|
||||||
(DisplayDevice.Default.Height / 2) - (Height / 2));
|
(DisplayDevice.Default.Height / 2) - (Height / 2));
|
||||||
|
|
||||||
|
ResizeEvent = false;
|
||||||
|
|
||||||
|
TitleEvent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnLoad(EventArgs e)
|
private void RenderLoop()
|
||||||
{
|
{
|
||||||
VSync = VSyncMode.On;
|
MakeCurrent();
|
||||||
|
|
||||||
|
Stopwatch Chrono = new Stopwatch();
|
||||||
|
|
||||||
|
Chrono.Start();
|
||||||
|
|
||||||
|
long TicksPerFrame = Stopwatch.Frequency / TargetFPS;
|
||||||
|
|
||||||
|
long Ticks = 0;
|
||||||
|
|
||||||
|
while (Exists && !IsExiting)
|
||||||
|
{
|
||||||
|
if (Ns.WaitFifo())
|
||||||
|
{
|
||||||
|
Ns.ProcessFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
Renderer.RunActions();
|
||||||
|
|
||||||
|
if (ResizeEvent)
|
||||||
|
{
|
||||||
|
ResizeEvent = false;
|
||||||
|
|
||||||
|
Renderer.FrameBuffer.SetWindowSize(Width, Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ticks += Chrono.ElapsedTicks;
|
||||||
|
|
||||||
|
Chrono.Restart();
|
||||||
|
|
||||||
|
if (Ticks >= TicksPerFrame)
|
||||||
|
{
|
||||||
|
RenderFrame();
|
||||||
|
|
||||||
|
//Queue max. 1 vsync
|
||||||
|
Ticks = Math.Min(Ticks - TicksPerFrame, TicksPerFrame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MainLoop()
|
||||||
|
{
|
||||||
|
VSync = VSyncMode.Off;
|
||||||
|
|
||||||
|
Visible = true;
|
||||||
|
|
||||||
Renderer.FrameBuffer.SetWindowSize(Width, Height);
|
Renderer.FrameBuffer.SetWindowSize(Width, Height);
|
||||||
|
|
||||||
|
Context.MakeCurrent(null);
|
||||||
|
|
||||||
|
//OpenTK doesn't like sleeps in its thread, to avoid this a renderer thread is created
|
||||||
|
RenderThread = new Thread(RenderLoop);
|
||||||
|
|
||||||
|
RenderThread.Start();
|
||||||
|
|
||||||
|
while (Exists && !IsExiting)
|
||||||
|
{
|
||||||
|
ProcessEvents();
|
||||||
|
|
||||||
|
if (!IsExiting)
|
||||||
|
{
|
||||||
|
UpdateFrame();
|
||||||
|
|
||||||
|
if (TitleEvent)
|
||||||
|
{
|
||||||
|
TitleEvent = false;
|
||||||
|
|
||||||
|
Title = NewTitle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsGamePadButtonPressedFromString(GamePadState GamePad, string Button)
|
private bool IsGamePadButtonPressedFromString(GamePadState GamePad, string Button)
|
||||||
|
@ -99,7 +184,7 @@ namespace Ryujinx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnUpdateFrame(FrameEventArgs e)
|
private new void UpdateFrame()
|
||||||
{
|
{
|
||||||
HidControllerButtons CurrentButton = 0;
|
HidControllerButtons CurrentButton = 0;
|
||||||
HidJoystickPosition LeftJoystick;
|
HidJoystickPosition LeftJoystick;
|
||||||
|
@ -278,13 +363,9 @@ namespace Ryujinx
|
||||||
CurrentButton,
|
CurrentButton,
|
||||||
LeftJoystick,
|
LeftJoystick,
|
||||||
RightJoystick);
|
RightJoystick);
|
||||||
|
|
||||||
Ns.ProcessFrame();
|
|
||||||
|
|
||||||
Renderer.RunActions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnRenderFrame(FrameEventArgs e)
|
private new void RenderFrame()
|
||||||
{
|
{
|
||||||
Renderer.FrameBuffer.Render();
|
Renderer.FrameBuffer.Render();
|
||||||
|
|
||||||
|
@ -293,16 +374,25 @@ namespace Ryujinx
|
||||||
double HostFps = Ns.Statistics.GetSystemFrameRate();
|
double HostFps = Ns.Statistics.GetSystemFrameRate();
|
||||||
double GameFps = Ns.Statistics.GetGameFrameRate();
|
double GameFps = Ns.Statistics.GetGameFrameRate();
|
||||||
|
|
||||||
Title = $"Ryujinx | Host FPS: {HostFps:0.0} | Game FPS: {GameFps:0.0}";
|
NewTitle = $"Ryujinx | Host FPS: {HostFps:0.0} | Game FPS: {GameFps:0.0}";
|
||||||
|
|
||||||
|
TitleEvent = true;
|
||||||
|
|
||||||
SwapBuffers();
|
SwapBuffers();
|
||||||
|
|
||||||
Ns.Os.SignalVsync();
|
Ns.Os.SignalVsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnUnload(EventArgs e)
|
||||||
|
{
|
||||||
|
RenderThread.Join();
|
||||||
|
|
||||||
|
base.OnUnload(e);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnResize(EventArgs e)
|
protected override void OnResize(EventArgs e)
|
||||||
{
|
{
|
||||||
Renderer.FrameBuffer.SetWindowSize(Width, Height);
|
ResizeEvent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnKeyDown(KeyboardKeyEventArgs e)
|
protected override void OnKeyDown(KeyboardKeyEventArgs e)
|
||||||
|
|
|
@ -67,7 +67,7 @@ namespace Ryujinx
|
||||||
Screen.Exit();
|
Screen.Exit();
|
||||||
};
|
};
|
||||||
|
|
||||||
Screen.Run(0.0, 60.0);
|
Screen.MainLoop();
|
||||||
}
|
}
|
||||||
|
|
||||||
Environment.Exit(0);
|
Environment.Exit(0);
|
||||||
|
|
Reference in a new issue