在上篇的《Wayland 1.0蓄势待发!》中,我连接了五年前写的文章,展示了Wayland最新得到的一个特性:2D Input redirection。并以此展望2012年末及2013年初Wayland将在Linux操作系统中正式得到应用。
对于开发者来说,在拥抱Wayland的时候,必然会与已经25岁的X Window作相互比较,特别是进行概念上的比对,以快速认识Wayland。
然而,Wayland不是X Window,我们势必抛开过去陈旧的概念,来彻底认识这个新玩意。
我打算从翻译国外的文章,来进行Wayland系列普及文章。目标读者群:开发者、Hacker、高级玩家等。今天是第一篇。
原文:Wayland misconceptions: Window,括号中是我的相关补充。
现在有很多关于Wayland的误解,于是我打算来纠正这些,让我们先从其中一个概念开始:
Wayland协议当中,并没有等同于X Window中的「Window」的对象。
感到奇怪吗?没有「Window」?在此,我们需要以一个复杂的应用程序——Firefox为例来详细的解释一下,「Window」到底是什么意思。
以一个打开的Firefox应用程序为例,一个窗口有几个标签打开着,而当前激活的那个标签,则有一个Flash视频正在播放。
注意,这里我所说的「窗口」,这是从终端用户的角度来看的,这是一个显示在屏幕上的「Firefox窗口」。如果同时还有一个终端的窗口打开着,那么它将是另一个「窗口」(而不是代码里的Window),让我们把这个叫做「应用程序窗口」。
然而在X Window当中(我猜想,可能现在不是这样了),应用程序窗口,将是X Window中对应Xlib数据类型——Window的一个实例(也就是说,前面用英文所指的「Window」本质都是Xlib里的一个数据类型,而不是你能看到或看不到的「Window」)。这个Window还包含了非常多的子Window。举个例子,每个按钮都包含一个独立的Window(相信做过X Window开发的同学都理解这个概念),每个可以滚动的文件框也是一个单独的Window,这些当中只有部分是可见的。当然每个标签也都是Window。在X Window当中,所有的这些Window的层叠关系(比如一个按钮的Window是在一个窗口的Window里,注意理解数据类型)、依赖关系、事件MASK,将都且X Servrer来管理,因而X Server在收到一些输入操作时,它会根据这些关系将输入事件发送至对应的Window当中(比如按钮收到了press操作,则X Server把这个消息发给按钮的Window而不是窗口的Window),并且渲染所有这些在屏幕上的Window(据我所知当前,这些渲染也由Client端来完成了)
Wayland却不是像这样的。
注意到上面我说所说的关于X Server渲染(render)的东西了吗?一个Wayland Compositor并不是一个渲染的API(只管合成)。
在Wayland当中,整个应用程序窗口(即用户能看到的),就是一个「wl_surface」结构,并且没有所谓的子wl_surface的说法(除了可能存在的菜单,但是这是一个例外,因为菜单是应用程序窗口之外的)。所有的渲染工作,都而且是必须完成在client端,应用程序将会申请一个新的「wl_buffer」,将所有的东西渲染到里面去,甚至包括视频的图像和窗口的边框,然后通过一个单独的「attach」请求,由此完成在屏幕上显示更新过的窗口内容的操作,整个过程一气呵成,将没有任何闪烁(木有闪烁!)。是的,当视频播放时,每帧的图像都将这么完成(当然你也可以缓存一些没有改变的图像以避免Client端总是进行完全重绘操作)。
最简单的描述是,wl_surface对应一个窗口,更准确的说是「应用程序窗口」而不是Xlib中的Window。在Wayland当中,没有像Xlbi中的Window一样的概念,除非你在你的工具包(toolkit)中实现类似的机制,然而这将是你工具包所具备的特性,它永远也不会通过Wayland协议进行传送。
TualatriX补充:
尽管X Window在近年来的发展也将越来越多的事情都丢到client去做(如render),但是限于其本身25年没变的核心架构所致,很难再前进一步。Wayland的协议彻底的精简了这些,简化了各种概念,让开发者可以用更直观的概念去理解并通过「wl_surface」及「wl_buffer」去操作Wayland,一切将变得异常的轻松。
另外,总会有人想念X Window的分层及分工及网络透明的设计,在此我要说,Wayland并不说不能做这些工作,而是它的核心协议并不规定这些东西,它就是提供了这么个核心协议完成一个「Display Server」该做的事情。(就像上面提到了,你依然可以在你的toolkit当中去做Xlib的Window那样的机制,如果你愿意的话)
想要用在更复杂的场景?Wayland没问题!如下图:
下图展示的是什么特性呢?相信你看出来了,下图运行着三个「Wayland Compositor」(尽管当前是在一个屏幕上,但是你也可以想像成三个屏幕)。然后,一个终端窗口分别被切成三分显示在了三个「Wayland Compositor」上。
这样的Wayland,还不值得你来期待么?