4. Weston合成器入门

Weston 是 Wayland 协议的开源参考合成器(Reference Compositor),由 Wayland 项目维护,承担着窗口管理、输入事件分发、图形缓冲区合成与呈现的核心职责。在车载 Linux 系统中,Weston 不仅是图形显示的“总装车间”,更是连接 GPU/Display Controller、输入设备、应用客户端与系统策略的枢纽。理解 Weston 的架构与启动机制,是后续进行 Wayland 功能定制、性能调优和故障排查的基础。本章将深入拆解 Weston 的模块化架构、插件化后端设计、三种典型后端(headless、DRM、X11)的适用场景,以及从配置文件到进程启动的完整流程。

Weston 合成器架构与后端关系图 Wayland 客户端 (车载HMI/仪表/中控) Wayland 协议 wl_surface / wl_buffer Weston 核心 (libweston) 合成器 (Compositor) Shell (桌面/车载Shell) 输入处理 (Input) 插件管理 (Plugin) 后端抽象层 (Backend) renderer / output / input 接口 DRM 后端 KMS/DRM + GPU 车载主屏/仪表 headless 后端 无显示输出 测试/远程渲染 X11 后端 运行在X Server上 开发调试/兼容 硬件层:GPU (Vivante/Adreno) | DRM/KMS | 显示控制器 | 输入设备 (触摸/按键)

上图展示了 Weston 的整体架构关系。客户端通过 Wayland 协议与 Weston 核心通信,核心通过后端抽象层适配不同的显示硬件与运行环境。在车载场景中,DRM 后端是量产首选,headless 后端常用于自动化测试,X11 后端则多用于开发阶段的快速验证。

4.1 Weston 核心架构与插件系统

4.1.1 核心原理:libweston 与插件化设计

Weston 自 1.12 版本起将核心逻辑抽取为 libweston 库,这是一个可复用的合成器库,而 Weston 可执行程序只是 libweston 的一个前端实例。这种设计使得 OEM 和 Tier1 供应商可以直接基于 libweston 构建自己的合成器,而不必从零实现 Wayland 协议。libweston 内部包含以下关键模块:

  • Compositor 核心:负责场景图(Scene Graph)管理、缓冲区分配与合成调度、输出帧呈现。
  • Shell 接口:定义窗口管理策略,包括窗口布局、焦点管理、全屏/分屏逻辑。Weston 默认提供 desktop-shell,车载场景常替换为 custom-shell 或 IVI-Shell。
  • Renderer 抽象:支持 pixman(软件渲染)和 GLES2(GPU 硬件渲染)。车载 SoC 通常使用 GLES2 以获得最佳性能。
  • Backend 插件:通过动态加载 .so 文件的方式接入不同的显示后端,这是 Weston 最具扩展性的设计之一。

插件系统采用 weston_plugin_api 机制。每个后端插件必须实现 weston_backend 接口,包括初始化、输出创建、输入设备注册等回调函数。Weston 在启动时通过 weston_compositor_load_backend() 动态加载指定插件,并调用其 backend_init() 函数完成初始化。

关键设计意图:插件化使得 Weston 可以针对不同硬件平台(如 i.MX8 的 Vivante GPU、高通 SA8155 的 Adreno GPU)提供专用后端,而核心合成逻辑无需修改。车载项目通常只需要编写一个适配特定 SoC 显示控制器的后端插件,即可复用 Weston 的全部上层能力。

4.1.2 判断方法:如何选择正确的后端

在车载项目中,选择后端需要根据目标硬件和运行阶段进行判断。下表总结了三种后端的核心差异:

后端类型 显示输出 硬件依赖 典型场景 性能特征
headless 无物理输出 仅需 CPU 内存 CI 自动化测试、离屏渲染、远程帧缓冲 无 vsync 同步,帧率不受硬件限制
DRM 直接输出到显示器 需要 /dev/dri/card0、GPU 驱动 量产车机、仪表盘、中控娱乐 支持硬件合成、零拷贝、Page Flip
X11 通过 X Server 间接输出 需要 X11 运行环境 开发调试、在 PC 上模拟车载环境 多一层拷贝,性能低于 DRM

判断流程通常如下:

  1. 确认目标硬件是否有 DRM 节点(ls /dev/dri/)。若存在 card0 且 GPU 驱动正常,优先选择 DRM 后端。
  2. 若仅用于单元测试或无需真实显示,选择 headless 后端,配合 weston --backend=headless-backend.so 启动。
  3. 若在开发主机(如 Ubuntu PC)上调试 Wayland 客户端,使用 X11 后端可避免直接操作显卡。

4.1.3 案例拆解:车载仪表盘双屏异显的后端配置

