使用 buildroot KMS/DRM 分层 Qt Windows

问题描述

我的项目在rockchip rk3288 处理器(Tinkerboard)上使用buildroot。我的项目使用 Qt QML 和 Qt 5.9.1 版。我正在使用 libmali--gbm.so 库,因为它为我的 Qt 应用程序提供了 eglfs_kms。我在 iMX6 设备上的旧帧缓冲内核上使用了 eglfs,它从启动开始就很快,简单,并且不像 Wayland 那样依赖于 weston。

我想分层两个Qt QML窗口,其中底层是视频,顶层是GUI。像这样:

__________________________
|              ___________|_______________
|              |                          |
|  video       |                          |
|  layer       |                          |
|              |    ui  layer             |
|              |                          |
|______________|                          |
               |__________________________|

UI 层将具有透明背景,因此可以在下方看到视频层。在我的上一个项目 (IMX6) 中,使用了较旧的内核,并使用了帧缓冲区来执行此操作。

QT_QPA_EGLFS_FB=/dev/fb0 QT_QPA_PLATFORM=eglfs ./bottomWindow & 
QT_QPA_EGLFS_FB=/dev/fb1 QT_QPA_PLATFORM=eglfs ./topWindow & 

topWindow 基本上是一个 applicationwindow,其中背景是透明的:

// main.qml
applicationwindow 
{
    flags: Qt.FramelessWindowHint | Qt.QWindow
    visible: true
    width: 1280
    height: 720

    color: "transparent" 

    Text
    {
        anchors.centerIn: parent
        text: "Hello" 
    }
}

原因我想要单独的 Windows 是因为我需要对在 QML 中有转换的 MyVideoApp 进行屏幕截图和视频录制。如果视频驻留在 MyUIApp 内的 QML 表面中,我将无法执行此操作。在我的 iMX 平台上,我只是简单地抓取了帧缓冲区 (/dev/fb0)。

我的新项目不使用帧缓冲区,它使用 KMS/DRM 平台。这没关系,但我不是 KMS/DRM 方面的专家。我的大部分知识来自 https://events.static.linuxfound.org/sites/events/files/slides/brezillon-drm-kms.pdf 。我知道 DRM 有一个基本帧缓冲区和 kms 覆盖平面。根据 Qt 文档 https://doc.qt.io/qt-5/embedded-linux.html 可以将 qt 窗口分配给 KMS 平面,但我尝试的变量不起作用:

# export QT_LOGGING_RULES=qt.qpa.egl*=true
# ./bottomWindow &
qt.qpa.egldeviceintegration: EGL device integration plugin keys: ("eglfs_emu","eglfs_kms_egldevice","eglfs_kms","eglfs_x11")
qt.qpa.egldeviceintegration: EGL device integration plugin keys (sorted): ("eglfs_kms","eglfs_emu","eglfs_x11")
qt.qpa.egldeviceintegration: Trying to load device EGL integration "eglfs_kms" 
qt.qpa.eglfs.kms: New DRM/KMS via GBM integration created
qt.qpa.egldeviceintegration: Using EGL device integration "eglfs_kms" 
qt.qpa.eglfs.kms: platformInit: opening DRM device
qt.qpa.eglfs.kms: Found the following video devices: ("/dev/dri/card0")
qt.qpa.eglfs.kms: Using "/dev/dri/card0" 
qt.qpa.eglfs.kms: Using backend-provided DRM device /dev/dri/card0
qt.qpa.eglfs.kms: Creating GBM device for file descriptor 5 obtained from "/dev/dri/card0" 
qt.qpa.eglfs.kms: "DSI1" mode count: 1
qt.qpa.eglfs.kms: mode 0 720 x 1280 @ 61 hz
qt.qpa.eglfs.kms: Selected mode 0 : 720 x 1280 @ 61 hz for output "DSI1" 
qt.qpa.eglfs.kms: Physical size is QSizef(0,0) mm for output "DSI1" 
qt.qpa.eglfs.kms: Creating new global GBM mouse cursor
qt.qpa.eglfs.kms: Initializing cursor atlas from ":/cursor.json" 
qt.qpa.eglfs.kms: Sorted screen list: QVector(OrderedScreen(QPlatformScreen=0x177e568 ("DSI1") : 2147483647 / QPoint(0,0) / primary: false))
qt.qpa.eglfs.kms: Adding QPlatformScreen 0x177e568 ( "DSI1" ) to QPA with geometry QRect(0,0 720x1280) and isPrimary= false
qt.qpa.input: X-less xkbcommon not available,not performing key mapping
qt.qpa.eglfs.kms: Creating window for screen "DSI1" 
eglfs >> createSurface GBM_FORMAT_ARGB8888
eglfs >> sucess to create KMS FB!


# QT_QPA_EGLFS_LAYER_INDEX=1 ./topWindow 
qt.qpa.egldeviceintegration: EGL device integration plugin keys: ("eglfs_emu",0) mm for output "DSI1" 
qt.qpa.eglfs.kms: Creating new global GBM mouse cursor
qt.qpa.eglfs.kms: Initializing cursor atlas from ":/cursor.json" 
qt.qpa.eglfs.kms: Sorted screen list: QVector(OrderedScreen(QPlatformScreen=0x14c1568 ("DSI1") : 2147483647 / QPoint(0,0) / primary: false))
qt.qpa.eglfs.kms: Adding QPlatformScreen 0x14c1568 ( "DSI1" ) to QPA with geometry QRect(0,not performing key mapping
qt.qpa.eglfs.kms: Creating window for screen "DSI1" 
eglfs >> createSurface GBM_FORMAT_ARGB8888
eglfs >> sucess to create KMS FB!

如您所见,topWindow 创建了一个新的帧缓冲区并请求 DRM 切换到该新的帧缓冲区。不使用KMS平面。我知道我有 4 公里的飞机:

GST_DEBUG="*:4" gst-launch videotestsrc ! kmssink 

Setting pipeline to PAUSED ...
...
INFO   GST_STATES gstbin.c:2506:gst_bin_element_set_state:<kmssink0> current NULL pending VOID_PENDING,desired next READY
INFO      kmssink gstkmssink.c:367:log_drm_version:<kmssink0> DRM v1.0.0 [rockchip — RockChip Soc DRM — 20140818]
INFO      kmssink gstkmssink.c:414:get_drm_caps:<kmssink0> prime import (✓) / prime export (✓) / async page flip (✓)
INFO      kmssink gstkmssink.c:569:ensure_allowed_caps:<kmssink0> ignoring format RG24
INFO      kmssink gstkmssink.c:569:ensure_allowed_caps:<kmssink0> ignoring format BG24
INFO      kmssink gstkmssink.c:569:ensure_allowed_caps:<kmssink0> ignoring format RG16
INFO      kmssink gstkmssink.c:569:ensure_allowed_caps:<kmssink0> ignoring format BG16
INFO      kmssink gstkmssink.c:569:ensure_allowed_caps:<kmssink0> ignoring format NV24
INFO      kmssink gstkmssink.c:569:ensure_allowed_caps:<kmssink0> ignoring format NA16
INFO      kmssink gstkmssink.c:569:ensure_allowed_caps:<kmssink0> ignoring format NA24
INFO      kmssink gstkmssink.c:686:gst_kms_sink_start:<kmssink0> connector id = 84 / crtc id = 74 / plane id = 75 <---------------plane id 75 being used
INFO      kmssink gstkmssink.c:708:gst_kms_sink_start:<kmssink0> display size: pixels = 720x1280 / millimeters = 0x0
INFO   GST_STATES gstelement.c:2676:gst_element_continue_state:<kmssink0> completed state change to READY
...

我也试过设置 QT_QPA_EGLFS_KMS_CONNECTOR_INDEX=0 和 QT_QPA_EGLFS_KMS_PLANE_INDEX=1 得到相同的结果。

如何让我的 qt 应用在 kms 飞机上启动?我是否在 Qt 中遗漏了一些东西,因此它不会创建新的帧缓冲区?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)