1
0
Fork 0

Launcher: quit if OpenGL 2.1 isn’t available

Avoid crashing if no OpenGL drivers are available, instead show a
warning message to alert the user.

Sentry-Id: FLIGHTGEAR-76
This commit is contained in:
James Turner 2020-12-27 17:37:06 +00:00
parent 85f870f607
commit b86baa68c0
3 changed files with 88 additions and 13 deletions

View file

@ -9,12 +9,13 @@
#include <QMenu>
#include <QMenuBar>
#include <QQuickItem>
#include <QQmlEngine>
#include <QOpenGLContext>
#include <QQmlComponent>
#include <QQmlContext>
#include <QQmlEngine>
#include <QQmlError>
#include <QQmlFileSelector>
#include <QQuickItem>
// launcher headers
#include "AddOnsController.hxx"
@ -30,6 +31,8 @@
#include "UpdateChecker.hxx"
#include "GettingStartedTip.hxx"
#include <Main/sentryIntegration.hxx>
//////////////////////////////////////////////////////////////////////////////
LauncherMainWindow::LauncherMainWindow(bool inSimMode) : QQuickView()
@ -39,6 +42,13 @@ LauncherMainWindow::LauncherMainWindow(bool inSimMode) : QQuickView()
m_controller = new LauncherController(this, this);
m_controller->initQML();
// use a direct connection to be notified synchronously when the render thread
// starts OpenGL. We use this to log the OpenGL information from the
// context at that time, for tracing purposes.
connect(this, &QQuickWindow::sceneGraphInitialized,
this, &LauncherMainWindow::renderTheadSceneGraphInitialized,
Qt::DirectConnection);
if (!inSimMode) {
#if defined(Q_OS_MAC)
QMenuBar* mb = new QMenuBar();
@ -195,3 +205,28 @@ bool LauncherMainWindow::execInApp()
return m_controller->inAppResult();
}
// this slot runs in the context of the render thread. Don't modify
void LauncherMainWindow::renderTheadSceneGraphInitialized()
{
auto qContext = QOpenGLContext::currentContext();
if (!qContext) {
qWarning() << Q_FUNC_INFO << "No current OpenGL context";
return;
}
std::string renderer = (char*)glGetString(GL_RENDERER);
// capture this to help with debugging this crash:
// https://sentry.io/share/issue/f98e38dceb4241dbaeed944d6ce4d746/
// https://bugreports.qt.io/browse/QTBUG-69703
flightgear::addSentryTag("qt-gl-vendor", (char*)glGetString(GL_VENDOR));
flightgear::addSentryTag("qt-gl-renderer", renderer.c_str());
flightgear::addSentryTag("qt-gl-version", (char*)glGetString(GL_VERSION));
flightgear::addSentryTag("qt-glsl-version", (char*)glGetString(GL_SHADING_LANGUAGE_VERSION));
const char* gltype[] = {"Desktop", "GLES 2", "GLES 1"};
flightgear::addSentryTag("qt-gl-module-type", gltype[QOpenGLContext::openGLModuleType()]);
// if necessary, borrow more code from:
// https://code.qt.io/cgit/qt/qtbase.git/tree/examples/opengl/contextinfo/widget.cpp?h=5.15#n358
// to expand what this reports
}

View file

@ -51,6 +51,7 @@ public:
private slots:
void onQuickStatusChanged(QQuickView::Status status);
void renderTheadSceneGraphInitialized();
private:
bool checkQQC2Availability();

View file

@ -25,21 +25,23 @@
#include <locale.h>
// Qt
#include <QtGlobal>
#include <QString>
#include <QProgressDialog>
#include <QApplication>
#include <QDebug>
#include <QDir>
#include <QFileInfo>
#include <QTimer>
#include <QDebug>
#include <QSettings>
#include <QUrl>
#include <QApplication>
#include <QThread>
#include <QProcess>
#include <QTranslator>
#include <QMessageBox>
#include <QOffscreenSurface>
#include <QOpenGLContext>
#include <QPointer>
#include <QProcess>
#include <QProgressDialog>
#include <QSettings>
#include <QString>
#include <QThread>
#include <QTimer>
#include <QTranslator>
#include <QUrl>
#include <QtGlobal>
// Simgear
#include <simgear/timing/timestamp.hxx>
@ -247,6 +249,35 @@ private:
bool m_abandoned = false;
};
bool checkForWorkingOpenGL()
{
QSurfaceFormat fmt;
fmt.setProfile(QSurfaceFormat::CompatibilityProfile);
fmt.setMajorVersion(2);
fmt.setMinorVersion(1);
QOpenGLContext ctx;
ctx.setFormat(fmt);
if (!ctx.create()) {
return false;
}
QOffscreenSurface offSurface;
offSurface.setFormat(ctx.format()); // ensure it's compatible
offSurface.create();
if (!ctx.makeCurrent(&offSurface)) {
return false;
}
std::string renderer = (char*)glGetString(GL_RENDERER);
if (renderer == "GDI Generic") {
flightgear::addSentryBreadcrumb("Detected GDI generic renderer", "info");
return false;
}
return true;
}
} // of anonymous namespace
static void initQtResources()
@ -411,6 +442,7 @@ void initQSettings()
qRegisterMetaType<QuantityValue>();
qRegisterMetaTypeStreamOperators<QuantityValue>("QuantityValue");
qSettingsInitDone = true;
string fgHome = globals->get_fg_home().utf8Str();
@ -501,6 +533,13 @@ void launcherSetSceneryPaths()
bool runLauncherDialog()
{
if (!checkForWorkingOpenGL()) {
QMessageBox::critical(nullptr, "Failed to find graphics drivers",
"This computer is missing suitable graphics drivers (OpenGL) to run FlightGear. "
"Please download and install drivers from your graphics card vendor.");
return false;
}
// Used for NavDataCache initialization: needed to find the apt.dat files
launcherSetSceneryPaths();
// startup the nav-cache now. This pre-empts normal startup of