X Server是一个广泛使用的图形引擎,对上层应用的绘画请求提供底层支撑。在上层应用请求引发的X server的图形操作中,经常会涉及到用某种颜色填充一个区域,将一个区域拷贝到另一个区域,或者将两个区域进行alpha-blending,等等。这些操作X server都提供了对应的软件实现,然而,性能相对来说不会太好,而且占用了大量的CPU资源。由于今天的手机系统中,对图形的效果要求越来越炫,同时对性能要求也越来越高,因此,如何有效的实现的这些操作是X server的一个重要课题。
幸运的是,今天很多的硬件显示设备都提供了图形加速功能,用硬件来实现区域填充,拷贝,以及混合等,速度都非常快,如果能充分利用图形加速功能,就能提高图形系统性能。
X Server 系统与时俱进,先后发展了一系列与图形硬件加速相关的框架,包括XAA, KAA, 以及EXA等。其中XAA今天用的越来越少,比较流行的是KAA和EXA。KAA和EXA大体架构差不多,EXA是在KAA基础上发展而来。KAA只能应用于kdrive (tinyX) 中, 而EXA即可用于kdrive (tinyX)中,也可用于Xorg server中。本文试图对KAA略作介绍,要更好的了解如何实现kaa和exa,可以参考openmoko 的Xserver: git://git.openmoko.org/git/xglamo (kdrive + kaa / kdrive+ exa)和git://git.openmoko.org/git/xf86-video-glamo.git (xorg + exa)
在了解KAA之前,大致了解一下硬件显示设备的framebuffer结构是非常有帮助的。下图给出了Fb的结构图。值得主义的是,只有源区域和目标区域都位于Fb上(OnScreen 或者是OffScreen)时,才可以使用硬件加速功能。也就是说,图形硬件设备不能对位于一块系统内存上的区域加速。
KAA
X server源码中,文件src/hw/kdrive/kdrive.h中的_KaaScreenInfo描述了可以使用硬件加速来实现的函数,主要有四 组:Solid, Copy, Blend和Composite。Solid组函数对屏幕上某块区域进行颜色填充;Copy组函数将屏幕上一个矩形区域拷贝到另一个位置。Blend组函 数将两块矩形区域alpha混合;Composite组函数更复杂,先将一块区域进行掩码操作,再和另一块区域alpha混合,可能还有填充,旋转能操 作。Blend函数可看作Composite的一个特例。
每组函数都有三个函数(Composite是四个), 如PrepareSolid, Solid, DoneSolid。PrepareXXX判断硬件能不能进行对应的加速操作,不能的话则仍然使用软件实现。XXX(如Solid)进行真正的硬件加速操作。DoneXXX一般不用实现。XXX中传入的参数表示当前操作对pixmap (src/dst)的相对坐标。
在对某个矩形区域加速之前,这块区域需要位于显卡的framebuffer之上,包括onscreen 和 offscreen framebuffer。KAA框架中的内存管理程序(koffscreen.c)实现将一个区域拷贝到framebuffer之上,并按一定算法将过期的区域移出。
可以使用gtkperf, render_bench, 或expedite等工具来测试X server的性能是否提高。
值得注意的是当需要加速的区域太小时,使用软件实现反而更快。这个时候可以再加上判断,当区域太小时,就不要移入framebuffer。如对Copy操作,在kaa.c的kaaCopyNtoN中加上判断即可。