2009年5月30日星期六

Linux 图形现状

在淡出 Xgl 方面的工作之后,我仍收到大量 email
并阅读许多帖子。我的结论是大多数人并没有真正理解 linux
图形方面正在发生的事情。人们无法看清整体的图景,这是可以理解的。图形是一个庞杂的领域,包含着众多软件组件和相互竞争的开发小组。作为一种尝试,
我写了这篇文章,来解释所有这些部分是如何组织到一起的。
俱往矣

今年是 X server 的二十一岁生日。脱胎于 Athena 项目,自 1984
年发端以来,过去的那些年中,它很好地满足了 Unix 社团的需要。 X
已经被广泛应用,推动着今天的大多数 Linux 桌面。这篇 Wikipedia
文章2提供了更多详细资料,除了两项开源的主要 X
创新,它们允许提供跨平台支持和网络通透性。

然而,自 X 着手设计,20
年时光匆匆流逝,视频硬件今非昔比了。如果瞥一下一块现代视频芯片的架构图,你会注意到一个小小的标记着
2D 的区块。那是由于芯片的 90% 专注于 3D 管线。你正好为那些 3D
硬件付了费,因此如果桌面能利用它那不是很棒吗。很多人并未意识到 3D
硬件也可用于绘制 2D 桌面。看看你的屏幕,它是一块平平的 2D
平面,对不对?任何由 3D 硬件生成的图画最终都要显示在平的 2D
屏幕上。此一事实应能让你认识到,通过适当地编程,3D 硬件可以绘制 2D 桌面。
图形供应商

多年以前图形芯片供应商乐于为他们的硬件公开数据表和编程信息。但是随着专利库的增大,对专利侵权的恐惧也增大了。现在图形芯片供应商将关于芯片的全部信息秘而不宣,作为使专利持有人更难搜寻侵权行为的一种手段。至少这是供应商给出的隐藏编程规范的理由。并且他们也宣称隐藏编程规范可使竞争对手更难对他们的芯片做反相工程,但我对此同样持怀疑态度。所有这些隐藏规范使为这些芯片编写开源设备驱动异常困难。作为替代方案,我们被迫依赖供应商来为最新的硬件提供驱动程序。如果你尚未留意,请注意图形供应商的确仅仅关心
MS Windows 因此他们只为 Linux 提供最低程度的驱动支持。也有例外。Intel
为他们的部分芯片提供开源驱动。Nvidia/ATI 提供专有驱动,但是落后于 Windows
版本。总的后果是一批非常参差不齐的驱动,品质从良好到完全空白。
桌面选择

其它的桌面选择, Windows 与 Mac,都拥有 GPU
加速的桌面。它们明显地、眼见地比他们的前辈要好。某些情况下这些新的带加速的桌面的绘制速度能够比旧的模型快过一百倍。在未来的某个时候,图形芯片供应商会移除标记为
2D 的那个小点,仅给我们留下 3D 硬件。Microsoft 和 Apple
看起来已经得到信儿说 3D 是未来的方向并开始进行转换。另一方面。几个 X
开发者曾告诉我停止谈论竞争的图景。他们说他们想做的是让 X 更好。尽管 X
开发者可能无动于衷,我确信当由于缺乏竞争力的 GUI
而开始丧失份额的时候,Redhat 和 Novell 的经理们不会赞同此一观点。

在桌面上使用 3D 并不只是为了制造更华丽的视觉效果3。有大量利用 3D
能力生成的效果只是虚饰,但仍有些真正的理由运用 3D。简单来说 3D 快过
2D,没有人动手使他们的 2D 功能更快,所有的硅工程师都转向了 3D
。你能够完成快速、任意的图像处理,例如色彩空间转换,拉伸/卷曲,等等。我曾见过某些消耗主
CPU 几秒钟才完成一帧的超级复杂的过滤操作在 shader
硬件上以实时达成。支持任意色彩映射的不同的 Windows 色深(同时支持 8、16、24
位窗口)。为项目管理者提供极快的屏幕翻转/旋转,为视力不良者提供全屏缩放,等等。分辨率无关性允许对象以任意分辨率/尺寸渲染,当显示到屏幕上的时候再降低/提高取样精度。更多有意思的应用在后面讨论窗口化的小节里阐述。
当前的 X.org 服务器

X.org 即将发布 X11R74。这个发布的主要特性是 X
源代码库的模块化。尽管对大多数用户并无意义,模块化将使在 X
源代码上工作容易得多。模块化之前 X 源代码树包含约 16M
行代码,全部作为一个单独的项目构建。模块化之后,代码树将分解为一打左右的独立部分,使项目的构建和理解容易得多。
X,作为操作系统

X
究竟是一个应用程序还是一个操作系统?在这里有一份优秀的参考文献帮助我们理解一个
X server 是如何组织到一起的。尽管写成已有 8
年之久,大多数内容仍然切题。如果你不知道何谓 DIX、mi、DDX、CFB
什么的,最好先读读它。大概在 X11R6.3 那会儿 Xfree86 分裂了,X
服务器的设计变得极度跨平台。X
面向的众多操作系统对硬件侦测这类事情提供不同程度的支持。为了解决此类问题,X
添加了代码侦测 PCI 总线来搜寻硬件,代码搜寻视频 ROM
并运行它们来重置硬件,搜寻鼠标和键盘并提供驱动,管理多个 VGA
设备的问题,最后甚至提供它自己的模块加载器。这一步让 X
开始模糊了它是应用程序还是操作系统的界线。虽然某些操作环境的确需要这种类
OS 支持,实现这些特性来提供同样服务的操作系统,比如 Linux, 终于落到 X 和
OS
之间互相冲突的境地。当然操作系统是一个移动的标靶,十年前恰当的决策今天看来可能已经不合时宜了。

Linux 内核提供在 BSD 和某些其它平台上并不存在的子系统,比如 PCI 和
framebuffer。出于对跨平台支持的兴趣,X
服务器内建了和这些子系统平行的实现。在过去对此确有需求但在当前 Linux
系统上这导致两块不同的软件都试图控制同一个硬件。Linux 具有多个非 X
的视频硬件使用者,它们与 X
交互的唯一位置就是内核。内核提供了很多机制来协调这些使用者;反正就是 PCI
子系统,输入驱动,热拔插检测,设备驱动这档子事。为了和 Linux
一致,最佳方案是使用内核提供的特性,仅仅在其它平台上运行这些重复的库。Fbdev
和 XAA 驱动是冗余驱动的主要例子。

Linux
有一个优秀的热拔插系统,图形系统真的有必要开始利用它。显示屏可以从多个来源上热拔插。有一个传统的热拔插来源;有些人将新的显示卡插入热拔插背板。然而存在其它非传统的途径来获得一次热拔插。另一位用户可能正在使用你要加到你的屏幕组的显示屏,当他注销的时候你就会获得一次热拔插。你可以将一台外部监视器连接到笔记本电脑上,从而生成一次热拔插。你可以以无线方式通过
DMX 或 Chromium 这类东西连接到显示墙。USB
也是很多热拔插的来源。用户能够热拔插鼠标、手写板、键盘、音频设备、甚至图形适配器。既然不和内核的热拔插系统通信,当前
X 服务器不能处理这些情形中的任何一种。

标准的 Linux 桌面使用 rooted X。Rooted X 指的是 X
控制最上级桌面的绘制,窗口则处于它之上。 Cygwin/X,Directfb 和 Apple
Darwin 都是用 rootless
X。这些环境拥有另一套窗口系统负责显示。这些宿主窗口系统绘制主桌面并实现它们自己的窗口
API。通过运行在 rootless 模式,X 能够象这样被整合到一个宿主窗口系统中。在
rootless 模式下应用程序窗口绘制到系统内存中的缓冲区。在适当的时候 X
窗口和宿主窗口系统同步,于是它们的内容被显示出来了。Rootless X
也提供协议在两个环境当中传递鼠标和键盘事件。
X Render

现在讲到 X Render 扩展。Keith P 于公元 2000 年宣称现存的 X
服务器无法有效地绘制清晰的、反锯齿的文本,起而提出 X Render
扩展来解决此问题。X Render 是核心 X 特性,允许漂亮的字体和 Cairo
这类事情在 X 服务器上实现。X Render 给 X 服务器添加了 Porter-Duff
操作5。这些操作允许图面以不同的方式合并。它们与 OpenGL
纹理和纹理操作的概念非常相似,但仅仅是相似而非完全一致。
XAA

XAA,既 X 加速体系结构,是在 XFree86 4.0
中引入的。为达成跨平台可迁移性,XAA
没有利用内核设备驱动,而在用户空间实现了 2D
视频驱动。用户空间驱动的确可行,然而既然不存在基于内核的驱动,Linux
内核就无法追踪 X 对硬件作了些什么。直到你的系统引导完毕,X
都未开始运行。你应该希望启动过程中在启动 X
出麻烦的情况下仍有显示,不是吗?Linux
下的启动显示通过文本模式(控制台)驱动实现,最常见的是 VGAcon。由此 Linux
下你困于两套设备驱动, X
和控制台的,都在试图控制同一块硬件。XAA、控制台和虚拟终端(Virtual
Terminal)这类 Linux 内核功能的组合会导致大量的冲突,不过容后细谈。
EXA

EXA 对现存 2D XAA
驱动的替代允许当前的服务器模型能工作更长一点。它通过提供远为高级的驱动和内存管理
API 来加速 X Redner 扩展。起初 EXA
定位为针对包括旧硬件在内的所有硬件的方案。但这并未成为现实。如果老旧的硬件缺少加速渲染核心所需的
alpha 混合硬件,你基本上就无能为力了,虽然EXA
有可能通过较好地管理显存帮助增强这些芯片的性能。所以归根结底硬件 EXA
相当程度上工作于现存OpenGL 驱动同样的硬件。Nv 和 i128
这样的例外也是有的,这些硬件具有 3D 能力却不存在 OpenGL 驱动。可以确定的是
EXA 会不断扩张来探求更多芯片中的 3D 能力。EXA
牌创可贴能顶一阵子,但非长远之计。必须牢记的是 EXA/render 仍然仅是庞大的
Mesa OpenGL API 的子集,而随着时间的推移我们总会寻求越来越多的特性。
Cairo6

Cairo 的目标是成为一套高品质的、同时适用于打印输出和屏幕显示的 2D 绘制
API。它被特别着意设计得同 X Render 扩展协同工作,实现了 PDF 1.4
图像模型。有趣的操作包括笔划和三次 Bézier
样条曲线,转换与合成半透明图像,反锯齿文本渲染。Cairo
的设计是可移植的,且允许可挂接的绘制后端例如图像、glitz、png、ps、PDF、svg、quartz、GDI
和 xlib。目前 Cairo 已经过大约两年的开发,在 GDK 和 Mozilla
即将到来的版本中应该能看到部署。Cairo 的主要目标是使处理屏幕上的高端 2D
图形更容易,然后轻松打印它们。可挂接后端允许应用程序使用相同的代码绘制和打印。

Cairo 后端之一,名为 glitz,基于 OpenGL 实现了
Cairo。这里有一篇上佳的论文说明了glitz 的细节。既然 Cairo 同时实现了 xlib
和 OpenGL
后端,我们可以在两者间做一直接性能比较。在已发表的基准测试中,OpenGL
的速度在所有地方都以 10 到 100 比 1 的比率击溃了
XAA。这样巨大的性能差异正是由于 glitz/OpenGL
对图形芯片上3D硬件的运用。比较 glitz 和 xlib 上的 Cairo
是一个展现3D硬件具有在 2D 屏幕上绘制之完美能力的好方法。
DRI 与 OpenGL

DRI,直接渲染机构7,实现了与 X 服务器协作的 OpenGL。DRI
有四个主要组件。首先,libGL 提供 OpenGL
API,并作为在多个驱动间的切换器。其次,存在一套用于编程图形芯片的硬件相关的
DRI 库。对于DRI 驱动未能提供的 OpenGL
特性你需要一套软件后备实现。这个后备实现由 Mesa 提供。注意 Mesa
是一套完全的 OpenGL
软件实现。一块没有提供任何加速的卡仍然能够通过将每一个函数都交给 Mesa
来实现 OpenGL8。最后,就是 DRM,直接渲染管理器。DRM
驱动运行于内核,管理着硬件并提供必要的安全保护。

DRI 有意思的方面在于名字当中的 direct 代表的那部分。每个使用 DRI
的应用程序直接(directly)对视频硬件编程。这和 X
大异其趣,在那里你发送绘制命令给服务器,由服务器代表你对硬件编程。 DRM
内核驱动协调多个用户防止冲突。此模型的优点在于 OpenGL
绘制能够在无须进程切换及传输数据至主控服务器开销的情况下发生。一个缺点是图形卡必须处理大量图形上下文切换。工作站级卡一般能应对裕如,但部分消费级卡不行。Microsoft
已经撞上这个问题,并要求 DirectX 10 硬件提供高级硬件上下文切换支持。

DRM
还实现了比普通用户拥有更多能力的主控用户的概念。这些额外能力允许图形设备被初始化以及GPU
资源的消耗受到控制。当前的 X 服务器,以根权限运行着,作为 DRM
主控用户工作。实际上并无 DRM
主控用户运行在根权限下的真实要求,而且存在一个初步的补丁移除此要求。

一旦硬件缺少某种特性,Mesa
就以软件实现它。这称为软件后备。人们有时被这个绕住了。他们说他们的 OpenGL
没有被完全加速而X服务器一切正常。再想想看。两款驱动都运行在相同的硬件上。
OpenGL 未能完全加速,因为它提供了很多需要加速能力的特性,而 X
仅提供少量此类特性。如果你利用了同时存在于两款驱动 API
中的特性,他们可能都会被加速。如果没有,那就开始动手编程来修复对应的驱动。
安全性与根权限

Linux 内核包含了约 1000 万行以根权限运行的代码。X 服务器包含了 1600
万行代码,其中大多数运行在根权限下。如果搜寻安全漏洞,你认为最好下注在哪一处呢?其实并无技术理由要求
X 服务器以根权限运行。打着跨平台兼容性的旗号,当前的 X
服务器以根权限运行,以便从用户空间直接对视频硬件编程。 Linux
有个方案针对这种情况。你可以把特权代码放到设备驱动里,无须特权即可运行用户空间应用。一款一般的显示卡的特权设备驱动在
100KB 左右。那可是比 1600 万行少得多的代码需要审核。
怀旧版硬件

任何视频硬件,低档至 VGA 适配器,都可以运行 X 服务器,而且 Mesa
会非常乐意以软件实现整个 OpenGL
API。问题是有多快。并没有很多编程活动投注于将一块 VGA 卡变成 ATI
X850。这些旧硬件能被当前的 X
服务器很好地支持。但是新系统的设计正围绕新的硬件展开,并且它们很可能在旧硬件上表现差劲。你也许应该考虑一下升级你的视频硬件;具有适当
OpenGL 性能的全新图形卡能在 40$
的价位买到,二手价格甚至更低。作为替代,你也可选择不要升级,继续运行那些旧的对你已经够用的软件。
内核级图形支持

当内核开始引导,你面对的就是引导控制台。在 x86
平台上,最常见的引导控制台为 VGAcon。 VGAcon 使用你图形卡上的遗留硬件 VGA
支持。既然几乎所有 x86 图形卡都支持 VGA, VGAcon
为此平台提供了一个通用控制台。在非 x86 平台上你也许无法获得 VGA
硬件支持。在这类平台上你通常加载针对特定芯片的帧缓冲驱动。内核提供为数众多的
fbdev 驱动,由此范围相当广泛的硬件都被支持了。
VGA之余孽犹存

IBM PC 的原始设计定义了少数位于固定的、预知的地址的外部设备,例如 COM1 在
0x3F8。很不幸,大多数图形卡的 VGA
支持是这些位于固定地址的遗留设备之一。只要你的系统中仅存在一块图形卡,VGA
并不成问题。插入第二块,现在你有了两片都试图独占相同总线地址的硬件。

目前的 X 服务器包含处理多块 VGA 适配卡的代码。但是这些 X
服务器代码并不会感知到这些设备上的其他用户,而是会让他们乱作一团。搞乱这些程序并不好玩,所以我们需要某种方法来协调
VGA 设备的多个用户。Linux 上最佳方案就是向内核添加一套 VGA 仲裁机制。BenH
已经动手在搞一种 OLS 上讨论过的。

另一症结在于多块显卡的初始化。显卡具有 ROM,又称
VBIOS,在引导时执行以初始化硬件。出于历史原因,很多这类初始化用到了 VGA
支持。既然我们仅能有一块遗留 VGA 设备,系统 BIOS
转移了问题,仅初始化第一块显卡。在引导期间某个较迟的点初始化第二块卡也是可能的。这是通过以
vm86 模式运行第二个 VBIOS 并同等使用单个遗留 VGA
设备来达成。为了使问题更复杂,存在两种常见 ROM 格式即 x86 代码和 Open
Firmware。既然供应商对他们的 Open Firmware 型号收取高额费用,在非 x86
机器上使用 x86 视频硬件是很常见的。为了让这种做法可行,VBIOS 不得不使用
x86 仿真器来运行。BenH 也在为这个问题的一种方案工作。

Fbdev,又名帧缓冲。Linux
下,帧缓冲主要用途包括:初始化硬件,检测连接的显示设备,确定它们的有效模式,设定输出模式及配置,硬件光标,黑屏处理,色彩映射,取景和休眠/恢复。内核中存在大量帧缓冲驱动,它们实现了对这些特性程度不同的支持。请注意,尽管
fbdev 接口是基于内核的,并无障碍阻止存在实现于用户空间的辅助应用 fbdev
支持。辅助应用可用在缺少源代码的时候让 VBIOS 可用。

当你运行 VBIOS
时它建立一套非常低级的、用于控制显示的入口点。这事太细节化,我不准备解释
VGA、 Int10 和 VESA 之间的所有差异。作为概括, VGA 是 IBM
创立的基本硬件寄存器标准。 Int10
专注于用软件中断的方式处理显示输出。软件中断仅工作在 x86 实模式下,且除了
GRUB 之类很少被使用。支持 Int10 功能的代码来自 VBIOS,当 ROM
运行时被安装。仅允许存在一个被安装的 Int10 驱动。VESA 取代了 Int10
模式并扩展它到保护模式。配置内核时,有三个驱动: VGA 和 VESA fbdev,
fbconsole 也需要加载运行,VGAcon 则总是必要的。在非 x86 系统你通常需要
fbdev 和 fbconsole。
让多用户运转

Linux
乃多用户操作系统。且它一贯如此。但是连接多个用户的唯一途径就是通过串行线和网络。如果你安装多块显示卡并在本地跑多用户会怎样?此路不通。有一堆
Linux console project 这样的补丁和针对 X
的各种黑客行为试图让它运作起来。问题在于 Linux
控制台虚拟终端系统控制着本地显示卡且只能有效地支持单个用户。注意 fbdev
被多个用户使用的时候可胜任愉快,单用户的是 VT 系统。

多个本地用户在学校、监控系统、网吧甚至家里这样的地方都有应用。由于普通 PC
仅支持单 AGP 插槽,过去对多显卡支持的需求并不紧迫。多块 PCI
显卡可以工作,但性能不彰。也有带有多个 AGP 插槽的高端机器,但并不普及。PCI
Express 改变了这种状况。通过 PCI
Express,所有插槽从机理上是等同的。唯一不同的地方就是有多少通道连接到每个插槽。硬件上的变更让构建具有多个高性能显卡的系统变得轻而易举。计划中的
PCIe 支持芯片允许最多 16 块显卡共存于单一系统中。
分裂控制台

当分析控制台系统时,你会很快注意到有两种不同类型的控制台用法。系统控制台,提供引导显示并并勇于系统错误报告、恢复和维护。以及用户控制台,用户登录并处理命令行交互或编辑的普通显示。在目前
Linux 控制台系统中,两种用法都由同一套控制台代码处理。

按照用途分离控制台代码是可能的,能够修正很多 Linux
控制台当前存在的问题。一开始,系统控制台应当完全可靠且防篡改。它不必很快。它需要尽可能以最简代码实现而且它需要在系统中断和内核
panic 时保持运作。用处包括系统恢复及单用户模式。引导时显示和 kdbg
支持也是可能的。系统控制台会提供 SAK
和安全登录屏幕。为了支持无关用户登录到显示卡的每个头,它需要无关地在每个头上实现。一种访问新系统控制台的方式是通过
SysReq,控制台将覆盖你当前的显示并使用你当前的显示模式。Novell kernel
debugger 以这种方式工作。系统控制台不支持
VT,而且不存在控制台切换。既然它清楚你的显示模式,它能够在紧急情况下抢占你的显示,比如一次致命的
kernel OOPS9。

系统控制台的设计使用 fbdev
来追踪特定的模式及扫描缓冲位于何处。为了使它尽可能地可靠任何加速支持都被移除。
Fbconsole 则使用系统 CPU 直接处理帧缓冲。控制台通过利用 fbconsole
中现有位图字体支持直接绘制到输出缓冲来显示。

用户控制台是系统控制台的对立面,它需要是高性能和用户友好的。一个用户空间实现让它易于通过为每个用户创建一个进程来处理多用户。用户空间(实现)允许全速的通过
fbdev 和 DRM 的 GPU 加速。你还能轻易访问 Xft/FreeType 获得 Unicode
支持。借助适当的设计,控制台甚至允许分配不同的用户到不同的头上。通过适当编码的热键,它能够表现得和现存
VT 一样且支持控制台切换。

既然目前的控制台是合并在一起的,当你切换 VT
时你同时遇到这两种类型。新的模型中当前 VT
切换键会把用户空间控制台提供给你。 SysReq
则激活系统控制台。连接到系统控制台上的 shell
进程能运行于高优先级,让从一个失去控制的进程手里夺得控制权更轻易。
物以群分

本地多用户支持暗示着 Linux 会为用于 UI
的外设实现控制台组的概念。控制台组是发起 login console
所须硬件的集合。一个范例组包括显示器、鼠标、键盘和音频设备。登录时, PAM
将这些设备的所有权赋予登入的用户。对此概念的有趣附加是将 USB hub
或端口作为控制台组的一部分包括进来。一旦用户登入,任何接在 USB
端口上的设备也属于他们。登出时所有这些又返回到未分派设备池中。
候补的候补10

小把戏们: directfb、 svgalib、 fresco、 Y Windows、 FBUI,诸如此类。
Linux 吸引了一票想在显示代码方面一展身手的人们。在当前的 VT
模型下,这些另类显示系统在 VT 切换时导致了很多问题。切换 VT
之后,新近激活的显示系统被允许对硬件干任何它想干的事。那包括重新初始化它,重编程它以及清除它的
VRAM。当你切换回来,原始系统被指望能从更动后的硬件状态下恢复。不仅仅是这些小把戏们才在VT
切换中造成问题。你能在控制台和 X 甚至两套桌面比如 X 和 Xegl 中切换。对具有
14 个寄存器和32KB 显存的 VGA 适配卡这可能不错。但对拥有 300
个寄存器、512MB 显存和独立 GPU 协处理器的显示卡而言它不是一个良好的模型。
合作无间

我确信对此问题的最佳方案是由内核为每种显示硬件提供单独的、广泛的设备驱动。这意味着
fbdev 和 DRM
这类冲突的驱动必须并入一套可协作的系统。它还意味着一旦基于内核的设备驱动加载,从用户空间摆弄硬件的行为就应予禁止。我怀疑如果
Linux 为不同的显卡提供广泛的标准驱动,许多创建另一版本Radeon
驱动的冲动会冷却下来。

这并不表示 fresco
这样的项目不能开发他们自己的显示硬件设备驱动。只表示你不得不卸载标准驱动,然后在运行新程序之前加载你的定制驱动。这种卸载/加载行为和内核中的其它驱动并无不同。运用热键在针对同一块硬件的两个活动的显示设备驱动之间跳转(VT
切换)将不再被支持。如果基本的驱动缺乏需要的特性,较好的方案是向标准驱动提交补丁。通过在标准驱动中实现需要的扩展,所有程序能共享它们,通过用户空间控制台系统在使用它们的应用程序间切换也会很容易。

若我们继续保持提供热键在显示驱动间跳转的 VT
设计,我认为用热键在磁盘和网络驱动间跳转也被实现才是公平的。
OpenGL|ES

Khronos Group11 是一个由超过一百家成员企业发起成立的新进标准组织。Khronos
Group 最成功的标准是 OpenGL ES。OpenGL ES
针对内存紧张系统定义了一套非常有用的 OpenGL 子集。它还定义了
EGL,一套平台无关的 OpenGL GLX/agl/wgl API 等价物。"EGL
提供机制创建可供诸如 OpenGL ES 和 OpenVG 这样的客户端 API
在其上绘制的渲染图面,为客户端 API 创建图形上下文,并同步 Client API
的绘制行为,让它和原生平台渲染 API 一般无二。这允许无缝地同时运用 OpenGL
ES 和 OpenVG 做高性能的、加速的、混合 2D 和 3D 的渲染动作12。"

EGL 假设了由操作系统的其它部分提供的窗口系统的存在性。但是 EGL
的设计是平台无关的,不象 GLX/agl/wgl,EGL API
中没有什么是局限于某个窗口系统的。所有引用到本地窗口系统的地方都由屏蔽指针来处理。

Mesa 开发者已经合计出了一些提议来扩展 EGL,以便一套窗口化系统能够实现于
EGL 之上。该扩展的核心提供了一套 API
来列举可用的屏幕,设置屏幕的模式和帧缓冲配置,摇动屏幕,以及查询属性。两个领域,硬件光标和色彩映射,仍然需要
EGL 扩展加以解决。向 EGL 添加这些扩展提供了足够的硬件控制来实现一套 Xegl
这样的服务器和窗口化系统。OpenGL 加上 EGL 和 Mesa 扩展提供一套真正可移植的
API 来访问多种形式的图形硬件,范围从当前的蜂窝电话到 Playstation 3 到 PC
到图像超级计算机13。

扩展后的 EGL API 能够很好地和 Linux
匹配。它提供了一个坚实的基础来构造窗口化系统或嵌入式应用。易于使用,这使它成为研发和体验版的有趣平台。它令你集中精力到你的新应用或窗口系统,忘记所有那些和硬件打交道的复杂性。

我相信 Khronos Group 是 X.org 和 Linux
图形社区一个重要的未加利用的机遇。大多数 Khronos
标准缺乏开源参考实现、开发系统支持以及一致性测试。Khronos Group
后台中不少在销售给予 Linux 的产品系统。如果 X.org
扩大它的宪章,它能够作为一个中立的非盈利媒介在创建开源参考实现和开发基于
Linux 和 Khronos 标准的系统方面与 Khronos Group
进行接触。这种伙伴关系允许Khronos Group 成员对 X.org 作出慈善捐赠,正如
IBM 对 Eclipse 基金会所做的那样。
完美像素

完全精确到每一个像素其实是个神话。你唯一能提高的只是逼近精确的程度。误差的来源是多方面的。你
LCD
背光的均匀度,打印机墨水的一致性,数模转换的质量,纸张的反光度,颜色匹配问题,GPU
中绘制算法的不同实现,等等。OpenGL
并不保证不同实现之间的像素级精确性。要获得像素级完美性,最接近的方法是在你的每一个输出目标上使用完全相同版本的
Mesa 软件。顺便提一句,X
服务器也不是像素精确的。我的经验法则是如果差异需要用放大镜才能找到那就足够接近了。人们在这一点上往往没搞清楚。如果你丢给
OpenGL
一张位图供显示,它会原封不动地复制那些像素到屏幕上除非你让它改变它们。像素绘制精确性的讨论主要是针对直线这类可缩放的向量。

子像素反锯齿字体(Subpixel antialiased font14)并不是问题,OpenGL
提供了多种显示子像素反锯齿字体的方案。如果你选择那么做的话,OpenGL
也能使用和当前 X
字型显示严格相同的机制。既然机制相同,字型的表现也就相同。锁定到某个特定算法也令人不快,这么做会妨碍前进。例如,这篇论文(视频)探索了一种在
GPU
上生成字体的全新方法15。这里还有另一篇让人感兴趣的论文,"使用可编程图形硬件做解析度无关的曲线渲染,Loop
和 Blinn",发表于 SIGGRAPH
2005。如果字体绘制拘泥于像素级完美精度,也许就不可能应用这些新技术。这些字型由
GPU
生成,使用了硬件内建的算法,无法被用户调整。转换轮廓字型到像素然后作为混合的图像加以渲染只是显示字型的一条途径。可编程
GPU 则提供了新的替代手段。任何眼光长远的 API 都需要把这一点考虑在内。
三代同窗

在当前的 X 服务器和许多别的窗口化系统中,窗口是用 painter's algorithm
绘制到屏幕上的剪裁多边形里。 painter's algorithm
用和真实绘画一样的方式工作 –
每一个后来的层都覆盖前一层。你先绘制背景,然后以反向 Z
序绘制每个窗口。如果不存在透明并且你清楚所有窗口的来龙去脉,你可通过剪裁长方形优化此算法(正如
X
所做的),使屏幕中的每个像素仅绘制一次。性能还可通过追踪破损来提升。仅仅破损区域的窗口需要重绘,屏幕的其余部分被剪裁多边形保护起来。更进一步的收益可由"背景保存"获得。窗口化系统意识到部分组件如弹出菜单在失效时向屏幕上重绘相同的内容。"背景保存"保存了这些弹出窗口下的屏幕并在完成后替代它。

合成机制利用了近期硬件性能增进的优势。通过合成,窗口能够离屏绘制到不可见的那部分显存上。窗口管理器随即将窗口与屏幕的可见部分合成到一起。合成仍然使用
painter's
algorithm,不过既然窗口管理器总是拥有所有窗口内容,就有可能实现透明窗口。透明通过在复制到输出缓冲区时混合窗口在屏幕上的内容与前一个窗口的内容来实现。这称作
alpha 混合(alpha
blending)。大多数现代硬件支持它。绘制闪烁也通过双缓冲得以消除。在此模型下,一切仍然是
2D 并有简单的 Z 序。

高端多纹理硬件能够防止一味使用 painter's
algorithm。每个处于屏幕上关注区域的窗口将被视为独立的纹理。你绘制多边形到屏幕上以再现窗口。对每个窗口/纹理,这些多边形在顶点上都具有适当的纹理坐标,由此纹理合并器硬件会合并所有窗口/纹理并生成期望的结果。在极端情况下,整个屏幕通过渲染单个多纹理矩形来重绘!这项技术超快,既然闪烁最小化了,你可能甚至无须双缓冲。多纹理化的完整桌面可能还在今天的硬件的能力之外,但这是一个随着每一代硬件正快速提升的领域。

Xgl 实现了合成模型。虽然并非必须,Xgl 会运用一项新的 OpenGL
特性,帧缓冲对象 (framebuffer object)。通过 OpenGL 的一项扩展,FBO
允许窗口管理器治下离屏应用程序窗口的非常有效的共享。这项扩展并不那么困难,毕竟我们已经跨进程共享了
pbuffer。对于应用程序,FBO
看起来好象普通的可绘制窗口。对于窗口管理器,窗口看起来就象纹理,可以通过多纹理这样普通的绘制命令来操纵。在这个模型下,应用程序窗口仍然是
2D,但现在编写 Luminosity 这样基于 OpenGL 地窗口管理器成为可能。基于
OpenGL 的窗口管理器能使用 Z 缓冲合并窗口,并跳出严苛的 2D Z
序限制。例如,一个窗口能够变换成波状,并反复和另一个窗口相交。

最终你能够打破应用程序窗口的 2D 限制,赋予它们厚度或别的 3D
性状。比方说,弹出窗口其实可以弹出在较高的 3D
坐标处。当你将它与光源组合使用,自然形成的下拉阴影即可取 2D
下的人工构造而代之。绘制漂亮的阴影是复杂的,然而借助 OpenGL
的能力,任务变得容易许多。Sun 的项目 Looking Glass
就是这种类型的窗口管理器。在 Looking Glass 的 demo
视频中演示了窗口厚度。Looking Glass 使用一个 rootless 的 X
服务器运行现有的 X 应用。窗口由此具有了厚度,并和 CD changer demo 中的真
3D 应用共存。

3D 桌面的概念并不那么古怪。自从 Windows 1.0
的并列窗口前进到可覆盖窗口时我们已经拥有了3D 桌面—一旦 Z
序被引入,桌面即成为一非透视的 3D 空间16。看看菜单和弹出窗口,3D
概念遍及桌面。实现合成的一个主要理由在于提供下拉阴影,很明显是 3D
空间的一个 2D 再现。甚至按钮这样的控件也通过 2D 仿真被做得象
3D。何不把它们画成 3D 的,让用户控制光源呢?窗口透明显然包含着 3D
概念。我们何不干脆承认桌面是 3D 空间并使用 3D 图形来绘制它呢?
划清界限

这个主题存在一些争论。通往基于 GPU 的桌面的开源转换 Linux
真的只有一个选择- Mesa OpenGL 实现。自然我们能够克隆
DirectX,但谁来编写全部的代码和驱动? OpenGL
是个不坏的选择。无论我们构建什么,它都是 Linux
上必不可少的一项要求。它是标准化的,由 ARB (architecture review
board,体系结构评审委员会)所掌控。它设计精良,文档齐备。它的部署和应用广泛。大学教授有关它的课程,大量关于它的书籍已经写就。很酷的应用程序和游戏在它之上运行。

应该在何种层次上划分图形设备驱动的界线?XAA 和 fbdev
在低层次上划下界线。这些 API 把自己卷入到 framebuffer、bitblit
也许还有直线绘制的众多像素中去。在这一层次上图形芯片提供的任何特性不是根本不可访问就是需要芯片特定的
API 通过转码来访问。 Xgl 实现则以相当不同的方法来划这条线。界线被划在
OpenGL API 自身这样相当高的层次。我确信 Xgl
方案是较佳的选择。为了允许硅芯片在不破坏 API
的前提下演进,你期望以位于当前实现于硅芯片中的特性集之上的方式划分界限。我不相信
Linux 会从 DirectX 那样运行一堆 API
中受益。较好的模型是从真正高的层次出发,提供参考软件实现,即
Mesa,然后用加速的硬件实现,即 DRI,分片替代 Mesa。我们也拥有多个 OpenGL
实现:Mesa、nVidia 和
ATI。使用哪一个取决于你的选择,信不信由你有些人竟喜欢专有驱动。

Xgl 被设计为一项短期过渡方案。Xgl 的模型是用一套基于 OpenGL
作为设备驱动的兼容系统透明地取代现存 X 服务器的绘制系统。Xgl 将全部现存 X
API 作为主要 API 来维护。没有任何新 X API 被引入,也没有任何被废弃。Xgl
是一套高层次的、跨平台的代码库。它是一般化的代码,需要被移植到特定的
OpenGL 环境中。一项移植, Xglx,立足于 GLX API 上。另一项移植,
Xegl,工作在跨平台的 EGL API 上。注意 EGL 是一种表现 GLX、agl 和 wgl API
的平台无关的方法。通过 Mesa 扩展 EGL
能控制低层帧缓冲。该组合提供了在裸显示硬件上实现窗口化系统(类似目前的 X
服务器)所需的一切。然而 XGL是一项短期过渡设计,通过推迟对 XGL 的需求,EXA
牌创可贴很大程度上缓解了对它的需要。

一个被反复提及的争议是,因为所有那些在这个不断发展的世界上仍在使用的老旧硬件,我们不应当使用
OpenGL。对这个问题有两个解。其一,OpenGL 是一套可伸缩的
API。借助软件后备实现它能运行在最低档的硬件上。 OpenGL ES 也提供 API
profile。 Profile 是定义良好的 OpenGL API
子集。如果有必要我们能够定义一套包含可能的最小 OpenGL API 子集的最简
profile。代码尺寸应当不成问题,一个专有的 100KB OpenGL ES
实现已经可用。另一套 OpenGL ES profile
则不要求浮点支持。没有什么能够妨碍开源的对应软件的构建,如果我们选择投入资源的话。

