Merge pull request #11258 from AdmiralCurtiss/imgui-crash-v2

ImGui render context race condition fix: Lock context during Init/Shutdown.
This commit is contained in:
Admiral H. Curtiss 2022-11-07 05:05:37 +01:00 committed by GitHub
commit ee7887b751
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 15 additions and 1 deletions

View File

@ -554,6 +554,9 @@ void RenderWidget::SetImGuiKeyMap()
}}; }};
auto lock = g_renderer->GetImGuiLock(); auto lock = g_renderer->GetImGuiLock();
if (!ImGui::GetCurrentContext())
return;
for (auto [imgui_key, qt_key] : key_map) for (auto [imgui_key, qt_key] : key_map)
ImGui::GetIO().KeyMap[imgui_key] = (qt_key & 0x1FF); ImGui::GetIO().KeyMap[imgui_key] = (qt_key & 0x1FF);
} }

View File

@ -1009,6 +1009,8 @@ void Renderer::RecordVideoMemory()
bool Renderer::InitializeImGui() bool Renderer::InitializeImGui()
{ {
std::unique_lock<std::mutex> imgui_lock(m_imgui_mutex);
if (!IMGUI_CHECKVERSION()) if (!IMGUI_CHECKVERSION())
{ {
PanicAlertFmt("ImGui version check failed"); PanicAlertFmt("ImGui version check failed");
@ -1068,7 +1070,7 @@ bool Renderer::InitializeImGui()
return false; return false;
m_imgui_last_frame_time = Common::Timer::NowUs(); m_imgui_last_frame_time = Common::Timer::NowUs();
BeginImGuiFrame(); BeginImGuiFrameUnlocked(); // lock is already held
return true; return true;
} }
@ -1129,6 +1131,8 @@ bool Renderer::RecompileImGuiPipeline()
void Renderer::ShutdownImGui() void Renderer::ShutdownImGui()
{ {
std::unique_lock<std::mutex> imgui_lock(m_imgui_mutex);
ImGui::EndFrame(); ImGui::EndFrame();
ImGui::DestroyContext(); ImGui::DestroyContext();
m_imgui_pipeline.reset(); m_imgui_pipeline.reset();
@ -1139,7 +1143,11 @@ void Renderer::ShutdownImGui()
void Renderer::BeginImGuiFrame() void Renderer::BeginImGuiFrame()
{ {
std::unique_lock<std::mutex> imgui_lock(m_imgui_mutex); std::unique_lock<std::mutex> imgui_lock(m_imgui_mutex);
BeginImGuiFrameUnlocked();
}
void Renderer::BeginImGuiFrameUnlocked()
{
const u64 current_time_us = Common::Timer::NowUs(); const u64 current_time_us = Common::Timer::NowUs();
const u64 time_diff_us = current_time_us - m_imgui_last_frame_time; const u64 time_diff_us = current_time_us - m_imgui_last_frame_time;
const float time_diff_secs = static_cast<float>(time_diff_us / 1000000.0); const float time_diff_secs = static_cast<float>(time_diff_us / 1000000.0);

View File

@ -303,6 +303,9 @@ protected:
// This function itself acquires the ImGui lock, so it should not be held. // This function itself acquires the ImGui lock, so it should not be held.
void BeginImGuiFrame(); void BeginImGuiFrame();
// Same as above but without locking the ImGui lock.
void BeginImGuiFrameUnlocked();
// Destroys all ImGui GPU resources, must do before shutdown. // Destroys all ImGui GPU resources, must do before shutdown.
void ShutdownImGui(); void ShutdownImGui();