mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2024-11-24 12:13:03 +00:00
Add workaround for broken Qt EGLFS card selection logic
This commit is contained in:
parent
f8c5d3c0ce
commit
011feab6ce
3 changed files with 67 additions and 1 deletions
19
app/main.cpp
19
app/main.cpp
|
@ -10,7 +10,7 @@
|
|||
#include <QFont>
|
||||
#include <QCursor>
|
||||
#include <QElapsedTimer>
|
||||
#include <QFile>
|
||||
#include <QTemporaryFile>
|
||||
|
||||
// Don't let SDL hook our main function, since Qt is already
|
||||
// doing the same thing. This needs to be before any headers
|
||||
|
@ -351,6 +351,11 @@ int main(int argc, char *argv[])
|
|||
SSL_free(nullptr);
|
||||
#endif
|
||||
|
||||
// We keep this at function scope to ensure it stays around while we're running,
|
||||
// becaue the Qt QPA will need to read it. Since the temporary file is only
|
||||
// created when open() is called, this doesn't do any harm for other platforms.
|
||||
QTemporaryFile eglfsConfigFile("eglfs_override_XXXXXX.conf");
|
||||
|
||||
// Avoid using High DPI on EGLFS. It breaks font rendering.
|
||||
// https://bugreports.qt.io/browse/QTBUG-64377
|
||||
//
|
||||
|
@ -372,6 +377,7 @@ int main(int argc, char *argv[])
|
|||
if (!qEnvironmentVariableIsSet("QT_QPA_PLATFORM")) {
|
||||
qInfo() << "Unable to detect Wayland or X11, so EGLFS will be used by default. Set QT_QPA_PLATFORM to override this.";
|
||||
qputenv("QT_QPA_PLATFORM", "eglfs");
|
||||
qputenv("SDL_VIDEODRIVER", "kmsdrm");
|
||||
|
||||
if (!qEnvironmentVariableIsSet("QT_QPA_EGLFS_ALWAYS_SET_MODE")) {
|
||||
qInfo() << "Setting display mode by default. Set QT_QPA_EGLFS_ALWAYS_SET_MODE=0 to override this.";
|
||||
|
@ -384,6 +390,17 @@ int main(int argc, char *argv[])
|
|||
qWarning() << "Unable to find a KMSDRM display device!";
|
||||
qWarning() << "On the Raspberry Pi, you must enable the 'fake KMS' driver in raspi-config to use Moonlight outside of the GUI environment.";
|
||||
}
|
||||
else if (!qEnvironmentVariableIsSet("QT_QPA_EGLFS_KMS_CONFIG")) {
|
||||
// HACK: Remove this when Qt is fixed to properly check for display support before picking a card
|
||||
QString cardOverride = WMUtils::getDrmCardOverride();
|
||||
if (!cardOverride.isEmpty()) {
|
||||
if (eglfsConfigFile.open()) {
|
||||
qInfo() << "Overriding default Qt EGLFS card selection to" << cardOverride;
|
||||
QTextStream(&eglfsConfigFile) << "{ \"device\": \"" << cardOverride << "\" }";
|
||||
qputenv("QT_QPA_EGLFS_KMS_CONFIG", eglfsConfigFile.fileName().toUtf8());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// EGLFS uses OpenGLES 2.0, so we will too. Some embedded platforms may not
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
||||
#define THROW_BAD_ALLOC_IF_NULL(x) \
|
||||
if ((x) == nullptr) throw std::bad_alloc()
|
||||
|
||||
|
@ -8,4 +10,5 @@ namespace WMUtils {
|
|||
bool isRunningWayland();
|
||||
bool isRunningWindowManager();
|
||||
bool isRunningDesktopEnvironment();
|
||||
QString getDrmCardOverride();
|
||||
}
|
||||
|
|
46
app/wm.cpp
46
app/wm.cpp
|
@ -1,4 +1,5 @@
|
|||
#include <QtGlobal>
|
||||
#include <QDir>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
|
@ -12,6 +13,11 @@
|
|||
#include <wayland-client.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DRM
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
#endif
|
||||
|
||||
#define VALUE_SET 0x01
|
||||
#define VALUE_TRUE 0x02
|
||||
|
||||
|
@ -96,3 +102,43 @@ bool WMUtils::isRunningDesktopEnvironment()
|
|||
return isRunningWindowManager();
|
||||
#endif
|
||||
}
|
||||
|
||||
QString WMUtils::getDrmCardOverride()
|
||||
{
|
||||
#ifdef HAVE_DRM
|
||||
QDir dir("/dev/dri");
|
||||
QStringList cardList = dir.entryList(QStringList("card*"), QDir::Files | QDir::System);
|
||||
if (cardList.length() == 0) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool needsOverride = false;
|
||||
for (const QString& card : cardList) {
|
||||
QFile cardFd(dir.filePath(card));
|
||||
if (!cardFd.open(QFile::ReadOnly)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto resources = drmModeGetResources(cardFd.handle());
|
||||
if (resources == nullptr) {
|
||||
// If we find a card that doesn't have a display before a card that
|
||||
// has one, we'll need to override Qt's EGLFS config because they
|
||||
// don't properly handle cards without displays.
|
||||
needsOverride = true;
|
||||
}
|
||||
else {
|
||||
// We found a card with a display
|
||||
drmModeFreeResources(resources);
|
||||
if (needsOverride) {
|
||||
// Override the default card with this one
|
||||
return dir.filePath(card);
|
||||
}
|
||||
else {
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue