Linux Graphic DRI Wayland 显示子系统
1. 前言
上篇文章(Linux graphic subsytem(1)_概述)介紹了linux圖形子系統(tǒng)基本的軟件框架,以及GUI、Windowing system、3D渲染等基本概念。文中提到了linux DRI(Direct Render Infrastructure)框架,但限于篇幅,沒有過多介紹。
蝸蝸覺得,DRI在當(dāng)前(或者說將來)的linux圖形子系統(tǒng)中,有著舉足輕重的地位,甚至可以說是新的linux圖形框架核心思想的體現(xiàn)。本文將基于linux圖形框架的發(fā)展歷程,從Why、What和How三個角度,介紹DRI框架。
2. 為什么需要DRI
在GUI環(huán)境中,一個Application想要將自身的UI界面呈現(xiàn)給用戶,需要2個步驟:
1)根據(jù)實際情況,將UI繪制出來,以一定的格式,保存在buffer中。該過程就是常說的“Rendering”。
不知道為什么,wowo一直覺得“Render”這個英文單詞太專業(yè)、太抽象了,理解起來有些困難。時間久了,也就不再執(zhí)著了,看到它時,就想象一下內(nèi)存中的圖像數(shù)據(jù)(RGB或YUV格式),Rendering就是生成它們的過程。
通常來說,Rendering有多種表現(xiàn)形式,但可歸結(jié)為如下幾類:
a)2D的點、線、面等繪圖,例如,“通過一個for循環(huán),生成一個大小為640x480、格式為RGB888、填充顏色為紅色的矩形框”,就是一個2D rendering的例子。
b)3D渲染。該過程牽涉比較復(fù)雜的專業(yè)知識,這里先不舉例了。
c)圖片、視頻等多媒體解碼。
d)字體渲染,例如直接從字庫中抽出。
2)將保存在buffer中的UI數(shù)據(jù),顯示在display device上。該過程一般稱作“送顯”。
然后問題就來了:這兩個步驟中,display server要承擔(dān)什么樣的角色?回答這個問題之前,我們需要知道這樣的一個理念:
在操作系統(tǒng)中,Application不應(yīng)該直接訪問硬件,通常的軟件框架是(從上到下):Application<---->Service<---->Driver<---->Hardware。這樣考慮的原因主要有二:安全性和共享硬件資源(例如顯示設(shè)備只有一個,卻有多個應(yīng)用想要顯示)。
對稍微有經(jīng)驗的軟件開發(fā)人員(特別是系統(tǒng)工程師和驅(qū)動工程師)來說,這種理念就像殺人償命、欠債還錢一樣天經(jīng)地義。但直到X server+3D出現(xiàn)之后,一切都不好了。因為X server大喊的著:“讓我來!”,給出了這樣的框架:
先不考慮上面的GLX、Utah GLX等術(shù)語,我們只需要理解一點即可:
基于OpenGL的3D program需要進行3D rendering的時候,需要通過X server的一個擴展(GLX),請求X server幫忙處理。X server再通過底層的driver(位于用戶空間),通過kernel,訪問硬件(如GPU)。
其它普通的2D rendering,如2D繪圖、字體等,則直接請求X server幫忙完成。
看著不錯哦,完全滿足上面的理念。但計算機游戲、圖形設(shè)備硬件等開發(fā)人員不樂意了:請讓我們直接訪問硬件!因為很多高性能的圖形設(shè)備,要求相應(yīng)的應(yīng)用程序直接訪問硬件,才能實現(xiàn)性能最優(yōu)[1]。
好像每個人都是對的,怎么辦?妥協(xié)的結(jié)果是,為3D Rendering另起爐灶,給出一個直接訪問硬件的框架,DRI就應(yīng)運而生了,如下:
上面好像講的都是Rendering有關(guān)的內(nèi)容,那送顯呢?還是由display server統(tǒng)一處理比較好,因為顯示設(shè)備是有限的,多個應(yīng)用程序的多個界面都要爭取這有限的資源,server會統(tǒng)一管理、疊加并顯示到屏幕上。而這里疊加的過程,通常稱作合成(Compositor),后續(xù)文章會重點說明。
3. 軟件架構(gòu)
DRI是因3D而生,但它卻不僅僅是為3D而存在,這背后涉及了最近Linux圖形系統(tǒng)設(shè)計思路的轉(zhuǎn)變,即:
從以前的:X serve是宇宙的中心,其它的接口都要和我對話。
轉(zhuǎn)變?yōu)?#xff1a;Linux kernel及其組件為中心,X server(如Wayland compositor等)只是角落里的一員,可有可無。
最終,基于DRI的linux圖形系統(tǒng)如下(參考自[4][5]):
該框架以基于Wayland的Windowing system為例,描述了linux graphic系統(tǒng)在DRI框架下,通過兩條路徑(DRM和KMS),分別實現(xiàn)Rendering和送顯兩個顯示步驟。從應(yīng)用的角度,顯示流程是:
1)Application(如3D game)根據(jù)用戶動作,需要重繪界面,此時它會通過OpenGL|ES、EGL等接口,將一系列的繪圖請求,提交給GPU。
a)OpenGL|ES、EGL的實現(xiàn),可以有多種形式,這里以Mesa 3D為例,所有的3D rendering請求,都會經(jīng)過該軟件庫,它會根據(jù)實際情況,通過硬件或者軟件的方式,響應(yīng)Application的rendering請求。
b)當(dāng)系統(tǒng)存在基于DRI的硬件rendering機制時,Mesa 3D會通過libGL-meas-DRI,調(diào)用DRI提供的rendering功能。
c)libGL-meas-DRI會調(diào)用libdrm,libdrm會通過ioctl調(diào)用kernel態(tài)的DRI驅(qū)動,這里稱作DRM(Direct Rendering Module)。
d)kernel的DRM模塊,最終通過GPU完成rendering動作。
2)GPU繪制完成后,將rendering的結(jié)果返回給Application。
rendering的結(jié)果是以image buffer的形式返回給應(yīng)用程序。
3)Application將這些繪制完成的圖像buffer(可能不知一個)送給Wayland compositor,Wayland compositor會控制硬件,將buffer顯示到屏幕上。
Wayland compositor會搜集系統(tǒng)Applications送來的所有image buffers,并處理buffer在屏幕上的坐標(biāo)、疊加方式后,直接通過ioctl,交給kernel KMS(kernel mode setting)模塊,該模塊會控制顯示控制器將圖像顯示到具體的顯示設(shè)備上。
4. DRM和KMS
DRM是Direct Rendering Module的縮寫,是DRI框架在kernel中的實現(xiàn),負(fù)責(zé)管理GPU(或顯卡,graphics card)及相應(yīng)的graphics memory,主要功能有二:
1)統(tǒng)一管理、調(diào)度多個應(yīng)用程序向顯卡發(fā)送的命令請求,可以類比為管理CPU資源的進程管理(process management)模塊。
2)統(tǒng)一管理顯示有關(guān)的memory(memory可以是GPU專用的,也可以是system ram劃給GPU的,后一種方法在嵌入式系統(tǒng)比較常用),該功能由GEM(Graphics Execution Manager)模塊實現(xiàn),主要包括:
a) 允許用戶空間程序創(chuàng)建、管理、銷毀video memory對象(稱作“"GEM objects”,以handle為句柄)。
b)允許不同用戶空間程序共享同一個"GEM objects”(需要將不唯一的handle轉(zhuǎn)換為同一個driver唯一的GEM name,后續(xù)使用dma buf)。
c)處理CPU和GPU之間內(nèi)存一致性的問題。
d)video memory都在kernel管理,便于給到display controller進行送顯(Application只需要把句柄通過Wayland Compositor遞給kernel即可,kernel會自行獲取memory及其內(nèi)容)。
KMS是Kernel Mode Setting的縮寫,也稱作Atomic KMS,它是一個在linux 4.2版本的kernel上,才最終定性的技術(shù)。從字面意義上理解,它要實現(xiàn)的功能比較簡單,即:顯示模式(display mode)的設(shè)置,包括屏幕分辨率(resolution)、顏色深的(color depth)、屏幕刷新率(refresh rate)等等。一般來說,是通過控制display controller的來實現(xiàn)上述功能的。
也許大家會有疑問:這些功能和DRI有什么關(guān)系?說實話,關(guān)系不大,之所以要在DRI框架里面提及KMS,完全是歷史原因,導(dǎo)致KMS的代碼,放到DRM中實現(xiàn)了。目前的kernel版本(如4.2之后),KMS和DRM基本上沒有什么邏輯耦合(除了代碼位于相同目錄,以及通過相同的設(shè)備節(jié)點提供ioctl之外),可以當(dāng)做獨立模塊看待。
繼續(xù)上面的話題,只是簡單的display mode設(shè)置的話,代碼實現(xiàn)不復(fù)雜吧?還真不一定!相反,KMS有關(guān)的技術(shù)背景、軟件實現(xiàn)等,是相當(dāng)復(fù)雜的,因此也就不能三言兩語說得清,我會在單獨的文章中重點分析KMS。
5. 參考文檔
[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
[4]:?Linux_kernel_and_daemons_with_exclusive_access.svg
[5]:?Wayland_display_server_protocol.svg
總結(jié)
以上是生活随笔為你收集整理的Linux Graphic DRI Wayland 显示子系统的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux Graphic DRI 显
- 下一篇: Android编译系统分析二:mm编译单