【Qt,OpenGL, RHI,Wayland 等概念梳理】

1. glxinfo 与 eglinfo 命令有什么关系

工具 接口层 运行环境(显示系统) 典型场景
glxinfo GLX (OpenGL + 强绑定X11) X11(老牌窗口系统依赖GLX) 传统桌面(PC / Xorg)
eglinfo EGL (窗口系统无关接口) Wayland / DRM / FB / X11 嵌入式 / Wayland / 无窗口系统
  • glxinfo 用于测试 GLX + OpenGL(桌面GL),glxinfo | grep -E 'vendor|OpenGL|llvmpipe输出 vendor: Mesa / llvmpipe → 结论:GLX → software rendering(CPU)。
  • eglinfo 用于测试 EGL 实现 + GLES(OpenGL ES) 驱动,eglinfo | grep -E 'vendor|OpenGL输出 OpenGL ES vendor: Vivante → 结论:EGL → Vivante GPU(真硬件)

2. OpenGL ,GLX与EGL什么关系?

  • OpenGL 是跨平台图形渲染API,只负责画出2D/3D图形,通过调用如glDrawArrays(...) glBindTexture(...)等接口,可以实现画三角,贴纹理等。但他本身不知道画完该显示到哪个拆给你看,不懂如何处理键盘鼠标等系统事件。

  • GLX 和 EGL 是接口,OpenGL与OpenGL ES是渲染API。前者为后者在显示平台上创建上下文环境。

  • GLX → 只能配 OpenGL(桌面GL)渲染到X11。

  • EGL → 可以配:OpenGL ES(主流嵌入式)或 OpenGL(桌面也支持)渲染到跨平台(Wayland / DRM / X11)。

  • GLX 是一套API规范(接口标准),只负责给 X11 窗口提供 OpenGL 上下文和帧缓冲交换。glx 有接口函数如:glXCreateContext() glXSwapBuffers()

  • EGL 是比 GLX 新的一套API规范,eglCreateContext() eglSwapBuffers(),相比于GLX 是 X11 专用版本,而EGL 是跨平台通用版本。EGL 本身只是一份由 Khronos Group 维护的 API 规范(标准)。在 Linux 下,具体的实现(也就是 .so 动态链接库)确实是由各硬件厂商或开源社区提供的。比如 NVIDIA 提供专有的 libEGL_nvidia.so,AMD/Intel 依赖开源的 Mesa (libEGL_mesa.so)。它们对外的函数签名完全一致,但底层的 GPU 指令翻译完全不同。

  • 在实际代码中,GLX/EGL 与 OpenGL 的API函数绝对是混着用的,是分工协作的平行关系 。GLX/EGL 负责"搭舞台和建画室这些山下文基础设置(初始化)",OpenGL 负责"在舞台上画画(渲染)。EGL/GLX 负责生命周期管理:创建/销毁上下文、绑定窗口、同步帧率(V-Sync)、交换前后缓冲区。OpenGL 负责纯图形计算:顶点处理、着色器执行、光栅化。

    EGL / GLX(接口层)

    Wayland / X11 / DRM / FB(显示系统)

    GPU Driver / Kernel

名称
X11(显示系统) 老牌窗口系统,架构复杂,依赖 GLX X11有两种客户端库:Xlib 与 xcb ,他们是用来访问 X11 的工具 GLX → 更常搭配 Xlib,EGL → 可以搭配 XCB
Xwayland "运行在 Wayland 上的迷你 X11 服务器,给只能识别x11的老程序用。
Wayland(协议) X11 的替代品,简单,compositor(合成器)直接控制显示。( Wayland 是协议(protocol),weston / mutter / kwin 是实现(compositor))
DRM(内核层) Linux 内核里的显示/显卡驱动层,不提供窗口系统,用户态通过 libdrm / gbm 使用,没有 DRM,就没有 GPU 显示
FB 最原始的显示方式(/dev/fb0),直接把像素写进一块内存,简单性能差,基本被 DRM 替代

如何看我当前的显示系统使用的X11还是Wayland还是DRM,有没有可能他们三个共存?

