Detect OpenGL crashes on Windows and automatically downgrade to the software engine.

This commit is contained in:
sawinglogz 2020-04-25 16:30:35 -04:00
parent 2ac43a4a79
commit 17e2ef0a12
3 changed files with 56 additions and 0 deletions

View File

@ -289,6 +289,18 @@ int main(int argc, char *argv[]) {
forcedEngine = "Software Engine forced by --legacy command line switch";
}
}
#ifdef Q_OS_WIN
bool oscarCrashed = false;
if (settings.value("OpenGLCompatibilityCheck").toBool()) {
oscarCrashed = true;
}
if (oscarCrashed) {
settings.setValue(GFXEngineSetting, (unsigned int)GFX_Software);
forcedEngine = "Software Engine forced by previous crash";
settings.remove("OpenGLCompatibilityCheck");
}
#endif
GFXEngine gfxEngine = (GFXEngine)qMin((unsigned int)settings.value(GFXEngineSetting, (unsigned int)GFX_OpenGL).toUInt(), (unsigned int)MaxGFXEngine);
switch (gfxEngine) {
case 0: // GFX_OpenGL
@ -305,6 +317,15 @@ int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QStringList args = a.arguments();
#ifdef Q_OS_WIN
// QMessageBox must come after the application is created. The graphics engine has to be selected before.
if (oscarCrashed) {
QMessageBox::warning(nullptr, STR_MessageBox_Error,
QObject::tr("OSCAR crashed due to an incompatibility with your graphics hardware.") + "\n\n" +
QObject::tr("To resolve this, OSCAR has reverted to a slower but more compatible method of drawing."),
QMessageBox::Ok);
}
#endif
QString lastlanguage = settings.value(LangSetting, "").toString();
if (lastlanguage.compare("is", Qt::CaseInsensitive)) // Convert code for Hebrew from 'is' to 'he'

View File

@ -628,8 +628,38 @@ void MainWindow::CloseProfile()
}
#ifdef Q_OS_WIN
void MainWindow::TestWindowsOpenGL()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,4,0)) && !defined(BROKEN_OPENGL_BUILD)
// 1. Set OpenGLCompatibilityCheck=1 in registry.
QSettings settings;
settings.setValue("OpenGLCompatibilityCheck", true);
// 2. See if OpenGL crashes the application:
QOpenGLWidget* gl;
gl = new QOpenGLWidget(ui->tabWidget);
ui->tabWidget->insertTab(2, gl, "");
//qDebug() << __LINE__;
QCoreApplication::processEvents(); // this triggers the SIGSEGV
//qDebug() << __LINE__;
// If we get here, OpenGL won't crash the application.
ui->tabWidget->removeTab(2);
delete gl;
// 3. Remove OpenGLCompatibilityCheck from the registry upon success.
settings.remove("OpenGLCompatibilityCheck");
#endif
}
#endif
void MainWindow::Startup()
{
#ifdef Q_OS_WIN
TestWindowsOpenGL();
#endif
for (auto & loader : GetLoaders()) {
loader->setParent(this);
}

View File

@ -204,6 +204,11 @@ class MainWindow : public QMainWindow
//! \brief Display About Dialog
void on_action_About_triggered();
#ifdef Q_OS_WIN
//! \brief Called on Windows to see whether the current OpenGL driver will cause the application to crash
void TestWindowsOpenGL();
#endif
//! \brief Called after a timeout to initiate loading of all summary data for this profile
void Startup();