Extend drm-lease-manager support - Qt6.x eglfs-kms 70/27170/2
authorNaoto Yamaguchi <naoto.yamaguchi@aisin.co.jp>
Sun, 13 Feb 2022 14:07:03 +0000 (23:07 +0900)
committerJan-Simon Moeller <jsmoeller@linuxfoundation.org>
Tue, 8 Mar 2022 14:44:44 +0000 (14:44 +0000)
The drm-lease-manager has capability for other drm client support.
This patch extend support.

Signed-off-by: Naoto Yamaguchi <naoto.yamaguchi@aisin.co.jp>
Change-Id: I6f4b66e63e8662dca4679f18955f7fc693bbdf3d

meta-agl-drm-lease/conf/layer.conf
meta-agl-drm-lease/dynamic-layers/meta-qt6/README.md [new file with mode: 0644]
meta-agl-drm-lease/dynamic-layers/meta-qt6/recipes-qt/qt6/qtbase/0001-Add-drm-lease-client-support-to-eglfs-kms-backend.patch [new file with mode: 0644]
meta-agl-drm-lease/dynamic-layers/meta-qt6/recipes-qt/qt6/qtbase_git.bbappend [new file with mode: 0644]

index d34d392..36bfbd3 100644 (file)
@@ -11,6 +11,8 @@ BBFILE_PRIORITY_agl-drm-lease = "80"
 BBFILES_DYNAMIC += " \
     rcar-gen3:${LAYERDIR}/dynamic-layers/meta-rcar-gen3/*/*/*.bb \
     rcar-gen3:${LAYERDIR}/dynamic-layers/meta-rcar-gen3/*/*/*.bbappend \
+    qt6-layer:${LAYERDIR}/dynamic-layers/meta-qt6/*/*/*.bb \
+    qt6-layer:${LAYERDIR}/dynamic-layers/meta-qt6/*/*/*.bbappend \
 "
 
 # This should only be incremented on significant changes that will
