Wayland Window System

Wayland is a protocol that a backend compositor uses to communicate with its clients. It is also a C library implementation of that protocol. Weston is the reference implementation of the Wayland compositor. The platform supports Wayland and Weston. Check the Release Notes for specific versions supported.
For more information about Wayland, see the Wayland home page and documentation page at:

EGLOutput/EGLDevice Specifications

NVIDIA defines extensions to enumerate and control devices and screens through EGL. These are collectively referred to as EGLOutput/EGLDevice.
The EGLOutput/EGLDevice specifications used by Weston are as follows:
Extension
Link
EGL_EXT_device_base—Allows the initialization of EGL displays directly on top of native GPU or device objects.
EGL_EXT_device_drm—Allows mapping of device between EGL and DRM/KMS.
EGL_EXT_output_base—Allows rendering to be directed to a screens or display outputs.
EGL_EXT_output_drm— Allows mapping of output handles between EGL and DRM/KMS.
EGL_EXT_stream_consumer_egloutput— Allows the binding of EGLOutputLayerEXTs as stream consumers.
EGL_KHR_stream_consumer_gltexture— Allows an OpenGL(ES) texture to be connected to an EGLStream as its consumer.
The Weston compositor uses EGLOutput/EGLDevice to display the composited Weston desktop or individual Wayland applications on a physical display device.

Runtime Configuration

The platform provides utilities for changing the configuration and runtime parameters.
Note:
For binary and library paths, Ubuntu root filesystem is assumed in the following sections. Other root filesystems (e.g., Yocto) may have different binary and library paths.
The full source code to the NVIDIA implementation of Weston is in:
drive-t186ref-linux/samples/wayland/weston
The NVIDIA implementation of Weston uses the Direct Rendering Manager (DRM) backend, found in the target filesystem at:
/usr/local/lib/weston/drm-backend.so
There are two implementations of the DRM display backend. One is implemented on the Linux KMS. The other is implemented on top of the EGLOutput series of extensions.
During the Weston startup, Weston creates an OpenGL ES EGLStream producer, if option use-egldevice is enabled. Weston then creates EGLOutput. EGLOutput is the EGLStream consumer that passes all the output frames from Weston to the display, For more information, see EGLOutput Specifications. If use-egldevice is not enabled, the output method switches to drm/kms.Wayland buffer sharing between EGL clients and Weston is implemented using EGLStreams. The EGL client creates an EGLStream producer and binds the EGLStream file descriptor to wl_buffer through the Wayland protocol. Weston queries the EGLStream file descriptor from wl_buffer through a query of EGL_WAYLAND_BUFFER_WL to eglQueryWaylandBufferWL(). This functionality is provided by the EGL_WL_bind_wayland_display extension.
Wayland buffer sharing also supports dma-buf sharing based on the linux-dmabuf-unstable-v1-protocol protocol. For more information, see Weston dma-buf Support.
The NVIDIA EGL implementation tries to detect what platform it is running on at runtime (e.g., Wayland, etc.). It is possible to bypass this detection by setting the EGL_PLATFORM environment variable. For Wayland, this variable must be set to "wayland". And do not set the environment variable DISPLAY in case of the wayland platform. If DISPLAY is set, you are assumed to be running X11.

libdrm Support

The libdrm.so library is used to set display modes and to attach framebuffer images to display overlays. The platform custom implementation of libdrm.so is not implemented on top of the DRM-KMS display driver. Instead, it is implemented on top of the NVIDIA NVDC display driver.
Weston requires the NVIDIA custom libdrm.so and is not compatible with the default Ubuntu libdrm.so.
The default Ubuntu libdrm libraries are located at:
/usr/lib/aarch64-linux-gnu/libdrm.so*
The SDK installation deletes those libraries and replaces them with libdrm.so at:
/usr/lib/libdrm.so
When installing 3rd party packages or new software with apt-get, you must make sure that libdrm.so* shared objects are not recreated. If they exist, remove them from:
/usr/lib/aarch64-linux-gnu/

DRM backend

Supported renderers

WESTON_DRM_BACKEND_RENDERER_PIXMAN
Software rendering in composition.
WESTON_DRM_BACKEND_RENDERER_HAL
Use VIC and GPU in composition. It is not available on automotive platforms.
WESTON_DRM_BACKEND_RENDERER_GL
Use EGL/OpenGL in composition.