情况 说明
$DISPLAY 有值(如 :0) ✅ X11
$WAYLAND_DISPLAY 有值 ✅ Wayland
两个都没有 ✅ DRM/GBM(无窗口系统

2.1 如何证明我支持哪种平台?

2.1.1 验证 Wayland 能力(平台级)

复制代码
echo $WAYLAND_DISPLAY # 看看有没有
unset DISPLAY # 阻断客户端直连 Xwayland的路径,只能走 Wayland
glmark2-es2-wayland # 展示3D渲染的马

成功显示:✅ 证明:Wayland + EGL + GPU 全链路 OK

2.1.2 验证 X11 能力(通过 Xwayland)

目标:证明板子能运行 X11 client

bash 复制代码
apt install x11-apps
root@imx8mpfrdm:~# echo $WAYLAND_DISPLAY
wayland-0
root@imx8mpfrdm:~# unset WAYLAND_DISPLAY   # 切断"客户端直连 Wayland"的路径,并没有关闭 Wayland(weston 仍在运行)
root@imx8mpfrdm:~# echo $WAYLAND_DISPLAY

root@imx8mpfrdm:~# ls /tmp/.X11-unix/
X0
root@imx8mpfrdm:~# xdpyinfo | grep version
version number:    11.0
X.Org version: 24.1.6
root@imx8mpfrdm:~# xeyes  # 成功弹出眼睛框框

成功显示:X11 socket + server 完整可用(Xwayland)

结论:我的程序支持:

  • 能跑 X11(走 Xwayland)
  • 能跑 Wayland(直接)
  • 能跑 DRM(纯嵌入式)

3. OpenGL 与 RHI 什么关系?

OpenGL 是什么?跨平台图形渲染API,只负责 "如何画图形" (顶点处理、着色器执行、纹理映射等)。但OpenGL是第一代高级抽象 API(1992 年诞生),Vulkan 和 Metal 属于第二代低开销 API(2014--2015 年推出),它们通过 更低的 CPU 开销 和 更精细的 GPU 控制 解决了 OpenGL 的固有瓶颈,OpenGL正在逐步被Vulkan 和 Metal取代。

RHI 是什么?Qt6 引入的位于Qt的内部抽象层,他将OpenGL/Vulkan/Metal 等图形 API做了封装,最终让Qt场景图无需关心底层用的是 OpenGL 还是 Vulkan,而自动选择最优后端。(Windows → 默认 Direct3D 12 ;macOS/iOS → 默认 Metal ;Linux/Android → 默认 Vulkan )在 Qt6中通过环境变量**QT_QUICK_BACKEND**来设置支持哪种渲染策略。只有个有效值,①默认设置为rhi,启用 RHI 渲染,由 RHI 选择具体图形 API。②software,纯 CPU 软件渲染(无 GPU 加速),性能极低,仅用于调试或无 GPU 环境。

RHI 的本质作用

  • Qt 内部的"翻译层"
    • 当你用 QML 写 Rectangle { color: "blue" } 时,Qt 的场景图会生成渲染指令,但不直接调用 OpenGL
    • RHI 会自动将这些指令翻译成 OpenGL/Vulkan/Metal 的调用,开发者无需修改代码。
  • 核心价值
    • 解耦 Qt 与图形 API:Qt 6 不再硬编码依赖 OpenGL(Apple 已废弃它),而是通过 RHI 无缝切换 Vulkan/Metal。
    • 统一资源管理:RHI 封装了 GPU 资源(纹理/缓冲区)的创建/释放逻辑,避免 OpenGL 的状态机陷阱。

#mermaid-svg-swgs9XDuDuoPBBa4{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-swgs9XDuDuoPBBa4 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-swgs9XDuDuoPBBa4 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-swgs9XDuDuoPBBa4 .error-icon{fill:#552222;}#mermaid-svg-swgs9XDuDuoPBBa4 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-swgs9XDuDuoPBBa4 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-swgs9XDuDuoPBBa4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-swgs9XDuDuoPBBa4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-swgs9XDuDuoPBBa4 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-swgs9XDuDuoPBBa4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-swgs9XDuDuoPBBa4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-swgs9XDuDuoPBBa4 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-swgs9XDuDuoPBBa4 .marker.cross{stroke:#333333;}#mermaid-svg-swgs9XDuDuoPBBa4 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-swgs9XDuDuoPBBa4 p{margin:0;}#mermaid-svg-swgs9XDuDuoPBBa4 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-swgs9XDuDuoPBBa4 .cluster-label text{fill:#333;}#mermaid-svg-swgs9XDuDuoPBBa4 .cluster-label span{color:#333;}#mermaid-svg-swgs9XDuDuoPBBa4 .cluster-label span p{background-color:transparent;}#mermaid-svg-swgs9XDuDuoPBBa4 .label text,#mermaid-svg-swgs9XDuDuoPBBa4 span{fill:#333;color:#333;}#mermaid-svg-swgs9XDuDuoPBBa4 .node rect,#mermaid-svg-swgs9XDuDuoPBBa4 .node circle,#mermaid-svg-swgs9XDuDuoPBBa4 .node ellipse,#mermaid-svg-swgs9XDuDuoPBBa4 .node polygon,#mermaid-svg-swgs9XDuDuoPBBa4 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-swgs9XDuDuoPBBa4 .rough-node .label text,#mermaid-svg-swgs9XDuDuoPBBa4 .node .label text,#mermaid-svg-swgs9XDuDuoPBBa4 .image-shape .label,#mermaid-svg-swgs9XDuDuoPBBa4 .icon-shape .label{text-anchor:middle;}#mermaid-svg-swgs9XDuDuoPBBa4 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-swgs9XDuDuoPBBa4 .rough-node .label,#mermaid-svg-swgs9XDuDuoPBBa4 .node .label,#mermaid-svg-swgs9XDuDuoPBBa4 .image-shape .label,#mermaid-svg-swgs9XDuDuoPBBa4 .icon-shape .label{text-align:center;}#mermaid-svg-swgs9XDuDuoPBBa4 .node.clickable{cursor:pointer;}#mermaid-svg-swgs9XDuDuoPBBa4 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-swgs9XDuDuoPBBa4 .arrowheadPath{fill:#333333;}#mermaid-svg-swgs9XDuDuoPBBa4 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-swgs9XDuDuoPBBa4 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-swgs9XDuDuoPBBa4 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-swgs9XDuDuoPBBa4 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-swgs9XDuDuoPBBa4 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-swgs9XDuDuoPBBa4 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-swgs9XDuDuoPBBa4 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-swgs9XDuDuoPBBa4 .cluster text{fill:#333;}#mermaid-svg-swgs9XDuDuoPBBa4 .cluster span{color:#333;}#mermaid-svg-swgs9XDuDuoPBBa4 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-swgs9XDuDuoPBBa4 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-swgs9XDuDuoPBBa4 rect.text{fill:none;stroke-width:0;}#mermaid-svg-swgs9XDuDuoPBBa4 .icon-shape,#mermaid-svg-swgs9XDuDuoPBBa4 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-swgs9XDuDuoPBBa4 .icon-shape p,#mermaid-svg-swgs9XDuDuoPBBa4 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-swgs9XDuDuoPBBa4 .icon-shape .label rect,#mermaid-svg-swgs9XDuDuoPBBa4 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-swgs9XDuDuoPBBa4 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-swgs9XDuDuoPBBa4 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-swgs9XDuDuoPBBa4 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} QML 代码
Qt Quick
场景图 QSGNode 树
RHI 渲染指令
QPA 平台插件
XCB / X11
Wayland
EGLFS
OpenGL/Vulkan surface
GPU 驱动

QT_QUICK_BACKEND 是RHI 模式时,可以通过 QSG_RHI_BACKEND 指定RHI 使用的具体图形 API:

适用平台 说明
vulkan Linux/Android/Windows 启用 Vulkan 后端
metal macOS/iOS 启用 Metal 后端
d3d11 Windows 启用 Direct3D 11 后端
d3d12 Windows 启用 Direct3D 12 后端
opengl 不推荐 启用 OpenGL 后端(仅当 Vulkan/Metal 不可用时回退)

RHI 与窗口系统是平行协作关系

  • RHI 负责 "画什么"(渲染指令)。
  • QPA(XCB/Wayland/EGLFS)负责 "画到哪"(提供渲染目标)。

更换窗口系统不影响 RHI 工作

  • 在 Wayland 上运行 Qt Quick 应用时,RHI 仍会默认使用 Vulkan(Linux)或 Metal(macOS),不行会回退到OpenGL。
  • 在 EGLFS(嵌入式无窗口系统)上,RHI 通过 EGL 直接与 GPU 交互,无需 X11/Wayland

3.1 Qt 会选择 EGL 还是 GLX?

这个问题本身就有毛病,Qt不会自动选择,如果设置了Qt为RHI模式,RHI负责自动选择渲染后端。

Qt图形路径分三层决策:① 选择 QPA 平台插件(决定窗口系统)② 在该平台插件下选择 GL backend(GLX / EGL)③ 创建 OpenGL / GLES 上下文。下面我们看每一步分别怎么做的。

3.1.1 第一步:QPA 平台插件如何选择

QPA = Qt Platform Abstraction ,本质是Qt和操作系统/窗口系统之间的适配层,常见 QPA 插件包括:

插件 对应系统
wayland Wayland compositor(weston)
xcb X11 / Xwayland
eglfs( eglfs = Qt + EGL + DRM 的"直出模式") 直接 DRM/KMS(不经过窗口系统)
linuxfb framebuffer
自动检测 优先 Wayland(若 WAYLAND_DISPLAY 存在且插件可用),否则回退 X11

优先级如下(Qt 只有在 qtwayland 插件可用且初始化成功 时才会走 Wayland;否则仍可能走 xcb(含 Xwayland)):

复制代码
1. QT_QPA_PLATFORM(环境变量)如:QT_QPA_PLATFORM=wayland  QT_QPA_PLATFORM=xcb
2. QApplication 参数 -platform 如:./my_qt_app -platform wayland ./my_qt_app -platform xcb
3. 编译默认 / 自动检测(自动加载策略:Wayland > X11)

3.1.2 第二步:QPA 插件内部决定 EGL/GLX(非 RHI 决策)

当设置QT_QUICK_BACKEND=rhi时,RHI 不参与 EGL/GLX 选择 ,这是 QPA 插件的内部实现细节。 仅当 RHI 选择 OpenGL 作为后端时 ,QPA 插件才会调用 EGL/GLX。若 RHI 选择 Vulkan,则完全跳过 EGL/GLX(直接使用 Vulkan WSI)。

QPA 平台插件 窗口系统 必须使用的窗口集成层 原因
wayland Wayland EGL Wayland 协议强制要求 EGL 创建 OpenGL 上下文(无 GLX 选项)。
xcb X11/Xwayland GLX(默认)或 EGL X11 历史兼容 GLX;可通过 QT_XCB_GL_INTEGRATION=xcb_egl 强制 EGL。
eglfs DRM/KMS 直出 EGL 无窗口系统,直接通过 EGL 绑定 DRM(无 GLX 可能)。

GBM是通用缓冲区管理器,GBM是用户态分配GPU/显示buffer的库。是EGL的下游工具库(libgbm.so 等等),跟Wayland不属于同一层。GBM就做一件事:分配显卡能用的 buffer。在 无 X11 无 Wayland的时候,可以选择 EGL+GBM+DRM 的模式。所以引出了两种模式(只有两种吗?):

  • 模式1:EGL → GBM(管buffer)→ DRM

  • 模式2:EGL → Wayland(weston) → compositor(管buffer)→ DRM

    Wayland:定义"怎么说话"
    compositor:负责"干活显示"
    GBM:负责"分配显存buffer"
    EGL:负责"OpenGL上下文"

相关推荐
小短腿的代码世界5 小时前
Qt对象树析构链与智能指针协同:零泄漏内存管理架构
开发语言·qt·架构
小庞在加油5 小时前
从qmake到CMake+VSCode:Qt项目现代化迁移与AI提效实战指南
vscode·qt·ai·ai工具
小短腿的代码世界6 小时前
Qt定时器高精度架构:从QTimer源码到纳秒级定时调度
数据库·qt·架构
尘中远7 小时前
Qt高性能绘图库QIm——实现二维三维科学绘图
开发语言·qt·信息可视化
人还是要有梦想的9 小时前
QT qml布局讲解
qt·布局·qml
小短腿的代码世界9 小时前
Qt交易系统审计日志与合规追踪引擎:从零构建金融级不可篡改日志架构
qt·金融·架构
sycmancia9 小时前
Qt——自定义模型类
开发语言·qt
郝学胜-神的一滴10 小时前
Qt 高级开发 031:QListWidget图标布局实战
开发语言·c++·qt·程序人生·软件构建·用户界面
艾莉丝努力练剑10 小时前
【Qt】界面优化:绘图API
linux·运维·开发语言·网络·qt·tcp/ip·udp