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

@ -118,6 +118,11 @@ if(${QT}DBus_FOUND AND UNIX AND NOT APPLE)
set(EXTRALIBS ${EXTRALIBS} ${QT}::DBus) set(EXTRALIBS ${EXTRALIBS} ${QT}::DBus)
message("udisks2 support enabled") message("udisks2 support enabled")
endif() endif()
# NOT ${QT}Widgets_FOUND AND
if (UNIX AND NOT APPLE)
find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBDRM REQUIRED libdrm)
endif()
if(${QT}WinExtras_FOUND) if(${QT}WinExtras_FOUND)
set(EXTRALIBS ${EXTRALIBS} ${QT}::WinExtras) set(EXTRALIBS ${EXTRALIBS} ${QT}::WinExtras)
endif() endif()
@ -352,5 +357,5 @@ else()
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/rpi-imager.metainfo.xml" DESTINATION share/metainfo) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/rpi-imager.metainfo.xml" DESTINATION share/metainfo)
endif() endif()
include_directories(${CURL_INCLUDE_DIR} ${LibArchive_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} ${LIBLZMA_INCLUDE_DIR}) include_directories(${CURL_INCLUDE_DIR} ${LibArchive_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} ${LIBLZMA_INCLUDE_DIR} ${LIBDRM_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} PRIVATE ${QT}::Core ${QT}::Quick ${QT}::Svg ${CURL_LIBRARIES} ${LibArchive_LIBRARIES} ${OPENSSL_LIBRARIES} ${ATOMIC_LIBRARY} ${EXTRALIBS}) target_link_libraries(${PROJECT_NAME} PRIVATE ${QT}::Core ${QT}::Quick ${QT}::Svg ${CURL_LIBRARIES} ${LibArchive_LIBRARIES} ${OPENSSL_LIBRARIES} ${LIBDRM_LIBRARIES} ${ATOMIC_LIBRARY} ${EXTRALIBS})

View file

@ -22,6 +22,11 @@
#include <QSettings> #include <QSettings>
#include <QFont> #include <QFont>
#include <QFontDatabase> #include <QFontDatabase>
#ifdef QT_NO_WIDGETS
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <QDir>
#endif
#ifndef QT_NO_WIDGETS #ifndef QT_NO_WIDGETS
#include <QtWidgets/QApplication> #include <QtWidgets/QApplication>
#endif #endif
@ -44,6 +49,84 @@ static void consoleMsgHandler(QtMsgType, const QMessageLogContext &, const QStri
} }
#endif #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[]) int main(int argc, char *argv[])
{ {
for (int i = 1; i < argc; i++) for (int i = 1; i < argc; i++)
@ -62,14 +145,8 @@ int main(int argc, char *argv[])
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
#endif #endif
#ifdef QT_NO_WIDGETS #ifdef QT_NO_WIDGETS
{ if ( !handleDri() )
QGuiApplication tmp(argc, argv); return 1;
int h = QGuiApplication::primaryScreen()->geometry().height();
if (h > 720)
{
qputenv("QT_SCALE_FACTOR", QByteArray::number(h / 720.0, 'f', 2));
}
}
QGuiApplication app(argc, argv); QGuiApplication app(argc, argv);