Embedded: deal with vc4-kms supplying multiple /dev/dri devices

This commit is contained in:
Floris Bos 2023-10-16 22:15:55 +02:00
parent 40a73c3797
commit 25a028ca58
2 changed files with 92 additions and 10 deletions

View file

@ -22,6 +22,11 @@
#include <QSettings>
#include <QFont>
#include <QFontDatabase>
#ifdef QT_NO_WIDGETS
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <QDir>
#endif
#ifndef QT_NO_WIDGETS
#include <QtWidgets/QApplication>
#endif
@ -44,6 +49,84 @@ static void consoleMsgHandler(QtMsgType, const QMessageLogContext &, const QStri
}
#endif
#ifdef QT_NO_WIDGETS
/* Embedded: deal with Pi having multiple DRI devices when vc4-kms (instead of fkms) is used */
bool handleDri()
{
QByteArray driDev;
QDir driDir("/dev/dri");
QStringList entries = driDir.entryList(QDir::System, QDir::Name);
for (const QString &fn : entries)
{
QFile f("/dev/dri/"+fn);
if (f.open(f.ReadWrite))
{
drmModeResPtr resources = drmModeGetResources(f.handle());
if (resources)
{
driDev = "/dev/dri/"+fn.toLatin1();
cerr << "Using " << driDev << endl;
/* Get current resolution to calculate scaling factor while we are at it */
for (int i=0; i<resources->count_connectors; i++)
{
drmModeConnectorPtr connector = drmModeGetConnector(f.handle(), resources->connectors[i]);
if (connector)
{
if (connector->connection != DRM_MODE_DISCONNECTED)
{
drmModeEncoderPtr encoder = drmModeGetEncoder(f.handle(), connector->encoder_id);
if (encoder)
{
drmModeModeInfo crtcMode = {0};
drmModeCrtcPtr crtc = drmModeGetCrtc(f.handle(), encoder->crtc_id);
if (crtc)
{
if (crtc->mode_valid)
{
cerr << "Current mode: connector " << i << " crtc_id " << crtc->crtc_id << " width: " << crtc->width << "px height: " << crtc->height << "px" << endl;
/*if (crtc->height > 720)
{
qputenv("QT_SCALE_FACTOR", QByteArray::number(crtc->height / 720.0, 'f', 2));
}*/
break;
}
drmModeFreeCrtc(crtc);
}
drmModeFreeEncoder(encoder);
}
}
drmModeFreeConnector(connector);
}
}
drmModeFreeResources(resources);
}
f.close();
}
else
{
cerr << "Error opening /dev/dri/"+fn << endl;
}
}
if (driDev.isEmpty())
{
cerr << "No capable /dev/dri device found" << endl;
return false;
}
QFile f("/tmp/qt-kms-config.json");
f.open(f.WriteOnly);
f.write("{ \"device\": \""+driDev+"\", \"hwcursor\": false }\n");
f.close();
qputenv("QT_QPA_EGLFS_KMS_CONFIG", "/tmp/qt-kms-config.json");
return true;
}
#endif
int main(int argc, char *argv[])
{
for (int i = 1; i < argc; i++)
@ -62,14 +145,8 @@ int main(int argc, char *argv[])
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
#endif
#ifdef QT_NO_WIDGETS
{
QGuiApplication tmp(argc, argv);
int h = QGuiApplication::primaryScreen()->geometry().height();
if (h > 720)
{
qputenv("QT_SCALE_FACTOR", QByteArray::number(h / 720.0, 'f', 2));
}
}
if ( !handleDri() )
return 1;
QGuiApplication app(argc, argv);