This page is an an example for RZ/G2L. It is based on using VLP 3.0.6.
Qt 5.15.2 can run on various backends. The EGLFS and Wayland backends are widely used. Here, we will talk about how to build and integrate Qt 5.15.2 with EGLFS and Wayland backends support based on VLP 3.0.6.
The default Yocto SDK of VLP 3.0.6 can only support the Qt with Wayland backend building. So the patch for the Qt 5.6.3(Qt version of VLP 3.0.6) recipe must be applied.
1.1) Modify meta-qt5/recipes-qt/qt5/qtbase_git.bb:
file://0008-configure-paths-for-target-qmake-properly.patch \
+ file://0001-dynamic-layers-qt5-qtbase-Add-DRM-KMS-support-for-EG.patch \
"
...
- PACKAGECONFIG_GL ?= "${@bb.utils.contains('DISTRO_FEATURES', 'opengl', 'gl', '', d)}"
+ PACKAGECONFIG_GL ?= "${@bb.utils.contains('DISTRO_FEATURES', 'opengl', 'gles2', '', d)}"
...
PACKAGECONFIG_DEFAULT ?= "dbus udev evdev widgets tools libs"
+ PACKAGECONFIG_EGLFS ?= "kms gbm"
...
${PACKAGECONFIG_DISTRO} \
+ ${PACKAGECONFIG_EGLFS} \
"
...
- PACKAGECONFIG[kms] = "-kms,-no-kms,virtual/mesa virtual/egl"
+ PACKAGECONFIG[kms] = "-kms,-no-kms,drm virtual/egl"
+ PACKAGECONFIG[gbm] = "-gbm,-no-gbm,virtual/libgbm"
...
QT_CONFIG_FLAGS += " \
+ -kms -gbm \
1.2) Add a patch file meta-qt5/recipes-qt/qt5/qtbase/0001-dynamic-layers-qt5-qtbase-Add-DRM-KMS-support-for-EG.patch:
From e9f4221e052c005593f4a5188e4293882edb4468 Mon Sep 17 00:00:00 2001
From: Cuong Doan <cuong.doan.ra@renesas.com>
Date: Wed, 23 Mar 2022 09:43:33 +0700
Subject: [PATCH] dynamic-layers: qt5: qtbase: Add DRM/KMS support for EGLFS.
This patch is for adding drm/kms support for eglfs.
Signed-off-by: Cuong Doan <cuong.doan.ra@renesas.com>
---
.../eglfs_kms/qeglfskmsintegration.cpp | 14 +++++++++++++-
.../eglfs_kms/qeglfskmsintegration.h | 7 ++++++-
.../eglfs_kms/qeglfskmsscreen.cpp | 2 +-
src/plugins/platforms/eglfs/qeglfsintegration.cpp | 6 +++---
4 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp
index d1814fb85d..7703b75207 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp
@@ -62,7 +62,10 @@ QEglFSKmsIntegration::QEglFSKmsIntegration()
, m_hwCursor(true)
, m_pbuffers(false)
, m_separateScreens(false)
-{}
+{
+ get_platform_display = (PFNEGLGETPLATFORMDISPLAYEXTPROC)
+ eglGetProcAddress("eglGetPlatformDisplayEXT");
+}
void QEglFSKmsIntegration::platformInit()
{
@@ -102,6 +105,15 @@ EGLNativeDisplayType QEglFSKmsIntegration::platformDisplay() const
return reinterpret_cast<EGLNativeDisplayType>(m_device->device());
}
+EGLDisplay QEglFSKmsIntegration::createDisplay(EGLNativeDisplayType nativeDisplay)
+{
+ if (get_platform_display)
+ m_display = get_platform_display(EGL_PLATFORM_GBM_KHR, nativeDisplay, NULL);
+ else
+ m_display = eglGetDisplay(nativeDisplay);
+ return m_display;
+}
+
bool QEglFSKmsIntegration::usesDefaultScreen()
{
return false;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.h
index edb6906a4b..808f19c4d5 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.h
@@ -38,6 +38,7 @@
#include "qeglfsdeviceintegration.h"
#include <QtCore/QMap>
#include <QtCore/QVariant>
+#include <EGL/eglext.h>
QT_BEGIN_NAMESPACE
@@ -50,6 +51,7 @@ public:
void platformInit() Q_DECL_OVERRIDE;
void platformDestroy() Q_DECL_OVERRIDE;
+ EGLDisplay createDisplay(EGLNativeDisplayType nativeDisplay) Q_DECL_OVERRIDE;
EGLNativeDisplayType platformDisplay() const Q_DECL_OVERRIDE;
bool usesDefaultScreen() Q_DECL_OVERRIDE;
void screenInit() Q_DECL_OVERRIDE;
@@ -68,16 +70,19 @@ public:
bool hwCursor() const;
bool separateScreens() const;
QMap<QString, QVariantMap> outputSettings() const;
+ EGLDisplay display() { return m_display; };
private:
void loadConfig();
-
QEglFSKmsDevice *m_device;
bool m_hwCursor;
bool m_pbuffers;
bool m_separateScreens;
QString m_devicePath;
QMap<QString, QVariantMap> m_outputSettings;
+
+ PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display;
+ EGLDisplay m_display;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp
index 048f5433dc..99bdba7142 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp
@@ -106,7 +106,7 @@ QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsIntegration *integration,
QEglFSKmsDevice *device,
QEglFSKmsOutput output,
QPoint position)
- : QEglFSScreen(eglGetDisplay(reinterpret_cast<EGLNativeDisplayType>(device->device())))
+ : QEglFSScreen(integration->display())
, m_integration(integration)
, m_device(device)
, m_gbm_surface(Q_NULLPTR)
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
index 2a6f3aa7cf..4a39d55b66 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
@@ -115,13 +115,13 @@ void QEglFSIntegration::initialize()
{
qt_egl_device_integration()->platformInit();
- m_display = qt_egl_device_integration()->createDisplay(nativeDisplay());
+ m_display = qt_egl_device_integration()->createDisplay(qt_egl_device_integration()->platformDisplay());
if (m_display == EGL_NO_DISPLAY)
- qFatal("Could not open egl display");
+ qFatal("Could not open egl display. Err:%x", eglGetError());
EGLint major, minor;
if (!eglInitialize(m_display, &major, &minor))
- qFatal("Could not initialize egl display");
+ qFatal("Could not initialize egl display. Err:%x", eglGetError());
m_inputContext = QPlatformInputContextFactory::create();
1.3) Build out the Yocto core-image-qt image, and then populate and install the SDK. Assume the SDK default install location is used(/opt/poky/3.1.31).
MACHINE=smarc-rzg2l bitbake core-image-qt
MACHINE=smarc-rzg2l bitbake core-image-qt -c populate_sdk
sudo sh poky-glibc-x86_64-core-image-weston-aarch64-smarc-rzg2l-toolchain-3.1.31.sh
Note: The Qt 5.6.3 with EGLFS backend support is ready. If you only need Qt 5.6.3, you can skip the following steps.
2.1) Get the Qt source code
# cd to any directory under ubuntu
cd <work-dir>
# download Qt 5.15.2 source code
wget https://download.qt.io/archive/qt/5.15/5.15.2/single/qt-everywhere-src-5.15.2.tar.xz
# decompress
tar -xvf qt-everywhere-src-5.15.2.tar.xz
2.2) Configure and build the source code
Prepare the output directory
mkdir output/
Replace the content of qt-everywhere-src-5.15.2/qtbase/mkspecs/linux-aarch64-gnu-g++/qmake.conf with following:
#
# qmake configuration for building with aarch64-linux-gnu-g++
#
MAKEFILE_GENERATOR = UNIX
CONFIG += incremental
QMAKE_INCREMENTAL_STYLE = sublib
QMAKE_LIBS_EGL += -lEGL
QMAKE_LIBS_OPENGL_ES2 += -lGLESv2 -lEGL
QMAKE_CFLAGS = -march=armv8-a -mtune=cortex-a55
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
EGLFS_DEVICE_INTEGRATION = eglfs_kms
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)
# modifications to g++.conf
QMAKE_CC = aarch64-poky-linux-gcc
QMAKE_CXX = aarch64-poky-linux-g++
QMAKE_LINK = aarch64-poky-linux-g++
QMAKE_LINK_SHLIB = aarch64-poky-linux-g++
# # modifications to linux.conf
QMAKE_AR = aarch64-poky-linux-ar cqs
QMAKE_OBJCOPY = aarch64-poky-linux-objcopy
QMAKE_NM = aarch64-poky-linux-nm -P
QMAKE_STRIP = aarch64-poky-linux-strip
load(qt_config)
Prepare the build script:
#!/bin/bash
if [ "x" == "x$1" ]; then
echo "No qt source dir specified"
exit 0
fi
PWD=`pwd`
OUTPUT=$PWD/output
YOCTOSDK=/opt/poky/3.1.31/sysroots
ROOTFS=$YOCTOSDK/aarch64-poky-linux
export PATH=$YOCTOSDK/x86_64-pokysdk-linux/usr/bin/aarch64-poky-linux:$PATH
export PKG_CONFIG_LIBDIR=$YOCTOSDK/aarch64-poky-linux/usr/lib64/pkgconfig
rm -rf $OUTPUT/*
cd $1
./configure -v -extprefix $OUTPUT -opensource -release -optimized-qmake -confirm-license -xplatform linux-aarch64-gnu-g++ -sysroot $ROOTFS -shared -silent -no-pch -no-rpath -pkg-config -no-pulseaudio -no-alsa -no-evdev -no-sse2 -no-sse3 -no-cups -dbus -make examples -compile-examples -no-fontconfig -opengl es2 -egl -eglfs -no-glib -no-harfbuzz -no-iconv -icu -system-libjpeg -kms -gbm -system-libpng -no-libproxy -make libs -linuxfb -no-mtdev -no-openssl -no-openvg -qt-pcre -sm -no-sql-db2 -no-sql-ibase -no-sql-mysql -no-sql-oci -no-sql-odbc -no-sql-psql -sql-sqlite -system-sqlite -sql-sqlite2 -no-sql-tds -nomake tests -make tools -no-tslib -libudev -widgets -no-xcb -system-zlib -skip webengine -c++std c++11 -skip qtdoc -qpa wayland
if [ "0" != "$?" ]; then
exit 1
fi
make
if [ "0" != "$?" ]; then
exit 1
fi
make install
if [ "0" != "$?" ]; then
exit 1
fi
cd $OUTPUT
tar -zcf ../qt-5.15.2-eglfs-wayland-build.tar.gz *
echo ====== SUCCESS ======
Run this script:
./build.sh qt-everywhere-src-5.15.2/
If everything is OK, you will get the built out binary Qt 5.15.2 in gzip file: qt-5.15.2-eglfs-wayland-build.tar.gz. The build process may take several hours.
It will coexist with Qt 5.6.3.
3.1) Install
Decompress qt-5.15.2-eglfs-wayland-build.tar.gz to some directory of the MPU target filesystem(Not ubuntu PC). Here we use /usr/share/qt-5.15.2.
mkdir /usr/share/qt-5.15.2
tar -zxf qt-5.15.2-eglfs-wayland-build.tar.gz -C /usr/share/qt-5.15.2
3.2) Run Qt 5.15.2 demo
Setup common Qt environment variables on the target board:
export QTDIR=/usr/share/qt-5.15.2/lib
export LD_LIBRARY_PATH=/usr/share/qt-5.15.2/lib:$LD_LIBRARY_PATH
Wayland backend based demo:
# make sure the weston service is running
export QT_QPA_PLATFORM=wayland
cd /usr/share/qt-5.15.2/examples/opengl/cube
./cube
EGLFS backend based demo:
# make sure the weston service is NOT running
systemctl stop weston@root
export QT_QPA_PLATFORM=eglfs
cd /usr/share/qt-5.15.2/examples/opengl/cube
./cube