Fix XCB out-of-sequence abort after switching to non-threaded Qt renderer

This commit is contained in:
Cameron Gutman 2021-03-07 16:48:10 -06:00
parent 783a57ef89
commit acb7a5b3c8
2 changed files with 65 additions and 1 deletions

View File

@ -91,7 +91,36 @@ QRect SystemProperties::getNativeResolution(int displayIndex)
return monitorNativeResolutions.value(displayIndex); return monitorNativeResolutions.value(displayIndex);
} }
class QuerySdlVideoThread : public QThread
{
public:
QuerySdlVideoThread(SystemProperties* me) :
QThread(nullptr),
m_Me(me) {}
void run() override
{
m_Me->querySdlVideoInfoInternal();
}
SystemProperties* m_Me;
};
void SystemProperties::querySdlVideoInfo() void SystemProperties::querySdlVideoInfo()
{
if (WMUtils::isRunningX11() || WMUtils::isRunningWayland()) {
// Use a separate thread to temporarily initialize SDL
// video to avoid stomping on Qt's X11 and OGL state.
QuerySdlVideoThread thread(this);
thread.start();
thread.wait();
}
else {
querySdlVideoInfoInternal();
}
}
void SystemProperties::querySdlVideoInfoInternal()
{ {
hasHardwareAcceleration = false; hasHardwareAcceleration = false;
@ -103,7 +132,8 @@ void SystemProperties::querySdlVideoInfo()
} }
// Update display related attributes (max FPS, native resolution, etc). // Update display related attributes (max FPS, native resolution, etc).
refreshDisplays(); // We call the internal variant because we're already in a safe thread context.
refreshDisplaysInternal();
SDL_Window* testWindow = SDL_CreateWindow("", 0, 0, 1280, 720, SDL_Window* testWindow = SDL_CreateWindow("", 0, 0, 1280, 720,
SDL_WINDOW_HIDDEN | StreamUtils::getPlatformWindowFlags()); SDL_WINDOW_HIDDEN | StreamUtils::getPlatformWindowFlags());
@ -129,7 +159,36 @@ void SystemProperties::querySdlVideoInfo()
SDL_QuitSubSystem(SDL_INIT_VIDEO); SDL_QuitSubSystem(SDL_INIT_VIDEO);
} }
class RefreshDisplaysThread : public QThread
{
public:
RefreshDisplaysThread(SystemProperties* me) :
QThread(nullptr),
m_Me(me) {}
void run() override
{
m_Me->refreshDisplaysInternal();
}
SystemProperties* m_Me;
};
void SystemProperties::refreshDisplays() void SystemProperties::refreshDisplays()
{
if (WMUtils::isRunningX11() || WMUtils::isRunningWayland()) {
// Use a separate thread to temporarily initialize SDL
// video to avoid stomping on Qt's X11 and OGL state.
RefreshDisplaysThread thread(this);
thread.start();
thread.wait();
}
else {
refreshDisplaysInternal();
}
}
void SystemProperties::refreshDisplaysInternal()
{ {
if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) { if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,

View File

@ -7,6 +7,9 @@ class SystemProperties : public QObject
{ {
Q_OBJECT Q_OBJECT
friend class QuerySdlVideoThread;
friend class RefreshDisplaysThread;
public: public:
SystemProperties(); SystemProperties();
@ -33,6 +36,8 @@ signals:
private: private:
void querySdlVideoInfo(); void querySdlVideoInfo();
void querySdlVideoInfoInternal();
void refreshDisplaysInternal();
bool hasHardwareAcceleration; bool hasHardwareAcceleration;
bool rendererAlwaysFullScreen; bool rendererAlwaysFullScreen;