亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 1802 | 回復: 0
打印 上一主題 下一主題

xorg 硬件加速淺析 系列 kdrive的kaa框架的加速的實現(xiàn) [復制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2009-06-22 13:39 |只看該作者 |倒序瀏覽

kaa是kdrive的硬件加速的框架。
還是直接看代碼吧。
hw/kdrive/src/kaa.c里面都是kaa的xserver這邊的實現(xiàn)了,
然后就是driver那邊的實現(xiàn)了。
我們硬件加速實際上就是實現(xiàn)driver那邊,也就是說具體的工作實際上都是在driver里面做的。
注冊回調(diào)函數(shù)到xserver那邊,xserver那邊會負責調(diào)用,然后就會調(diào)用到我們driver里面來。
這個driver和xserver是在同一個進程空間的,無論是kdrive還是xorg都一樣。
對于kdrive來說,這個driver是直接編譯到xserver里面也就是Xfbdev里面
對于xorg來說這個是一個單獨的模塊,xorg這邊的框架是從kaa學習過來的,叫exa。
xorg這邊加速的模塊exa的實現(xiàn)都在xf86-video-ati等等類似這樣的里面
具體下載的路徑在
http://xorg.freedesktop.org/releases/individual/driver/
下面有很多video的驅(qū)動,基本上都是exa的實現(xiàn)。
這些東西編譯完成之后都是so文件,
以intel的為例。
ailantian@vax:/mnt/sdb1/ubd/soft/xorg/temp/xorg-server-1.5.3$ dpkg -L xserver-xorg-video-intel
/.
/usr
/usr/share
/usr/share/doc
/usr/share/doc/xserver-xorg-video-intel
/usr/share/doc/xserver-xorg-video-intel/copyright
/usr/share/doc/xserver-xorg-video-intel/changelog.gz
/usr/share/doc/xserver-xorg-video-intel/README.gz
/usr/share/doc/xserver-xorg-video-intel/changelog.Debian.gz
/usr/share/xserver-xorg
/usr/share/xserver-xorg/pci
/usr/share/xserver-xorg/pci/intel.ids
/usr/share/man
/usr/share/man/man4
/usr/share/man/man4/intel.4.gz
/usr/share/bug
/usr/share/bug/xserver-xorg-video-intel
/usr/lib
/usr/lib/xorg
/usr/lib/xorg/modules
/usr/lib/xorg/modules/drivers
/usr/lib/xorg/modules/drivers/ch7017.so
/usr/lib/xorg/modules/drivers/ch7xxx.so
/usr/lib/xorg/modules/drivers/intel_drv.so
/usr/lib/xorg/modules/drivers/ivch.so
/usr/lib/xorg/modules/drivers/sil164.so
/usr/lib/xorg/modules/drivers/tfp410.so
/usr/lib/libI810XvMC.so.1.0.0
/usr/lib/libIntelXvMC.so.1.0.0
/usr/share/man/man4/i810.4.gz
/usr/share/bug/xserver-xorg-video-intel/script
/usr/lib/xorg/modules/drivers/i810_drv.so
/usr/lib/libI810XvMC.so
/usr/lib/libI810XvMC.so.1
/usr/lib/libIntelXvMC.so
/usr/lib/libIntelXvMC.so.1
ailantian@vax:/mnt/sdb1/ubd/soft/xorg/temp/xorg-server-1.5.3$  
比如i810的驅(qū)動。
/usr/lib/xorg/modules/drivers/i810_drv.so
其他的xvmc等等這個是擴展的實現(xiàn)了,如果不關(guān)注的話,可以不看這些東西。
好的,說遠了,xorg的另外分出來說吧,這里還是看看kdrive的,xorg和kdrive差不多。
static const GCOps    kaaOps = {
    kaaFillSpans,
    KdCheckSetSpans,
    KdCheckPutImage,
    kaaCopyArea,
    KdCheckCopyPlane,
    KdCheckPolyPoint,
    KdCheckPolylines,
    KdCheckPolySegment,
    miPolyRectangle,
    KdCheckPolyArc,
    miFillPolygon,
    kaaPolyFillRect,
    miPolyFillArc,
    miPolyText8,
    miPolyText16,
    miImageText8,
    miImageText16,
    kaaImageGlyphBlt,
    KdCheckPolyGlyphBlt,
    KdCheckPushPixels,
};
GCFuncs    kaaGCFuncs = {
    kaaValidateGC,
    miChangeGC,
    miCopyGC,
    miDestroyGC,
    miChangeClip,
    miDestroyClip,
    miCopyClip
};
上面這些都是最基本的gc的函數(shù)了,實際上圖形系統(tǒng)里面都是使用gc的,這樣可以避免傳遞的參數(shù)太多,
如果感興趣的可以看看microwindows的介紹。雖然很簡陋但是基本的圖形系統(tǒng)的設(shè)計還是可以看出來的。
對xserver上層來說調(diào)用的都是gc的操作函數(shù),不同的gc是不一樣的,所以這里有機會給我們注冊這些基本的函數(shù)了。
我們還是找一個驅(qū)動來看看,我寫的部分也是照抄的,因為模式都定的。
我們還是看ati的實現(xiàn)吧,開源的來說,ati和intel的做的不錯。
ati_stub.c這個是給上層的一些最基本的接口。我們可以不用管。
一般來說,kaa的實現(xiàn),都是在XXX_draw.c里面來實現(xiàn)的,比如ati_draw.c
我們先看看最核心的一個函數(shù)。這個drawinit是注冊回調(diào)函數(shù)的。
如果大家覺得ati的做的太復雜,可以看看epson的實現(xiàn),這個實現(xiàn)的加速比較少,所以看起來比較簡單。
Bool
ATIDrawInit(ScreenPtr pScreen)
{
    KdScreenPriv(pScreen);
    ATIScreenInfo(pScreenPriv);
    ATICardInfo(pScreenPriv);
    ErrorF("Screen: %d/%d depth/bpp\n", pScreenPriv->screen->fb[0].depth,
        pScreenPriv->screen->fb[0].bitsPerPixel);
    RegisterBlockAndWakeupHandlers(ATIBlockHandler, ATIWakeupHandler,
        pScreen);
#ifdef USE_DRI
    atis->using_dri = ATIDRIScreenInit(pScreen);
#endif /* USE_DRI */
    memset(&atis->kaa, 0, sizeof(KaaScreenInfoRec));
    atis->kaa.waitMarker = ATIWaitMarker;
    atis->kaa.PrepareSolid = ATIPrepareSolid;
    atis->kaa.Solid = ATISolid;
    atis->kaa.DoneSolid = ATIDoneSolid;
    atis->kaa.PrepareCopy = ATIPrepareCopy;
    atis->kaa.Copy = ATICopy;
    atis->kaa.DoneCopy = ATIDoneCopy;
    /* Other acceleration will be hooked in in DrawEnable depending on
     * what type of DMA gets initialized.
     */
    atis->kaa.flags = KAA_OFFSCREEN_PIXMAPS;
    if (atic->is_radeon) {
        atis->kaa.offsetAlign = 1024;
        atis->kaa.pitchAlign = 64;
    } else {
        /* Rage 128 compositing wants power-of-two pitches. */
        atis->kaa.flags |= KAA_OFFSCREEN_ALIGN_POT;
        atis->kaa.offsetAlign = 32;
        /* Pitch alignment is in sets of 8 pixels, and we need to cover
         * 32bpp, so 32 bytes.
         */
        atis->kaa.pitchAlign = 32;
    }
    kaaInitTrapOffsets(8, sample_offsets_x, sample_offsets_y, 0.0, 0.0);
    sample_count = (1 kaa))
        return FALSE;
    return TRUE;
}
可以看出,實際上kaa的加速分為三類操作,這個也是kaa的核心,無非是Solid,Copy,Composite
這三類操作如下解釋
Solid,
就是填充一個區(qū)域,比如我們創(chuàng)建一個window的時候背景一般都是白色或者灰色,實際上這個是需要填充的,注意這里的solid并不是
我們想像的簡單的solid,這里有mask,有fg,還有alu,怎么說呢,實際上圖形學是比較復雜的,也就是說,我們往一個區(qū)域里面畫的時候,實際上這個
東西應該說是一個狀態(tài)機,比如畫之前是什么狀態(tài),我畫什么上去,畫完之后是什么效果,這個東西我一句兩句實在是說不清楚。
mask就是把某些位給mask掉,fg是前景色,alu,這個是畫的方法,就是說,是or,xor等等,定義的比較多,如果大家像了解,需要先補一補圖形學的只是,
這個不是這里要說明的要點,不過總之,一般pc的硬件可以很簡單的處理這樣的狀況。
Copy.
我們簡單的理解,就是比如我們有一個窗口,我們現(xiàn)在拿鼠標來拖動這個窗口,實際上在xserver上面是這么處理的,就是把這個區(qū)域copy到新的區(qū)域,當然這個copy
的速度很快,所以我們感覺不到閃,但是如果系統(tǒng)很慢,或者屏幕很大,或者沒有任何硬件加速,我們拖動的時候就會看到大家所說的屏幕撕開的情況,其實就是copy的速度
太慢了,實際上copy來說就是一行一行的copy,這里的處理有些是linar buffer有些是tiled buffer,不過有些pc的硬件可以很好的處理這不同的狀況。
屏幕大了之后,copy的速度沒變的話,由于數(shù)據(jù)量的變大,導致我們繪圖看起來比較慢,所以看到上部先顯示,然后下部后顯示,就是我們看到的屏幕撕裂了,當然這個說的是
沒有硬件加速的情況,我們這里說的是online buffer的情況,沒有swap buffer的情況,kaa里面沒有double buffer的處理。當然copy和solid一樣,
都要考慮采用什么畫法。alu.
Composite
Composite是這三種操作里面最復雜的一種了,本身composite操作就種類多?梢詤⒖既缦骆溄
http://en.wikipedia.org/wiki/Alpha_compositing
本身composite的操作就比較多,再加上狀態(tài)處理,組合就更多了,另外composite里面還要加上trasform的處理,這樣導致這個地方的處理很復雜,2d的engine一般
沒法完全處理這些,只能靠3d的engine來處理。
當然對應的每個類別里面都有prepare, do, done三類處理,以solid為例
PrepareSolid
Solid
DoneSolid
composite復雜一些,會多一些操作,比如CheckComposite的操作,如果發(fā)現(xiàn)不支持的話,就會采用軟件的實現(xiàn)。
如果沒有硬件的實現(xiàn),就是使用xserver自己的軟件實現(xiàn),以前都是在xserver里面實現(xiàn),好像現(xiàn)在傾向于拿到pixman這個庫里面去處理了。
所以這個庫現(xiàn)在更新的很快,有很多cpu相關(guān)的優(yōu)化,arm的優(yōu)化也比較多0.15.10里面加入的noen優(yōu)化指令比較多,其實這個優(yōu)化最早是從maemo的項目,ti的omap的cpu里面來的。
因為ti的xv的硬件有問題,暫時只能靠軟件來實現(xiàn)。不過ti的3d的驅(qū)動做的還不錯,powerVR那邊支持的很好.高通的相對落后不少。
剩下的還有一些函數(shù)
比如
UploadToScreen
UploadToScratch
自己感覺好像用的頻率不高。
BlockHandler
WakeupHandler
這兩個函數(shù)是如果硬件需要lock的時候就會用,不過好像有些硬件不需要。留空就行了。
然后我們要實現(xiàn)的就是上面的Solid,Copy,Composite函數(shù)了,
比如cairo的Xlib的后端就會調(diào)用XrenderComposite,然后就會調(diào)用Composite這個函數(shù)了,如果這個函數(shù)做的快,自然 cairo就快了。
當然cairo還可以使用glitz的后端,只要有opengl就可以了.不過embedded一般都沒有opengl了,不過exa/kaa這個還是可以實現(xiàn)的。畢竟只是2d的東西
當然也可以使用3d的engine來實現(xiàn)。
至于具體的實現(xiàn),這里不多說了,根據(jù)硬件的功能,完整這個目的就行了,這里只是說說架構(gòu)。
不同的硬件是不一樣的,另外就是對上層的接口也不一樣。
舉一個例子來說明調(diào)用流程
kaaCopyWindow這個是gc里面的函數(shù),注冊到xserver里面去了。
當copywindow發(fā)生的時候kaa的實現(xiàn)就會調(diào)用kaaCopyWindow
調(diào)用下面的函數(shù)。
   fbCopyRegion (&pPixmap->drawable, &pPixmap->drawable,
          0,
          &rgnDst, dx, dy, kaaCopyNtoN, 0, 0);
會調(diào)用這個函數(shù)。
kaaCopyNtoN
這個函數(shù)里面就會調(diào)用copy的硬件回調(diào)函數(shù)了,具體如下kaa.c
這是一個標準的硬件處理流程,其他的流程也類似。
   if (pScreenPriv->enabled &&
    (pSrcPixmap = kaaGetOffscreenPixmap (pSrcDrawable, &src_off_x, &src_off_y)) &&
    (pDstPixmap = kaaGetOffscreenPixmap (pDstDrawable, &dst_off_x, &dst_off_y)) &&
    (*pKaaScr->info->PrepareCopy) (pSrcPixmap,
                       pDstPixmap,
                       dx,
                       dy,
                       pGC ? pGC->alu : GXcopy,
                       pGC ? pGC->planemask : FB_ALLONES))
    {
    while (nbox--)
    {
        (*pKaaScr->info->Copy) (pbox->x1 + dx + src_off_x,
                    pbox->y1 + dy + src_off_y,
                    pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
                    pbox->x2 - pbox->x1,
                    pbox->y2 - pbox->y1);
        pbox++;
    }
    (*pKaaScr->info->DoneCopy) ();
    kaaMarkSync (pDstDrawable->pScreen);
大家也能看到,一次preparecopy之后會有多次的copy,最后是donecopy。
如果沒有硬件加速的話,走的就是這邊
  else
    {
    kaaWaitSync (pDstDrawable->pScreen);
    fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
            pbox, nbox, dx, dy, reverse, upsidedown,
            bitplane, closure);
    }
