据我所知,Wayland 没有使用 OpenGL,而是使用 OpenGL ES 进行 3D 渲染,通常用于嵌入式系统(Intel IGP 除外)。从长远来看,我了解到 OpenGL 支持将会实现,但目前不是优先事项。
我想这是因为 OpenGL ES 稍微简单一些,但它似乎并不是做出这样选择的一个强点。
我想知道这个决定的原因是什么,以及这个选择的后果是什么(对于 Linux 的未来来说)。
更新:
这韦兰常见问题解答在考虑在这里问之前,这是我的第一站。如果我错了,请随时纠正我,但最后一部分似乎至少不太清楚,恕我直言:
EGL 是唯一可以让我们避免依赖现有窗口系统(特别是 X)的 GL 绑定 API。
据我所知,事情没那么简单。EGL 是 OpenGL 等 GL 之间的接口和OpenGL ES。 OpenGL ES 调用可以直接通过 Wayland/Weston 进行,而 OpenGL 支持需要 XWayland。
GLX 显然引入了 X 依赖项,并且只允许我们在 X 可绘制对象上设置 GL。另一种方法是编写 Wayland 特定的 GL 绑定 API,例如 WaylandGL。
所以,这部分指的是我上面所说的,据我所知,Wayland 开发团队不想采取这条替代路线。因此,目前,愿意移植不直接使用 Wayland/Weston 的应用程序的人们被迫将其 OpenGL API 调用转换为 OpenGL ES 调用。
更微妙的一点是 libGL.so 包含 GLX 符号,因此链接到该库将引入所有 X 依赖项。这意味着我们无法在不拉入 X 客户端的情况下链接到完整的 GL,因此 Weston 使用 OpenGL ES 进行渲染。
至少在短期内,这似乎是可以理解的。不过,从长远来看,Wayland 开发团队也希望添加 OpenGL API,因此对我来说,在事情变得严重之前,这似乎更像是一种解决方法。这是首先引发我的问题的句子之一。
然而,如上所述,客户可以自由使用他们喜欢的任何渲染 API。
如果我没记错的话,这意味着要选择用于 OpenGL 应用程序的 XWayland 和 Weston OpenGL ES,这似乎比这句话所暗示的意义更大,尤其是在 3D 渲染方面,更不用说 Wayland/Weston 的目标了来取代 Xorg.
XWayland 是 X.Org 服务器代码库上的一系列补丁,用于实现在 Wayland 协议上运行的 X 服务器。这些补丁由 Wayland 开发人员开发和维护,以便在过渡到 Wayland 期间与 X11 应用程序兼容,[28] 并在 2014 年的 X.Org Server 版本 1.16 中主流化。当用户从 Weston 内运行 X 应用程序时,它要求 XWayland 满足该请求。
注意:我正在尝试了解有关 Wayland/Weston 的更多信息,特别是在(3D)渲染方面,但很难找到有关此主题的确切信息,特别是因为似乎唯一真正精通 X11 的人似乎是 Wayland开发商。
据我目前所知,对于 OpenGL:
- 如果 OpenGL 函数调用是通过 GLX 接口进行的,则它会回退到 XWayland,因此该程序(确实)不使用 Wayland。
附录
看起来讨论超出了原始问题的范围,但它实际上与底层 OpenGL 接口/库相关,并且很难将所有这些与原始问题分开。
由于这似乎是一个复杂且令人困惑的主题,这里有一些不同的链接和引用,使我认为 OpenGL(不是 ES)不是真的由 Wayland 本身支持,但通过 XWayland 回落到 X11:
图中的 Wayland 服务器是带有 DRM 后端的 Weston。服务器 > 使用 GL ES 2 进行渲染,并通过调用 EGL 对其进行初始化。
Wayland实际上相当稳定。 Nvidia 在 Xwayland 中的 OpenGL 有问题(即 x11 应用程序的 3d accel),否则,它应该可以工作。不过,使用 Wayland 时也存在一些缺陷。当使用缩放(也不必是小数)时,X11 应用程序会放大而不是缩小,从而导致模糊。不幸的是,Firefox 和 Chrome 本身都不支持 Wayland,谁想在计算机上以模糊模式使用最常用的应用程序呢?
为什么基于 GLX 的应用程序可以在 Ubuntu 上的 Wayland 上运行?
因此,根据 @genpfault 提供的链接:
因此,根据 @genpfault 提供的链接:
- XWayland 是 XOrg 的一部分,它在 Wayland 之上提供 X 服务器。任何与 X11 库链接并在 Wayland 下运行的应用程序都会自动使用 XWayland 作为其后端。所以XWayland的GLX部分是允许基于GLX的OpenGL应用程序在Wayland上运行的机制。
- 无法在基于 GLX 的应用程序中使用 MSAA 似乎是 XWayland 的一个已知错误,至少对于 Intel 和 AMD GPU 而言(参见 https://bugs.freedesktop.org/show_bug.cgi?id=98272)。但我找不到有关此事的任何其他信息。
答案1
你的问题的前提是错误的。 Wayland 根本不使用 OpenGL ES 或 OpenGL。让我们了解一下,以便正确理解软件堆栈:
Wayland 是一种 IPC 协议,允许客户端和合成器相互通信。虽然从技术上讲,libwayland 只是该协议的单个实现,不应将其单独识别,但目前它仍然是唯一的实现,并且通常也称为“wayland”。它不是运行您的硬件的完整合成器。
Wayland Compositor 是一个应用程序,它使用 wayland 协议从客户端接收缓冲区并将其组合成显示屏上显示的单个图像。 Wayland 协议对合成器本身的内部工作原理做出相对较少的假设。特别是,渲染技术的选择是完全开放的。核心协议定义的默认缓冲区类型是简单的共享内存缓冲区,GPU 不会以任何方式加速,主要适用于仅使用 CPU 渲染 UI 的简单应用程序。在我们的例子中,这种缓冲区类型并不有趣,并且在答案的其余部分中很容易被遗忘。
Weston 是 Wayland 合成器的参考实现。虽然它是由参与 libwayland 本身开发的人员开发的,但它并不是 wayland 生态系统的重要组成部分 - 它只是一个单一的合成器实现。如果您正在运行任何包含 Wayland 桌面环境的 Linux 发行版,那么几乎可以肯定您使用的不是 Weston,而是其他一些合成器实现。 Weston 使用 OpenGL ES 进行渲染 - 这主要是由于当前的 libGL 实现仍然链接到一些 X 相关库,而 Weston 创建者希望保持其纯粹的 wayland - 毕竟这是一个参考实现。此外,它还使其与可能不支持完整 OpenGL 的嵌入式设备兼容。
EGL - libEGL 是一个包含胶水代码的库,允许初始化多种渲染上下文(不同版本的 OpenGL、OpenGL ES 或 OpenVG)。它还允许在此类上下文之间共享数据 - 即它允许传递使用 OpenGL 渲染的帧缓冲区并将其传递给 OpenVG 进行进一步处理。这些资源的共享可以跨进程边界进行——资源的接收者可能是与创建它的进程不同的应用程序。对共享资源(缓冲区)的引用可以通过多种方式在进程之间传递,例如通过兼容的 Wayland IPC 连接。以这种方式传递的缓冲区(EGL 图像)不会保留对用于获取它的渲染 API 的任何引用。虽然据称 EGL 层还负责将帧缓冲区绑定到底层操作系统元素(如窗口或显示器),但实际上这意味着与某些系统进程共享缓冲区,这些系统进程可以使用它来将其绘制在窗口或特定的窗口上。展示。因此,它只是上述功能的变体,而不是单独的功能。 libEGL 具有很强的可扩展性,并且有大量可用的扩展,因此您的 libEGL 实现可能还负责其他不符合上述描述的任务。
GLX - EGL 的较旧且更有限的变体。它允许共享各种类型的缓冲区,但仅限于 X11 客户端和 X11 服务器之间。它本质上与 X11 协议相关 - 如果客户端应用程序使用 X11 协议,它也可以使用 GLX。如果它使用 Wayland 协议,则不能。 EGL 是作为其替代品而开发的,以允许更广泛地共享此类数据。现代 X11 服务器也允许客户端使用 EGL 而不是 GLX。
所以wayland技术并不要求你使用OpenGL ES,甚至也没有模糊地指出它的方向。参考合成器 Weston 使用它在内部,但这对客户端渲染 API 没有影响。唯一的要求是无论您渲染什么都可以转换为 EGL 图像。由于这是 libEGL 的工作,因此客户端渲染 API 的选择仅取决于 libEGL 实现的限制。对于其他可能使用或不使用 OpenGL ES 渲染最终桌面图像的合成器来说也是如此。
libEGL 是 GPU 驱动程序软件的一部分(就像 libGL 一样),因此它是否允许将 OpenGL 缓冲区转换为 EGL 图像(以及随后在合成器端将 EGL 图像转换为 OpenGL ES 纹理)取决于您的硬件,但实际上几乎所有硬件都允许这样做,只要它支持完整的 OpenGL。这就是为什么你很难找到 Wayland 支持完整 OpenGL 的明确证据——wayland 根本不关心渲染技术。正如常见问题解答所说:
绘图API是什么?
“无论你想要什么,亲爱的”[...]
因此,是否支持OpenGL的问题超出了wayland的范围。它实际上仅由 libEGL 和硬件的功能决定。
客户端应用程序必须使用特定的 API 才能初始化其窗口和 GL(ES) 上下文。如果客户端应用程序使用 X11 API 创建其窗口,那么它将连接到 XWayland 兼容性 shim,该 shim 伪装成客户端的完整 X11 服务器。然后客户端将能够使用 GLX 或 EGL-on-X11 来初始化其上下文并与 X11 服务器共享渲染缓冲区。如果客户端使用 Wayland 客户端 API 创建其窗口,它将能够使用 EGL-on-wayland 来初始化其上下文并与 Wayland 合成器共享渲染缓冲区。大多数情况下这个选择在于完全在客户端。
许多不支持 Wayland 的旧软件仅使用 X11 API 和 GLX - 仅仅是因为 Wayland 和 EGL API 在开发过程中不存在(或不够成熟)。出于兼容性原因,更现代的软件通常只使用 X11 API - 仍然有相当多的非 Wayland 系统。 GTK 或 QT 等现代 UI 工具包实际上支持多个“后端”,这意味着它们可以在初始化时检测会话类型,并使用最合适的 API 来创建窗口和绘图上下文。由于游戏通常不使用此类工具包,因此此类检测的负担完全落在其开发人员身上。没有多少像这样的项目会费心实际实现它,并且他们通常在 X11 和 wayland 会话(通过 Xwayland)上依赖 X11 和 GLX 协议。所以如果你有一个游戏使用GLX来初始化OpenGL意味着它选择了使用X11 API。这是因为游戏根本不支持 Wayland 或 EGL,还是游戏尝试使用 EGL 初始化 OpenGL 但由于某种原因失败,如果没有大量附加信息,我无法判断。无论如何,它不以任何方式依赖于 Wayland 协议或所使用的合成器。
答案2
从https://wayland.freedesktop.org/faq.html:
Wayland 为什么使用 EGL?
EGL 是唯一可以让我们避免对现有窗口系统(特别是 X)的依赖的 GL 绑定 API。GLX 显然引入了 X 依赖项,并且只允许我们在 X 可绘制对象上设置 GL。另一种方法是编写 Wayland 特定的 GL 绑定 API,例如 WaylandGL。
更微妙的一点是 libGL.so 包含 GLX 符号,因此链接到该库将引入所有 X 依赖项。这意味着我们无法在不拉入 X 客户端的情况下链接到完整的 GL,因此 Weston 使用 OpenGL ES 进行渲染。这也使得 Weston 能够在不支持完整 OpenGL API 的 GPU 上运行。
然而,如上所述,客户可以自由使用他们喜欢的任何渲染 API。
答案3
我认为,如果您愿意相信所有这些文档(其中一些文档在其他答案中引用),那么它们的全部内容就足够清晰了。我承认……有时这种策略会产生不可靠的结果 :-)。所以这是您的“确凿证据”。
网页搜索[wayland opengl egl]:“使用存储库中的 weston 合成器,在我的 X 版 Debian 稳定版机器上完美运行”。
根据我的评论,这是我建议您运行的命令:
$ git clone https://github.com/eyelash/tutorials/
cloning into 'tutorials'...
remote: Enumerating objects: 88, done.
remote: Total 88 (delta 0), reused 0 (delta 0), pack-reused 88
Unpacking objects: 100% (88/88), done.
$ cd tutorials
$ gcc -o wayland-egl wayland-egl.c -lwayland-client -lwayland-egl -lEGL -lGL
$ ./wayland-egl & # a green square appears! $ ss --unix -a -p | grep wayland-egl u_str ESTAB 0 0 * 3920430 * 3921234 users:(("wayland-egl",pid=3260,fd=3)) $ ss --unix -a -p | grep 3921234 u_str ESTAB 0 0 /run/user/1001/wayland-0 3921234 * 3920430 users:(("gnome-shell",pid=2271,fd=100),("gnome-shell",pid=2271,fd=20)) u_str ESTAB 0 0 * 3920430 * 3921234 users:(("wayland-egl",pid=3260,fd=3))
此代码使用 Wayland 协议与合成器共享其渲染缓冲区gnome-shell
。并使用OpenGL进行渲染。该程序绝对不可能使用 XWayland 服务器进程、X11 协议或 OpenGL ES (GLES) API 运行。我认为这没有任何疑问。
测试的目的ss
是证明wayland-egl
未连接到由 XWayland 进程提供服务的 X11 协议套接字。 (进程=正在运行的程序)。 XWayland 服务器是一个与 gnome-shell 或 weston 完全独立的进程。 weston 根本不讲 X11 协议。 XWayland 确实如此。
对比:
$ glxgears >/dev/null 2>&1 & # spinning gears appear! $ ss --unix -a -p | grep glxgears u_str ESTAB 0 0 * 3924917 * 3922619 users:(("glxgears",pid=3310,fd=3)) $ ss --unix -a -p | grep 3922619 u_str ESTAB 0 0 * 3924917 * 3922619 users:(("glxgears",pid=3310,fd=3)) u_str ESTAB 0 0 @/tmp/.X11-unix/X0 3922619 * 3924917 users:(("Xwayland",pid=2307,fd=14))
另外,如果你设置了DISPLAY=:666
,你会发现它wayland-egl
仍然可以运行。而xterm
、 或glxgears
,需要 X11 服务器,并且设置虚假的显示号码将阻止它们运行。 DISPLAY
是所有 X11 客户端使用的标准环境变量,用于了解要连接到哪个显示器编号。
答案4
tl;博士回答:
EGL != OpenGL ES
EGL 是一个管理渲染缓冲区的库。
OpenGL、OpenGL ES 或 OpenVG 等 API 可以直接渲染到这些渲染缓冲区中。
为什么 Wayland 使用 EGL 而不是自己的渲染缓冲区管理?
实际上 Wayland 有它自己的渲染缓冲区 ( wl_buffer
),但内部结构取决于实现,并且出于性能原因,Wayland 允许客户端直接渲染到 GPU 帧缓冲区,在直接渲染模式下,需要一个渲染缓冲区模型来允许直接渲染到屏幕,但同时在进程之间共享渲染缓冲区,并且这两种情况都可以通过 EGL 实现,EGL 已经存在并且得到了很好的支持,那么为什么 Wayland 不使用它呢?
那么 Wayland 并不总是使用 EGL?
Wayland 客户端不会在间接渲染模式下使用 EGL。也就是说,客户端不直接渲染到屏幕,而是渲染到共享内存缓冲区(在客户端和合成器之间共享)。然而,合成器仍然可以使用 EGL 将该缓冲区的内容渲染到屏幕上。此外,当使用 Vulkan API 时,不涉及 EGL,因为 Vulkan 不会渲染到 EGL 缓冲区。 Vulkan 可以使用扩展直接渲染到 Wayland 表面VK_KHR_wayland_surface
(它可能以某种方式在幕后使用 EGL,但这不关你的事)。