diff --git a/meta-agl-drm-lease/dynamic-layers/meta-qt6/README.md b/meta-agl-drm-lease/dynamic-layers/meta-qt6/README.md
new file mode 100644 (file)
index 0000000..85069c0
--- /dev/null
@@ -0,0 +1,33 @@
+# DRM lease support for Qt 6.x
+
+The meta-agl-drm-lease/dynamic-layers/meta-qt6 is a DRM lease support for Qt 6.x eglfs kms backend.
+
+This patch tested in Qt6.2.2 and Qt6.2.3.
+
+## Usage
+
+Qt application shall configured to use eglfs/kms backend.
+
+In addition, there are two environment variable shall be configured.
+
+### QT_QPA_EGLFS_DRMLEASE
+
+When this variable is set, drm-lease-manager client support is enable.  
+Shall set drm lease device such as  `card0-LVDS-1`, `card0-HDMI-A-1 ` and etc.  
+
+#### Example
+
+```
+  $ export QT_QPA_EGLFS_DRMLEASE=card0-HDMI-A-1
+```
+
+### DLM_RUNTIME_PATH
+
+DLM_RUNTIME_PATH is required from libdlmclient.  This environment variable shall be set.
+
+#### Example
+
+```
+  $ export DLM_RUNTIME_PATH=/var/display/drm-lease-manager
+```
+
diff --git a/meta-agl-drm-lease/dynamic-layers/meta-qt6/recipes-qt/qt6/qtbase/0001-Add-drm-lease-client-support-to-eglfs-kms-backend.patch b/meta-agl-drm-lease/dynamic-layers/meta-qt6/recipes-qt/qt6/qtbase/0001-Add-drm-lease-client-support-to-eglfs-kms-backend.patch
new file mode 100644 (file)
index 0000000..f4d197e
--- /dev/null
@@ -0,0 +1,296 @@
+From 85a85537b17742a839092bcc2a4684ab0bdb65d5 Mon Sep 17 00:00:00 2001
+From: Naoto Yamaguchi <naoto.yamaguchi@aisin.co.jp>
+Date: Tue, 4 Jan 2022 23:52:31 +0900
+Subject: [PATCH] Add drm-lease client support to eglfs kms backend
+
+This patch is adding drm-lease-manager client support to Qt eglfs backend.
+When this patch is enable, Qt wayland compositor and Qt eglfs without
+compositor possible to use leased drm device.
+
+List of environment variable:
+
+QT_QPA_EGLFS_DRMLEASE :
+    When this variable is set, drm-lease-manager client support is enable.
+    Shall set drm lease device such as  `card0-LVDS-1`, `card0-HDMI-A-1 ` and etc.
+
+DLM_RUNTIME_PATH :
+    It use drm-lease-manager client, typically it need to set own.
+
+Signed-off-by: Naoto Yamaguchi <naoto.yamaguchi@aisin.co.jp>
+---
+ cmake/3rdparty/kwin/FindLibdlmclient.cmake    | 127 ++++++++++++++++++
+ src/gui/configure.cmake                       |   1 +
+ .../eglfs_kms/CMakeLists.txt                  |   2 +
+ .../eglfs_kms/qeglfskmsgbmdevice.cpp          |  43 ++++--
+ .../eglfs_kms/qeglfskmsgbmdevice_p.h          |   4 +
+ 5 files changed, 167 insertions(+), 10 deletions(-)
+ create mode 100644 cmake/3rdparty/kwin/FindLibdlmclient.cmake
+
+diff --git a/cmake/3rdparty/kwin/FindLibdlmclient.cmake b/cmake/3rdparty/kwin/FindLibdlmclient.cmake
+new file mode 100644
+index 0000000000..8dfac920ca
+--- /dev/null
++++ b/cmake/3rdparty/kwin/FindLibdlmclient.cmake
+@@ -0,0 +1,127 @@
++#.rst:
++# FindLibdlmclient
++# -------
++# FindLibdlmclient.cmake is created based on FindLibinput.cmake
++#
++# Try to find libdlmclient on a Unix system.
++#
++# This will define the following variables:
++#
++# ``Libdlmclient_FOUND``
++#     True if (the requested version of) libdlmclient is available
++# ``Libdlmclient_VERSION``
++#     The version of libdlmclient
++# ``Libdlmclient_LIBRARIES``
++#     This can be passed to target_link_libraries() instead of the ``Libdlmclient::Libdlmclient``
++#     target
++# ``Libdlmclient_INCLUDE_DIRS``
++#     This should be passed to target_include_directories() if the target is not
++#     used for linking
++# ``Libdlmclient_DEFINITIONS``
++#     This should be passed to target_compile_options() if the target is not
++#     used for linking
++#
++# If ``Libdlmclient_FOUND`` is TRUE, it will also define the following imported target:
++#
++# ``Libdlmclient::Libdlmclient``
++#     The libdlmclient library
++#
++# In general we recommend using the imported target, as it is easier to use.
++# Bear in mind, however, that if the target is in the link interface of an
++# exported library, it must be made available by the package config file.
++
++#=============================================================================
++# Copyright 2014 Alex Merry <alex.merry@kde.org>
++# Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
++# Copyright 2022 Naoto Yamaguchi <naoto.yamaguchi@aisin.co.jp>
++#
++# Redistribution and use in source and binary forms, with or without
++# modification, are permitted provided that the following conditions
++# are met:
++#
++# 1. Redistributions of source code must retain the copyright
++#    notice, this list of conditions and the following disclaimer.
++# 2. Redistributions in binary form must reproduce the copyright
++#    notice, this list of conditions and the following disclaimer in the
++#    documentation and/or other materials provided with the distribution.
++# 3. The name of the author may not be used to endorse or promote products
++#    derived from this software without specific prior written permission.
++#
++# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
++# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++#=============================================================================
++
++if(CMAKE_VERSION VERSION_LESS 2.8.12)
++    message(FATAL_ERROR "CMake 2.8.12 is required by FindLibdlmclient.cmake")
++endif()
++if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.12)
++    message(AUTHOR_WARNING "Your project should require at least CMake 2.8.12 to use FindLibdlmclient.cmake")
++endif()
++
++if(NOT WIN32)
++    # Use pkg-config to get the directories and then use these values
++    # in the FIND_PATH() and FIND_LIBRARY() calls
++    find_package(PkgConfig QUIET)
++    pkg_check_modules(PKG_Libdlmclient QUIET libdlmclient)
++
++    set(Libdlmclient_DEFINITIONS ${PKG_Libdlmclient_CFLAGS_OTHER})
++    set(Libdlmclient_VERSION ${PKG_Libdlmclient_VERSION})
++
++    find_path(Libdlmclient_INCLUDE_DIR
++        NAMES
++            dlmclient.h
++        HINTS
++            ${PKG_Libdlmclient_INCLUDE_DIRS}
++    )
++    find_library(Libdlmclient_LIBRARY
++        NAMES
++            dlmclient
++        HINTS
++            ${PKG_Libdlmclient_LIBRARY_DIRS}
++    )
++
++    include(FindPackageHandleStandardArgs)
++    find_package_handle_standard_args(Libdlmclient
++        FOUND_VAR
++            Libdlmclient_FOUND
++        REQUIRED_VARS
++            Libdlmclient_LIBRARY
++            Libdlmclient_INCLUDE_DIR
++        VERSION_VAR
++            Libdlmclient_VERSION
++    )
++
++    if(Libdlmclient_FOUND AND NOT TARGET Libdlmclient::Libdlmclient)
++        add_library(Libdlmclient::Libdlmclient UNKNOWN IMPORTED)
++        set_target_properties(Libdlmclient::Libdlmclient PROPERTIES
++            IMPORTED_LOCATION "${Libdlmclient_LIBRARY}"
++            INTERFACE_COMPILE_OPTIONS "${Libdlmclient_DEFINITIONS}"
++            INTERFACE_INCLUDE_DIRECTORIES "${Libdlmclient_INCLUDE_DIR}"
++        )
++    endif()
++
++    mark_as_advanced(Libdlmclient_LIBRARY Libdlmclient_INCLUDE_DIR)
++
++    # compatibility variables
++    set(Libdlmclient_LIBRARIES ${Libdlmclient_LIBRARY})
++    set(Libdlmclient_INCLUDE_DIRS ${Libdlmclient_INCLUDE_DIR})
++    set(Libdlmclient_VERSION_STRING ${Libdlmclient_VERSION})
++
++else()
++    message(STATUS "FindLibdlmclient.cmake cannot find libdlmclient on Windows systems.")
++    set(Libdlmclient_FOUND FALSE)
++endif()
++
++include(FeatureSummary)
++set_package_properties(Libdlmclient PROPERTIES
++    URL "https://git.automotivelinux.org/src/drm-lease-manager/"
++    DESCRIPTION "The DRM Lease Manager uses the DRM Lease feature, introduced in the Linux kernel version 4.15, to partition display controller output resources between multiple processes."
++)
+diff --git a/src/gui/configure.cmake b/src/gui/configure.cmake
+index 0bf250eab6..b092b746c0 100644
+--- a/src/gui/configure.cmake
++++ b/src/gui/configure.cmake
+@@ -38,6 +38,7 @@ endif()
+ qt_find_package(Fontconfig PROVIDED_TARGETS Fontconfig::Fontconfig MODULE_NAME gui QMAKE_LIB fontconfig)
+ qt_add_qmake_lib_dependency(fontconfig freetype)
+ qt_find_package(gbm PROVIDED_TARGETS gbm::gbm MODULE_NAME gui QMAKE_LIB gbm)
++qt_find_package(Libdlmclient PROVIDED_TARGETS Libdlmclient::Libdlmclient MODULE_NAME gui QMAKE_LIB libdlmclient)
+ qt_find_package(WrapSystemHarfbuzz 2.6.0 PROVIDED_TARGETS WrapSystemHarfbuzz::WrapSystemHarfbuzz MODULE_NAME gui QMAKE_LIB harfbuzz)
+ qt_find_package(Libinput PROVIDED_TARGETS Libinput::Libinput MODULE_NAME gui QMAKE_LIB libinput)
+ qt_find_package(JPEG PROVIDED_TARGETS JPEG::JPEG MODULE_NAME gui QMAKE_LIB libjpeg)
+diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/CMakeLists.txt b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/CMakeLists.txt
+index a20a4a084d..2af7904eb6 100644
+--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/CMakeLists.txt
++++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/CMakeLists.txt
+@@ -23,6 +23,7 @@ qt_internal_add_module(EglFsKmsGbmSupportPrivate
+         Qt::GuiPrivate
+         Qt::KmsSupportPrivate
+         gbm::gbm
++        Libdlmclient::Libdlmclient
+ )
+ #####################################################################
+ ## QEglFSKmsGbmIntegrationPlugin Plugin:
+@@ -44,6 +45,7 @@ qt_internal_add_plugin(QEglFSKmsGbmIntegrationPlugin
+         Qt::GuiPrivate
+         Qt::KmsSupportPrivate
+         gbm::gbm
++        Libdlmclient::Libdlmclient
+ )
+ #### Keys ignored in scope 3:.:.:eglfs_kms-plugin.pro:<TRUE>:
+diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp
+index b5b7811b79..1e77c72ee5 100644
+--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp
++++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp
+@@ -56,32 +56,51 @@ Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug)
+ QEglFSKmsGbmDevice::QEglFSKmsGbmDevice(QKmsScreenConfig *screenConfig, const QString &path)
+     : QEglFSKmsDevice(screenConfig, path)
+     , m_gbm_device(nullptr)
++    , m_lease(nullptr)
+     , m_globalCursor(nullptr)
+ {
+ }
+ bool QEglFSKmsGbmDevice::open()
+ {
++    QByteArray lease = qgetenv("QT_QPA_EGLFS_DRMLEASE");
++    int drmfd = -1;
+     Q_ASSERT(fd() == -1);
+     Q_ASSERT(m_gbm_device == nullptr);
+-    int fd = qt_safe_open(devicePath().toLocal8Bit().constData(), O_RDWR | O_CLOEXEC);
+-    if (fd == -1) {
+-        qErrnoWarning("Could not open DRM device %s", qPrintable(devicePath()));
+-        return false;
++    if (lease.isEmpty()) {
++        drmfd = qt_safe_open(devicePath().toLocal8Bit().constData(), O_RDWR | O_CLOEXEC);
++        if (drmfd == -1) {
++            qErrnoWarning("Could not open DRM device %s", qPrintable(devicePath()));
++            return false;
++        }
++    } else {
++        QString lease_path(QString::fromUtf8(lease));
++        
++        m_lease = ::dlm_get_lease(lease_path.toLocal8Bit().constData());
++        if (m_lease == nullptr) {
++            qErrnoWarning("Could not open DRM lease %s", qPrintable(lease_path));
++            return false;
++        }
++        drmfd = dlm_lease_fd(m_lease);
+     }
+-    qCDebug(qLcEglfsKmsDebug) << "Creating GBM device for file descriptor" << fd
++    qCDebug(qLcEglfsKmsDebug) << "Creating GBM device for file descriptor" << drmfd
+                               << "obtained from" << devicePath();
+-    m_gbm_device = gbm_create_device(fd);
++    m_gbm_device = gbm_create_device(drmfd);
+     if (!m_gbm_device) {
+         qErrnoWarning("Could not create GBM device");
+-        qt_safe_close(fd);
+-        fd = -1;
++        if (m_lease) {
++            ::dlm_release_lease(m_lease);
++            m_lease = nullptr;
++        } else {
++            qt_safe_close(drmfd);
++        }
++        drmfd = -1;
+         return false;
+     }
+-    setFd(fd);
++    setFd(drmfd);
+     m_eventReader.create(this);
+@@ -99,7 +118,11 @@ void QEglFSKmsGbmDevice::close()
+         m_gbm_device = nullptr;
+     }
+-    if (fd() != -1) {
++    if (m_lease) {
++        setFd(-1);
++        ::dlm_release_lease(m_lease);
++        m_lease = nullptr;
++    } else if (fd() != -1) {
+         qt_safe_close(fd());
+         setFd(-1);
+     }
+diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice_p.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice_p.h
+index bb67d800ee..b2d705800e 100644
+--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice_p.h
++++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice_p.h
+@@ -57,6 +57,7 @@
+ #include <private/qeglfskmsdevice_p.h>
+ #include <gbm.h>
++#include <dlmclient.h>
+ QT_BEGIN_NAMESPACE
+@@ -92,6 +93,9 @@ private:
+     gbm_device *m_gbm_device;
++    // only used for DRM lease
++    struct dlm_lease *m_lease;
++
+     QEglFSKmsGbmCursor *m_globalCursor;
+ };
+-- 
+2.25.1
+
diff --git a/meta-agl-drm-lease/dynamic-layers/meta-qt6/recipes-qt/qt6/qtbase_git.bbappend b/meta-agl-drm-lease/dynamic-layers/meta-qt6/recipes-qt/qt6/qtbase_git.bbappend
new file mode 100644 (file)
index 0000000..0aa5bd6
--- /dev/null
@@ -0,0 +1,7 @@
+FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
+
+DEPENDS:append = " drm-lease-manager"
+DEPENDS:remove:class-native = " drm-lease-manager"
+DEPENDS:remove:class-nativesdk = " drm-lease-manager"
+
+SRC_URI:append = " file://0001-Add-drm-lease-client-support-to-eglfs-kms-backend.patch"