You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 7 Next »

Overview

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.


Prepare the SDK or toolchain

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.

Download, configure and build the Qt 5.15.2 source code

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/aarch64-poky-linux-objcopy
QMAKE_NM = aarch64-poky-linux/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.

Integrate Qt 5.15.2 to the target Yocto filesystem

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
  • No labels