轉:https://blog.csdn.net/u013165704/article/details/80709547html
上篇文章(Linux graphic subsytem(1)_概述)介紹了linux圖形子系統基本的軟件框架,以及GUI、Windowing system、3D渲染等基本概念。文中提到了linux DRI(Direct Render Infrastructure)框架,但限於篇幅,沒有過多介紹。linux
蝸蝸以爲,DRI在當前(或者說未來)的linux圖形子系統中,有着舉足輕重的地位,甚至能夠說是新的linux圖形框架核心思想的體現。本文將基於linux圖形框架的發展歷程,從Why、What和How三個角度,介紹DRI框架。安全
在GUI環境中,一個Application想要將自身的UI界面呈現給用戶,須要2個步驟:架構
1)根據實際狀況,將UI繪製出來,以必定的格式,保存在buffer中。該過程就是常說的「Rendering」。框架
不知道爲何,wowo一直以爲「Render」這個英文單詞太專業、太抽象了,理解起來有些困難。時間久了,也就再也不執著了,看到它時,就想象一下內存中的圖像數據(RGB或YUV格式),Rendering就是生成它們的過程。ide
一般來講,Rendering有多種表現形式,但可歸結爲以下幾類:svg
a)2D的點、線、面等繪圖,例如,「經過一個for循環,生成一個大小爲640x480、格式爲RGB88八、填充顏色爲紅色的矩形框」,就是一個2D rendering的例子。性能
b)3D渲染。該過程牽涉比較複雜的專業知識,這裏先不舉例了。字體
c)圖片、視頻等多媒體解碼。操作系統
d)字體渲染,例如直接從字庫中抽出。
2)將保存在buffer中的UI數據,顯示在display device上。該過程通常稱做「送顯」。
而後問題就來了:這兩個步驟中,display server要承擔什麼樣的角色?回答這個問題以前,咱們須要知道這樣的一個理念:
在操做系統中,Application不該該直接訪問硬件,一般的軟件框架是(從上到下):Application<---->Service<---->Driver<---->Hardware。這樣考慮的緣由主要有二:安全性和共享硬件資源(例如顯示設備只有一個,卻有多個應用想要顯示)。
對稍微有經驗的軟件開發人員(特別是系統工程師和驅動工程師)來講,這種理念就像殺人償命、欠債還錢同樣天經地義。但直到X server+3D出現以後,一切都很差了。由於X server大喊的着:「讓我來!」,給出了這樣的框架:
先不考慮上面的GLX、Utah GLX等術語,咱們只須要理解一點便可:
基於OpenGL的3D program須要進行3D rendering的時候,須要經過X server的一個擴展(GLX),請求X server幫忙處理。X server再經過底層的driver(位於用戶空間),經過kernel,訪問硬件(如GPU)。
其它普通的2D rendering,如2D繪圖、字體等,則直接請求X server幫忙完成。
看着不錯哦,徹底知足上面的理念。但計算機遊戲、圖形設備硬件等開發人員不樂意了:請讓咱們直接訪問硬件!由於不少高性能的圖形設備,要求相應的應用程序直接訪問硬件,才能實現性能最優[1]。
好像每一個人都是對的,怎麼辦?妥協的結果是,爲3D Rendering另起爐竈,給出一個直接訪問硬件的框架,DRI就應運而生了,以下:
上面好像講的都是Rendering有關的內容,那送顯呢?仍是由display server統一處理比較好,由於顯示設備是有限的,多個應用程序的多個界面都要爭取這有限的資源,server會統一管理、疊加並顯示到屏幕上。而這裏疊加的過程,一般稱做合成(Compositor),後續文章會重點說明。
DRI是因3D而生,但它卻不只僅是爲3D而存在,這背後涉及了最近Linux圖形系統設計思路的轉變,即:
從之前的:X serve是宇宙的中心,其它的接口都要和我對話。
轉變爲:Linux kernel及其組件爲中心,X server(如Wayland compositor等)只是角落裏的一員,無關緊要。
最終,基於DRI的linux圖形系統以下(參考自[4][5]):
該框架以基於Wayland的Windowing system爲例,描述了linux graphic系統在DRI框架下,經過兩條路徑(DRM和KMS),分別實現Rendering和送顯兩個顯示步驟。從應用的角度,顯示流程是:
1)Application(如3D game)根據用戶動做,須要重繪界面,此時它會經過OpenGL|ES、EGL等接口,將一系列的繪圖請求,提交給GPU。
a)OpenGL|ES、EGL的實現,能夠有多種形式,這裏以Mesa 3D爲例,全部的3D rendering請求,都會通過該軟件庫,它會根據實際狀況,經過硬件或者軟件的方式,響應Application的rendering請求。
b)當系統存在基於DRI的硬件rendering機制時,Mesa 3D會經過libGL-meas-DRI,調用DRI提供的rendering功能。
c)libGL-meas-DRI會調用libdrm,libdrm會經過ioctl調用kernel態的DRI驅動,這裏稱做DRM(Direct Rendering Module)。
d)kernel的DRM模塊,最終經過GPU完成rendering動做。
2)GPU繪製完成後,將rendering的結果返回給Application。
rendering的結果是以image buffer的形式返回給應用程序。
3)Application將這些繪製完成的圖像buffer(可能不知一個)送給Wayland compositor,Wayland compositor會控制硬件,將buffer顯示到屏幕上。
Wayland compositor會蒐集系統Applications送來的全部image buffers,並處理buffer在屏幕上的座標、疊加方式後,直接經過ioctl,交給kernel KMS(kernel mode setting)模塊,該模塊會控制顯示控制器將圖像顯示到具體的顯示設備上。
DRM是Direct Rendering Module的縮寫,是DRI框架在kernel中的實現,負責管理GPU(或顯卡,graphics card)及相應的graphics memory,主要功能有二:
1)統一管理、調度多個應用程序向顯卡發送的命令請求,能夠類比爲管理CPU資源的進程管理(process management)模塊。
2)統一管理顯示有關的memory(memory能夠是GPU專用的,也能夠是system ram劃給GPU的,後一種方法在嵌入式系統比較經常使用),該功能由GEM(Graphics Execution Manager)模塊實現,主要包括:
a) 容許用戶空間程序建立、管理、銷燬video memory對象(稱做「"GEM objects」,以handle爲句柄)。
b)容許不一樣用戶空間程序共享同一個"GEM objects」(須要將不惟一的handle轉換爲同一個driver惟一的GEM name,後續使用dma buf)。
c)處理CPU和GPU之間內存一致性的問題。
d)video memory都在kernel管理,便於給到display controller進行送顯(Application只須要把句柄經過Wayland Compositor遞給kernel便可,kernel會自行獲取memory及其內容)。
KMS是Kernel Mode Setting的縮寫,也稱做Atomic KMS,它是一個在linux 4.2版本的kernel上,才最終定性的技術。從字面意義上理解,它要實現的功能比較簡單,即:顯示模式(display mode)的設置,包括屏幕分辨率(resolution)、顏色深的(color depth)、屏幕刷新率(refresh rate)等等。通常來講,是經過控制display controller的來實現上述功能的。
也許你們會有疑問:這些功能和DRI有什麼關係?說實話,關係不大,之因此要在DRI框架裏面說起KMS,徹底是歷史緣由,致使KMS的代碼,放到DRM中實現了。目前的kernel版本(如4.2以後),KMS和DRM基本上沒有什麼邏輯耦合(除了代碼位於相同目錄,以及經過相同的設備節點提供ioctl以外),能夠當作獨立模塊看待。
繼續上面的話題,只是簡單的display mode設置的話,代碼實現不復雜吧?還真不必定!相反,KMS有關的技術背景、軟件實現等,是至關複雜的,所以也就不能三言兩語說得清,我會在單獨的文章中重點分析KMS。
[1]: https://en.wikipedia.org/wiki/Direct_Rendering_Infrastructure
[2]: https://en.wikipedia.org/wiki/Wayland_(display_server_protocol)
[3]: http://wayland.freedesktop.org/architecture.html