Supported Output methods

DRM_OUTPUT_METHOD_EGLSTREAM
Use EGLOutput. EGLOutput is the EGLStream consumer that passes all the output frames from Weston to the display. For more information, see EGLOutput Specifications.
DRM_OUTPUT_METHOD_GBMSURFACE
Default output method. If not enabled, use-egldevice.
DRM_OUTPUT_METHOD_SWAPCHAIN
Internal maintained framebuffer swapchain if EGL does not support platform_gbm.

Weston Common Options

Weston supports multiple backends. This section describes the core options that all Weston backends support.
Command
Parameter(s)
Description
--version
N/A
Prints the Weston version.
-B, --backend
drm-backend.so
eglstream-backend.so (for cross partition use cases)
Specifies the backend module. Defaults to drm-backend.so.
Usage: --backend=<module>, where module is one of the parameters.
--shell
desktop-shell.so
ivi-shell.so
Specifies the shell module. Defaults to desktop-sheel.so.
Usage: --shell=<module>, where module is one of the parameters.
-S, --socket
<socket name>
Listens to the specified socket name.
Usage: --socket=<socket name>for applications.
-i, --idle-time
<seconds>
Specifies the idle time in seconds.
--log
<file name>
Displays the log for the given file.
Usage: --log=<file name>
-h, --help
N/A
Displays the help message.

Weston Backend Options

Weston supports multiple backends and, depending on the backend used, accepts different options. NVIDIA supports drm-backend.so, which allows Weston to support NVIDIA graphics.
drm-backend.so options
The supported drm-backend.so options and the values they consume are as follows.
Command
Parameter(s)
Description
--seat
<SEAT>
The seat that weston should run on, instead of the seat defined in XDG_SEAT
--tty
<TTY>
Select which tty to use
--drm-device
<CARD>
The DRM device to use, e.g. "card0".
--use-pixman
N/A
Use the pixman (CPU) renderer
--use-hal
N/A
Use the HAL renderer
--use-egldevice
N/A
Use the EGLDevice and EGLOutput with GL render
--current-mode
N/A
Specifies that current DRM mode is preferred over EDID mode. If the display is already turned on by any DRM application other than Weston, Weston uses the current DRM mode instead of a new display mode from the monitor EDID.

Weston Configuration File Location

Weston uses a configuration file called weston.ini for its setup. When Weston starts, it will search for the weston.ini configuration file in one of the following places:
If $XDG_CONFIG_HOME is set, Weston searches in:
$XDG_CONFIG_HOME/weston.ini
If $HOME is set, Weston searches in:
$HOME/.config/weston.ini
If $XDG_CONFIG_DIRS is set, Weston searches in:
$XDG_CONFIG_DIR/weston/weston.ini
If $XDG_CONFIG_DIRS is not set, Weston searches in:
/etc/xdg/weston/weston.ini
If no variables are set, Weston searches in:
<current dir>/weston.ini
Where the environment variable:
$HOME is your home directory.
$XDG_CONFIG_HOME is your specific configuration directory.
$XDG_CONFIG_DIRS is a colon ':' delimited list of configuration base directories, such as /etc/xdg-foo:/etc/xdg.

Weston Display Configuration

Weston picks the default settings for display by itself. If the default settings are insufficient, the display settings can be defined in weston.ini.
To configure the display, add the following to weston.ini with the appropriate values for output name, mode, and transform:
[output]
name=<output_name>
mode=<mode>
transform=<transformation>
Where name=<output_name> sets a name for the output string. The backend uses the name to identify the output.
Output Name
Description
LVDS1
Laptop internal panel number 1.
VGA1
VGA connector number.
The mode=<mode> assignment sets the output mode string. The mode parameter is handled differently depending on the backend. The DRM backend accepts different modes:
Mode
Description
WIDTHxHEIGHT
Resolution size width and height in pixels.
preferred
Uses the preferred mode.
current
Uses the current CRT controller mode.
off
Disables the output.
Optionally, you can specify a modeline, for example:
173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync
A modeline consists of the refresh rate in Hz, the horizontal and vertical resolution, and options for horizontal and vertical synchronization. The cvt(1) program provides a suitable modeline string.
The transform=<transformation> assignment applies the transformation to the screen output string. The transform key must be one of the following 8 strings:
Transform string
Description
normal
Normal output.
90
90 degrees clockwise.
180
Upside down.
270
90 degrees counter clockwise.
flipped
Horizontally flipped.
flipped-90
Flipped and rotated 90 degrees clockwise.
flipped-180
Flipped upside down.
flipped-270
Flipped and 90 degrees counter clockwise.
The following is a weston.ini configuration example:
[output]
name=LVDS1
mode=1680x1050
transform=90
icc_profile=/usr/share/color/icc/colord/Bluish.icc

