Permalink
Browse files

Merge pull request #7437 from stenzek/graphics-options-race

Fix race condition caused by opening graphics options while running
  • Loading branch information...
lioncash committed Oct 12, 2018
2 parents 7ac90b5 + 349765b commit ecd4897d43e115dbc00534fe74a5cc9d2c3a0fed
@@ -127,10 +127,6 @@ bool Host_RendererIsFullscreen()
return false;
}
void Host_ShowVideoConfig(void*, const std::string&)
{
}
void Host_YieldToUI()
{
}
@@ -74,6 +74,7 @@
#include "VideoCommon/OnScreenDisplay.h"
#include "VideoCommon/RenderBase.h"
#include "VideoCommon/VideoBackendBase.h"
#include "VideoCommon/VideoConfig.h"
namespace Core
{
@@ -434,6 +435,12 @@ static void EmuThread(std::unique_ptr<BootParameters> boot)
HLE::Clear();
}};
// Backend info has to be initialized before we can initialize the backend.
// This is because when we load the config, we validate it against the current backend info.
// We also should have the correct adapter selected for creating the device in Initialize().
g_video_backend->InitBackendInfo();
g_Config.Refresh();
if (!g_video_backend->Initialize(s_window_handle))
{
PanicAlert("Failed to initialize video backend!");
View
@@ -42,7 +42,6 @@ void Host_RequestRenderWindowSize(int width, int height);
void Host_UpdateDisasmDialog();
void Host_UpdateMainFrame();
void Host_UpdateTitle(const std::string& title);
void Host_ShowVideoConfig(void* parent, const std::string& backend_name);
void Host_YieldToUI();
void Host_UpdateProgressDialog(const char* caption, int position, int total);
@@ -130,10 +130,6 @@ bool Host_RendererIsFullscreen()
return rendererIsFullscreen;
}
void Host_ShowVideoConfig(void*, const std::string&)
{
}
void Host_YieldToUI()
{
}
@@ -313,7 +313,7 @@ void GeneralWidget::OnBackendChanged(const QString& backend_name)
const bool supports_adapters = !adapters.empty();
m_adapter_combo->setCurrentIndex(g_Config.iAdapter);
m_adapter_combo->setEnabled(supports_adapters);
m_adapter_combo->setEnabled(supports_adapters && !Core::IsRunning());
m_adapter_combo->setToolTip(supports_adapters ?
QStringLiteral("") :
@@ -38,9 +38,6 @@ void GraphicsWindow::Initialize()
m_lazy_initialized = true;
g_Config.Refresh();
g_video_backend->InitBackendInfo();
CreateMainLayout();
setWindowTitle(tr("Graphics"));
@@ -109,18 +106,7 @@ void GraphicsWindow::CreateMainLayout()
void GraphicsWindow::OnBackendChanged(const QString& backend_name)
{
SConfig::GetInstance().m_strVideoBackend = backend_name.toStdString();
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;
}
}
VideoBackendBase::PopulateBackendInfo();
setWindowTitle(
tr("%1 Graphics Configuration").arg(tr(g_video_backend->GetDisplayName().c_str())));
@@ -150,9 +150,6 @@ bool Host_UINeedsControllerState()
{
return Settings::Instance().IsControllerStateNeeded();
}
void Host_ShowVideoConfig(void* parent, const std::string& backend_name)
{
}
void Host_RefreshDSPDebuggerWindow()
{
}
@@ -132,7 +132,6 @@ bool VideoBackend::Initialize(void* window_handle)
if (window_handle == nullptr)
return false;
InitBackendInfo();
InitializeShared();
if (FAILED(D3D::Create(reinterpret_cast<HWND>(window_handle))))
@@ -57,7 +57,6 @@ void VideoBackend::InitBackendInfo()
bool VideoBackend::Initialize(void* window_handle)
{
InitializeShared();
InitBackendInfo();
g_renderer = std::make_unique<Renderer>();
g_vertex_manager = std::make_unique<VertexManager>();
@@ -159,7 +159,6 @@ bool VideoBackend::FillBackendInfo()
bool VideoBackend::Initialize(void* window_handle)
{
InitBackendInfo();
InitializeShared();
GLUtil::InitInterface();
@@ -80,7 +80,6 @@ void VideoSoftware::InitBackendInfo()
bool VideoSoftware::Initialize(void* window_handle)
{
InitBackendInfo();
InitializeShared();
SWOGLWindow::Init(window_handle);
@@ -14,6 +14,8 @@
#include "Common/CommonTypes.h"
#include "Common/Event.h"
#include "Common/Logging/Log.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/Host.h"
// TODO: ugly
@@ -60,14 +62,6 @@ __declspec(dllexport) DWORD NvOptimusEnablement = 1;
}
#endif
void VideoBackendBase::ShowConfig(void* parent_handle)
{
if (!m_initialized)
InitBackendInfo();
Host_ShowVideoConfig(parent_handle, GetDisplayName());
}
void VideoBackendBase::Video_ExitLoop()
{
Fifo::ExitGpuLoop();
@@ -231,6 +225,20 @@ void VideoBackendBase::ActivateBackend(const std::string& name)
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
void VideoBackendBase::DoState(PointerWrap& p)
{
@@ -294,7 +302,6 @@ void VideoBackendBase::InitializeShared()
GeometryShaderManager::Init();
PixelShaderManager::Init();
g_Config.Refresh();
UpdateActiveConfig();
}
@@ -40,7 +40,6 @@ class VideoBackendBase
virtual std::string GetName() const = 0;
virtual std::string GetDisplayName() const { return GetName(); }
void ShowConfig(void* parent_handle);
virtual void InitBackendInfo() = 0;
void Video_ExitLoop();
@@ -55,6 +54,10 @@ class VideoBackendBase
static void ClearList();
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
// PauseAndLock now
void DoState(PointerWrap& p);
@@ -46,9 +46,6 @@ bool Host_RendererIsFullscreen()
{
return false;
}
void Host_ShowVideoConfig(void*, const std::string&)
{
}
void Host_YieldToUI()
{
}
@@ -48,9 +48,6 @@ bool Host_RendererIsFullscreen()
{
return false;
}
void Host_ShowVideoConfig(void*, const std::string&)
{
}
void Host_YieldToUI()
{
}

0 comments on commit ecd4897

Please sign in to comment.