X与Wayland
前言
对于X和Wayland的历史,可以阅读这篇:揭开Wayland的面纱(一):X Window的前生今世 。
X协议发展到今天已有30多年历史,许多性能问题日益严重,为了提效,人们将xserver中的一些功能(如字体)独立成模块放入了内核;
这就导致xserver的大部分功能被剥离,而xserver只剩下传递消息的功能。
Wayland就是为了取代X,解耦合xserver,实现更高效的通信方式。
Wayland的优势是:
- 使用合成器取代x服务器,减少通信损耗;
- 不提供渲染API,渲染由客户端完成,提高渲染效率。
X协议
这张图是Wayland官网提供的,用以说明x的通信原理,但是官网没有解释术语和细节,我增加了实例解释过程:
1. evdev接收到鼠标事件,如点击了画图工具上的一个画矩形的按钮;
evdev将鼠标事件(坐标,单击)放入消息队列(/dev/input/eventX)中,X是数字不是x服务器;
xserver会打开相应的eventX文件,然后监听文件的读取事件来获取输入设备产生的事件信息。
2. xserver将evdev事件(坐标,单击)转换为窗口事件(窗口,按钮,单击);
xserver将窗口事件发给应用(x Client);
3. 画图工具通过消息处理函数,调用x的画矩形API,XFillRectangle,将画矩形命令传送给了xserver;
4. xserver接收到画矩形事件,并将事件发给了合成器;
5. 合成器接收到画矩形事件,调用x内置渲染器或者OpenGL等渲染器,完成了渲染,将图形信息转化成像素信息,并合成最后的屏幕图像信息,传递给xserver;
6. xserver将屏幕图像发送给KMS,KMS调用显卡驱动进行显示,显示新的屏幕图像。
到这里,我们知道了xserver的架构原理,看上去没啥问题。
但是对比x架构图和下边的Wayland架构图,就会发现,合成器完全可以平移到xserver的位置,而通信架构不变。
啥意思呢?就是xserver是多余的,用合成器取代xserver,是Wayland提效的方法之一。
Wayland协议
在Wayland架构中,xserver的位置被合成器取代了,架构由星型架构(围绕xserver)变成了三层架构(以合成器为中心);
1. evdev接收到鼠标事件;
2. 合成器负责转化为窗口事件,并传递给客户端;
3. 客户端调用消息处理函数,
此处,合成器不再提供绘图和渲染命令,也就是不再提供类似XFillRectangle这样的接口函数,而是由客户端调用OpenGL函数,如glDrawElements,来完成画矩形的动作,然后将图像保存到surface结构体中,并调用wl_surface_commit函数通知合成器有图像刷新;
4. 和x不同的是,Wayland中每个应用都维护一个surface缓存,当窗口需要更新时,通过wl_surface_commit函数通知合成器,合成器会读取surface缓存,合成新的屏幕图像。
在Wayland中,合成器只负责合成屏幕图像,而不负责渲染,这是Wayland加速的主要原因:
一者,Wayland取消了xserver作为中心地位的多余通信步骤;
二者,将渲染过程放在客户端处理,相当于并发渲染,而x放在合成器中集中渲染,影响了性能。
X API简介
- 窗口管理
- 窗口通信
- 渲染:2D绘图、文字等
使用x接口画矩形:
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
int main() {
Display *dpy = XOpenDisplay(NULL);
if (dpy == NULL) {
fprintf(stderr, "Cannot open display\n");
exit(1);
}
int screen_num = DefaultScreen(dpy);
Window root = RootWindow(dpy, screen_num);
// 创建窗口
Window win = XCreateSimpleWindow(dpy, root, 0, 0, 400, 400, 0,
BlackPixel(dpy, screen_num),
WhitePixel(dpy, screen_num));
// 选择输入事件
XSelectInput(dpy, win, ButtonPressMask);
// 显示窗口
XMapWindow(dpy, win);
// 获取画布
GC gc = XCreateGC(dpy, win, 0, NULL);
// 绘制矩形
XSetForeground(dpy, gc, 0x00FF00); // 设置颜色
XFillRectangle(dpy, win, gc, 100, 100, 200, 200);
// 处理事件
XEvent event;
while (1) {
XNextEvent(dpy, &event);
switch (event.type) {
case ButtonPress:
// 点击窗口关闭
XCloseDisplay(dpy);
return 0;
default:
break;
}
}
}
Wayland API简介
- 窗口管理
- 窗口通信
使用Wayland和OpenGL接口画矩形:
todo.
术语
- 像素:显示器上的最小显示单元(一个LED),不同的显示器像素大小不同;
- 显示器:屏幕,由若干显示单元(LED)构成,通过显卡激活显示单元来显示图像。
- 显卡:硬件设备,包括 GPU 和显存等组件,支持RGB等图像格式;
- 显卡驱动:软件,API库;
- OpenGL:用户级显卡抽象层,提供统一API调用各类显卡驱动。
- KMS(Kernel Mode Setting):内核级显卡驱动抽象层,提供统一的API管理显卡,OpenGL也是调用KMS工作的;
- GPU:显卡的计算单元,用于处理图形渲染等工作;
- 渲染:将三维模型数据映射为二维图像,并计算纹理光照等,最终转化为像素信息的过程。渲染器包括Cairo、OpenGL、Vulkun等。
- 显存:显卡存储图像数据的地方;
- 图片:存储像素信息的文件;
- compositor(合成器):在x服务器中,合成器的任务包括渲染+屏幕图像合成等部分;在wayland中,合成器包括事件处理+屏幕图像合成等部分;
- x协议:是一套API,应用调用他来实现窗口的管理,包括x服务器和x客户端两部分;
- x-server(x服务器):x服务器负责处理硬件,包括接收鼠标键盘事件,和控制显示器显示;
- x-client(x客户端):即GUI应用,比如火狐浏览器、文本编辑器、百度网盘啥啥的;
- wayland:是一套API,应用调用他来实现窗口的管理;
- 桌面环境:由窗管+桌面组件+SDK+核心应用组成;
- 窗管:窗口管理器,负责创建窗口,移动窗口,显示窗口(包括合成器),多窗口交互等,通过调用X协议或者Wayland协议实现的;
- 桌面组件:包括桌面面板,任务栏,开始菜单,任务管理器等;
- SDK:开发工具套件,至少包括一个API库,有的还提供编辑工具,调试工具等;
- 桌面核心应用:包括浏览器,多媒体查看器,文本编辑器等;
- evdev:内核级输入设备驱动抽象层,提供统一API管理输入设备;
- GUI(图形用户接口):通过操作图形来完成指令输入。GUI和图像的区别是,GUI是可交互图形,点了会有反应,图像是静态图片,只能查看,点了不会有反应。
- CLI(文字用户接口):通过在命令行输入文字来完成指令输入,如bash shell等。
- Shell:用户操作内核的中间件。在Windows和MAC中,Shell既包括图形界面也包括文字界面,因为他们都是在内核中实现的;但是在Linux中,Shell只包括文字界面,不包括图形界面,因为Linux GUI是以软件形态实现的。
- 内核:接管所有硬件,提供多任务运行。
参考链接
Wayland 官网
揭开Wayland的面纱(一):X Window的前生今世
揭开Wayland的面纱(二):Wayland应运而生