Remove ScopedGlContext (#933)

As MakeCurrent can be slow to execute, this PR changes GLRenderer to not
have to reexecute MakeCurrent when processing frames.
This commit is contained in:
Thog 2020-02-14 11:52:34 +01:00 committed by GitHub
parent 949bb81a9e
commit dbe3f938c7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 76 deletions

View file

@ -84,7 +84,7 @@ namespace Ryujinx.Ui
private void GLRenderer_ShuttingDown(object sender, EventArgs args) private void GLRenderer_ShuttingDown(object sender, EventArgs args)
{ {
Exit(); _device.DisposeGpu();
} }
private void Parent_FocusOutEvent(object o, Gtk.FocusOutEventArgs args) private void Parent_FocusOutEvent(object o, Gtk.FocusOutEventArgs args)
@ -146,7 +146,7 @@ namespace Ryujinx.Ui
private void GLRenderer_Initialized(object sender, EventArgs e) private void GLRenderer_Initialized(object sender, EventArgs e)
{ {
// Release the GL exclusivity that OpenTK gave us. // Release the GL exclusivity that OpenTK gave us as we aren't going to use it in GTK Thread.
GraphicsContext.MakeCurrent(null); GraphicsContext.MakeCurrent(null);
WaitEvent.Set(); WaitEvent.Set();
@ -234,14 +234,7 @@ namespace Ryujinx.Ui
} }
IsStopped = true; IsStopped = true;
IsActive = false; IsActive = false;
using (ScopedGlContext scopedGLContext = new ScopedGlContext(WindowInfo, GraphicsContext))
{
_device.DisposeGpu();
}
WaitEvent.Set();
} }
public void Initialize() public void Initialize()
@ -256,12 +249,15 @@ namespace Ryujinx.Ui
public void Render() public void Render()
{ {
using (ScopedGlContext scopedGLContext = new ScopedGlContext(WindowInfo, GraphicsContext)) // First take exclusivity on the OpenGL context.
{ GraphicsContext.MakeCurrent(WindowInfo);
_renderer.Initialize();
SwapBuffers(); _renderer.Initialize();
}
// Make sure the first frame is not transparent.
GL.ClearColor(OpenTK.Color.Black);
GL.Clear(ClearBufferMask.ColorBufferBit);
SwapBuffers();
while (IsActive) while (IsActive)
{ {
@ -270,43 +266,40 @@ namespace Ryujinx.Ui
return; return;
} }
using (ScopedGlContext scopedGLContext = new ScopedGlContext(WindowInfo, GraphicsContext)) _ticks += _chrono.ElapsedTicks;
_chrono.Restart();
if (_device.WaitFifo())
{ {
_ticks += _chrono.ElapsedTicks; _device.ProcessFrame();
}
_chrono.Restart(); if (_ticks >= _ticksPerFrame)
{
_device.PresentFrame(SwapBuffers);
if (_device.WaitFifo()) _device.Statistics.RecordSystemFrameTime();
{
_device.ProcessFrame();
}
if (_ticks >= _ticksPerFrame) double hostFps = _device.Statistics.GetSystemFrameRate();
{ double gameFps = _device.Statistics.GetGameFrameRate();
_device.PresentFrame(SwapBuffers);
_device.Statistics.RecordSystemFrameTime(); string titleNameSection = string.IsNullOrWhiteSpace(_device.System.TitleName) ? string.Empty
: " | " + _device.System.TitleName;
double hostFps = _device.Statistics.GetSystemFrameRate(); string titleIdSection = string.IsNullOrWhiteSpace(_device.System.TitleIdText) ? string.Empty
double gameFps = _device.Statistics.GetGameFrameRate(); : " | " + _device.System.TitleIdText.ToUpper();
string titleNameSection = string.IsNullOrWhiteSpace(_device.System.TitleName) ? string.Empty _newTitle = $"Ryujinx {Program.Version}{titleNameSection}{titleIdSection} | Host FPS: {hostFps:0.0} | Game FPS: {gameFps:0.0} | " +
: " | " + _device.System.TitleName; $"Game Vsync: {(_device.EnableDeviceVsync ? "On" : "Off")}";
string titleIdSection = string.IsNullOrWhiteSpace(_device.System.TitleIdText) ? string.Empty _titleEvent = true;
: " | " + _device.System.TitleIdText.ToUpper();
_newTitle = $"Ryujinx {Program.Version}{titleNameSection}{titleIdSection} | Host FPS: {hostFps:0.0} | Game FPS: {gameFps:0.0} | " + _device.System.SignalVsync();
$"Game Vsync: {(_device.EnableDeviceVsync ? "On" : "Off")}";
_titleEvent = true; _device.VsyncEvent.Set();
_device.System.SignalVsync(); _ticks = Math.Min(_ticks - _ticksPerFrame, _ticksPerFrame);
_device.VsyncEvent.Set();
_ticks = Math.Min(_ticks - _ticksPerFrame, _ticksPerFrame);
}
} }
} }
} }

View file

@ -1,35 +0,0 @@
using OpenTK.Graphics;
using OpenTK.Platform;
using System;
using System.Threading;
namespace Ryujinx.Ui
{
class ScopedGlContext : IDisposable
{
private IGraphicsContext _graphicsContext;
private static readonly object _lock = new object();
public ScopedGlContext(IWindowInfo windowInfo, IGraphicsContext graphicsContext)
{
_graphicsContext = graphicsContext;
Monitor.Enter(_lock);
MakeCurrent(windowInfo);
}
private void MakeCurrent(IWindowInfo windowInfo)
{
_graphicsContext.MakeCurrent(windowInfo);
}
public void Dispose()
{
MakeCurrent(null);
Monitor.Exit(_lock);
}
}
}