From 1dff22d5768d6860ef6ed6ee8ad3a353bbea0093 Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Wed, 8 Nov 2023 18:43:00 -0800 Subject: [PATCH] Movie: Fix crash when starting input recording on OpenGL single-core Use RunOnCPUThread instead of RunAsCPUThread in BeginRecordingInput. Most OpenGL functions require an OpenGL context to have been created on that thread before calling the function; when that isn't the case they return invalid results which can cause crashes when passed into other functions. Dolphin creates the OpenGL context in the EmuThread which then becomes either the CPU-GPU thread or the Video thread for single and dual core respectively. OpenGL functions must therefore be called from that thread. Movie::BeginRecordingInput is called from the Host thread and runs a block of code which ultimately creates a savestate, which in turn embeds the framebuffer which requires calling various OpenGL functions. In single core the use of RunAsCPUThread leads to this all happening on the Host thread, eventually leading to invalid OpenGL calls and a crash. In Dual core the crash is avoided because VideoBackendBase::DoState uses the AsyncRequests::DO_SAVE_STATE event which causes VideoCommon_DoState and its subsequent OpenGL calls to safely run on the Video thread. This commit uses RunOnCPUThread instead of RunAsCPUThread, which causes the subsequent code to run on the CPU-GPU thread in single core which has the valid OpenGL context and so doesn't crash. --- Source/Core/Core/Movie.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/Movie.cpp b/Source/Core/Core/Movie.cpp index 152f5617b2..5b66b707ea 100644 --- a/Source/Core/Core/Movie.cpp +++ b/Source/Core/Core/Movie.cpp @@ -545,7 +545,7 @@ bool BeginRecordingInput(const ControllerTypeArray& controllers, (controllers == ControllerTypeArray{} && wiimotes == WiimoteEnabledArray{})) return false; - Core::RunAsCPUThread([controllers, wiimotes] { + const auto start_recording = [controllers, wiimotes] { s_controllers = controllers; s_wiimotes = wiimotes; s_currentFrame = s_totalFrames = 0; @@ -615,7 +615,8 @@ bool BeginRecordingInput(const ControllerTypeArray& controllers, if (Core::IsRunning()) Core::UpdateWantDeterminism(); - }); + }; + Core::RunOnCPUThread(start_recording, true); Core::DisplayMessage("Starting movie recording", 2000); return true;