嵌入式Linux的Qt

嵌入式Linux的Qt

在嵌入式Linux系统上,可以使用多个平台插件:EGLFS,LinuxFB,DirectFB或Wayland。但是,这些插件的可用性取决于Qt的配置方式。

EGLFS是许多主板上的默认插件。如果不合适,请使用QT_QPA_PLATFORM环境变量来请求另一个插件。另外,对于快速测试,请使用-platform具有相同语法的命令行参数。

注意:从Qt 5.0开始,Qt不再具有自己的窗口系统(QWS)实现。对于单流程用例,Qt Platform Abstraction是一种出色的解决方案;Wayland支持多流程用例。

嵌入式Linux设备的平台插件

EGLFS

EGL是OpenGL与本机窗口系统之间的接口。Qt可以将EGL用于上下文和表面管理,但是API不包含特定于平台的内容。创建本机窗口(不一定是屏幕上的实际窗口),仍然必须通过特定于平台的方式来完成。这就是为什么我们需要主板或GPU专用的适配代码的原因。通常,这些改编提供为:

  • EGLFS挂钩 -将单个源文件编译到平台插件中
  • EGL设备集成 -动态加载的插件

EGLFS是一个平台插件,用于在EGL和OpenGL ES 2.0之上运行Qt5应用程序,而没有像X11或Wayland这样的实际窗口系统。除了Qt Quick 2和本机OpenGL应用程序之外,EGLFS还支持软件渲染的窗口,例如QWidget。对于QWidget,小部件的内容使用CPU渲染为图像,然后将其上载为纹理并由插件进行合成。

对于包含GPU的现代嵌入式Linux设备,推荐使用EGLFS插件。

EGLFS迫使第一顶层窗口-无论是QWidget的或QQuickView -成为全屏。该窗口也被选择为所有其他顶级窗口小部件都合并到其中的窗口小部件窗口。例如,对话框,弹出菜单或组合框。这种行为是必要的,因为使用EGLFS时,总是只有一个本机窗口和一个EGL窗口表面;这些属于首先创建的小部件或窗口。当存在显示应用程序生命周期的主窗口并且所有其他窗口小部件不是非顶层窗口或在之后创建的所有其他窗口小部件时,此方法效果很好。

基于OpenGL的窗口还有其他限制。EGLFS支持单个单一的全屏GL窗口(从Qt 5.3开始),例如基于OpenGL的QWindow,QQuickView或QOpenGLWidget。不支持打开其他OpenGL窗口或将此类窗口与基于QWidget的内容混合使用;Qt使用错误消息终止应用程序。

如有必要,eglfs可以使用以下环境变量进行配置:

环境变量 描述
QT_QPA_EGLFS_INTEGRATION 除了内置的钩子之外,还可以使用动态加载的插件来提供设备或供应商特定的适配。此环境变量强制执行特定的插件。例如,将其设置为eglfs_kms将使用KMS / DRM后端。仅当在设备makespecs中未指定静态或内置挂钩时,这才是一个选项。实际上,很少使用传统的内置挂钩,现在几乎所有后端都已迁移到插件。设备的制造规范仍然包含相关内容EGLFS_DEVICE_INTEGRATIONentry:该特定设备的首选后端的名称。这是可选的,但对于避免在目标系统中存在多个插件的情况下避免设置此环境变量非常有用。在桌面环境中,根据DISPLAY环境变量的存在,对KMS或X11后端进行优先级排序。注意:在某些板上,使用特殊值none代替实际的插件。这表明将EGL与帧缓冲区一起使用不需要任何特殊的集成。无需加载任何插件。
QT_QPA_EGLFS_PHYSICAL_WIDTHQT_QPA_EGLFS_PHYSICAL_HEIGHT 指定物理屏幕的宽度和高度(以毫米为单位)。在无法从帧缓冲设备/ dev / fb0或通过其他方式查询该值的平台上,使用默认DPI为100。使用此变量来覆盖任何此类默认值。设置此变量很重要,因为基于QWidget或基于Qt Quick Controls的应用程序依赖于这些值。使用硬编码设置运行这些应用程序可能会导致用户界面元素的大小不适合所使用的显示器。
QT_QPA_EGLFS_ROTATION 指定在基于QWidget的应用程序中应用于软件渲染内容的轮播。支持的值为180、90和-90。此变量不适用于基于OpenGL的窗口,包括Qt Quick。Qt Quick应用程序可以在其QML场景中应用转换。eglfs无论应用程序类型如何,标准鼠标光标都会始终将值考虑在内,并具有适当放置和旋转的指针图像。但是,特殊的游标实现(例如KMS / DRM后端的硬件游标)可能不支持旋转。
QT_QPA_EGLFS_FORCEVSYNC 设置后,在每次调用eglSwapBuffers()之后在帧缓冲设备上eglfs请求FBIO_WAITFORVSYNC。该变量仅与依赖于传统Linux fbdev子系统的后端有关。通常,在默认交换间隔为1的情况下,Qt假设调用eglSwapBuffers()会处理vsync。如果不是(例如由于驱动程序错误),请尝试将其设置QT_QPA_EGLFS_FORCEVSYNC为非零值。
QT_QPA_EGLFS_FORCE888 设置后,在eglfs创建新的上下文,窗口或屏幕外表面时,红色,绿色和蓝色通道大小将被忽略。而是,插件请求每通道8位的配置。这对于在默认情况下选择每像素少于32或24位的配置(例如5-6-5或4-4-4)的设备很有帮助,尽管知道它们不理想,例如由于条带效果。代替更改应用程序代码,此变量提供了强制执行24或32 bpp配置的快捷方式。

此外,还提供以下不常用的变量:

环境变量 描述
QT_QPA_EGLFS_FB 覆盖帧缓冲设备。默认值为/dev/fb0。在大多数嵌入式平台上,此变量不是很相关,因为帧缓冲区仅用于查询显示尺寸等设置。但是,在某些设备上,此变量提供了指定在多个显示设置中使用哪个显示器的功能,类似于LinuxFB中的fb参数。
QT_QPA_EGLFS_WIDTHQT_QPA_EGLFS_HEIGHT 包含屏幕的宽度和高度(以像素为单位)。虽然eglfs尝试从帧缓冲设备/ dev / fb0确定尺寸,但这并不总是有效。可能需要手动指定尺寸。
QT_QPA_EGLFS_DEPTH 覆盖屏幕的颜色深度。在帧缓冲设备/ dev / fb0不可用或查询不成功的平台上,使用默认值32。使用此变量来覆盖任何此类默认值。注意:此变量仅影响QScreen报告的色深值。它与EGL配置和OpenGL渲染所使用的颜色深度无关。
QT_QPA_EGLFS_SWAPINTERVAL 默认情况下,1请求的交换间隔为。使用此变量可以同步到显示器的垂直刷新。使用此变量覆盖交换间隔的值。例如,传递0将禁用交换阻塞,从而导致在没有任何同步的情况下尽可能快地运行。
QT_QPA_EGLFS_DEBUG 设置后,一些调试信息会打印在调试输出上。例如,在创建新上下文时,将打印输入QSurfaceFormat和所选EGL配置的属性。与Qt Quick的QSG_INFO变量一起使用时,您可以获得有用的信息,可用于解决与EGL配置有关的问题。

除了QT_QPA_EGLFS_DEBUGeglfs还支持Qt的现代分类日志系统。以下日志记录类别可用:

  • qt.qpa.egldeviceintegration–为动态加载的后端启用日志记录。使用此类别可以检查正在使用的后端。
  • qt.qpa.input–启用evdevlibinput输入处理程序的调试输出。使用此类别来检查是否识别并打开了给定的输入设备。
  • qt.qpa.eglfs.kms –在KMS / DRM后端中启用详细日志记录。

运行之后configure,请确保检查其输出。这是识别您是否启用了必需的EGLFS后端,libudev或libinput的最简单,最快的方法。简而言之,如果您的configure输出中有不希望的“否”,请运行:

./configure -v

打开详细输出,以便您可以查看每个configure测试的编译器和链接器调用。

注意:如果经常遇到有关缺少标题,库或看似神秘的链接器故障的错误,则它们通常是sysroot不完整或损坏的迹象,并且与Qt不相关。

例如,当使用Broadcom专有的图形驱动程序作为Raspberry Pi的目标时,输出应包含以下内容:

