帧缓冲器

帧缓冲器是一个视频输出设备,它从一个包含了完整帧数据的内存缓冲区驱动视频显示器。

昇阳TGX影格缓冲区

内存缓冲区中的信息通常包含屏幕上每个像素的色彩值,色彩值常以1位、4位、8位、16位及 24位真彩色格式存储。有时还有一个alpha通道来保存像素的透明度。驱动帧缓冲器所需的总内存量取决于输出信号的分辨率色彩深度和调色板大小。

向量显示器比帧缓冲器出现得早,二者有很大的不同。使用向量显示器时,只存储了图元(graphics primitives)的顶点。输出显示器的电子束按命令从一个顶点移动到另一个顶点,在这些点之间形成一个模拟的线条。而使用帧缓冲器时,电子束(如果显示技术使用了电子束)按命令在整个屏幕上从左到右、从上到下描绘(trace),也就是电视机呈现广播信号的方式。与此同时,屏幕上每个点的色彩信息从帧缓冲器中取出,形成一系列离散的像素

显示模式

个人和家用计算机中的帧缓冲器中常有一些定义好的模式,也就是帧缓冲器可以工作的模式。这些模式可以自动配置硬件以输出不同的分辨率、色彩深度、内存布局及刷新频率英语Refresh rate等。

Unix中则通常没有这些便利,而是更倾向于直接操纵硬件。这可以更灵活地设置可以使用的分辨率、色彩深度和刷新频率,只受限于可用作帧缓冲器的内存。这种方法的一个副作用是,显示设备可能被迫工作在其力不能及的模式下,有时这会导致设备器硬件上的损坏。不过更常见的是,它会产生一些垃圾而无用的输出。现代的CRT显示器通过引入智能保护电路而解决了这一问题。如果被设置成了不可用的显示模式,则会显示出错误信息。

LCD也会含有这样一个保护电路,但并不是出于这个原因。由于LCD必须以数字形式采样显示信号(这样来模拟电子束),所以超出范围的信号无法物理地显示在监视器上。

调色板

传统的帧缓冲器支持的色彩模式很广泛。受限于昂贵的内存,大多数早期的帧缓冲器使用的是1位、2位、4位或 8位的色深。小的色深导致不能产生完整的色彩范围。其解决方法是为帧缓冲器增加一个查找表(lookup table,LUT),把帧缓冲器中存储的每个“颜色”作为一个索引。这就是所谓的索引色(indexed color)模式。

查找表扮演着调色板的角色,它包含的数据用以定义数量有限的——比如256种——色彩。但这256种色彩中的每种色彩本身,则是可能是用许多位(比如24b,每8位对应于三原色中的一色)定义的。有了24位,色彩就可以定义得更精细了。色彩总数有限的图像总还有些捉襟见肘,不过它们可以被精挑细选出来,故仍被认为比直接使用8位色略胜一畴。

在索引色模式下,帧缓冲器中存储的数据决定了调色板中256种色彩中的哪一种将用于当前像素,然后查找表中存储的数据被送往3个数-模转换器,这样来为显示器创建视频信号。

在有些设计中,也可以临时向查找表中写入数据或在已有调色板中切换,也允许把图像分割成一个个水平条,每个水平条使用自己的调色板,这样就可以呈现调色板范围更广的图像了。

内存访问

帧缓冲器通常是以直接映射到CPU内存空间的方式访问的,但这并不是唯一的方法。比如:

  • 把整个帧缓冲器映射到一个给定的内存范围;
  • 通过操作对应端口直接控制像素点或者色块;
  • 把帧缓冲器映射到一个比它小的内存范围内,必要时进行内存库切换(bank switching)。

虚拟帧缓冲器

许多系统尝试模拟帧缓冲器设备的功能,通常是出于兼容性的考虑。两个最常见的虚拟帧缓冲器是Linux的fbdev及X Window的Xvfb。Linux的fbdev把对访问底层帧缓冲器的物理方式抽象成一个可靠的内存映射,以易于程序访问。这样增加了移植性,因为程序无须应对内存映射不连续的系统或要求内存库切换(bank switching)了。

X Window System中添加Xvfb是为了在没有图形帧缓冲器时运行X,最初的原因已不可考,而在现代系统中它常被用以支持JVM之类的程序,这些程序不允许在无界面环境中产生动态图形。

画面交换

由于帧缓冲器通常是为处理多个分辨率而设计的,故其内存也通常比以低分辨率显示单帧所需要的内存大。由于内存的大小相当可观,故可以在不妨碍当前所显示帧的前提下向视频内存中写入新帧。这是通过告诉帧缓冲器为当前帧使用某一部分特定内存来实现的。这一部分的内存内容正在显示时,另一部分完全独立的内存被填充为下一帧的数据。一旦从缓冲区(通常称为“后端缓冲区”)被填充,帧缓冲器就被要求查看从缓冲区。此时主缓冲区(通常称为“前端缓冲区”)变成从缓冲区,从缓冲区则变成了主缓冲区。这一交换通常在垂直遮没间隔中完成,以避免屏幕被“撕裂”(即显示一半旧帧、一半新帧)。

现代多数帧缓冲器都有足够多的内存,以执行主从缓冲区的交换——即使是在高分辨率下。这样,它就成了PC游戏程序员所使用的一种标准技术。

图形加速器

图形加速器也就是现在所说的显卡。

随着对高质量图形的需求的增长,硬件厂商想出了一种方法以减少填充帧缓冲器所需的CPU时间。在Unix中常把这种硬件称为图形加速器。

常见的绘图命令(多为几何绘图指令)以原始形式(raw form)发送给图形加速器,加速器再把命令的结果点阵化(rasterize)给帧缓冲器。用这种方法,每条命令可以节约几千到几百万个CPU周期,这样CPU就可以转去处理其他工作了。

早期加速器专注于提高2D GUI系统的性能,现代的则专注于实时产生3D图像。常见的设计是使用OpenGL/DirectX之类的库把命令发给图形加速器,之后图形驱动程序把命令(commands)转换成加速器的GPU的指令(instructions),GPU使用这些微指令来计算出点阵化的结果。这些点阵化结果以位块形式(bit blitted)传送到帧缓冲器。之后帧缓冲器的信号与内置视频叠加设备(通常用以在不修改帧缓冲器数据的情况下产生鼠标指针)组合,模拟特效则通过修改输出信号的方式产生。模拟信号修改的一个例子是3dfx Voodoo卡使用的抗锯齿技术,它为输出信号添加一些轻微的模糊以淡化点阵化图像的锯齿。