Framebuffer 驱动程序的实现分为两个方面:一方面是对LCD及其相关部分的初始化,包括画在缓冲区的创建和对DMA通道的设置;另外一方面是对画面缓冲区的读写,具体到代码为read、write、lseek等系统调用接口。至于将画面缓冲区的内容输出到LCD显示屏上,则由硬件自动完成。对于软件来说是透明的。当对于DMA通道和画面缓冲区设置完成后,DMA开始正常工作,并将缓冲区中的内容不断发送到LCD上。这个过程是基于DMA对于LCD的不断刷新的。基于该特性,framebuffer驱动程序必须将画面缓冲区的存储空间(物理空间)重新映射到一个不加高缓存和写缓存的虚拟地址区间中,这样能才保证应用程序通过mmap将该缓存映射到用户空间后,对于该画面缓存的写操作能够实时的体现在LCD上。
在Qt/Embedded 中,Qscreen类为抽象出的底层显示设备基类,其中声明了对于显示设备的基本描述和操作方式,如打开、关闭、获得显示能力、创建GFX操作对象等。另外一个重要的基类是QGfx类。该类抽象出对于显示设备的具体操作接口(图形设备环境),如选择画刷、画线、画矩形、alpha操作等。以上两个基类是 Qt/Embedded图形引擎的底层抽象。其中所有具体函数基本都是虚函数,Qt/Embedded对于具体的显示设备,如Linux的 framebuffer、Qt Virtual Framebuffer做的抽象接口类全都由此继承并重载基类中的虚函数实现。图2为Qt/Embedded中底层图形引擎实现结构。
在图2中,对于基本的framebuffer设备,Qt/Embedded用 QlinuxFbScreen来处理。针对具体显示硬件(如Mach卡、Voodoo卡)的加速特性,Qt/Embedded从 QlinuxFbScreen和图形设备环境模板类QgfxRaster继承出相应子类,并针对相应硬件重载相关虚函数。
Qt/Embedded 在体系上为C/S结构,任何一个Qt/Embedded程序都可以作为系统中唯一的一个GUI Server存在。当应用程序首次以系统GUI Server的方式加载时,将建立QWSServer实体。此时调用QWSServer::openDisplay()函数创建窗体,在 QWSServer::openDisplay()中对QWSDisplay::Data中的init()加以调用;根据 QgfxDriverFactory实体中的定义(QLinuxFbScreen)设置关键的Qscreen指针qt_screen并调用connect ()打开显示设备(dev/fb0)。在QWSServer中所有对于显示设备的调用都由qt_screen发起。至此完成了Qt/Embedded中 QWSServer的图形发生引擎的创建。当系统中建立好GUI Server后,其它需要运行的Qt/Embedded程序在加载后采用共享内存及有名管道的进程通信方式,以同步访问模式获得对共享资源 framebuffer设备的访问权。
1.2 Qt/Embedded的事件驱动基础
Qt/Embedded 中与用户输入事件相关的信号,是建立在对底层输入设备的接口调用之上的。Qt/Embedded中的输入设备,分为鼠标类与键盘类。以3.x版本系列为例,其中鼠标设备的抽象基类为QWSMouse Handler,从该类又重新派生出一些具体的鼠标类设备的实现类。该版本系列的Qt/Embedded中,鼠标类设备的派生结构如图3所示。
与图形发生引擎加载方式类似的,在系统加载构造QWSServer时,调用QWSServer::openMouse与QWSServer:: openKeyboard函数。这两个函数分别调用QmouseDriverFactory::create()与 QkbdDriverFactory::create()函数。这时会根据Linux系统的环境变量QWS_MOUSE_PROTO与 QWS_KEYBOARD获得鼠标类设备和键盘类设备的设备类型和设备节点。打开相应设备并返回相应设备的基类句柄指针给系统,系统通过将该基类指令强制转换为对应的具体子类设备指针,获得对具体鼠标类设备和键盘类设备的调用操作。
|