QPA backends:
EGLFS ................................ yes
EGLFS details:
  EGLFS i.Mx6 ........................ no
  EGLFS i.Mx6 Wayland ................ no
  EGLFS EGLDevice .................... no
  EGLFS GBM .......................... no
  EGLFS Mali ......................... no
  EGLFS Rasberry Pi .................. yes
  EGL on X11 ......................... no

如果不是这种情况,则不建议继续进行构建,因为没有Raspberry Pi特定的后端,加速的图形将无法工作,即使Qt的其余部分也可以成功编译。

LinuxFB

该插件通过Linux的fbdev子系统直接写入帧缓冲区。仅支持软件渲染的内容。请注意,在某些设置下,显示性能可能会受到限制。

但是,由于在Linux内核中已弃用fbdev,因此从Qt 5.9开始,还提供了DRM哑缓存支持。要使用它,请将QT_QPA_FB_DRM环境变量设置为非零值。设置后,只要系统支持哑缓存,/dev/fb0就不会访问旧式帧缓存设备。取而代之的是,通过DRM API来设置呈现,类似于eglfs_kmsEGLFS中的后端。输出经过双缓冲和页面翻转,也为软件渲染的内容提供了适当的垂直同步。

注意:使用哑缓冲区时,以下描述的选项均不适用,因为会自动查询物理和逻辑屏幕大小之类的属性。

linuxfb插件允许您通过QT_QPA_PLATFORM环境变量或-platform命令行选项指定其他设置。例如,QT_QPA_PLATFORM=linuxfb:fb=/dev/fb1指定/dev/fb1必须使用framebuffer设备而不是default fb0。要指定多个设置,请用冒号(:)分隔。

设定值 描述
fb=/dev/fbN 指定帧缓冲设备。在多个显示器设置上,此设置使您可以在不同的显示器上运行该应用程序。当前,无法从一个Qt应用程序中使用多个帧缓冲区。
size=<宽度> x<高度> 指定屏幕尺寸(以像素为单位)。该插件尝试从帧缓冲设备查询物理和逻辑的显示尺寸。但是,此查询可能并不总是会导致正确的结果。可能需要明确指定这些值。
mmsize=<宽度> x<高度> 指定物理宽度和高度(以毫米为单位)。
offset=<宽度> x<高度> 指定屏幕的左上角偏移量(以像素为单位)。默认位置为(0, 0)
nographicsmodeswitch 指定不将虚拟终端切换到图形模式(KD_GRAPHICS)。通常,启用图形模式会禁用闪烁的光标和屏幕空白。但是,设置此参数后,这两个功能也会被跳过。
tty=/dev/ttyN 覆盖虚拟控制台。仅在nographicsmodeswitch未设置时使用。

从Qt 5.9 开始,就窗口大小调整策略而言,EGLFS和LinuxFB的行为已同步:使用两个平台插件,第一个顶级窗口被迫覆盖整个屏幕。如果不希望这样做,请将QT_QPA_FB_FORCE_FULLSCREEN环境变量设置为0从早期的Qt版本恢复行为。

显示输出

当您连接了多个显示器时,从一个单独的Qt应用程序中定位一个或多个这些显示器的支持级别在平台插件之间会有所不同,并且通常取决于设备及其图形堆栈。

带有eglfs_kms后端的EGLFS

使用KMS / DRM后端时,EGLFS报告QGuiApplication :: screens()中的所有可用屏幕。应用程序可以通过QWindow :: setScreen()将具有不同窗口的不同屏幕作为目标。

注意:每个屏幕一个全屏窗口的限制仍然适用。也不支持在使QWindow可见后更改屏幕。因此,嵌入式应用程序必须在调用QWindow :: show()之前进行所有必需的QWindow :: setScreen()调用。

当您开始在给定的嵌入式设备上进行开发时,通常需要验证设备和驱动程序的行为,以及所连接的显示器是否按预期工作。一种简单的方法是使用hellowindow示例。使用-platform eglfs --multiscreen --timeout参数启动它会在每个连接的屏幕上显示旋转的Qt徽标几秒钟。

KMS / DRM后端还通过JSON文件支持自定义配置。要启用此功能,请将QT_QPA_EGLFS_KMS_CONFIG环境变量设置为文件名。您也可以通过Qt资源系统将此文件嵌入到应用程序中。

