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:
ReinUsesLisp 2018-07-12 14:03:52 -03:00 committed by gdkchan
parent 37071285bc
commit cd18ab29df
4 changed files with 113 additions and 11 deletions

View File

@ -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()

View File

@ -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();

View File

@ -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,15 +49,87 @@ 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); 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);
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)
{ {
if (Button.ToUpper() == "LTRIGGER" || Button.ToUpper() == "RTRIGGER") if (Button.ToUpper() == "LTRIGGER" || Button.ToUpper() == "RTRIGGER")
@ -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)

View File

@ -67,7 +67,7 @@ namespace Ryujinx
Screen.Exit(); Screen.Exit();
}; };
Screen.Run(0.0, 60.0); Screen.MainLoop();
} }
Environment.Exit(0); Environment.Exit(0);