X Window研究笔记(5)



5.显示设备(TinyX)

显示设备曾一度是性能的瓶颈,尽管有些显示标准存在,但各厂家为了提高市场竞争力,增强显示设备的性能,加入了各种加速功能和其它一些专有特性,各OS提供的接口也各不相同,X Window为了保持可移植性,又要充分发挥硬件特性,所以显示设备驱动接口看起来有点复杂。幸运的是,对TinyX来说,这块相对比较简单。

显示设备初始化过程。

  1. X Server在初始化时会调用InitOutput函数初始化显示设备。
  2. InitOutput调用KdInitOutput完成TinyX显示设备的初始化。
  3. 在KdInitOutput中:首先调用InitCard把所有Card放到一个链表中,对于fbdev来说,就是调用KdCardInfoAdd把fbdevFuncs注册到kdCardInfo里。再为最后一个Card增加一个KdScreenInfo,并初始化它(实际上TinyX假设的是单Card和单Screen)。
  4. 在KdInitOutput中:接下来调用card->cfuncs->cardinit初始化链表中的Card,调用KdInitScreen初始化Card中的KdScreenInfo。
  5. 最后通过KdInitScreen,再经过AddScreen把所有Card中的所有Screen加入到screenInfo.screens的全局的数组中,完成显示设备的初始化。

KdScreenInit是真正初始化Screen(不是前面的ScreenInfo)的函数,初始化完成之后DIX看到的是ScreenPtr这样的抽象对象。

KdCardFuncs的结构描述

X Window研究笔记(5)_serverX Window研究笔记(5)_server_02typedef struct _KdCardFuncs ...{
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    Bool        (*cardinit) (KdCardInfo *); /**//* detect and map device */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    Bool        (*scrinit) (KdScreenInfo *);/**//* initialize screen information */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    Bool        (*initScreen) (ScreenPtr);  /**//* initialize ScreenRec */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    void        (*preserve) (KdCardInfo *); /**//* save graphics card state */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    Bool        (*enable) (ScreenPtr);      /**//* set up for rendering */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    Bool        (*dpms) (ScreenPtr, int);   /**//* set DPMS screen saver */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    void        (*disable) (ScreenPtr);     /**//* turn off rendering */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    void        (*restore) (KdCardInfo *);  /**//* restore graphics card state */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    void        (*scrfini) (KdScreenInfo *);/**//* close down screen */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    void        (*cardfini) (KdCardInfo *); /**//* close down */
X Window研究笔记(5)_os_23
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    Bool        (*initCursor) (ScreenPtr);      /**//* detect and map cursor */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    void        (*enableCursor) (ScreenPtr);    /**//* enable cursor */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    void        (*disableCursor) (ScreenPtr);   /**//* disable cursor */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    void        (*finiCursor) (ScreenPtr);      /**//* close down */
X Window研究笔记(5)_os_23    void        (*recolorCursor) (ScreenPtr, int, xColorItem *);
X Window研究笔记(5)_os_23
X Window研究笔记(5)_os_23    Bool        (*initAccel) (ScreenPtr);
X Window研究笔记(5)_os_23    void        (*enableAccel) (ScreenPtr);
X Window研究笔记(5)_os_23    void        (*syncAccel) (ScreenPtr);
X Window研究笔记(5)_os_23    void        (*disableAccel) (ScreenPtr);
X Window研究笔记(5)_os_23    void        (*finiAccel) (ScreenPtr);
X Window研究笔记(5)_os_23   
X Window研究笔记(5)_os_23    void        (*getColors) (ScreenPtr, int, int, xColorItem *);
X Window研究笔记(5)_os_23    void        (*putColors) (ScreenPtr, int, int, xColorItem *);
X Window研究笔记(5)_os_23   
X Window研究笔记(5)_os_23    Bool        (*finishInitScreen) (ScreenPtr pScreen);
X Window研究笔记(5)_os_44} KdCardFuncs;


Fbdev是基于FrameBuffer实现的显示设备驱动,前面的KdCardFuncs定义了很多接口函数,由下面的fbdev的初始化,我们可以看出,很多接口函数并不是必须的。

X Window研究笔记(5)_serverX Window研究笔记(5)_server_02KdCardFuncs     fbdevFuncs = ...{
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    fbdevCardInit,          /**//* cardinit */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    fbdevScreenInit,        /**//* scrinit */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    fbdevInitScreen,        /**//* initScreen */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    fbdevPreserve,          /**//* preserve */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    fbdevEnable,            /**//* enable */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    fbdevDPMS,              /**//* dpms */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    fbdevDisable,           /**//* disable */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    fbdevRestore,           /**//* restore */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    fbdevScreenFini,        /**//* scrfini */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    fbdevCardFini,          /**//* cardfini */
X Window研究笔记(5)_os_23   
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    0,                      /**//* initCursor */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    0,                      /**//* enableCursor */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    0,                      /**//* disableCursor */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    0,                      /**//* finiCursor */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    0,                      /**//* recolorCursor */
X Window研究笔记(5)_os_23   
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    0,                      /**//* initAccel */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    0,                      /**//* enableAccel */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    0,                      /**//* syncAccel */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    0,                      /**//* disableAccel */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    0,                      /**//* finiAccel */
X Window研究笔记(5)_os_23
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    fbdevGetColors,         /**//* getColors */
X Window研究笔记(5)_os_03X Window研究笔记(5)_struct_04    fbdevPutColors,         /**//* putColors */
X Window研究笔记(5)_os_44};
X Window研究笔记(5)_os_95
  1. FbdevCardInit 创建FbdevPriv结构,打开/dev/fb0设备文件,获取framebuffer信息,并映射显存到用户空间。
  2. FbdevScreenInit 根据framebuffer的信息初始化ScreenInfo。
  3. FbdevInitScreen 初始化Screen的信息和虚函数表。
  4. FbdevPreserve 空函数。
  5. FbdevEnable 激活framebuffer并设置调色板。
  6. FbdevDPMS 显示器电源管理,通过ioctl控制framebuffer的电源模式。
  7. FbdevDisable 空函数。
  8. FbdevRestore  空函数。
  9. FbdevScreenFini  空函数。
  10. FbdevCardFini  unmap显存,并关闭framebuffer设备文件。
  11. FbdevGetColors 得到调色板信息。
  12. FbdevPutColors 设置调色板信息。

Screen的初始化并不是在Tinyx/Fbdev中完成的,原因是framebuffer的操作是公共的,非Tinyx下也可以使用,所以这些函数的实现是放在Xserver/fb中,由fbSetupScreen来初始化的。

(待续)