Prerequisites to Starting Weston

Weston creates its Unix socket file, for example wayland-0, in the directory specified by the required environment variable $XDG_RUNTIME_DIR. $XDG_RUNTIME_DIR defines the base directory relative to which user-specific non-essential runtime files and other file objects (such as sockets, named pipes, etc.) are stored.
Check whether the $XDG_RUNTIME_DIR environment variable is set, if it is not set please set it as follows.
Setting the $XDG_RUNTIME_DIR Directory
Use either of the following two methods to set the $XDG_RUNTIME_DIR directory before running Weston:
Set $XDG_RUNTIME_DIR manually
Set $XDG_RUNTIME_DIR using your shell profile
To set the $XDG_RUNTIME_DIR directory manually
Execute the following:
mkdir /tmp/xdgruntime
chmod 700 /tmp/xdgruntime
export XDG_RUNTIME_DIR=/tmp/xdgruntime
At runtime, /tmp/xdgruntime looks like:
root@nvidia:/# ls -lt /tmp/xdgruntime
total 0
srwxr-xr-x 1 root root 0 May 12 11:31 wayland-0
-rw-r----- 1 root root 0 May 12 11:31 wayland-0.lock
To set the $XDG_RUNTIME_DIR directory using your shell profile
Modify your shell profile to perform the manual steps described above. For information on modifying your shell, see the manual for your shell. Also see these important tips for when modifying your shell profile to set up $XDG_RUNTIME_DIR:
Determine the correct shell profile to modify.
Some shells read multiple files (Zshell). Others pick the first available file, ignoring the others (Bash). ~/.profile is generally a good guess for most Bourne-shell compatible shells; ~/.zprofile is the Zshell equivalent. Use the profile file if there is one; otherwise, use the login file. The software automatically uses the variable once it is set. This is useful if you want to use your profile file on different systems.
Put the following code in your shell profile and adapt it to your shell’s internals. This code is Bourne-shell compatible.
if test -z "${XDG_RUNTIME_DIR}"; then export XDG_RUNTIME_DIR=/tmp/${UID}-runtime-dir
if ! test -d "${XDG_RUNTIME_DIR}"; then mkdir "${XDG_RUNTIME_DIR}"
chmod 0700 "${XDG_RUNTIME_DIR}"

Starting Weston

Weston can be launched with root privileges or via weston-launch tool.
To start Weston with root privileges
Execute the following command to switch to superuser:
sudo su
The default password is nvidia.
Check and load tegra-udrm driver:
Command to check tegra-udrm to see if it is loaded:
lsmod |grep tegra_udrm
Command to load tegra-udrm if it is not loaded:
sudo modprobe tegra-udrm modeset=1
 
Create symbol links:
sudo ln -sf /usr/lib/libnvgbm.so /usr/lib/aarch64-linux-gnu/libgbm.so.1
 