然后就跑到pixman里面去了,fbimage,fbcopy等等里面的實現(xiàn),現(xiàn)在看起來都慢慢移動到pixman里面去了,都是基本的像素操作,
以后xorg只管基本的邏輯了。具體的繪圖或者加速,都在外邊了。
因為driver一般都做成一個,所以xvideo等實現(xiàn)也一般就做在這個driver里面,核心的文件是ati_draw.c
因為所有的回調(diào)函數(shù)的具體實現(xiàn)都是在這個里面實現(xiàn)的,注冊回調(diào)函數(shù)也是在這個函數(shù)里面實現(xiàn)的。
另外一個重要的文件就是ati.c這個和框架有點關(guān)系,但是也基本是一個數(shù)組,然后填充數(shù)據(jù)就行了。
kdrive和xorg不同,kdrive是直接操作fb空間的,所以這些驅(qū)動都是基于framebuffer的
kaa的內(nèi)存管理也是一樣。
KdCardFuncs ATIFuncs = {
    ATICardInit,        /* cardinit */
    ATIScreenInit,        /* scrinit */
    ATIInitScreen,        /* initScreen */
    ATIFinishInitScreen,    /* finishInitScreen */
    ATICreateResources,    /* createRes */
    ATIPreserve,        /* preserve */
    ATIEnable,        /* enable */
    ATIDPMS,        /* dpms */
    ATIDisable,        /* disable */
    ATIRestore,        /* restore */
    ATIScreenFini,        /* scrfini */
    ATICardFini,        /* cardfini */
    ATICursorInit,        /* initCursor */
    ATICursorEnable,    /* enableCursor */
    ATICursorDisable,    /* disableCursor */
    ATICursorFini,        /* finiCursor */
    ATIRecolorCursor,    /* recolorCursor */
    ATIDrawInit,        /* initAccel */
    ATIDrawEnable,        /* enableAccel */
    ATIDrawDisable,        /* disableAccel */
    ATIDrawFini,        /* finiAccel */
    ATIGetColors,        /* getColors */
    ATIPutColors,        /* putColors */
};
這里是所有將要被調(diào)用的函數(shù),沒有注冊的就是空NULL,
ATIScreenInit
里面的主要函數(shù)就是這個函數(shù)調(diào)用,
#ifdef KDRIVEFBDEV
    if (atic->use_fbdev) {
        success = fbdevScreenInitialize(screen,
                        &atis->backend_priv.fbdev);
    }