这些配置选项中的大多数都适用于所有基于KMS / DRM的后端,而与缓冲区管理技术(GBM或EGLStreams)无关。

这是一个示例配置:

{
  "device": "/dev/dri/card1",
  "hwcursor": false,
  "pbuffers": true,
  "outputs": [
    {
      "name": "VGA1",
      "mode": "off"
    },
    {
      "name": "HDMI1",
      "mode": "1024x768"
    }
  ]
}

在这里,我们配置指定的设备,以便:

  • 它不会使用硬件光标(可通过OpenGL渲染鼠标光标;默认情况下会启用硬件光标,因为它们效率更高)。
  • 它使用标准EGL pbuffer表面支持QOffscreenSurface(默认情况下,此功能处于禁用状态,而是使用gbm表面)。
  • 当HDMI的分辨率为1024x768时,VGA接口上的输出被禁用。

另外,这样的配置还禁止通过libudev; 查找设备。而是使用指定的设备。

如果mode未定义,则选择系统的首选模式。为可接受的值mode是:offcurrentpreferredskip,宽度x高度,宽度x高度@vrefresh,或模式行字符串。

指定将current选择一种分辨率与当前模式匹配的模式。因为仅当所需模式实际上与活动模式不同时才进行模式设置(除非通过QT_QPA_EGLFS_ALWAYS_SET_MODE环境变量强制设置),所以此值可用于保存当前模式以及Qt未触及的平面中的任何内容。

skip使输出的连接器被忽略,就像已断开连接一样。off类似于,但它更改了模式并关闭了显示。

默认情况下,DRM层报告的所有屏幕都被视为一个大的虚拟桌面。鼠标光标的实现考虑到了这一点,并按预期在屏幕上移动。尽管不建议这样做,但可以通过在配置中设置separateScreens为来禁用虚拟桌面false

默认情况下,虚拟桌面是根据系统报告的连接器顺序从左到右形成的。要更改此设置,请设置virtualIndex一个从0开始的值。

例如,以下配置使用首选分辨率,但要确保虚拟桌面的左侧是连接到HDMI端口的屏幕​​。而右侧是连接到DisplayPort的屏幕:

{
  "device": "drm-nvdc",
  "outputs": [
    {
      "name": "HDMI1",
      "virtualIndex": 0
    },
    {
      "name": "DP1",
      "virtualIndex": 1
    }
  ]
}

数组中元素的顺序无关紧要。具有未指定虚拟索引的输出将放置在其他输出之后,并保留DRM连接器列表中的原始顺序。

要创建垂直桌面空间(即从上到下而不是从左到右堆叠),请virtualDesktopLayout在其后添加一个device值为的属性vertical

警告:建议虚拟桌面中的所有屏幕使用相同的分辨率,否则当进入仅存在于一个给定屏幕上的区域时,诸如鼠标光标之类的元素可能会以意外的方式表现。

如果virtualIndex还不够,则virtualPos可以使用该属性来明确指定相关屏幕的左上角位置。以前面的示例为例,假设HDMI1的分辨率为1080p,下面的代码段将第二个基于HDMI的屏幕放在第一个屏幕下方:

{
   ...
  "outputs": [
    ...
    {
      "name": "HDMI2",
      "virtualPos": "0, 1080"
    }
  ]
}

注意:当需要鼠标支持时,避免进行此类配置。对于非线性布局,鼠标光标的行为可能是意外的。触摸应该没有问题。

在某些情况下,通过DRM自动查询物理屏幕尺寸可能会失败。通常,QT_QPA_EGLFS_PHYSICAL_WIDTHand QT_QPA_EGLFS_PHYSICAL_HEIGHT环境变量将用于提供缺少的值,但是当存在多个屏幕时,这不再适用。而是使用列表中的physicalWidthphysicalHeight属性outputs以毫米为单位指定尺寸。

注意:不建议使用不同的物理尺寸,从而避免使用不同的逻辑DPI,因为某些图形堆栈组件不了解多个屏幕,而仅依赖于第一个屏幕的值,这可能会导致意外问题。

从每个有源输出outputs阵列对应于一个QScreen例如从报道QGuiApplication ::屏幕()。默认情况下,QGuiApplication :: primaryScreen()报告的主屏幕是首先注册的屏幕。如果您未使用virtualIndex,则表示该决定基于DRM连接器的顺序。要覆盖此primary属性,请将属性设置trueoutputs列表中所需的条目。

例如,即使系统碰巧先报告HDMI时,也要确保与VGA输出相对应的屏幕是主要屏幕,请执行以下操作:

{
  "device": "/dev/dri/card0",
  "outputs": [
      { "name": "HDMI1" },
      { "name": "VGA1", "mode": "1280x720", "primary": true },
      { "name": "LVDS1", "mode": "off" }
  ]
}

为了进行故障排除,从KMS / DRM后端启用调试日志可能会很有用。为此,请启用qt.qpa.eglfs.kms分类日志记录规则。

注意:在嵌入式环境中,与完整的窗口系统相比,虚拟桌面的局限性更大。应避免重叠多个屏幕的窗口,非全屏窗口以及在屏幕之间移动窗口,并且这些窗口可能无法正常运行。

对于多屏幕设置,最常见和最受支持的用例是为每个屏幕打开专用的QQuickWindow或QQuickView。使用threadedQt Quick场景图的默认渲染循环,这些窗口中的每个窗口都将拥有自己的专用渲染线程。这很好,因为可以基于vsync独立限制线程,并且不会互相干扰。使用basic循环可能会出现问题,导致动画质量下降。

例如,发现所有连接的屏幕并为每个屏幕创建一个QQuickView可以像这样完成:

int main(int argc, char **argv)
{
    QGuiApplication app(argc, argv);

    QVector views;
    for (QScreen *screen : app.screens()) {
        QQuickView *view = new QQuickView;
        view->setScreen(screen);
        view->setResizeMode(QQuickView::SizeRootObjectToView);
        view->setSource(QUrl("qrc:/main.qml"));
        QObject::connect(view->engine(), &QQmlEngine::quit, qGuiApp, &QCoreApplication::quit);
        views.append(view);
        view->showFullScreen();
    }

    int result = app.exec();

    qDeleteAll(views);
    return result;
}

eglfs_kms的高级功能

从Qt 5.11开始,支持屏幕克隆(镜像)。这通过clones属性启用:

{
  "device": "/dev/dri/card0",
  "outputs": [
      { "name": "HDMI1", "mode": "1920x1080" },
      { "name": "DP1", "mode": "1920x1080", "clones": "HDMI1" }
 ]
}

在这种情况下,通过DisplayPort连接的显示器上的内容将与HDMI上的内容相同。通过在两者上扫描出相同的缓冲区来确保这一点。

但是,仅当分辨率相同,接受的缓冲区格式没有不兼容并且应用程序在与克隆目标相关联的QScreen上没有任何输出时,此功能才能起作用。在实践中,后者是指没有QWindow与相关联的QScreen中的问题-在DP1的例子-必须永远执行QOpenGLContext :: swapBuffers()操作。确保这些由配置和应用程序决定。

从Qt 5.11开始,支持通过DRM渲染节点的无头模式。这允许执行GPU计算(OpenGL计算着色器,OpenCL)或屏幕外OpenGL渲染,而无需DRM主权限。在这种模式下,即使已经有另一个进程输出到屏幕,应用程序也可以运行。

只需切换device/dev/dri/card0/dev/dri/renderD128,因为有一些操作无法在无头的模式下进行是对自己徒劳的。因此,它必须与一个headless属性结合使用,例如:

{
    "device": "/dev/dri/renderD128",
    "headless": "1024x768"
}

请记住,窗口的大小仍要与现在的虚拟屏幕大小匹配,因此需要在headless属性中指定大小。也缺少基于vsync的限制。

启用后,应用程序有两种典型选择以无头模式执行屏幕外渲染:

使用一个普通的窗口(例如QOpenGLWindow子类),以该窗口的默认帧缓冲区为目标,这gbm_surface实际上意味着:

MyOpenGLWindow w;
w.show(); // will not actually show up on screen
w.grabFramebuffer().save("output.png");

或带有额外FBO的典型屏幕外方法:

QOffscreenSurface s;
s.setFormat(ctx.format());
s.create();
ctx.makeCurrent(&s);
QOpenGLFramebufferObject fbo(1024, 768);
fbo.bind();
ctx.functions()->glClearColor(1, 0, 0, 1);
ctx.functions()->glClear(GL_COLOR_BUFFER_BIT);
fbo.toImage().save("output.png");
ctx.doneCurrent();