sudo ln -sf /usr/lib/libdrm.so.2 /usr/lib/aarch64-linux-gnu/libdrm.so.2
Environment and directory setup:
unset DISPLAY
mkdir /tmp/xdg
chmod 700 /tmp/xdg
export XDG_RUNTIME_DIR=/tmp/xdg
Launch weston as specified below.
To start Weston on desktop-shell
Execute the following command:
weston --idle-time=0 &
By default, Weston runs using desktop-shell.
To start Weston with ivi-shell and hmi-controller
Execute the following command:
weston --tty="$WESTON_TTY" --idle-time=0 --shell=ivi-shell.so --modules=hmi-controller.so &
ivi-shell can pull different controllers that effectively take care of the window management.
Note:
By default, weston.ini sets the background-color to 0xff000000 (ARGB color). Therefore, a plain, dark background is expected.
To start Weston with ivi-shell and ivi-controller
weston --shell=ivi-shell.so --modules=ivi-controller.so
To start Weston with ivi-shell, ivi-controller and ivi-input-controller.so
Modify weston.ini to load ivi-input-controller:
[ivi-shell]
ivi-input-module=ivi-controller.so
Execute the following command:
weston --shell=ivi-shell.so &
This starts Weston with IVI shell using the corresponding controller module. The display should remain dark. The ivi-controller does not provide any desktop decorations, by default.
To start Weston without root privileges
Weston can be launched as non-root with the weston-launch binary. It is present in /usr/local/bin for Ubuntu rootfs. Follow the steps below to launch weston as non-root.
1. Add the non root user to weston-launch group:
sudo su
usermod -a -G weston-launch <non_root_user_name>
chown root /usr/local/bin/weston-launch
chmod +s /usr/local/bin/weston-launch
2. Launch weston with weston-launch binary as non-root:
su <non_root_user_name>
weston-launch [args...] [-- [weston args..]]
For example:
Run weston-launch with desktop-shell:
weston-launch -- --shell=desktop-shell.so
Run weston-launch with ivi-shell:
weston-launch -- --shell=ivi-shell.so

Running Weston Samples

The instructions provided assume Weston and Wayland are running as superuser.
To start Weston-simple-egl with ivi-shell and hmi-controller
Execute the command:
weston-simple-egl &
To start Weston-simple-egl with ivi-shell and ivi-controller
1. Execute the command:
weston-simple-egl -width 1920 -height 1080 -surface 10 &
2. Manually configuring the client surface:
LayerManagerControl set surface 10 source region 0 0 1920 1080
LayerManagerControl set surface 10 destination region 0 0 1920 1080
LayerManagerControl set surface 10 visibility 1
Nothing appears on the screen because the application surface is not linked to a layer.
3. Create a layer and attach the client surface to it:
LayerManagerControl create layer 1000 1920 1080
LayerManagerControl set layer 1000 render order 10
LayerManagerControl set layer 1000 visibility 1
4. Link your layer to a screen:
LayerManagerControl set screen 0 render order 1000

Compositing Mode in Weston

Weston supports mixed mode compositing using dma-buf. Weston collects all the overlay planes and assigns one to the GFX as the primary plane. Others are available as overlay planes. Weston evaluates all surfaces and views on every frame, and chooses one of these strategies to composite them:
DRM_OUTPUT_PROPOSE_STATE_MIXED (Overlay + GL)
DRM_OUTPUT_PROPOSE_STATE_RENDERER_ONLY (GL)
DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY (Overlay only)
The weston-simple-dmabuf-egldevice demo application demonstrates mixed-mode compositing path in weston, where some surfaces are assigned overlay planes and others are composited with GL.

Display Hardware Compositing in Weston

The DRM compositor in Weston calls drmModeAddFB2WithModifiers() to associate a DRM framebuffer ID with the dma-buf it receives via Linux DMA-BUF Unstable V1 Protocol. It then uses the framebuffer ID to present the dma-buf to one of the available display hardware planes using drmModeSetPlane(), in the legacy path, or drmModeAtomicCommit(), in the atomic modeset path. This takes the form of a flip, where the reference to the new buffer is swapped in during vblank.

weston-debug

The weston-debug client application receives and prints debug messages using the weston-debug protocol. For example, when Weston is recompositing, it prints all surface views and descriptions of the decision process regarding their assignment to overlays and GL compositing.
For weston-debug to work, you must run Weston with the ‑‑debug switch. Do not use this switch in production.
You can pass weston-debug additional parameters to choose categories of debug output to display:
$ sudo XDG_RUNTIME_DIR=/tmp/xdg weston –debug
$ sudo XDG_RUNTIME_DIR=/tmp/xdg ./weston-debug -a
Alternatively, you can enable Weston debug output by setting the environment variable WAYLAND_DEBUG=server, and Weston client debug by setting WAYLAND_DEBUG=1.

Weston dma-buf Support

Clients can post dma-buf buffers to Weston using Wayland’s Linux DMA-BUF Unstable V1 Protocol. Dma-buf support with Weston contains the following components.

Buffer Allocation