#endif
這個函數(shù)里面的主要實現(xiàn)
static Bool
ATIInitScreen(ScreenPtr pScreen)
{
    KdScreenPriv(pScreen);
    ATICardInfo(pScreenPriv);
#ifdef XV
    ATIInitVideo(pScreen);
#endif
    return atic->backend_funcs.initScreen(pScreen);
}
一個就是xvideo的初始化,大家看到其實就只有一行代碼。
其實這里都有默認的函數(shù),默認的就是fbdev里面的函數(shù)。
ati還是有硬件加速的reg的這些的處理,實際上對于之前我們實現(xiàn)的driver來說,這些東西都完全省略了,因為fb這邊我基本不用任何處理。
只要使用MDP對fb來做上面的Solid,Copy,Composite的處理
對應init的函數(shù)我們也有fina的函數(shù),比如deregister Xvideo
static void
ATIScreenFini(KdScreenInfo *screen)
{
    ATIScreenInfo *atis = (ATIScreenInfo *)screen->driver;
    ATICardInfo *atic = screen->card->driver;
#ifdef XV
    ATIFiniVideo(screen->pScreen);
#endif
    atic->backend_funcs.scrfini(screen);
    xfree(atis);
    screen->driver = 0;
}
這里其實很多函數(shù)都是不需要實現(xiàn)的,可以參考epson的實現(xiàn),epson實現(xiàn)的功能比較簡單。
ati的顯卡相對來說復雜一些,但是對于嵌入式來講沒有那么復雜的顯示芯片(2d,3d集成)。
然后大家可能問這些個回調(diào)函數(shù)都是在什么地方調(diào)用的。
這個就是kdrive了。
hw/kdrive/src/kdrive.c里面會調(diào)用。這個是kdrive的主程序。
比如kdrive的初始化screen的函數(shù)
void
KdInitScreen (ScreenInfo    *pScreenInfo,
          KdScreenInfo  *screen,
          int        argc,
          char        **argv)
{
    KdCardInfo    *card = screen->card;
   
    (*card->cfuncs->scrinit) (screen);
   
    if (!card->cfuncs->initAccel)
    screen->dumb = TRUE;
    if (!card->cfuncs->initCursor)
    screen->softCursor = TRUE;
}
比如下面,都會調(diào)用這些回調(diào)函數(shù)。
Bool
KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
{
    KdScreenInfo    *screen = kdCurrentScreen;
    KdCardInfo        *card = screen->card;
    KdPrivScreenPtr    pScreenPriv;
    int            fb;
    /*
     * note that screen->fb is set up for the nominal orientation
     * of the screen; that means if randr is rotated, the values
     * there should reflect a rotated frame buffer (or shadow).
     */
    Bool        rotated = (screen->randr & (RR_Rotate_90|RR_Rotate_270)) != 0;
    int            width, height, *width_mmp, *height_mmp;
    KdAllocatePrivates (pScreen);
    pScreenPriv = KdGetScreenPriv(pScreen);
   
    if (!rotated)
    {
    width = screen->width;
    height = screen->height;
    width_mmp = &screen->width_mm;
    height_mmp = &screen->height_mm;
    }
    else
    {
    width = screen->height;
    height = screen->width;
    width_mmp = &screen->height_mm;
    height_mmp = &screen->width_mm;
    }
    screen->pScreen = pScreen;
    pScreenPriv->screen = screen;
    pScreenPriv->card = card;
    for (fb = 0; fb fb[fb].depth; fb++)
    pScreenPriv->bytesPerPixel[fb] = screen->fb[fb].bitsPerPixel >> 3;
    pScreenPriv->dpmsState = KD_DPMS_NORMAL;
#ifdef PANORAMIX
    dixScreenOrigins[pScreen->myNum] = screen->origin;
#endif
    if (!monitorResolution)
    monitorResolution = 75;
    /*
     * This is done in this order so that backing store wraps
     * our GC functions; fbFinishScreenInit initializes MI
     * backing store
     */
    if (!fbSetupScreen (pScreen,
            screen->fb[0].frameBuffer,
            width, height,
            monitorResolution, monitorResolution,
            screen->fb[0].pixelStride,
            screen->fb[0].bitsPerPixel))
    {
    return FALSE;
    }
    /*
     * Set colormap functions
     */
    pScreen->InstallColormap    = KdInstallColormap;
    pScreen->UninstallColormap    = KdUninstallColormap;
    pScreen->ListInstalledColormaps = KdListInstalledColormaps;
    pScreen->StoreColors    = KdStoreColors;
     
    pScreen->SaveScreen        = KdSaveScreen;
    pScreen->CreateWindow    = KdCreateWindow;
#if KD_MAX_FB > 1
    if (screen->fb[1].depth)
    {
    if (!fbOverlayFinishScreenInit (pScreen,
                    screen->fb[0].frameBuffer,
                    screen->fb[1].frameBuffer,
                    width, height,
                    monitorResolution, monitorResolution,
                    screen->fb[0].pixelStride,
                    screen->fb[1].pixelStride,
                    screen->fb[0].bitsPerPixel,
                    screen->fb[1].bitsPerPixel,
                    screen->fb[0].depth,
                    screen->fb[1].depth))
    {
        return FALSE;
    }
    }
    else
#endif
    {
    if (!fbFinishScreenInit (pScreen,
                 screen->fb[0].frameBuffer,
                 width, height,
                 monitorResolution, monitorResolution,
                 screen->fb[0].pixelStride,
                 screen->fb[0].bitsPerPixel))
    {
        return FALSE;
    }
    }
   
    /*
     * Fix screen sizes; for some reason mi takes dpi instead of mm.
     * Rounding errors are annoying
     */
    if (*width_mmp)
    pScreen->mmWidth = *width_mmp;
    else
    *width_mmp = pScreen->mmWidth;
    if (*height_mmp)
    pScreen->mmHeight = *height_mmp;
    else
    *height_mmp = pScreen->mmHeight;
   
    /*
     * Plug in our own block/wakeup handlers.
     * miScreenInit installs NoopDDA in both places
     */
    pScreen->BlockHandler    = KdBlockHandler;
    pScreen->WakeupHandler    = KdWakeupHandler;
   
#ifdef RENDER
    if (!fbPictureInit (pScreen, 0, 0))
    return FALSE;
#endif
    if (card->cfuncs->initScreen)
    if (!(*card->cfuncs->initScreen) (pScreen))
        return FALSE;
        
    if (!screen->dumb && card->cfuncs->initAccel)
    if (!(*card->cfuncs->initAccel) (pScreen))
        screen->dumb = TRUE;
    if (screen->off_screen_base memory_size)
    KdOffscreenInit (pScreen);
   
#ifdef PSEUDO8
    (void) p8Init (pScreen, PSEUDO8_USE_DEFAULT);
#endif
   
    if (card->cfuncs->finishInitScreen)
    if (!(*card->cfuncs->finishInitScreen) (pScreen))
        return FALSE;
        
#if 0
    fbInitValidateTree (pScreen);
#endif
   
#if 0
    pScreen->backingStoreSupport = Always;
    miInitializeBackingStore (pScreen);
#endif
    /*
     * Wrap CloseScreen, the order now is:
     *    KdCloseScreen
     *    miBSCloseScreen
     *    fbCloseScreen
     */
    pScreenPriv->CloseScreen = pScreen->CloseScreen;
    pScreen->CloseScreen = KdCloseScreen;
    pScreenPriv->CreateScreenResources = pScreen->CreateScreenResources;
    pScreen->CreateScreenResources = KdCreateScreenResources;
   
    if (screen->softCursor ||
    !card->cfuncs->initCursor ||
    !(*card->cfuncs->initCursor) (pScreen))
    {
    /* Use MI for cursor display and event queueing. */
    screen->softCursor = TRUE;
    miDCInitialize(pScreen, &kdPointerScreenFuncs);
    }
   
    if (!fbCreateDefColormap (pScreen))
    {
    return FALSE;
    }
    KdSetSubpixelOrder (pScreen, screen->randr);
    /*
     * Enable the hardware
     */
    if (!kdEnabled)
    {
    kdEnabled = TRUE;
    if(kdOsFuncs->Enable)
        (*kdOsFuncs->Enable) ();
    }
   
    if (screen->mynum == card->selected)
    {
    if(card->cfuncs->preserve)
        (*card->cfuncs->preserve) (card);
    if(card->cfuncs->enable)
        if (!(*card->cfuncs->enable) (pScreen))
        return FALSE;
    pScreenPriv->enabled = TRUE;
    if (!screen->softCursor && card->cfuncs->enableCursor)
        (*card->cfuncs->enableCursor) (pScreen);
    KdEnableColormap (pScreen);
    if (!screen->dumb && card->cfuncs->enableAccel)
        (*card->cfuncs->enableAccel) (pScreen);
    }
   
    return TRUE;
}
那么KdInitScreen又是誰調(diào)用呢,
KdInitOutput,這個函數(shù)在我們每個顯卡驅(qū)動里面都會被調(diào)用,在ati_stub.c里面
void
InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
{
    KdInitOutput(pScreenInfo, argc, argv);
}
所以這里一會在driver里面一會在xserver(kdrive)里面,大家都覺得比較混亂,
實際上就是這樣的,因為kdrive自己會提供一些函數(shù)來給driver調(diào)用,而driver本來就是xserver一個進程空間的東西,所以就兩邊跳轉(zhuǎn),
這個其實和linux kernel里面的file system實現(xiàn)是很像的,cache的產(chǎn)生,就是在linux filesystem的框架和filesystem的driver之間跳轉(zhuǎn)的時候
把內(nèi)容放到cache里面去的。最新的內(nèi)核不知道是怎么實現(xiàn)的。這個東西更新一直都很快。
每個driver都會提供InitOutput這個函數(shù)。這個是標準的driver的stub
而這個InitOutput是在Xserver初始化的時候會被調(diào)用的,會初始化input和output。
那么xserver的主入口在什么地方?
在dix/main.c里面
這個是xserver的主入口。
當然,xorg和kdrive都是一樣的。
xserver實際上是一個死循環(huán),while(1)的
這個死循環(huán)里面會處理各種消息,就是大家看到里面有dispatch的函數(shù)。
Xserver這個大框架和事件處理比較大,這里就不多說了。其實大多都是消息處理。輸入,輸出,window管理等等這些的。
輸入輸出和我們關(guān)系比較近,可以簡單的說說,大家可能也比較關(guān)心,這個鍵盤鼠標等等是怎么工作的,比如從驅(qū)動里面到最上層的widget是怎么得到這個事件的。
打字還是很累的,尤其是用全拼輸入法打這么多字。


本文來自ChinaUnix博客,如果查看原文請點:http://blog.chinaunix.net/u1/40978/showart_1972995.html
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP