Merge branch 'jorth/buffer-exchange' into 'main'

doc: update GPU buffer exchange section

Closes #551

See merge request wayland/wayland!490
This commit is contained in:
Julian Orth 2025-09-16 15:31:25 +02:00
commit 7630779c14

View file

@ -280,65 +280,58 @@
</para>
</section>
<section id="sect-Wayland-Architecture-wayland_hw_enabling">
<title>Hardware Enabling for Wayland</title>
<title>Accelerated GPU Buffer Exchange</title>
<para>
Typically, hardware enabling includes modesetting/display
and EGL/GLES2. On top of that Wayland needs a way to share
buffers efficiently between processes. There are two sides
to that, the client side and the server side.
Clients exchange GPU buffers with the compositor through dma-buf
file descriptors. The linux-dmabuf-v1 protocol is used to turn
one or more dma-buf FDs into a wl_buffer.
</para>
<para>
On the client side we've defined a Wayland EGL platform. In
the EGL model, that consists of the native types
(EGLNativeDisplayType, EGLNativeWindowType and
EGLNativePixmapType) and a way to create those types. In
other words, it's the glue code that binds the EGL stack and
its buffer sharing mechanism to the generic Wayland API. The
EGL stack is expected to provide an implementation of the
Wayland EGL platform. The full API is in the wayland-egl.h
header. The open source implementation in the mesa EGL stack
is in wayland-egl.c and platform_wayland.c.
If the client uses the Vulkan or EGL window-system integration
(WSI), this is done transparently by the WSI.
</para>
<para>
Under the hood, the EGL stack is expected to define a
vendor-specific protocol extension that lets the client side
EGL stack communicate buffer details with the compositor in
order to share buffers. The point of the wayland-egl.h API
is to abstract that away and just let the client create an
EGLSurface for a Wayland surface and start rendering. The
open source stack uses the drm Wayland extension, which lets
the client discover the drm device to use and authenticate
and then share drm (GEM) buffers with the compositor.
Clients can alternatively allocate and import dma-bufs themselves
using the GBM library or Vulkan/OpenGL.
</para>
<itemizedlist>
<listitem>
<para>
Using GBM, the client can allocate a gbm_bo and export one or more
dma-buf FDs from it.
</para>
</listitem>
<listitem>
<para>
Using Vulkan, the client can create a VkDeviceMemory object and use
VK_EXT_external_memory_dma_buf to export a dma-buf FD from it.
</para>
</listitem>
<listitem>
<para>
Using EGL, the client can create an EGLImageKHR and use
EGL_MESA_image_dma_buf_export to export one or more dma-buf FDs from
it.
</para>
</listitem>
</itemizedlist>
<para>
Compositors use VK_EXT_external_memory_dma_buf or EGL_EXT_image_dma_buf_import
to import the dma-bufs provided by the client into their own Vulkan or
EGL renderers.
</para>
<para>
The server side of Wayland is the compositor and core UX for
the vertical, typically integrating task switcher, app
launcher, lock screen in one monolithic application. The
server runs on top of a modesetting API (kernel modesetting,
OpenWF Display or similar) and composites the final UI using
a mix of EGL/GLES2 compositor and hardware overlays if
available. Enabling modesetting, EGL/GLES2 and overlays is
something that should be part of standard hardware bringup.
The extra requirement for Wayland enabling is the
EGL_WL_bind_wayland_display extension that lets the
compositor create an EGLImage from a generic Wayland shared
buffer. It's similar to the EGL_KHR_image_pixmap extension
to create an EGLImage from an X pixmap.
Clients do not need to wait for the GPU to finish rendering before submitting
dma-bufs to the compositor. Clients can use the linux-drm-syncobj-v1 protocol to
exchange DRM synchronization objects with the compositor. These objects are used
to asynchronously signal ownership transfer of buffers from clients to the
compositor and vice versa. The WSIs do this transparently.
</para>
<para>
The extension has a setup step where you have to bind the
EGL display to a Wayland display. Then as the compositor
receives generic Wayland buffers from the clients (typically
when the client calls eglSwapBuffers), it will be able to
pass the struct wl_buffer pointer to eglCreateImageKHR as
the EGLClientBuffer argument and with EGL_WAYLAND_BUFFER_WL
as the target. This will create an EGLImage, which can then
be used by the compositor as a texture or passed to the
modesetting code to use as an overlay plane. Again, this is
implemented by the vendor specific protocol extension, which
on the server side will receive the driver specific details
about the shared buffer and turn that into an EGL image when
the user calls eglCreateImageKHR.
If the linux-drm-syncobj-v1 protocol is not supported by the compositor, clients
and compositors can use the DMA_BUF_IOCTL_EXPORT_SYNC_FILE and
DMA_BUF_IOCTL_IMPORT_SYNC_FILE ioctls to access and create implicit synchronization
barriers.
</para>
</section>
</chapter>