tech-sharing / 2026-05-09
从 X11 到 Wayland:为什么显示服务器值得一次重新设计。
agenda.toml
// x11-legacy
X11 诞生于 1984 年,网络透明是灵魂——所有渲染都经过 socket。Overhead 极高。
❌ 本地渲染也走网络协议30 年生态积累了几百个 extension,GE、GLX、DRI……相互叠加,维护成本爆炸。
😩 扩展地狱任何 X 客户端理论上可以监听/控制其他窗口。等同于 root 权限级别的攻击面。
❌ 缺乏沙箱// wayland-core
Wayland 不是协议的全部——它只是一个架子。实际协议是 wl_protocol,通过 wayland-scanner 从 .xml 生成。
// globals
Client 与 Compositor 通过 wl_display 建立连接。全局对象由 wl_registry 统一注册和发现。
// 绑定一个全局对象 let comp = wl_compositor.bind( registry, name, version, id ) // name → Compositor 全局对象的 id // version → 协商接口版本 // 全局对象列表由 Compositor 发布, // Client 通过 wl_registry.listener 接收。
// event-queue
Wayland 连接基于 wl_event_queue。Client 调用 wl_display.dispatch() 读取 socket 并分发消息。没有独立线程模型——默认在调用线程处理。
// wl-protocol.xml
Client 创建 wl_surface,填充内容写入 wl_buffer(由合成器分配或 Client 自己提供),然后 commit 给 Compositor 合成。
// Client → Compositor (Unix FD) wl_buffer → attach(surface, buffer, x, y) wl_surface → commit() // Compositor → Client wl_buffer → release() wl_callback → done(callback_data)
// image-data-flow
一张图片的完整渲染链路,涉及多个全局对象的协作。
// advantages
Client 直接写入 shared memory 或 DMA buffer,Compositor 直接从 GPU 读取,无需 X11 的 CPU 中转。延迟从 ~16ms 降到 ~1ms。
⚡ 低延迟X11 是被动合成(应用通知才更新)。Wayland Compositor 可以在任何时候重绘。滚动撕裂?不存在的。
🎯 无撕裂Client 只能操作自己的 surface,没有 keystrokes、screenshots 权限(除非明确 granted)。flatpak / portals 的基础。
🔒 安全隔离// ecosystem
GNOME / KDE 均已默认 Wayland 多年。游戏和媒体是最后两个痛点。
遗留 X11 应用通过 XWayland 运行(合成器内置 X 服务器)。Wine / Steam / Electron 都走这条路。
// takeaways
它是一套设计哲学——本地优先、最小接口、合成器中心。
wl_registry 是所有功能的入口,通过 bind 获取具体接口。版本协商决定兼容性。
wl_display.dispatch() 在调用线程分发消息。多线程使用需创建独立 wl_event_queue。
延伸阅读:wayland-book.freedesktop.org · wayland.freedesktop.org/docs