aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Ava/AppHost.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Ava/AppHost.cs')
-rw-r--r--src/Ryujinx.Ava/AppHost.cs19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/Ryujinx.Ava/AppHost.cs b/src/Ryujinx.Ava/AppHost.cs
index 349b64b4..2502fa41 100644
--- a/src/Ryujinx.Ava/AppHost.cs
+++ b/src/Ryujinx.Ava/AppHost.cs
@@ -92,6 +92,8 @@ namespace Ryujinx.Ava
private bool _isActive;
private bool _renderingStarted;
+ private ManualResetEvent _gpuDoneEvent;
+
private IRenderer _renderer;
private readonly Thread _renderingThread;
private readonly CancellationTokenSource _gpuCancellationTokenSource;
@@ -183,6 +185,7 @@ namespace Ryujinx.Ava
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Event += UpdateLanInterfaceIdState;
_gpuCancellationTokenSource = new CancellationTokenSource();
+ _gpuDoneEvent = new ManualResetEvent(false);
}
private void TopLevel_PointerEnterOrMoved(object sender, PointerEventArgs e)
@@ -423,10 +426,10 @@ namespace Ryujinx.Ava
_isActive = false;
- if (_renderingThread.IsAlive)
- {
- _renderingThread.Join();
- }
+ // NOTE: The render loop is allowed to stay alive until the renderer itself is disposed, as it may handle resource dispose.
+ // We only need to wait for all commands submitted during the main gpu loop to be processed.
+ _gpuDoneEvent.WaitOne();
+ _gpuDoneEvent.Dispose();
DisplaySleep.Restore();
@@ -917,6 +920,14 @@ namespace Ryujinx.Ava
UpdateStatus();
}
}
+
+ // Make sure all commands in the run loop are fully executed before leaving the loop.
+ if (Device.Gpu.Renderer is ThreadedRenderer threaded)
+ {
+ threaded.FlushThreadedCommands();
+ }
+
+ _gpuDoneEvent.Set();
});
(_rendererHost.EmbeddedWindow as EmbeddedWindowOpenGL)?.MakeCurrent(null);