[idd] make mode filtering rebuilds thread safe

This commit is contained in:
Geoffrey McRae
2026-08-04 13:48:23 +10:00
parent f0696e079f
commit 84d1427cab
3 changed files with 15 additions and 16 deletions

View File

@@ -148,20 +148,21 @@ void CIndirectDeviceContext::QueryIddCxCapabilities()
bool CIndirectDeviceContext::PopulateDefaultModes()
{
g_settings.LoadModes();
const CSettings::DisplayModes configuredModes =
g_settings.LoadModes();
// Build the new mode list into a local first so we only hold the lock for
// the swap. IddCx readers may be iterating the live container on another
// thread; a clear()/push_back() under them would reallocate the backing
// store and crash. std::move makes the publish a pointer swap.
CSettings::DisplayModes newModes;
newModes.reserve(g_settings.GetDisplayModes().size());
newModes.reserve(configuredModes.size());
const UINT64 alignment = m_alignSize ? m_alignSize :
D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
bool hasPreferred = false;
for (const auto& configuredMode : g_settings.GetDisplayModes())
for (const auto& configuredMode : configuredModes)
{
UINT64 frameSize;
UINT64 requiredIVSHMEMSize;

View File

@@ -32,24 +32,24 @@ CSettings::CSettings()
{
}
void CSettings::LoadModes()
CSettings::DisplayModes CSettings::LoadModes()
{
const unsigned defaultRefresh = GetDefaultRefresh();
m_displayModes.clear();
DisplayModes displayModes;
bool hasPreferred = false;
DisplayMode m;
if (GetExtraMode(m))
{
DEBUG_INFO("ExtraMode: %ux%u@%u%s", m.width, m.height, m.refresh, m.preferred ? "*" : "");
m_displayModes.push_back(m);
displayModes.push_back(m);
hasPreferred = m.preferred;
}
std::vector<std::wstring> entries;
if (!ReadModesValue(entries))
{
m_displayModes.reserve(m_displayModes.size() +
displayModes.reserve(displayModes.size() +
ARRAYSIZE(DefaultDisplayModes));
for (int i = 0; i < ARRAYSIZE(DefaultDisplayModes); ++i)
@@ -59,9 +59,9 @@ void CSettings::LoadModes()
m.refresh = defaultRefresh;
m.preferred = !hasPreferred && (i == DefaultPreferredDisplayMode);
m.extraMode = false;
m_displayModes.push_back(m);
displayModes.push_back(m);
}
return;
return displayModes;
}
for (const auto& line : entries)
@@ -69,10 +69,11 @@ void CSettings::LoadModes()
{
if (hasPreferred)
m.preferred = false;
m_displayModes.push_back(m);
displayModes.push_back(m);
}
DEBUG_INFO("Parsed %d modes", m_displayModes.size());
DEBUG_INFO("Parsed %d modes", displayModes.size());
return displayModes;
}
void CSettings::SetExtraMode(const DisplayMode& mode)

View File

@@ -38,8 +38,7 @@ class CSettings
CSettings();
void LoadModes();
const DisplayModes& GetDisplayModes() { return m_displayModes; }
DisplayModes LoadModes();
void SetExtraMode(const DisplayMode & mode);
bool GetExtraMode(DisplayMode & mode);
unsigned GetDefaultRefresh() const;
@@ -48,8 +47,6 @@ class CSettings
bool ReadBoolValue(const wchar_t* name, bool defaultValue = false);
private:
DisplayModes m_displayModes;
bool ReadModesValue(std::vector<std::wstring> &out) const;
bool ParseModeString(const std::wstring& in, DisplayMode& out);
};