Some fixes for the new GLRenderer

Changelog:
- Fix transparency of the window on some games on Windows.
- Fix escape key not being able to exit emulation.
- Fix inverted logic in fullscreen event handling.
- Fix a race condition when stoping emulation causing a hang.
- Fix a memory leak of the OpenGL context when stoping emulation (saving ~200MB of RAM when stoping emulation).
- Simplify and document behaviours when exiting the emulator while the
emulation is running.
This commit is contained in:
Thog 2020-02-12 15:55:45 +01:00
commit a528199cd4
2 changed files with 60 additions and 58 deletions

View file

@ -63,6 +63,7 @@ namespace Ryujinx.Ui
this.Initialized += GLRenderer_Initialized;
this.Destroyed += GLRenderer_Destroyed;
this.ShuttingDown += GLRenderer_ShuttingDown;
Initialize();
@ -81,6 +82,11 @@ namespace Ryujinx.Ui
this.Shown += Renderer_Shown;
}
private void GLRenderer_ShuttingDown(object sender, EventArgs args)
{
Exit();
}
private void Parent_FocusOutEvent(object o, Gtk.FocusOutEventArgs args)
{
IsFocused = false;
@ -93,9 +99,7 @@ namespace Ryujinx.Ui
private void GLRenderer_Destroyed(object sender, EventArgs e)
{
Exit();
this.Dispose();
Dispose();
}
protected void Renderer_Shown(object sender, EventArgs e)
@ -106,41 +110,38 @@ namespace Ryujinx.Ui
public void HandleScreenState(KeyboardState keyboard)
{
bool toggleFullscreen = keyboard.IsKeyDown(OpenTK.Input.Key.F11)
|| ((keyboard.IsKeyDown(OpenTK.Input.Key.AltLeft)
|| keyboard.IsKeyDown(OpenTK.Input.Key.AltRight))
&& keyboard.IsKeyDown(OpenTK.Input.Key.Enter));
|| ((keyboard.IsKeyDown(OpenTK.Input.Key.AltLeft)
|| keyboard.IsKeyDown(OpenTK.Input.Key.AltRight))
&& keyboard.IsKeyDown(OpenTK.Input.Key.Enter))
|| keyboard.IsKeyDown(OpenTK.Input.Key.Escape);
if (toggleFullscreen == _toggleFullscreen)
bool fullScreenToggled = ParentWindow.State.HasFlag(Gdk.WindowState.Fullscreen);
if (toggleFullscreen != _toggleFullscreen)
{
return;
if (toggleFullscreen)
{
if (fullScreenToggled)
{
ParentWindow.Unfullscreen();
(Toplevel as MainWindow)?.ToggleExtraWidgets(true);
}
else
{
if (keyboard.IsKeyDown(OpenTK.Input.Key.Escape))
{
Exit();
}
else
{
ParentWindow.Fullscreen();
(Toplevel as MainWindow)?.ToggleExtraWidgets(false);
}
}
}
}
_toggleFullscreen = toggleFullscreen;
Gtk.Application.Invoke(delegate
{
if (this.ParentWindow.State.HasFlag(Gdk.WindowState.Fullscreen))
{
if (keyboard.IsKeyDown(OpenTK.Input.Key.Escape) || _toggleFullscreen)
{
this.ParentWindow.Unfullscreen();
(this.Toplevel as MainWindow)?.ToggleExtraWidgets(true);
}
}
else
{
if (keyboard.IsKeyDown(OpenTK.Input.Key.Escape))
{
Exit();
}
if (_toggleFullscreen)
{
this.ParentWindow.Fullscreen();
(this.Toplevel as MainWindow)?.ToggleExtraWidgets(false);
}
}
});
}
private void GLRenderer_Initialized(object sender, EventArgs e)
@ -282,6 +283,11 @@ namespace Ryujinx.Ui
if (_ticks >= _ticksPerFrame)
{
// Ensure that the content is Opaque.
GL.ColorMask(false, false, false, true);
GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
GL.ColorMask(true, true, true, true);
_device.PresentFrame(SwapBuffers);
_device.Statistics.RecordSystemFrameTime();

View file

@ -31,7 +31,7 @@ namespace Ryujinx.Ui
private static GLRenderer _gLWidget;
private static AutoResetEvent _screenExitStatus = new AutoResetEvent(false);
private static AutoResetEvent _deviceExitStatus = new AutoResetEvent(false);
private static ListStore _tableStore;
@ -356,7 +356,7 @@ namespace Ryujinx.Ui
_emulationContext = device;
_screenExitStatus.Reset();
_deviceExitStatus.Reset();
#if MACOS_BUILD
CreateGameWindow(device);
@ -391,8 +391,6 @@ namespace Ryujinx.Ui
{
device.Hid.InitializePrimaryController(ConfigurationState.Instance.Hid.ControllerType);
_gLWidget?.Exit();
_gLWidget?.Dispose();
_gLWidget = new GLRenderer(_emulationContext);
Application.Invoke(delegate
@ -409,6 +407,10 @@ namespace Ryujinx.Ui
_gLWidget.Start();
device.Dispose();
_deviceExitStatus.Set();
// NOTE: Everything that is here will not be executed when you close the UI.
Application.Invoke(delegate
{
_viewBox.Remove(_gLWidget);
@ -419,36 +421,31 @@ namespace Ryujinx.Ui
_gLWidget.Window.Dispose();
}
_gLWidget.Dispose();
_viewBox.Add(_gameTableWindow);
_gameTableWindow.Expand = true;
this.Window.Title = "Ryujinx";
_emulationContext = null;
_gameLoaded = false;
_gLWidget = null;
DiscordIntegrationModule.SwitchToMainMenu();
_listStatusBox.ShowAll();
UpdateColumns();
UpdateGameTable();
Task.Run(RefreshFirmwareLabel);
});
device.Dispose();
_emulationContext = null;
_gameLoaded = false;
_gLWidget = null;
DiscordIntegrationModule.SwitchToMainMenu();
Application.Invoke(delegate
{
_stopEmulation.Sensitive = false;
_firmwareInstallFile.Sensitive = true;
_firmwareInstallDirectory.Sensitive = true;
});
_screenExitStatus.Set();
}
public void ToggleExtraWidgets(bool show)
@ -469,7 +466,7 @@ namespace Ryujinx.Ui
bool fullScreenToggled = this.Window.State.HasFlag(Gdk.WindowState.Fullscreen);
_fullScreen.Label = !fullScreenToggled ? "Exit Fullscreen" : "Enter Fullscreen";
_fullScreen.Label = fullScreenToggled ? "Exit Fullscreen" : "Enter Fullscreen";
}
private static void UpdateGameMetadata(string titleId)
@ -506,8 +503,11 @@ namespace Ryujinx.Ui
if (_gLWidget != null)
{
// We tell the widget that we are exiting
_gLWidget.Exit();
_screenExitStatus.WaitOne();
// Wait for the other thread to dispose the HLE context before exiting.
_deviceExitStatus.WaitOne();
}
}
@ -874,17 +874,13 @@ namespace Ryujinx.Ui
{
Fullscreen();
_fullScreen.Label = "Exit Fullscreen";
ToggleExtraWidgets(false);
ToggleExtraWidgets(true);
}
else
{
Unfullscreen();
_fullScreen.Label = "Enter Fullscreen";
ToggleExtraWidgets(true);
ToggleExtraWidgets(false);
}
}