Graphics on Linux

 

X Window System

X窗口系统(X Window System)是一种以位图方式显示的软件窗口系统。最初是1984年麻省理工学院的研究项目,之后变成UNIX、类UNIX、以及OpenVMS等操作系统所一致适用的标准化软件工具包及显示架构的运作协议。随着时间的推移,X Window System协议不断修订,并于1987年9月发布第11版,一直沿用至今,所以X Window System也常简称为X11或X。

 

X.Org

X只是工具包及架构的规范,本身并无真正可用、可运行的实体。所以必须有人依据此标准进行开发可运行的程序实现体。依据X的规范架构所开发撰写成的实现体中,比较常见的有:XFree86,X.Org以及Apple X11。显然Apple X11是Apple Mac OS X专用的,而XFree86项目是1989年到2004年间使用最广泛的X Window系统,2004年因为开发模式的分歧,X.Org基金会成立,并以XFree86 4.4RC2发行版本为基础发起了一个新的X Window项目,这个项目发布的X Window系统叫做X.Org Foundation Implementation of X11,通常就简称为X.Org。目前X.Org已取代XFree86成为最普遍最受欢迎的X Window系统。X.Org最新版本是2010年10月发布X11R7.6。

众所周知,X采用C/S的架构模型。X为GUI环境提供基本的框架:在屏幕上描绘、体现图像与移动程序窗口,同时也受理、运行、及管理电脑与鼠标、键盘的交互程序,但是X并不管理应用程序在用户界面上的具体细节设计,所以,XFree86、X.Org等只是个Server。而界面细节由其他以X为基础的实现体来负责,这些实现体包括窗口管理器(Window Manager)、GUI构件工具包、桌面环境(Desktop Environment)或者应用程序指定的GUI(如POS)等客户端程序。

从X11R6.9开始,X.Org的架构被模块化,每个模块做为分离的项目独立维护。

此外随着硬件操作被移入内核,从X11R6.7开始,对视频硬件的访问将通过OpenGL(没有硬件OpenGL加速的系统使用Mesa 3D)和基层直接渲染模块(DRI)进行。

 

窗口管理器

在X的系统架构中,窗口管理器用于控制窗口程序的位置和外观,维护窗口的位置、周围加上装饰性的边框、处理图标、处理鼠标对窗口外表的点击、处理按键等等。从X服务器的角度来看,窗口管理器和其他的客户端并没有什么不同。常见的有KWin(KDE的默认窗口管理器)、Metacity(GNOME的默认窗口管理器)、Xfwm(Xfce的GNOME的默认窗口管理器)、twm(X提供的基本窗口管理器)。更多窗口管理器介绍参考 http://en.wikipedia.org/wiki/X_window_manager。窗口管理器可能只是个框架(如twm),也可能提供了全套的桌面环境功能(如Enlightenment)。高度全套化的桌面环境不仅有窗口管理器,还具备各种应用程序以及协调一致的界面。目前最流行的桌面环境是GNOME和KDE。而UNIX桌面环境多采用通用桌面环境CDE。http://tldp.org/HOWTO/XWindow-User-HOWTO/windowman.html

 

桌面环境

桌面环境是一系列X客户端应用程序的集合,旨在为计算机提供一个直观、便捷、协调一致的图形用户界面。通常包含窗口管理器、图形库、文档系统等组成部分。常见的桌面环境有KDE、GNOME、Xfce等。

以GNOME桌面系统为例,它由许多不同的项目构成,最重要的项目包括如下这些:
GTK+       ——构件工具包
Metacity       ——窗口管理器
Cairo        ——复杂的2D图形库
LibXML       ——为GNOME设计的XML库
ORBit       ——使软件组件化的CORBAORB
Pango       ——i18n文本排列和变换库 Bonobo——复合文档技术
GObject      ——用于C语言的面向对象框架
GConf       ——保存应用软件设置
GNOME VFS    ——虚拟檔案系统
GNOME Keyring ——安全系统
GNOME Print    ——GNOME软件打印文档
GStreamer     ——GNOME软件的多媒体框架
Human Interface Guidelines ——Sun微系统公司提供的使得GNOME应用软件易于使用的研究和文档X显示管理。

 

X显示管理器

