summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorAdmiral H. Curtiss <pikachu025@gmail.com>2022-11-07 05:05:37 +0100
committerGitHub <noreply@github.com>2022-11-07 05:05:37 +0100
commitee7887b7511dd3cdb27fd8517d42088cf26cdade (patch)
treecff8eaf076c6f07a006f79a582ca5a74cf977712 /Source/Core
parentc931529e7aa5926b8a21a193bf8f80244b3ae888 (diff)
parenta98df1894705195f7051ef1dfccafffe135149c5 (diff)
Merge pull request #11258 from AdmiralCurtiss/imgui-crash-v2
ImGui render context race condition fix: Lock context during Init/Shutdown.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/DolphinQt/RenderWidget.cpp3
-rw-r--r--Source/Core/VideoCommon/RenderBase.cpp10
-rw-r--r--Source/Core/VideoCommon/RenderBase.h3
3 files changed, 15 insertions, 1 deletions
diff --git a/Source/Core/DolphinQt/RenderWidget.cpp b/Source/Core/DolphinQt/RenderWidget.cpp
index cb55877ace..891d3614c8 100644
--- a/Source/Core/DolphinQt/RenderWidget.cpp
+++ b/Source/Core/DolphinQt/RenderWidget.cpp
@@ -554,6 +554,9 @@ void RenderWidget::SetImGuiKeyMap()
}};
auto lock = g_renderer->GetImGuiLock();
+ if (!ImGui::GetCurrentContext())
+ return;
+
for (auto [imgui_key, qt_key] : key_map)
ImGui::GetIO().KeyMap[imgui_key] = (qt_key & 0x1FF);
}
diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp
index f787ab7dab..c2fdcbaa3d 100644
--- a/Source/Core/VideoCommon/RenderBase.cpp
+++ b/Source/Core/VideoCommon/RenderBase.cpp
@@ -1009,6 +1009,8 @@ void Renderer::RecordVideoMemory()
bool Renderer::InitializeImGui()
{
+ std::unique_lock<std::mutex> imgui_lock(m_imgui_mutex);
+
if (!IMGUI_CHECKVERSION())
{
PanicAlertFmt("ImGui version check failed");
@@ -1068,7 +1070,7 @@ bool Renderer::InitializeImGui()
return false;
m_imgui_last_frame_time = Common::Timer::NowUs();
- BeginImGuiFrame();
+ BeginImGuiFrameUnlocked(); // lock is already held
return true;
}
@@ -1129,6 +1131,8 @@ bool Renderer::RecompileImGuiPipeline()
void Renderer::ShutdownImGui()
{
+ std::unique_lock<std::mutex> imgui_lock(m_imgui_mutex);
+
ImGui::EndFrame();
ImGui::DestroyContext();
m_imgui_pipeline.reset();
@@ -1139,7 +1143,11 @@ void Renderer::ShutdownImGui()
void Renderer::BeginImGuiFrame()
{
std::unique_lock<std::mutex> imgui_lock(m_imgui_mutex);
+ BeginImGuiFrameUnlocked();
+}
+void Renderer::BeginImGuiFrameUnlocked()
+{
const u64 current_time_us = Common::Timer::NowUs();
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);
diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h
index 8824e6ff77..0553d59f73 100644
--- a/Source/Core/VideoCommon/RenderBase.h
+++ b/Source/Core/VideoCommon/RenderBase.h
@@ -303,6 +303,9 @@ protected:
// This function itself acquires the ImGui lock, so it should not be held.
void BeginImGuiFrame();
+ // Same as above but without locking the ImGui lock.
+ void BeginImGuiFrameUnlocked();
+
// Destroys all ImGui GPU resources, must do before shutdown.
void ShutdownImGui();