Don't fill backend info when core is running
The current approach results in the UI thread creating a graphics device whilst the core is running, leading to races on function pointers, and potentially crashing.
This commit is contained in:
parent
a877d5f6dc
commit
93923e2b29
|
@ -38,9 +38,6 @@ void GraphicsWindow::Initialize()
|
||||||
|
|
||||||
m_lazy_initialized = true;
|
m_lazy_initialized = true;
|
||||||
|
|
||||||
g_Config.Refresh();
|
|
||||||
g_video_backend->InitBackendInfo();
|
|
||||||
|
|
||||||
CreateMainLayout();
|
CreateMainLayout();
|
||||||
|
|
||||||
setWindowTitle(tr("Graphics"));
|
setWindowTitle(tr("Graphics"));
|
||||||
|
@ -109,18 +106,7 @@ void GraphicsWindow::CreateMainLayout()
|
||||||
void GraphicsWindow::OnBackendChanged(const QString& backend_name)
|
void GraphicsWindow::OnBackendChanged(const QString& backend_name)
|
||||||
{
|
{
|
||||||
SConfig::GetInstance().m_strVideoBackend = backend_name.toStdString();
|
SConfig::GetInstance().m_strVideoBackend = backend_name.toStdString();
|
||||||
|
VideoBackendBase::PopulateBackendInfo();
|
||||||
for (const auto& backend : g_available_video_backends)
|
|
||||||
{
|
|
||||||
if (backend->GetName() == backend_name.toStdString())
|
|
||||||
{
|
|
||||||
g_Config.Refresh();
|
|
||||||
|
|
||||||
g_video_backend = backend.get();
|
|
||||||
g_video_backend->InitBackendInfo();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setWindowTitle(
|
setWindowTitle(
|
||||||
tr("%1 Graphics Configuration").arg(tr(g_video_backend->GetDisplayName().c_str())));
|
tr("%1 Graphics Configuration").arg(tr(g_video_backend->GetDisplayName().c_str())));
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/Event.h"
|
#include "Common/Event.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
|
#include "Core/ConfigManager.h"
|
||||||
|
#include "Core/Core.h"
|
||||||
#include "Core/Host.h"
|
#include "Core/Host.h"
|
||||||
|
|
||||||
// TODO: ugly
|
// TODO: ugly
|
||||||
|
@ -223,6 +225,20 @@ void VideoBackendBase::ActivateBackend(const std::string& name)
|
||||||
g_video_backend = iter->get();
|
g_video_backend = iter->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VideoBackendBase::PopulateBackendInfo()
|
||||||
|
{
|
||||||
|
// If the core is running, the backend info will have been populated already.
|
||||||
|
// If we did it here, the UI thread can race with the with the GPU thread.
|
||||||
|
if (Core::IsRunning())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// We refresh the config after initializing the backend info, as system-specific settings
|
||||||
|
// such as anti-aliasing, or the selected adapter may be invalid, and should be checked.
|
||||||
|
ActivateBackend(SConfig::GetInstance().m_strVideoBackend);
|
||||||
|
g_video_backend->InitBackendInfo();
|
||||||
|
g_Config.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
// Run from the CPU thread
|
// Run from the CPU thread
|
||||||
void VideoBackendBase::DoState(PointerWrap& p)
|
void VideoBackendBase::DoState(PointerWrap& p)
|
||||||
{
|
{
|
||||||
|
|
|
@ -54,6 +54,10 @@ public:
|
||||||
static void ClearList();
|
static void ClearList();
|
||||||
static void ActivateBackend(const std::string& name);
|
static void ActivateBackend(const std::string& name);
|
||||||
|
|
||||||
|
// Fills the backend_info fields with the capabilities of the selected backend/device.
|
||||||
|
// Called by the UI thread when the graphics config is opened.
|
||||||
|
static void PopulateBackendInfo();
|
||||||
|
|
||||||
// the implementation needs not do synchronization logic, because calls to it are surrounded by
|
// the implementation needs not do synchronization logic, because calls to it are surrounded by
|
||||||
// PauseAndLock now
|
// PauseAndLock now
|
||||||
void DoState(PointerWrap& p);
|
void DoState(PointerWrap& p);
|
||||||
|
|
Loading…
Reference in New Issue