Nano-X图形引擎分析及其优化
刘峥嵘 sword_lzr@tom.com
MicroWindows是一个开放源码的嵌入式GUI软件,目的是把图形视窗环境引入到运行Linux的小型设备和平台上。作为X Window系统的替代品,MicroWindows可以用更少的RAM和文件存储空间(100KB~600KB)提供相似的功能,允许设计者轻松加入各种显示设备、鼠标、触摸屏和键盘等;可移植性非常好,可用C语言实现;支持Intel 16位/32位CPU、MIPS R4000以及基于ARM内核的处理器芯片。由于和微软的windows注册商标存在冲突,从2005年月起,MicroWindows改名为Nano-X。
作为一个嵌入式的GUI,Nano-X因其体积小,定制性好的优点而在嵌入式领域得到了广泛的应用。但同时,一些专业开发者和竞争对手也对它的图形引擎提出了诸多批评,认为它过于原始,算法过于低效。下面就对Nano-X的图形引擎进行分析,并试图对之进行优化。
Nano-X采用分层次的设计方法,在底层提供对屏幕、鼠标、触摸屏和键盘的驱动,在程序能访问实际的硬件设备和其它用户定制设备。在中间层 有一个可移植图形引擎,提供绘制线程、区域填充、绘制多边形、裁减和使用颜色模式的方法。在顶层实现多种API以适应不同的应用环境。目前, MicroWindows中使用两种流行的图形编程接口:Microsoft Windows Win32/WinCE图形显示接口(GDI)和Xlib接口。前者应用于所有的Windows CE和Win32应用程序;后者就像Nano-X,应用于所有Linux X插件集的最底层,这样可让Linux图形程序员X接口开发图形应用程序。
显然Nano-X窗口刷新速度取决于两个因素,一个是准备显示的时间,也就是生成要显示的数据的时间,GUI要运算出窗口的哪部分需要刷新重画,它们的位置是什么,这就是属于中间层的图形引擎层的工作。另一个是显示的时间,也就是把放在缓冲区(内存)的显示数据搬移到显存中的时间,这部分的时间与硬件设备的外部总线访问时间有关,如果在显存中是连续的,还可以使用DMA的方式,这属于驱动层的内容。
对于Nano-X的图形引擎层,它被API层调用(GrXXX()),提供绘制线程、区域填充、绘制多边形、裁减和使用颜色模式的方法。由于驱动程只提供画点、画横线、画竖线和填充矩形的方法,所以它首先要把API层一些比较复杂的绘图调用进行分化,以便能够调用驱动层的一些比较原始的方法去实现,比如把画矩形的函数分解为四次画边的调用。而另一方面,驱动层还不能直接在窗口上画,它必须判断要画的图形是否已经超过窗口的大小,还有,要画的窗口是否已经被别的窗口覆盖,如果被覆盖,就要把被覆盖的部分从本窗口中剪切出去,这就牵涉到窗口的剪切问题了,如果有窗口的多重覆盖,就要对每一个可能覆盖的窗口进行检查,这也是图形引擎层比较复杂的原因了。
首先要说明,所有的API调用函数中,都是必须要指明要画的窗口的(另外也可以指明在pixelmap上画),也就是要提供窗口的ID。下面看看MicroWindows中记录窗口信息的数据结构:
typedef struct {
GR_WINDOW_ID wid; /* window id (or 0 if no such window) */
GR_WINDOW_ID parent;