某车载项目使用 NXP i.MX8QM 处理器,需要同时驱动 12.3 英寸仪表屏(1920x720)和 15.6 英寸中控屏(1920x1080)。初始现象是两块屏幕只能克隆显示,无法独立输出不同内容。分析发现 Weston 默认只创建一个输出(Output),需要配置 DRM 后端的多输出支持。

关键操作步骤:

# 1. 检查 DRM 设备节点
ls /dev/dri/
# 输出: card0 card1  (card0 为内嵌DP, card1 为LVDS)

# 2. 在 weston.ini 中配置两个输出
[output]
name=LVDS-1
mode=1920x720@60
transform=normal

[output]
name=DP-1
mode=1920x1080@60
transform=normal

# 3. 启动 Weston 时指定 DRM 后端
weston --backend=drm-backend.so --tty=1 --config=/etc/weston.ini

结果对比:配置前 weston --info 仅显示一个输出;配置后显示两个输出,且可通过 wayland-info 工具看到两个 wl_output 全局对象。风险点在于:若两个屏幕的时序参数(mode)不匹配,可能导致其中一个输出黑屏。复盘经验:在车载多屏场景中,务必为每个输出显式指定 mode,避免 Weston 自动协商失败。

4.1.4 常见误区与总结

误区1:认为 headless 后端不能用于性能测试。实际上,headless 后端配合 weston --renderer=pixman 可以用于 CPU 渲染性能基准测试,但无法反映 GPU 合成能力。
误区2:忽略插件 ABI 兼容性。Weston 版本升级后,旧的后端插件 .so 文件可能因 ABI 变化而无法加载,报错 undefined symbol。车载项目应锁定 Weston 版本并同步编译所有插件。

总结:Weston 的插件化架构是其适应多样化车载硬件的关键。理解 libweston 与后端插件的边界,能够帮助工程师快速定位问题——是合成逻辑问题还是后端适配问题。

4.2 后端详解:headless、DRM 与 X11

4.2.1 核心原理:三种后端的实现差异

headless 后端(headless-backend.so)不创建任何物理输出,它使用共享内存(shm)作为缓冲区,通过 weston_output 的虚拟输出接口将渲染结果提交到内存中。该后端常用于:

  • Weston 自带的 weston-simple-egl 测试程序离屏渲染。
  • 配合 weston-test 插件进行自动化集成测试。
  • 远程桌面场景(如通过 GStreamer 将帧编码推流)。

DRM 后端(drm-backend.so)直接与 Linux 内核的 DRM/KMS 子系统交互。它通过 drmModeGetResources 枚举连接器(Connector)和编码器(Encoder),使用 drmModeSetCrtc 设置显示模式,并通过 drmModePageFlip 实现无撕裂的帧提交。DRM 后端还支持硬件平面(Plane)合成,可将多个窗口直接映射到不同的硬件平面,减少 GPU 合成负载。

X11 后端(x11-backend.so)将 Weston 作为一个 X11 客户端运行。它创建一个 X11 窗口作为 Weston 的“画布”,所有 Wayland 客户端的表面(Surface)最终都合成到这个 X11 窗口中。该后端主要用于开发调试,因为它允许在普通桌面环境中运行 Weston,而无需切换 TTY 或独占显卡。

4.2.2 操作流程:DRM 后端的启动与验证

在车载 Linux 系统中,DRM 后端是量产标准。以下是标准启动流程:

# 1. 确保 DRM 驱动已加载
dmesg | grep -i drm
# 应看到 [drm] Initialized i915 或 [drm] Initialized vivante

# 2. 停止可能占用 DRM 的进程(如 X Server)
systemctl stop gdm  # 或 lightdm

# 3. 切换到空闲 TTY
chvt 1

# 4. 启动 Weston(使用 DRM 后端)
weston --backend=drm-backend.so --tty=1 --config=/etc/weston.ini --log=/var/log/weston.log &

# 5. 验证运行状态
weston --info  # 查看输出信息
cat /var/log/weston.log | grep -i "output"

验证关键点:

  • 日志中出现 Output LVDS-1 (crtc 32) video modes: 表示输出创建成功。
  • 使用 modetest -M imx-drm 查看当前 CRTC 状态,确认 Weston 已接管显示。
  • 运行 weston-simple-egl 测试客户端,观察屏幕是否有旋转的三角形。

4.2.3 案例拆解:headless 后端在 CI 测试中的应用

某 Tier1 供应商需要在无显示硬件的 Jenkins 服务器上运行 Wayland 客户端回归测试。初始方案是使用 Xvfb(虚拟 X Server),但无法验证 Wayland 特有的缓冲区共享和帧回调机制。改用 Weston headless 后端后:

