From 25a028ca58c92c03c0dd1db2185cb2d209a11bb8 Mon Sep 17 00:00:00 2001 From: Floris Bos Date: Mon, 16 Oct 2023 22:15:55 +0200 Subject: [PATCH] Embedded: deal with vc4-kms supplying multiple /dev/dri devices --- src/CMakeLists.txt | 9 ++++- src/main.cpp | 93 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 92 insertions(+), 10 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d338580..20a94dc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -118,6 +118,11 @@ if(${QT}DBus_FOUND AND UNIX AND NOT APPLE) set(EXTRALIBS ${EXTRALIBS} ${QT}::DBus) message("udisks2 support enabled") 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) set(EXTRALIBS ${EXTRALIBS} ${QT}::WinExtras) endif() @@ -352,5 +357,5 @@ else() install(FILES "${CMAKE_CURRENT_BINARY_DIR}/rpi-imager.metainfo.xml" DESTINATION share/metainfo) endif() -include_directories(${CURL_INCLUDE_DIR} ${LibArchive_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} ${LIBLZMA_INCLUDE_DIR}) -target_link_libraries(${PROJECT_NAME} PRIVATE ${QT}::Core ${QT}::Quick ${QT}::Svg ${CURL_LIBRARIES} ${LibArchive_LIBRARIES} ${OPENSSL_LIBRARIES} ${ATOMIC_LIBRARY} ${EXTRALIBS}) +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} ${LIBDRM_LIBRARIES} ${ATOMIC_LIBRARY} ${EXTRALIBS}) diff --git a/src/main.cpp b/src/main.cpp index 8406771..b4876ac 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -22,6 +22,11 @@ #include #include #include +#ifdef QT_NO_WIDGETS +#include +#include +#include +#endif #ifndef QT_NO_WIDGETS #include #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; icount_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);