另一个分歧是简单地在软件被设计来使用的硬件上运行它们。没人期望一台原始的
IBM PC 运行 Windows Longhorn,但是同一台 PC 可以毫无问题地继续运行 DOS。

这里的关键之处在于 OpenGL 比 EXA 更具伸缩性。在高端 EXA
的伸缩性不堪一用,它并未包含 3D 和可编程性这样的高级 GPU 特性。透过
OpenGL,就有可能对从蜂窝电话到超级计算机的所有情况都拥有单一 API。
九层之台

你有一堆缩写需要消化。感觉一下这些库是如何协同工作的例子:

App -> gtk+ -> X -> XAA -> hw

这就是当前的 X 服务器。应用程序和 toolkit 对话,toolkit 使用 xlib API 调用
X 服务器。X 服务器利用当前的 XAA 驱动绘制到硬件上。X
和应用程序位于两个不同的进程中。

App -> gtk+ -> Cairo -> X Render -> X -> XAA/EXA -> hw

Toolkit 使用新的 Cairo 库。Cairo 的行为则取决于 X Render。如果 EXA 可用,X
Render 被加速。X 和应用程序位于两个不同的进程中。

App -> qt -> Arthur -> X Render -> X -> XAA/EXA -> hw

Arthur 是 Trolltech 的 Cairo 等价物,很大程度上两者的作用是相同的。

App -> gtk+ -> Cairo -> glitz -> GL -> hw

Toolkit 使用新的 Cairo 库。Cairo 选择 glitz 后端来获得基于 OpenGL
直接渲染。一切都是加速的,鉴于 OpenGL 是直接渲染的,绘制发生在单个进程内。

App -> gtk+ -> Cairo -> X Render -> Xgl -> EGL(standalone) -> GL -> hw

这种情况下,toolkit 为 Cairo 选择 xlib 后端,从而和邻接 X Render 的 Xegl
服务器对话。Xegl 使用 Xegl 提供渲染实现。Glitz 则直接渲染到硬件。Xegl
和应用程序位于两个不同的进程中。注意 toolkit 能够选择直接使用 glitz
并在单个进程内直接渲染。

App -> gtk+ -> Cairo -> X Render -> Xgl -> GLX(X) -> GL -> hw

再一次地,Toolkit 通过 X render 和 Xglx 服务器对话。Xglx
并非独立的服务器,它是一个嵌套服务器。Xglx
也非一个普通的嵌套服务器,它利用嵌套获得输入,但在由父服务器提供的单个
OpenGL窗口内绘制自身的整个桌面。一旦进入全屏,你不再见到父服务器。存在三个进程,应用程序、Xglx
和 X 服务器。绘制在应用程序和 Xglx 之间发生,因为 Xglx
使用直接渲染。既然第三个进程,即 X
服务器,提供窗口和输入服务,它也是重任在肩。它还是 Xglx 程序的宿主。
前路17

Linux 目前成为最迟实现充分利用 GPU 优势的桌面 GUI
的主要桌面。鉴于这个既成事实,不再有任何时间压力,也许应该考虑一项长远的方案。我们能够围绕
OpenGL 和 Cairo 设计一个新的服务器。

一般而言,整个可编程图形硬件的概念并未在 xlib 和 Cairo 这样的 API
当中触及。这是非常重要的一点。一项主要的 GPU
新特性,即可编程性,简单地无法从当前的 X API 中访问。 OpenGL 通过它的
shader 语言提供这种可编程性。

当考虑新服务器的时候,理所当然将概念设计分解为两个组件:平台相关与平台无关。设备驱动属于平台相关部分,拟议中的模型里
OpenGL 被看作设备驱动,所以会有平台相关的实现。所有同其它 Linux
子系统整合的细节问题都会隐藏在特定的驱动之后。主服务器将使用跨平台
API,诸如 sockets、OpenGL 和 EGL,来实现。一套用于热拔插设备的跨平台 API
也需要规范。此服务器无须从头设计,其实质部分能够重用来自其它项目的代码,只是要合并到新路子上来。依我之见,构建一个新服务器所需代码的百分之九十五甚至更多已经有了。

模块化是构建优秀服务器的关键之处。设计应当分解为通过标准化接口沟通的独立库。这样分解让替代某个库变得容易。你可以在不同的平台上采用不同的库实现,或者在单个平台上以不同的方式实现库。自然,跨平台代码有它的优点。Mesa
库这类材料能在所有目标系统上共享。

还记得 DirectFB 是如何使用 rootless X 的吗?新服务器将通过运行软件渲染的
rootless X 来保持与遗留系统的兼容。 DRI
的直接渲染模型是良好的设计,在未来的服务器上应予保留。将 X
转为遗留状态允许在设计新服务器时获得完全的自由。

比方说,新服务器能够设计一个全新的网络协议。最近 Linux Journal 上关于 No
Machine 和 NX 协议的文章表明 X 协议能够被压缩至 200:1
甚至更多。新协议将是基于 OpenGL
的,并被设计来防止双程延迟以及提供持久图像缓存。 Chromium
是一套有吸引力的系统,支持将 OpenGL
显示分解到通过网络连接的多个显示器上。他们的网络库处理 OpenGL
状态追踪,作为防止网络流量的一种手段。

字型缓存也应当加以分析。在目前的 X
服务器中,客户端生成字型位图,然后将它们发送到服务器,在那里它们被缓存起来。这个模型排除了早先引用的论文中讨论的利用
GPU
生成字型的方法。客户端字体是好的想法。应用程序理所当然应当负责布局。但是并无实际的要求由客户端生成字型位图。

新服务器能够解决当前在网络音频和打印方面的不足。它能够支持重连会话所需要的适当的代理行为。它也应当明确地从一开始就设计为支持多用户。

事件处理是用库构建系统的良好范例。 Linux 有 evdev、kernel hotplug、HAL 和
D-BUS。这些子系统在大多数其它平台上并不存在。因此,为 BSD
设计的输入子系统看起来会和为 Linux
设计的相当不同。将主要的子系统模块化让它们能够被定制和充分利用它们运行的平台环境。比起针对不同环境的最小公分母来设计,这是一种不同的途径。

X 为世界各地的众多情报机构使用。当前的 X
服务器被认为还没有足够安全到可用于处理敏感文档。如果主要的设计工作开始进行,它能够从根基上就特别留意安全性。适当的投入会持续以确保正确的特性被实现。

长话短说,有很多工作需要完成,最近的开发已经开始解决这些问题。第一位的是
DRM 的内存管理器和打开 DRI 驱动中
FBO(帧缓冲对象)所需要的改写。第二位的是清理现有 fbdev
驱动,使它能与已有DRM
驱动的硬件协调工作。随着奠基工作的就绪,全新服务器的设计工作就可以着手进行了。
结语

我从 Xegl
的失败获得的经验告诉我,构建一个图形子系统是一项大而复杂的工作,其规模远超过一两个人所能承担的。作为一个整体,X.org
社区仅仅具有足够的资源创建单个服务器。将这些资源分配到不同的方向上只会导致一堆半途而废的项目。我理解开发者比较愿意为那些引起他们兴趣的东西工作,但是鉴于
X.org
拥有的资源,这种做法不会在近期孕育出新的服务器甚或基于旧服务器然而富有竞争力的桌面。也许
X.org 是时候释出一份路线图供所有人追随了18。

Jon Smirl

于 2005 年 8 月 30 日

授权可自由地翻译和再发布19。

0 以下的注解都是译者另加,主要目的是提供一点背景和 Linux
图形方面的进展供读者参考。首份译文完成于 2006 年 7 月 7 日,是 gogoliu
发起的《Modern X Tech. 中文翻译计划 》项目的一部分,这是 2006 年 8 月 4
日修正版,都是极细微的修正,读过的可略过。另外我花了点时间看了下 html 和
xhtml,现在的 html 和 xhtml 格式都是我手工编写的了,效果应该比
OpenOffice.org 2 生成的为佳,尺寸也小些。对译文的指教,可联络 mopz0506
[AT] gmail [DOT] com,标题请务必包含"The State of Linux Graphics"
字样。永远怀念在八年抗日战争中牺牲的国共两党将士们。

1 原文(http://jonsmirl.googlepages.com/graphics.html)发布于 2005 年 8 月
30 日,所以基本上是一年前的现状。

2 但是随着 Internet 的增大,对人们获取知识和真相的恐惧也增大了。

3 和 Jon Smirl 不同,其实 K.P. 作为 XFree86 的叛逆者,对一切 3D
化的倾向,反应并不是很积极的。 K.P. 说过,95% 的时间都是在跑
2D。译者就无所谓了,反正 95% 的时间都在跑控制台和 ncursor :)

4 X11R7.0 已于 2005 年 12 月 21 日由 X.Org 正式发布。 X11R7.1 已于 2006 年
5 月 22 日由 X.Org 正式发布。这是第一个享受模块化带来的益处的 roll-up
发布。

5 Porter-Duff 操作是 1 组 12 项用于描述数字图像合成的基本手法,包括
Clear、Source Only、Destination Only、Source Over、Source In、Source
Out、Source Atop、Destination Over、Destination In、Destination
Out、Destination Atop、XOR。通过组合使用 Porter-Duff 操作,可完成任意 2D
图像的合成。这里有 Thomas Porter 和 Tom Duff 发表于 1984
年原始论文的扫描版本 http://keithp.com/~keithp/porterduff/p253-porter.pdf

6 Cairo 1.2 已于 2006 年 7 月 1 日正式发布。另外,最近 Cairo 项目在 google
上搜索 Cairo 关键词时的排名已超过埃及城市 Cairo,稳居第一。

7
机构这个词很少在计算机方面的文章中出现。其实机构是一个很有内涵的词,也是机械方面的一种专门学问。我不喜欢架构这个词,因为架字让我感到隐含有草率的意味。我更喜欢体系结构这个说法。其实国内大概最早关于
architecture 的一本书(98年?99年?),《Software Architecture: Perspectives
on an Emerging Discipline》
影印版,印象中书名就是译成《软件体系结构》的。可惜不小心遗失了。

8 Mesa 就是作者忘了说的那个"再次"。

9 kernel OOPS 中的 OOPS 并不是某个缩写,来自英语中常说的
Oops,相当于汉语中哎呀呀,坏乐这类意思,随着时间逐步演进为特定场景下的专有名词。内核源代码的
Documents 目录下有一篇 oops-tracking.txt 文档。《Linux Kernel
Development》第18章 Debugging 有一节专门介绍 oops 的,可参考。

10 这让我回想起很久以前读过的一本描述 DEC 公司一群年轻工程师设计 PDP
小型机的故事的书,当中有个非常好的比喻,说某个改进方案是瘤子上又长瘤子。书名大概是《The
soul of a new machine》。

11 根据 opengl.org 在 The OpenGL Pipeline Newsletter
第一期(估计也是最后一期)中的官方说法,OpenGL ARB 将并入 Khronos
组织,OpenGL 也将随之和 OpenGL ES
成为同门,甚至再次融合也不是没有可能的。让我们期待此举为沉寂已久的 OpenGL
带来更多活力。

12 这段引文是来自 http://www.khronos.org/ 描述 EGL 的一段话。

13 graphics supercomputers 一般指比较强的可视化工作站,SGI 那种类型的。

14 LCD 上 RGB
三色其实是靠得很近的三个点,所谓子像素反锯齿字体就是利用这个特性增强 LCD
显示效果的一种手段。

15 论文中述及的方法已经在XGL中实现了。

16 这是说,此3D空间的对象并不具备透视关系,比如距离近点看起来大点什么的。

17 在那崎岖崎岖里看阳光......

18 很想译为:噫!树一帜而天下影从,此其时也!

19
译完了,似乎懂了一些,其实没有懂。一篇文章想要译得神完气足,实在需要不菲的心力。以我的理解,作者对
Linux
图形的现状显然是失望的,我无法译出这种味道来。感到非常对不起作者,可是没办法。

原文地址 http://mxtctp.googlepages.com/GraphicsCN.html

Linux的X窗口系统结构说明

一、说明
以X Server为中心,简要地分为四层,如图所示


二、X方式与Framebuffer方式的差异

1. X方式

1) 什么是X
我们常说的X Window,X,X11(指X协议的11版本)一般指X协议,或指是基于X协议的X服务端程序(X Server)

2) X Server与X Client

a) X协议指X Server及X Client组成的c/s架构,及其通讯协议的实现

b) X Server有主事件循环,由它来处理用户输入、显示及与X Client通讯

c) X Client即X桌面上运行的普通应用程序
应用程序如果想显示数据,需要利用X Lib库建立X窗口(X Client),它通过X协议与X Server通讯,让X Server完成显示;X Server会把接到键盘鼠标事件,传给焦点所在的X Client处理

2. Framebuffer方式
Framebuffer方式相对简单,它由内核直接支持,通常用于嵌入式系统。应用程序可以得到屏幕显示区域的指针,然后对其写数据来进行显示,其中窗口的概念不强,它自身不带窗口管理,需要应用软件自己管理窗口。比如qtopia基本于framebuffer显示时,qtopia自身实现了窗口管理功能

3. 应用程序的显示方式
很多应用程序同时支持X和Framebuffer两种模式显示,如gtk,qt等,以下我们只讨论它基本于X实现的部分

三、分层

1. 应用层(Application)
指X Window上运行所有带图形界面的应用程序,每个窗口都是一个X Client

1) X Lib app
直接使用X函数的应用程序,这种程序一般界面简单,比较底层,比如很多窗口管理器直接写在这层

2) Gtk app
gtk又分为gtk和gdk两层,
gtk为控件及主循环的实现
gdk相对底层,控制底层绘图部分,它支持framebuffer、X11、DirectFb等
应用程序可调用gtk函数,也可直接调用gdk函数
gtk常和cairo一起实现二维特效

3) Qt app
Qt也通过调用X Lib实现图形界面
Qt的优势在于它是C++实现的,使用起来程序结构更好,也有较成熟的嵌入式版本

4) SDL app
SDL也通过调用X Lib实现图形界面
SDL更底层,代码少,没有控件,但做特殊效果很好用

2. 窗口管理器层(Window manager简称wm)
Window manager是特殊的X Client,也通过X Lib库与X Server交互,与一般应用不同的是:它负责控制各个窗口的动作,及操作主窗口
WM的功能分为管理(manager)和工具(tools),

1) Manager
负责各个窗口的建立销毁/显示隐藏/最大最小化/移动缩放,管理窗口队列,设置焦点窗口,窗口切换效果等

2) Tools
实现桌面工具条,桌面菜单等基本界面及小工具

3) 具体实现
实现通常有两种方式:一种是manager和tools在一个程序中实现,一种是分开两个程序实现,使用时可以随意组合

a) qvwm, blackbox等较早期的wm,都是manager和tools在一个程序中实现的

b)
xfce、metacity等是分开的,例如:xfce包含tools和manager,但不在一个程序中实现,它的manager是xfwm,我们可在使用xfce时把xfwm替成metacity(metacity是一个manager,不带tools)

3. X服务器层(X Server)
主循环控制显示,读取设备数据,与X Client通讯,事件循环,并把事件送给焦点窗口

1) 普通X Server
功能完整的X Server,代码量大,支持全,常见的如XFree86,Xorg等

2) Tiny X Server
一般用于嵌入式系统,资源占用小,代码少,功能及逻辑相对简单,如KDrive(Xvesa/Xchips/Xfbdev/Xi810……)

4. 系统底层(System)

1) Kernel
与硬件交互,获得输入设备的数据,向显示设备输出

2) Dev
文件系统中的设备文件,程序通过对它的读写和操作与kernel交互,控制硬件

3) 中间层
在程序和Dev层之间,有时还需要库或程序处理设备数据,比如触摸屏就使用libts去除噪点,过滤出更有效的数据

Linux 服务的介绍

服务列表(按字母顺序排列)


服务名 必需(是/否) 用途描述

acon 否 语言支持
acpi 否 电源管理
acpid 否 监听精灵进程
adsl 否 内部ADSL开关控制
alsa 否 高级Linux声音构件
anacron 否 周期命令调度程序
apmd 否 电源管理
apmiser 否 电源管理
arpwatch 否 以太网IP地址配对监控器
atd 否 周期命令调度程序
autofs 否 自动安装服务
bluetooth 否 蓝牙技术核心
bootparamd 否 导入服务
canna 否 日语转换引擎
capi4linux 否 基本CAPI子系统
cpqarrayd 否 硬件服务
cpufreq 否 硬件服务
cpufreqd 否 硬件服务
crond 是 周期命令调度程序
Cups-lpd 否 使旧式Lunux或商业Unix系统连接到打印主机上.
cups 是 公共Unix打印系统
cvs 否 并发版本系统
devfsd 否 系统维护
dhcpd 否 DHCP服务器
diald 否 拨号网络智能自动拨号器
dkms 否 DKMS自安装导入
dm 是 显示管理器
dnbc 否 数字网络绑定Chrooter
Drakxtools-http 否 小型服务管理服务器
dund 否 蓝牙拨号网络
fam 否 文件系统变更监控器
finger 否 数据远程访问
freshclam 是 ClamAV更新器
gpm 是 鼠标
haldaemon 否 硬件监控系统
harddrake 否 硬件服务
heartbeat 否 高可用性服务
hidd 否 蓝牙H.I.D.服务器
hplip 否 惠普Linux打印与成像
hpoj 否 Pital?init,惠普办公喷墨打印机驱动器
httpd 否 Apache网络服务器
hylafax?server 否 企业传真机?调制调解器服务
ibod 否 按需ISDN MPPP带宽
identd 否 TCP连接鉴定
imaps 否 安全IMAP服务器
imaps 否 IMAP服务器
iplog 否 用主机名或远程主机记录TCP,UDP,ICMP.
ipop2 否 POP2邮件服务器
ipop3 否 POP3邮件服务器
ipsec 否 加密与验证通信
iptables 是 基于Packet过滤防火墙内核
ipvsadmin 否 Linux核心IP虚拟服务器
irda 否 红外线设备界面
keytable 是 键盘映射
kheader 否 导入服务
lads 否 登录异常探测系统
laptop mode 否 电源管理
leafnode 否 X? INETD NNTP服务
lisa 否 局域网信息服务器
lmsensors 否 硬件健康监控器
mailman 否 GUN邮件列表管理器
mandi 否 交互式防火墙
mdadm 否 软阵列监控服务
mdnsresponder 否 零配置DNS配置工具
messagebus 是 事件监控服务
mon 是 系统监控精灵进程
mysqld 否 MySQL服务器
named 否 绑定(BIND)服务器
netplugd 否 网卡精灵进程
network 是 网络
nfs 否 网络文件共享
nfsfs 否 网络文件共享服务器
nfslock 否 NFS文件锁定
nifd 否 Howl 客户端
nscd 否 密码与群查找服务
ntpd 否 NTP服务器的第4版
numlock 否 数字锁定键灯光控制
Oki4daemon 否 OKI4和兼容win打印机的兼容性精灵进程
pand 否 蓝牙个人区域网络
partmon 是 分区监控
pcmcia 否 个人电脑内存卡国际协会
pg_autovacum 否 PostgreSQL维护
pop3s 否 安全POP3服务
portmap 否 RPC支持
postgresql 否 Postgresql数据库引擎
postfix 否 电子邮件服务器
pptp 否 PPP断电服务
prelude 否 IDS
psacct 否 进程计算
rawdevices 是 分配raw设备,阻止其使用
rsync 否 远程同步
saned 否 网络扫描仪
shorwall 是 防火墙
smartd 否 自我监控服务
smb 否 Samba网络服务
snmpd 否 简单的网络管理协议
sound 否 声音系统
squid 否 高速缓存工具
ssh?xinetd 否 X?inetd OpenSSH服务器
sshd 否 OpenSSH服务器
subversion 否 并发版本系统
swat 否 Samba网络管理工具
syslog 是 系统登录
tmdns 否 多点传送DNS响应器
ultrabayed 否 ThinkPad工具
upsd 否 NUT精灵进程及驱动器
upsmon 否 UPS监控工具
vncserver 否 虚拟网络计算服务器
Webmin 否 远程管理工具
winbind 否 Samba名称服务器
wine 否 Wine并非竞争者
wlan 否 控制精灵进程
x?inetd 是 监控并控制其它服务器的服务器
xfs 是 X字体服务器
ypbind 否 SUN的YP服务器名称服务器

