通过这些箭头,你已经可以明白一些X Window的工作机制了,不过还从一个应用场景来解释一下,想像一下,当你点击了Firefox(X Client)的“刷新”按钮,将会发生以下事情: - 你用鼠标点击了Firefox的“刷新”按钮,这时内核收到了鼠标发来的事件,并将其通过evdev输入驱动发送至了X Server。这时内核实际上做了很多事情,包括将不同品牌的鼠标发出的不同信号转换成了标准的“evdev”输入信息。
- 这时X Server可以判断哪个Window该收到这个消息,并将某座标按下按钮的消息发往X Client——Firefox。但事实上X Server并不知道它得到的窗口信息是不是正确!为什么呢?因为当前的Linux桌面早已经不是10年前的那样了,现在是“Composite”即合成 桌面的时代,合成桌面的一个特点便是:Compositor(如Compiz)管理窗口的一切,X Server只能知道屏幕的某个点收到了鼠标消息,却不知道这个点下面到底有没有窗口——谁知道Compiz是不是正在搞一个漂亮的、缓慢的动画,把窗口 收缩起来了呢?
- 假设应用场景没这么复杂,Firefox顺利地收到了消息,这时Firefox要决定该如何做:按钮要有按下的效果。于是Firefox再发送请求给X Server,说:“麻烦画一下按钮按下的效果。”
- 当X Server收到消息后,它就准备开始做具体的绘图工作了:首先它告诉显卡驱动,要画怎么样一个效果,然后它也计算了被改变的那块区域,同时告诉Compiz那块区域需要重新合成一下。
- Compiz收到消息后,它将从缓冲里取得显卡渲染出的图形并重新合成至整个屏幕——当然,Compiz的“合成”动作,也属于“渲染(render)”,也是需要请求X Server,我要画这块,然后X Server回复:你可以画了。
- 整个过程可能已经明了了,请求和渲染的动作,从X Client->X Server,再从X Server->Compositor,而且是双向的,确实是比较耗时的,但是,事实还不是如此。介于X Window已有的机制,尽管Compiz已经掌管了全部最终桌面呈现的效果,但X Server在收到Compiz的“渲染”请求时,还会做一些“本职工作”,如:窗口的重叠判断、被覆盖窗口的剪载计算等等(不然它怎么知道鼠标按下的坐 标下,是Firefox的窗口呢)——这些都是无意义的重复工作,而且Compiz不会理会这些,Compiz依然会在自己的全屏幕“画布”上,画着自己 的动画效果……
从这个过程,基本可以得出结论: - X Client <-> X Server <-> Compositor,这三者请求渲染的过程,不是很高效;
- X Server,Compositor,这两者做了很多不必要的重复工作和正文切换。
当然,这里我没有直接说明这种模式有没有给X Window造成效率问题,因为我们还少一个对照组。再看对照组之前,再来看看X Server的另一个趋势: 从“什么都做”到“做得越来越少”的X Window X Window刚出现那会,主要提供一个在操作系统内核上的抽象层,来实现一个图形环境。所谓图形环境,最主要的便是:图形+文字。当时的X Window便提供“绘图”和“渲染文字”的机制。图形桌面上的图案和文字,都通过X Window合成并绘制出来。 一个典型的例子,如果你要用X来画点,就要在你的程序中通过“XDrawPoint”来进行,X Server收到消息后,便会画出相应的点。 现在,稍微接触过图形开发的人都知道了,在X Window下,一般都通过GTK+和Qt来进行了。更深一层的是,通过Cairo(Qt不是)来绘制图形。Cairo是什么?它是一个绘图+渲染引擎,著名的浏览器Firefox,便是使用Cairo来渲染网页和文字的。 Cairo是一个全能的、跨平台的矢量绘图库,它不是简单的包装一下各个平台的绘图库而已,尽管它最初是基于X Window开发出来的绘图库。现在Cairo支持各种不同的后端,来向其输出图形,比如X、Windows的GDI、Mac OS X的Quartz,还有各种文件格式:PNG、PDF,当然还有SVG。可以说,Cairo是一个很彻底的、全能的绘图库,现在无论绘制什么图形,都不会 考虑到用XLib了。 在Cairo之上,还有文字排版库:Pango,同样很明显的,处理文字排版,都不会用XFont之类的东西了,而是直接用Pango画。当然Pango也是跨平台的。 |