# Jenkins 构建脚本中启动 headless Weston
weston --backend=headless-backend.so --width=1920 --height=1080 --config=/dev/null &
sleep 2
export WAYLAND_DISPLAY=wayland-1
# 运行测试客户端
./test_client --test-case=surface_attach
./test_client --test-case=pointer_motion

关键参数:--width 和 --height 指定虚拟输出分辨率。测试结果通过 weston-test 插件提供的 weston_test_runner 接口获取帧呈现时间戳,从而验证帧率是否达标。该方案将测试时间从 15 分钟缩短至 3 分钟,且无需物理显示设备。

4.2.4 常见误区与总结

经验提醒:DRM 后端下,如果 GPU 驱动不支持某些像素格式(如 ARGB2101010),Weston 可能无法创建硬件平面,导致合成性能下降。排查时使用 weston --debug 查看平面分配日志。

总结:三种后端各有适用边界。车载量产必须使用 DRM 后端,但 headless 后端在测试和远程诊断中价值巨大。X11 后端则作为开发阶段的“安”,避免频繁切换 TTY 带来的不便。

4.3 配置与启动流程

4.3.1 核心原理:weston.ini 配置体系

Weston 的配置文件采用 INI 格式,默认路径为 /etc/xdg/weston/weston.ini 或 ~/.config/weston.ini。配置分为多个 section:

Section 关键键值 作用
[core] shell、backend、renderer 指定核心模块、后端类型、渲染器
[shell] panel-location、background-color 配置桌面壳的面板位置和背景
[output] name、mode、transform、scale 定义每个显示输出的参数
[input-method] path、options 加载输入法模块
[launcher] icon、path 定义桌面启动器图标

启动流程分为四个阶段:

  1. 解析配置:Weston 读取 weston.ini,确定后端类型、渲染器、输出列表。
  2. 加载插件:通过 dlopen() 加载后端 .so 文件,并调用 backend_init()。
  3. 初始化输出:后端创建 weston_output,设置模式、缩放、变换。
  4. 启动 Shell:加载 shell 模块(如 desktop-shell.so),创建面板、背景、启动应用。

4.3.2 操作流程:车载场景的典型配置

以下是一个适用于车载中控的 weston.ini 配置示例:

[core]
shell=desktop-shell.so
backend=drm-backend.so
renderer=gles2
idle-time=0

[shell]
panel-location=top
panel-size=48
background-color=0xff002233
# 禁止屏幕保护
locking=false

[output]
name=LVDS-1
mode=1920x720@60
transform=normal
scale=1

[output]
name=HDMI-A-1
mode=1920x1080@60
transform=normal
scale=1

[launcher]
icon=/usr/share/icons/ic_launcher_home.png
path=/usr/bin/vehicle_hmi

[input-method]
path=/usr/lib/libinput-method-ivi.so
options=--enable-auto-switch

启动命令:

weston --config=/etc/weston.ini --log=/var/log/weston.log --tty=1

关键参数说明:

  • idle-time=0:禁用空闲休眠,避免车载屏幕意外熄灭。
  • locking=false:禁用屏幕锁定,防止 HMI 无法唤醒。
  • background-color:使用 ARGB 格式,设置深色背景以减少 OLED 烧屏风险。

4.3.3 案例拆解:启动失败排查流程

某项目在实车启动时,Weston 进程反复崩溃,日志显示 fatal: failed to create output。初步排查步骤:

# 1. 查看完整日志
tail -50 /var/log/weston.log
# 关键行: [drm] failed to set mode 1920x720@60 for output LVDS-1

# 2. 检查 DRM 是否支持该模式
modetest -M imx-drm -c
# 发现 LVDS-1 支持的最大分辨率为 1366x768,不支持 1920x720

# 3. 修改配置,使用 EDID 推荐模式
[output]
name=LVDS-1
mode=preferred

结果对比:修改后 Weston 正常启动,屏幕显示 1366x768。复盘经验:车载屏幕的 EDID 信息可能不完整,导致 Weston 无法读取正确的 mode 列表。建议在开发阶段使用 weston --info 确认实际支持的 mode,再写入配置。

4.3.4 常见误区与总结

风险提示:不要在生产环境中使用 --idle-time=0 以外的值,否则长时间停车后屏幕可能休眠,且无法通过触摸唤醒(需配置 input-method 的 wakeup 功能)。
注意:Weston 启动时若检测到已有进程占用 DRM master(如 X Server),会报 drmSetMaster failed。务必先停止 X Server 或使用 loginctl 切换 session。

总结:配置与启动流程是 Weston 落地的“最后一公里”。车载项目应提前固化 weston.ini 模板,并在 CI 中验证配置变更,避免因配置错误导致量产启动失败。