新“诗词填句”

年轻的女老师,在批改学生们的试卷时,被雷翻了!

1."床前明月光",下一句同学填"李白睡的香"…
2."三个臭皮匠"下一句他竟然填"臭味都一样"…批卷老师立即昏倒…
3.陶渊明的"不为五斗米折腰",那同学斗胆的写"给我六斗就可以"…
4."穷则独善其身",下一句同学填"富则妻妾成群"。
5."西塞山前白鹭飞",下一句"东村河边乌龟爬"?
6."天若有情天亦老",下一句"人若有情死的早"?
7."葡萄美酒夜光杯",下一句"金钱美女一大堆"…
8."想当年,金戈铁马",下一句"看今朝,死缠烂打"…
9.这个才过瘾!"洛阳亲友如相问",同学对"请你不要告诉他"…
10."两情若是长久时",同学对"该是两人结婚时"
11."书到用时方恨少",同学对"钱到月底不够花"…
12."清水出芙蓉",有人写"乱世出英雄"…
13."问君能有几多愁",同学填"恰似一壶二锅头"。
14.这个绝了!"日照香炉生紫烟,李白来到洗手间,小李飞刀一瞬间,李白变成小太监"…

2009年5月26日星期二

LCD刷新频率对系统性能影响

在ARM体系结构中:
在ARM体系结构中,GPU是不带自身的显存,而往往是在系统的RAM中预留一块留给GPU做为显存。这样的结果就是GPU对于显存操作时,要走AHB总线,LCD周期性从Frame
buffer中刷新也要走AHB总线。这样就会造成AHB总线的繁忙,从而造成性能的瓶颈。
以AHB总线频率为133Mhz,采用SDRAM内存,屏幕分辨率为800*600,32位色。
先说明一点,LCD从SDRAM中获取屏幕数据,是通过DMA的方式,其存储效率很高。
先来计算SDRAM的内存吞吐率,SDRAM的频率和AHB总线频率保持一致为133Mhz,按照数据总线宽度为32位,那么SDRAM的理论吞吐率为133*4=512MB/s。

LCD一帧的数据量:800*600*4=1,920,000。
那么LCD通过AHB总线传输一帧所花费的时间为1.92M/512M=3.75ms。
如果按照LCD刷新频率为60hz,那么AHB总线在一秒内光花在LCD刷新屏幕的时间就为3.75*60=225ms,可以说1/5的时间就没了。

在PC体系架构中:

在PC架构上,GPU自身是带显存的,这是和ARM架构中最重要的区别。这样LCD在刷新屏幕内容时,可以直接和GPU相连,而不必内部总线。这样LCD的刷新频率对于内部总线没有影响。

针对ARM平台下,LCD刷新频率的优化。
1、 减少每一帧的数据量:减小屏幕的分辨率、降低每像素的位数。
2、 减小LCD的刷新频率,对于LCD来讲没有必要做到60hz。
3、
如果LCD支持异步局部刷新的话,这样其能够只是刷新变化的内容,会减少总线数据传输量。
4、采用更加高速的内存,比如说DDR,或者提高AHB总线的频率。

一个研究生毕业以后的人生规划

我今年39岁了,
25岁研究生毕业,工作14年,回头看看,应该说走了不少的弯路,有一些经验和教训。现在开一个小公司,赚的钱刚够养家糊口的。看看这些刚毕业的学生,对前景也很迷茫,想抛砖引玉,谈谈自己的看法,局限于理工科的学生,我对文科的不懂,身边的朋友也没有这一类型的。
91年研究生毕业,那时出路就是1种:留在北京的国营单位,搞一个北京户口,这是最
好的选择。到后来的2~3年内,户口落定了,又分成4条出路:
1、 上国内的大企业,如:华为
2、 自己做公司,做产品开发;
3、 上外企,比如:爱立信、诺基亚
4、 自己做公司,做买卖;
5、 移民加拿大
我想,首先要看自己适合做什么?做技术还是做买卖。
做技术,需要你对技术感兴趣。我掰着数了一遍,我们研究生班的30来号人,实际上,适合做技术的,大概只有3、4个人,这几个人,1个现在还在华为,3个移民加拿大了,现在这4个人混的还可以,在华为的同学也移民加拿大了,他在华为呆了6年,在华为奖金工资加起来大概30万吧,还有华为的股票,再过几年,华为的股票一上市,也能值个100~200万。要是一毕业就去华为,那现在就绝对不是这个数字了。
要是做技术,最好的就是上大公司,国内的大型企业,象华为中兴肯定是首选,能学到很多东西。华为虽然累,但是,年轻人不能怕累,要是到老了,还需要去打拼,那才是
真的累啊。

在外企,我想他们主要就是技术支持和销售,但是技术是学不到的,当然不能一概而论,我指的是象爱立信和诺基亚,真正的研发不会在中国做的,学到的也不如在华为多,其它的中兴我不是很了解,我想应该也不错啊。一个人都有一技之长,有傍身之技,那是最好的,走到哪里,都能有一口饭吃,还吃的不错,这是传统的观点。

任何技术都是要在某个行业去应用,这个行业市场越大当然越好;要在一个领域之内,做深做精,成为绝对的专家,这是走技术道路的人的选择。不要跳来跳去,在中国,再小的行业你要做精深了,都可以产生很大的利润。
研究生刚毕业的时候,做产品开发的有不少人,都是自己拍拍脑子,觉得这个产品有市场,就自己出来做。现在看来,我的这些同学,做产品开发的成功的没有一例,为什么?资源不足。
1.
资金,刚毕业的学生啊,就是没钱;没钱,也意味着你开发的东西都是小产品;而且只能哥几个自己上,研发、生产、销售都是一个人或者几个人自己来,没有积累,什么都是重新来过。
2.
人脉,任何一个行业,要想进去,需要有很深的人脉,否则,谁会用你的东西啊
?谁敢用你的东西啊?
我看到的,我这个班上开发产品的,自己还在坚持的,只剩下一个人了,说实在的,
到现在,没有自己的汽车,也没有自己的房子,混的挺惨的。现在出国的不说了,在外企、在华为,至少都是几十万的年薪了,还有各种福利,就是产品开发成功了,又能如何?
也就是这样了,但是以前那些年,都没有金钱的积累,等于白干。
我身边的一个自动化系的研究生班的同学,能靠自己开发产品活得还可以的,也只有2个人。说明这条路不是那么好走的啊。
其次就是上外企。我的2个同学,一个上了爱立信,一个先到爱立信后到诺基亚,都混的不错。到诺基亚的后来利用在诺基亚结识的人脉(就是哪些电信的头头脑脑),自己开了公司,也赚了不少的钱。
外企最大的好处就是除了能学到比较规范的管理外,还能给你的职业生涯镀金。到了一个外企外,再到同行业的外企我想就很容易了。而且外企的收入高啊。
自己做公司,做买卖,一开始有3~4个人走这条路,但是真正发财的只有一个人,其他人后来上外企了。做买卖,还是要有一定的天赋,还有机遇。要有对金钱的赤裸裸的欲望,要有商业上的头脑。后来我们同学在一起谈,说,我们即使给自己这个机遇,也未必能做的好。何况当时那个同学看好的产品(做一个台湾产品的代理),我们大家都没有看好,说明,真理还是掌握在少数人手里。到后来,同学们纷纷移民移民加拿大。
移民加拿大对搞技术的人来说,还是一个不错的选择,但是要尽早,练了几年的技术,就赶紧出去,大概是在1996年走了不到10个,现在都还可以,买了房子和车了。要是晚
了,语言再学也难了,而且在国内都混的还可以了,也就没有必要出去了。
我自己呢,先是在国营的研究所混了4年,后来到一家公司干了6年,2002年出来自己做公司,现在也就是混了一个温饱吧,算是有房有车,有点积蓄,但是不多,还有一个可爱的女儿。回首这10来年,有一些经验和教训。
1.
要有一个职业生涯的规划。首先需要定位自己做什么合适,是做买卖还是做技术,一条路走到黑;当然,做了技术,后来改行也行;
2.
做技术,就是要做精做深,成为这个行业的这个技术的专家;最好就是去国内的大公司,才能全面学到东西,能够给你培训的机会;如果大公司进不去,先到小公司练技
术,找机会再到大公司去镀金,学高深的技术。千万不要自己做产品,要做也是对这个行业熟悉了,再去做。
3 .
积极争取机会。积极争取学习和进步的机会。比如,做技术,就需要多锻炼,多学习,来提高自己的水平。一门技术,只要有机会去学习,都能学的会;要是没有机会,天才也没有办法学到这个技术。柳传志就说,杨元庆就是"哭着喊着要进步",实际上,就是争取自己的机会;当然,这种强烈的进步欲望,也是领导看重的地方。每一步都走在前面,积累10年,你就有了比其他人更多的机会了。
4.
积累个人的信誉。从你的职业生涯的第一天,就要按照诚信的原则办事。要做到,当人们提起你的名字的时候,说,这哥们还不错,做事还行。
5.
注意利用资源。如果你有有钱的亲戚、成功的长辈或者朋友,可以充分利用这些机会,得到更加顺利的发展前景。
6.
注意财富的不断积累。人生要想得到自由,财富是很关键的。否则,永远仰人鼻息,永远看人脸色。人都是势利眼。今后的家庭、职业生涯,金钱的积累很重要,没有钱,永远不能开张自己的事业,得到更多的机会;财富要做到逐年积累,你才能家庭生活幸福。没有钱是不可能有幸福的家庭的。
7.
注意人脉的积累。最终,事业要靠在社会上的人脉的资源。要注意认识在你这个行业的人,结交他们,最终他们会成为你事业上的助力。
8.
寻求贵人相助。要找大老板来帮助你,得到大老板的赏识。想想看,大蛋糕,切一点就够了,小蛋糕,都给你也吃不饱啊。
9.
多听听成功的前辈和成功的朋友的意见。注意少听家里长辈的意见,尤其是都已经退休的长辈,他们对社会的认识还停留在很久以前,而这个社会已经发生很大的变化呢
。
最重要的是,长辈有时候会强求你做一些事情,但是,最终的结果他们是不负责的。

上拉电阻下拉电阻的总结

上拉电阻:
1、当TTL电路驱动COMS电路时,如果TTL电路输出的高电平低于COMS电路的最低高电平(一般为3.5V),这时就需要在TTL的输出端接上拉电阻,以提高输出高电平的值。
2、OC门电路必须加上拉电阻,才能使用。
3、为加大输出引脚的驱动能力,有的单片机管脚上也常使用上拉电阻。
4、在COMS芯片上,为了防止静电造成损坏,不用的管脚不能悬空,一般接上拉电阻产生降低输入阻抗,提供泄荷通路。
5、芯片的管脚加上拉电阻来提高输出电平,从而提高芯片输入信号的噪声容限增强抗干扰能力。
6、提高总线的抗电磁干扰能力。管脚悬空就比较容易接受外界的电磁干扰。
7、长线传输中电阻不匹配容易引起反射波干扰,加上下拉电阻是电阻匹配,有效的抑制反射波干扰。
上拉电阻阻值的选择原则包括:
1、从节约功耗及芯片的灌电流能力考虑应当足够大;电阻大,电流小。
2、从确保足够的驱动电流考虑应当足够小;电阻小,电流大。
3、对于高速电路,过大的上拉电阻可能边沿变平缓。综合考虑
以上三点,通常在1k到10k之间选取。对下拉电阻也有类似道理
对上拉电阻和下拉电阻的选择应结合开关管特性和下级电路的输入特性进行设定,主要需要考虑以下几个因素:
1.
驱动能力与功耗的平衡。以上拉电阻为例,一般地说,上拉电阻越小,驱动能力越强,但功耗越大,设计是应注意两者之间的均衡。
2.
下级电路的驱动需求。同样以上拉电阻为例,当输出高电平时,开关管断开,上拉电阻应适当选择以能够向下级电路提供足够的电流。
3.
高低电平的设定。不同电路的高低电平的门槛电平会有不同,电阻应适当设定以确保能输出正确的电平。以上拉电阻为例,当输出低电平时,开关管导通,上拉电阻和开关管导通电阻分压值应确保在零电平门槛之下。
4.
频率特性。以上拉电阻为例,上拉电阻和开关管漏源级之间的电容和下级电路之间的输入电容会形成RC延迟,电阻越大,延迟越大。上拉电阻的设定应考虑电路在这方面的需求。
下拉电阻的设定的原则和上拉电阻是一样的。
OC门输出高电平时是一个高阻态,其上拉电流要由上拉电阻来提供,设输入端每端口不大于100uA,设输出口驱动电流约500uA,标准工作电压是5V,输入口的高低电平门限为0.8V(低于此值为低电平);2V(高电平门限值)。
选上拉电阻时:
500uA x 8.4K=
4.2即选大于8.4K时输出端能下拉至0.8V以下,此为最小阻值,再小就拉不下来了。如果输出口驱动电流较大,则阻值可减小,保证下拉时能低于0.8V即可。
当输出高电平时,忽略管子的漏电流,两输入口需200uA
200uA
x15K=3V即上拉电阻压降为3V,输出口可达到2V,此阻值为最大阻值,再大就拉不到2V了。选10K可用。COMS门的可参考74HC系列
设计时管子的漏电流不可忽略,IO口实际电流在不同电平下也是不同的,上述仅仅是原理,一句话概括为:输出高电平时要喂饱后面的输入口,输出低电平不要把输出口喂撑了(否则多余的电流喂给了级联的输入口,高于低电平门限值就不可靠了)

在数字电路中不用的输入脚都要接固定电平,通过1k电阻接高电平或接地。
1. 电阻作用:
l 接电组就是为了防止输入端悬空
l 减弱外部电流对芯片产生的干扰
l 保护cmos内的保护二极管,一般电流不大于10mA
l 上拉和下拉、限流
l 1. 改变电平的电位,常用在TTL-CMOS匹配
2. 在引脚悬空时有确定的状态
3.增加高电平输出时的驱动能力。
4、为OC门提供电流
l
那要看输出口驱动的是什么器件,如果该器件需要高电压的话,而输出口的输出电压又不够,就需要加上拉电阻。
l
如果有上拉电阻那它的端口在默认值为高电平你要控制它必须用低电平才能控制如三态门电路三极管的集电极,或二极管正极去控制把上拉电阻的电流拉下来成为低电平。反之,
l
尤其用在接口电路中,为了得到确定的电平,一般采用这种方法,以保证正确的电路状态,以免发生意外,比如,在电机控制中,逆变桥上下桥臂不能直通,如果它们都用同一个单片机来驱动,必须设置初始状态.防止直通!

2、定义:
l
上拉就是将不确定的信号通过一个电阻嵌位在高电平!电阻同时起限流作用!下拉同理!
l 上拉是对器件注入电流,下拉是输出电流
l 弱强只是上拉电阻的阻值不同,没有什么严格区分
l
对于非集电极(或漏极)开路输出型电路(如普通门电路)提升电流和电压的能力是有限的,上拉电阻的功能主要是为集电极开路输出型电路输出电流通道。

3、为什么要使用拉电阻:
l
一般作单键触发使用时,如果IC本身没有内接电阻,为了使单键维持在不被触发的状态或是触发后回到原状态,必须在IC外部另接一电阻。
l
数字电路有三种状态:高电平、低电平、和高阻状态,有些应用场合不希望出现高阻状态,可以通过上拉电阻或下拉电阻的方式使处于稳定状态,具体视设计要求而定!
l
一般说的是I/O端口,有的可以设置,有的不可以设置,有的是内置,有的是需要外接,I/O端口的输出类似与一个三极管的C,当C接通过一个电阻和电源连接在一起的时候,该电阻成为上C拉电阻,也就是说,如果该端口正常时为高电平,C通过一个电阻和地连接在一起的时候,该电阻称为下拉电阻,使该端口平时为低电平,作用吗:
比如:当一个接有上拉电阻的端口设为输如状态时,他的常态就为高电平,用于检测低电平的输入。
l
上拉电阻是用来解决总线驱动能力不足时提供电流的。一般说法是拉电流,下拉电阻是用来吸收电流的,也就是所谓的灌电流。