GBM is commonly used to allocate buffers, which are backed by the dma-buf file descriptor.
This code snippet shows how to allocate a buffer using GBM:
drm_fd = open("/dev/dri/card0", O_RDWR);
device = gbm_create_device(drm_fd);
bo = gbm_bo_create_with_modifiers(device, width, height,
format, modifiers, modifiers_count);
Weston supports the DRM_FORMAT_XRGB8888 and DRM_FORMAT_ARGB8888 formats.
A modifier is an encoding of vendor-specific buffer layout parameters. Weston modifiers are supported by DRM (read the IN_FORMATS plane property blob) and by EGL (call eglQueryDmaBufModifiersEXT()).

Buffer Read/Write from CPU

You can use this API function to write data directly into a GBM buffer:
gbm_bo_write(bo, user_buffer, sizeof user_buffer);
You can also memory map a GBM buffer and get a CPU-accessible address to the data written to or read from it:
uint32_t dst_stride = 0;
void *gbo_mapping = NULL;
// Map bo to CPU accessible address.
char *dst_ptr = gbm_bo_map(bo,
0, 0,
width,
height,
GBM_BO_TRANSFER_READ_WRITE,
&dst_stride,
&gbo_mapping);
// Write data to or read data from dst_ptr.
. . .
// Unmap bo.
gbm_bo_unmap(bo, gbo_mapping);

Wayland Protocol to Post dma-buf Buffers to Weston

Weston uses the Generic Buffer Management (GBM) library to allocate buffers that are backed by dma-buf file descriptors. Client applications must call the following GBM functions to get the dma-buf file descriptor and associated parameters from the GBM buffer object. To post the dma-buf to a Wayland surface, the file descriptor and parameters must be provided via Linux DMA-BUF Unstable V1 Protocol.
The following code snippet shows the main calls involved (assume gbm buffer object contains one plane only).
stride = gbm_bo_get_stride_for_plane(bo, 0);
offset = gbm_bo_get_offset(bo, 0);
handle = gbm_bo_get_handle_for_plane(bo, 0);
modifier = gbm_bo_get_modifier(bo);
drmPrimeHandleToFD(drm_fd, handle, 0, &dmabuf_fd);
zwp_linux_buffer_params_v1_add(params, dmabuf_fds, 0, offset,
stride, modifier >> 32,
modifier & 0xffffffff);
zwp_linux_buffer_params_v1_create(params, width, height,
format, flags);

GL Renderer in Weston

The GL renderer in Weston creates an eglImage from a dma-buf object that it receives with Linux DMA-BUF Unstable V1 Protocol using the EGL_EXT_image_dma_buf_import and EGL_EXT_image_dma_buf_import_modifiers extensions. Weston obtains the GL texture target to be used with this eglImage by calling eglQueryDmaBufModifiersEXT(), and binds the eglImage to the texture.

Gnome-Wayland Desktop Shell Support

To enable experimental Gnome-Wayland desktop shell support:
1. Install gdm3, mutter, and their dependencies:
sudo apt update
sudo apt install -y gdm3 mutter adwaita-icon-theme-full
sudo apt install -y --reinstall libdrm2 ubuntu-session
2. Repair the broken drm-nvdc soft link and rename the Ubuntu session file:
sudo ln -sf /usr/lib/libdrm.so.2 /usr/lib/aarch64-linux-gnu/libdrm.so.2
sudo mv /usr/share/wayland-sessions/ubuntu-wayland.desktop /usr/share/wayland-sessions/ubuntu.desktop
3. Add the gdm daemon to the video group:
sudo usermod -a -G video gdm
4. Configure gdm to use Wayland by setting the following flag in the [daemon] section of /etc/gdm3/custom.conf:
[daemon]
WaylandEnable=true
5. Load the tegra-udrm kernel module:
sudo modprobe tegra-udrm modeset=1
6. Start gdm:
sudo systemctl start gdm3.service
7. Log in and verify the Wayland backend is running:
ps -e | grep wayland
8. Configure the tegra-udrm kernel module to load on boot:
sudo bash -c 'echo "options tegra-udrm modeset=1" > /lib/modprobe.d/tegra-udrm.conf'
sudo bash -c 'echo "tegra-udrm" >> /etc/modules-load.d/modules.conf'
9. Reboot and repeat step 7 to verify the Wayland backend auto-started successfully.