在X窗口系统中,显示管理器是一个用来显示图形化登录提示的程序。通常用来运行一个或多个X服务器,选择并管理某个XServer使用的桌面环境。X Window系统默认的标准显示管理器是XDM。其他X显示管理器有:GDM(由GNOME提供)、KDM(由KDE提供)、LXDM(一个轻量级的显示管理器 http://wiki.lxde.org/en/LXDM)、SLiM(一个独立的登录管理器)、CDM(一个Linux下的超轻量级控制台显示管理器)、xlogin(X Window登录和独立的XDMCP服务器)、Enter(轻量级的图形登录管理器)、Orthos(另一个轻量级的解决方案附带真正的结构化主题)、nodm(针对收款机、电器和移动电话的自动登录的显示管理器)等。这些显示管理器在基本的显示管理功能之外,还提供了检查过期密码或执行一些管理任务等附加功能。
在大多数Linux发行版中,系统当前使用的显示管理器由/etc/X11/default-display-manager文件选择(使用GNOME或KDE的现代Linux发行版通常不再采用这种配置方式)。

 

用户界面组件组件工具包GUI ToolKits

也称为Widget Toolkits,是一些基本的GUI的构件元素的集合。他们一般以库或者应用程序框架的形式出现。X早期的ToolKits有Xaw、Motif、Tk等,Motif 为CDE提供基础工具包。目前比较新的工具包包括Qt(用于KDE)、GTK+(用于GNOME)、wxWidgets、FLTK、FOX。他们用来构建Linux、UNIX系统下的X应用程序,作用类似于Windows平台上的MFC、.Net的Windows Forms、Mac OSX中的Cocoa,或者Java中的AWT、Swing、SWT等等,参考http://en.wikipedia.org/wiki/Widget_toolkit

 

Xlib

上述的这些形形色色的X应用程序都是X Window系统中的Client,他们与X Server之间的接口就是Xlib。Xlib是X协议的具体实现,是X Window System协议的客户端,发表于1985年,以C语言撰写。其功能是与X server沟通,传输X协议。有了Xlib,程序员在编写X程序时就可以不必了解X协议的细节。但目前很少有应用程序会直接使用Xlib,通常只有GTK+、Qt等ToolKits会直接或通过其它库简介调用Xlib。其它X应用程序基于ToolKits构建。

Xlib在X Window中的地位,就好象libc在整个操作系统中的地位一样:X Server的角色就如同操作系统的核心,libc提供了呼叫核心系统调用的接口,同样,Xlib可以直接与X Server沟通。对编写X Window应用程序的人来说,则最底层可用的函式库就是Xlib。 Xlib常见的应用有Intrinsics(Xt)、Motif、GTK+、Qt、Tk等。

简单的说:GNOME、KDE等桌面环境由Metacity、KWin等窗口管理器以及其它应用程序组成,这些应用程序又是构建于Qt、GTK+等ToolKits基础之上,而Qt、GTK+等ToolKits构建于Xlib之上,Xlib负责与Xserver直接交互。

目前XCB有可能取代Xlib。

 

XCB

XCB,全称X protocol C-language Binding,目标是降低函数库的大小与复杂度,并可直接存取X11 protocol,以期用来取代Xlib。XCB提供了transport layer让尚未修改的程序也可使用XCB(通过Xlib/XCB)。JRE,vmware这些程序都使用了XCB库。如果原本使用xlib的程序没有按照规范编写,在使用XCB时就会发生assertion。要避免出错主要有两个办法:退回Xlib,或者在XCB源代码中注释掉assert语句并重新编译安装XCB。

 

OpenGL/Mesa3D

Mesa3D是一个开源的三维计算机图形库,以开源形式实现了OpenGL的应用程序接口。正如Windows平台上的Direct3D一样,并没 有一个程序叫做Direct3D,Direct3D只是微软定义的一个3D图形框架,微软定义了编程接口,具体库函数的实现和执行都是由显卡厂商提供的显 卡硬件和驱动程序完成。OpenGL也只是一个3D图形应用程序编程接口规范,具体实现同样依赖硬件厂商。为了开发和调试方便,Direct3D包含了一 个纯软件实现的图形库,可以通过创建一个Reference设备来调用,而接口和调用硬件设备的一样。同样,OpenGL也有一个与此类似的纯软件实现的图形库。在Windows平台上 运行OpenGL的话,这个纯软件图形库由微软提供,在OpenGL32.dll这个文件里实现(只实现了OpenGL1.1标准),在Linux平台 上,就是由这个Mesa3D提供。Linux上现在把Mesa做为API,为OpenGL应用程序提供了完整的接口,在后端,Mesa通过后面讲到的DRI技术来使用GPU的硬件加速功能,这样碰到硬件不提供的特性,可以自动调用Mesa软件实现的功能。


MMX/SSE/AVX指令集

分别是MultiMedia eXtensions、Streaming SIMD Extensions、Advanced Vector Extensions的缩写,这都是Intel提出的一些CPU扩展指令集。这些指令的特点或者说作用就是寄存器位宽比较长,支持SIMD(单指令多数据)。SIMD顾名思义就是一条指令可以有多个操作数,这在多媒体应用中非常普遍,比如可以对RGBA格式的颜色值的4个通道同时运算,因此3D应用程序或者驱动程序中都要涉及到。

GLX

如前所述,随着硬件操作被移入内核,从X11R6.7开始XServer通过OpenGL访问视频硬件。而OpenGL和X Window之间的联系正是由GLX(OpenGL Extension to the X Window System)完成的。Direct3D图形库中有处理D3D图形协议的函数,也有为了与Windows图形系统交互的函数如DrvEnableSurace、DDCreateSurface等等。OpenGL下同样有处理图形协议的核心库函数(以gl为函数前缀),也有用来与图形系统交互的窗口库函数,在Windows使用OpenGL,这个窗口库是WGL(以wgl为前缀);在Mac OS下使用OpenGL,这个窗口库就是AGL、CGL或者Cocoa;在Linux下,这个窗口库就是GLX(以glx为前缀)。OpenGL中还有实用库函数(以glu为前缀)、辅助库函数(以aux为前缀)等方便程序开发使用。

有了GLX,基本上所有的OpenGL应用程序都能在Linux上运行了。又因为OpenGL画的东西最后还是通过GLX送到X Server,所以,即使做为Client的OpenGL应用程序和X Server运行在两台不同的电脑上,也一样可以很好的呈现。

一个OpenGL应用程序如果调用了glxXXX这样的函数,那就是通过GLX/XServer来完成3D渲染的了。

GLX是个架构,在Linux中真正提供了这个接口的是libGL,libGL也提供了OpenGL的其它API,也提供DRI的API。

DRM/DRI

有了GLX就能支持OpenGL程序了。可是仍然通过X Server来画。虽然这可以支持Remote Client,但在如今PC高速普及的年代,大多数情况下都是本机运行,所以可以不通过X Server完成渲染的话,程序架构上可以少走很多path。于是就催生了DRI(Direct Rendering Infrastructure,直接渲染机制)技术。

DRI架构由下面这些部分组成:首先是DRM(Direct Rendering Manager,直接渲染管理器)。DRM 驱动运行于内核,它主要包括两个内核模式的模块,一方面DRM给用户空间的程序提供API,让这些程序可以访问到硬件功能,另一方面DRM要管理硬件并提供必要的安全保护。这样来讲,DRM有点类似于Windows7中WDDM图形驱动架构下的Direct X Graphics Kernel Mode Runtime(DXGK,dxgkrnl.sys)。

其次是图形硬件的驱动程序。这也主要由两个模块组成,一方面要负责对硬件DMA、AGP内存管理、资源管理和硬件互斥访问,为了支持多个OpenGL应用同时运行,3D图形硬件必须被看成一个共享资源。需要使用“锁”来实现互斥访问。这个模块是个内核模式的模块,通常位于/lib/modules/kernel-version/misc目录,命名为device.ko(如mga.ko,r128.ko),由XServer自动装载,类似于Windows WDDM架构下的Kernel Mode驱动。另一方面驱动要将OpenGL命令序列转换成硬件命令,然后它通过前面的模块传输到硬件,也就是说这个模块的作用是处理OpenGL的协议,这个模块运行在用户模式,通常在/usr/X11R6/lib/modules/dri目录,命名为device_dri.so(mga.so,r128.so),由LibGL.so库装载,实现了OpenGL的API。类似于Windows WDDM架构下的User Mode驱动。这两个模块构成的驱动基本上是实现了整个OpenGL渲染管道。

在Linx中,这个驱动的内核部分叫做内核模块,用户态部分叫做DRI 3D驱动。大多数DRI 3D驱动都是基于Mesa的,也就是说翻译OpenGL的协议都直接使用Mesa写好的程序。然而,Mesa不是必须的,驱动开发人员可以像Windows中一样实现自己的3D DRI驱动。

再次是libGL,libGL提供OpenGL API(也包括了GLX接口,所以说libGL不是DRI独有的组成部分,只是DRI架构也要用到libGL),这有点类似于Windows WDDM架构下的用户模式的Runtime(d3d9.dll等)。当使用间接渲染时,libGL创建GLX协议消息,通过socket将它们发送到X Server。当使用直接渲染时,libGL装载相应的DRI 3D驱动,然后将OpenGL调用分发给该驱动。libGL也支持异构、多显卡,即一个系统中有多块不同类型的显卡。libGL可使用应用程序同时使用这 些显卡。一般来讲,libGL从/usr/X11R6/lib/modules/dri目录装载DRI 3D驱动,也 可通过设置环境变量LIBGL_DRIVERS_PATH来改变装载路径。

2D XFree86 驱动

对于每种图形卡,都有一个 XFree86 2D (或者 DDX)驱动,它负责初始化、管理 显示和完成 2D 渲染。XFree86 4.0 引入了一个新的设备驱动接口(XAA),它使 得 XFree86 驱动向后兼容。

XFree86 驱动一般在 /usr/X11R6/lib/modules/drivers 目录下,名字为 device_drv.o。

每个 2D 驱动都包含一些代码 bootstrap 3D/DRI 特征。

 

每个使用DRI的应用程序直接对视频硬件编程。这和GLX大相径庭,GLX发送绘制命令给服务器,由服务器代劳对硬件编程。 DRM内核驱动协调多个用户防止冲突。此模型的优点在于OpenGL绘制能够在无须进程切换及传输数据至主控服务器开销的情况下发生。一个缺点是图形卡必须处理大量图形上下文切换。工作站级卡一般能应对裕如,但部分消费级卡不行。Microsoft的WDDM架构也已遇到这个问题,并要求DirectX 10硬件提供高级硬件上下文切换支持。

从X11R6.7开始,X.Org中就包含了GLX,也包含了Mesa和DRI。所以目前的XServer都是与OpenGL协作的Server。这样的Server即支持用GLX写的OpenGL应用程序,也支持DRI方式的应用程序,一个OpenGL如果没有调用glxXXX函数,而是调用DRI API,那么它就是完全通过DRI来渲染的了。

 

XGL、Xglx、Xegl

Linux平台可以运行OpenGL应用程序了。然而随着GPU的急速发展,Windows和Mac的桌面系统都采用了GPU加速,Linux显然也要有类似于Windows Vista/Windows7的DWM这种可以充分利用GPU硬件特性的桌面系统。

XGL是一个X Server的架构,利用了OpenGL的图形加速能力。XGL通过glitz位于OpenGL的上层。XGL要利用聚合窗口管理器(如Compiz或Beryl)的帮助,才能完成对基于X、XVideo的程序像对OpenGL程序一样提供硬件加速。XGLX和XEGL是XGL的两个实现。

Xglx是XGL架构的第一个后端实现,也是目前XGL发展的焦点核心。其原理就是在已经存在的X server上用GLX开一个OpenGL窗口,Xglx再来使用这个OpenGL窗口,折合Xnest的概念类似。未来这种运行模式将只提供给专业的开发者,因为它存在着一个看似多余的X Server机制。2006年XDev会议上,NVidia表示这是一个错误的发展方向,因为这让XGL的后端竟然只是一个次级的OpenGL窗口(layered server)而不是一二独立的个体(like XServer),这将使很多显卡特效受(像3D Stereo Glass)限于前最前端的X Server而无法呈现。尽管如此,这个设计方法毕竟是将整个后端"原型机""完整实现"的最快速简单的一个方式。这样的做法可以让开发者避免开发一些已经存在于前置X Server上的项目,而把精力集中在实现XGL本身的独特架构。

Xegl曾被认为是Xgl的未来,X Server开发过程的长期日标。它和Xglx Server分享部分绘画代码,但是OpenGL可绘画的初始化和上下文管理则是由EGL API管理,EGL由Khronos开发(EGL是窗口系统无关的,相当于GLX和WGL,GLX用于在X Window系统上支持OpenGL,WGL用于微软Windows)。当前的实现是使用Mesa 3D提供直接的OpenGL渲染到帧缓存或通过DRI到图形硬件。Xegl当前开发已经暂停了。

DirectFB

Wayland

  

  

GTK+

GTK+是构建在Xlib之上的GUI Toolkits,是构建应用程序的框架。目前有GTK+的基础开始向Wayland转变。

glib

glib是GTK+的一套函数,不要混淆glib、Xlib和glibc。不管以后GTK+是基于Xlib还是Wayland,它都会给应用程序提供glib这个开发库。

glib是在开发gtk+的过程中,慢慢总结和完善的结果。glib是用C编写的,glib为c编程提供了动态数组、单/双向链表、哈希表、多叉树、平衡二叉树、字符串等常用容器,完全是面向对象设计的,实现得非常精致。免除了在C编程工作中成千上万个人,成千上万次的重复劳动。

posted @ 2011-03-01 11:17  童年的纸灰机  阅读(699)  评论(0)    收藏  举报