KMS / DRM可以与两种不同的DRM API(旧版原子版)一起使用。DRM原子API的主要好处是允许在同一renderloop中进行多个DRM平面更新,而旧版API每个vsync需要一个平面更新。

当您的应用程序需要将内容混合到叠加层中并将所有更新保持在同一vsync内时,原子API很有用。仍然不是所有的设备都支持此API,在某些较旧的设备上可能不可用。默认情况下,KMS后端将使用旧版API,但是您可以启用DRM原子API,并将QT_QPA_EGLFS_KMS_ATOMIC环境变量设置为1。

使用比屏幕分辨率小的帧缓冲区也很有用。使用DRM原子,可以使用sizeJSON文件中的参数来实现。以下示例在3840x2160视频模式下使用1280x720帧缓冲区:

{
  "device": "/dev/dri/card0",
  "outputs": [
    { "name": "HDMI1", "mode": "3840x2160", "size": "1280x720", "format": "argb8888" }
  ]
}

带有eglfs_kms_egldevice后端的eglfs

该后端通常在Tegra设备上使用,类似于上面提到的KMS / DRM后端,不同之处在于它依赖于EGLDevice和EGLStream扩展而不是GBM。

有关此方法的技术细节,请查看此演示文稿。

从Qt 5.7开始,此后端与基于GBM的后端共享许多内部实现。这意味着支持多个屏幕和高级配置QT_QPA_EGLFS_KMS_CONFIG。某些设置,例如hwcursorpbuffers不适用。

默认情况下,后端将自动为每个输出的默认平面选择正确的EGL层。必要时,可以通过将QT_QPA_EGLFS_LAYER_INDEX环境变量设置为所需图层的索引来覆盖此设置。该方法当前不支持多个输出,因此应仅将其用于具有单个屏幕的系统。要查看可用的层并调试潜在的启动问题,请启用日志记录类别qt.qpa.eglfs.kms

在某些情况下,即使屏幕报告已经设置了所需的分辨率,也可能需要在应用程序启动时执行视频模式设置。通常可以进行优化,但是如果屏幕保持关闭状态,请尝试将环境变量设置为QT_QPA_EGLFS_ALWAYS_SET_MODE非零值,然后重新启动应用程序。

要配置后端使用的EGLStream对象的行为,请使用QT_QPA_EGLFS_STREAM_FIFO_LENGTH环境变量。这假定KHR_stream_fifo目标系统支持。默认情况下,流以邮箱模式运行。要切换到FIFO模式,请将值设置为1或更大。该值指定流可以容纳的最大帧数。

在某些系统上,可能有必要通过预定义的连接器来定位特定的覆盖平面。仅强制通过层索引QT_QPA_EGLFS_LAYER_INDEX不执行平面配置,因此本身不适合。相反,在这种特殊情况下,请使用QT_QPA_EGLFS_KMS_CONNECTOR_INDEXQT_QPA_EGLFS_KMS_PLANE_INDEX环境变量。设置这些选项后,将仅使用指定的连接器和平面,所有其他输出将被忽略。后端将负责挑选与所需平面相对应的EGL层,并对平面进行配置。

KMS / DRM上具有多个屏幕的系统中的触摸输入

在多显示器系统中,触摸屏还需要考虑其他因素,因为触摸事件必须路由到正确的虚拟屏幕,并且这需要在触摸屏和显示输出之间进行正确的映射。

映射是通过上一部分中指定QT_QPA_EGLFS_KMS_CONFIG和描述的JSON配置文件完成的。当数组touchDevice的元素中存在属性时outputs,该值将被视为设备节点,并且触摸设备将与相关的显示输出相关联。

例如,假设我们的触摸屏的设备节点为/ dev / input / event5,并且是集成到显示器中的触摸屏,该显示器通过HDMI作为辅助屏幕连接,则以下配置可确保正确的触摸(和合成鼠标)事件转换:

 {
    "device": "drm-nvdc",
    "outputs": [
      {
        "name": "HDMI1",
        "touchDevice": "/dev/input/event5",
        "virtualIndex": 1
      },
      {
        "name": "DP1",
        "virtualIndex": 0
      }
    ]
}

注意:如有疑问,请QT_LOGGING_RULES=qt.qpa.*=true在启动应用程序之前通过设置环境变量来启用来自图形子系统和输入子系统的日志记录。这将有助于识别正确的输入设备节点,并可能发现可能难以调试的输出配置问题。

注意:从Qt 5.8开始,仅evdevtouch输入后端支持以上功能。其他变体,例如基于libinput的变体,将继续将事件路由到主屏幕。要在有多个输入后端可用的系统上强制使用evdevtouch,请将环境变量设置QT_QPA_EGLFS_NO_LIBINPUT1

带有其他后端的eglfs

其他后端通常基于直接通过供应商的EGL实现定位帧缓冲区或合成API的后端,通常对多个显示器提供有限的支持或不提供支持。在具有Vivante GPU的基于i.MX6的板上,与QT_QPA_EGLFS_FBlinuxfb类似,可以使用环境变量来指定要定位的帧缓冲区。在Raspberry Pi上,QT_QPA_EGLFS_DISPMANX_ID环境变量可用于指定要输出到的屏幕。该值对应于DISPMANX_ID_常量,请参阅Dispmanx文档。请注意,与KMS / DRM不同,这些方法通常不允许从同一应用程序输出到多个屏幕。或者,也可以使用特定于驱动程序的环境变量或内核参数来控制使用的帧缓冲区。请参阅嵌入式板的文档。

显存

在运行基于Qt Quick或QOpenGLWidget之类的Qt应用程序之前,具有固定数量专用视频内存的系统可能需要格外小心。对于这些应用程序,默认设置可能不足,尤其是当它们以高分辨率(例如,全高清)屏幕显示时。在这种情况下,它们可能会以意外的方式开始失败。建议确保至少有128 MB的GPU内存可用。对于没有为GPU保留固定内存量的系统,这不是问题。

linuxfb

使用fbplugin参数指定要使用的帧缓冲设备。

Unix信号处理程序

面向主机平台的插件,像eglfs和linuxfb默认情况下捕获中断(安装信号处理器SIGINT),暂停和继续(SIGTSTPSIGCONT)和终止(SIGTERM)。通过这种方式,键盘,光标终端,以及其他可能的图形状态可以在应用程序终止或被停用由于恢复kill,或Ctrl+CCtrl+Z。(尽管只有在QT_QPA_ENABLE_TERMINAL_KEYBOARD设置时才可以通过键盘终止或挂起,如上面“输入”部分所述)。但是,在某些情况下,捕获SIGINT可能是不希望的,因为它可能与例如远程调试冲突。因此,提供了环境变量QT_QPA_NO_SIGNAL_HANDLER以退出所有内置信号处理。

字型

Qt通常用于fontconfig提供对系统字体的访问。如果fontconfig不可用,则Qt将退回到使用QBasicFontDatabase。在这种情况下,Qt应用程序将在Qt的lib/fonts目录中查找字体。Qt将自动检测预渲染的字体和TrueType字体。可以通过设置QT_QPA_FONTDIR环境变量来覆盖此目录。

有关支持的格式的更多信息,请参见《嵌入式Linux字体的Qt》。

注意: Qt不再在lib/fonts目录中附带任何字体。这意味着由平台(系统映像)提供必要的字体。

嵌入式Linux设备上用于窗口系统的平台插件

XCB

这是在常规桌面Linux平台上使用的X11插件。在某些提供X和xcb必要的开发文件的嵌入式环境中,此插件的功能与在常规PC桌面上一样。

注意:在某些设备上,X下没有EGL和OpenGL支持,因为EGL实现与Xlib不兼容。在这种情况下,XCB插件是在没有EGL支持的情况下构建的,这意味着Qt Quick 2或其他基于OpenGL的应用程序无法与此平台插件一起使用。但是,它仍然可以用于运行软件渲染的应用程序(例如,基于QWidget)。

通常,不建议在嵌入式设备上使用XCB。像eglfs这样的插件可能会提供更好的性能和硬件加速。

韦兰

Wayland是一种轻巧的窗户系统。或更确切地说,它是客户端与显示服务器对话的协议。

Qt Wayland提供了一个wayland平台插件,允许Qt应用程序连接到Wayland合成器。

你可能感兴趣的:(嵌入式Linux的Qt)