Linux Graphic DRI Wayland 顯示子系統


轉:https://blog.csdn.net/u013165704/article/details/80709547

1. 前言

上篇文章(Linux graphic subsytem(1)_概述)介紹了linux圖形子系統基本的軟件框架,以及GUI、Windowing system、3D渲染等基本概念。文中提到了linux DRI(Direct Render Infrastructure)框架,但限於篇幅,沒有過多介紹。

蝸蝸覺得,DRI在當前(或者說將來)的linux圖形子系統中,有着舉足輕重的地位,甚至可以說是新的linux圖形框架核心思想的體現。本文將基於linux圖形框架的發展歷程,從Why、What和How三個角度,介紹DRI框架。

2. 為什么需要DRI

在GUI環境中,一個Application想要將自身的UI界面呈現給用戶,需要2個步驟:

1)根據實際情況,將UI繪制出來,以一定的格式,保存在buffer中。該過程就是常說的“Rendering”。

不知道為什么,wowo一直覺得“Render”這個英文單詞太專業、太抽象了,理解起來有些困難。時間久了,也就不再執著了,看到它時,就想象一下內存中的圖像數據(RGB或YUV格式),Rendering就是生成它們的過程。

通常來說,Rendering有多種表現形式,但可歸結為如下幾類:

a)2D的點、線、面等繪圖,例如,“通過一個for循環,生成一個大小為640x480、格式為RGB888、填充顏色為紅色的矩形框”,就是一個2D rendering的例子。

b)3D渲染。該過程牽涉比較復雜的專業知識,這里先不舉例了。

c)圖片、視頻等多媒體解碼。

d)字體渲染,例如直接從字庫中抽出。

2)將保存在buffer中的UI數據,顯示在display device上。該過程一般稱作“送顯”。

然后問題就來了:這兩個步驟中,display server要承擔什么樣的角色?回答這個問題之前,我們需要知道這樣的一個理念:

在操作系統中,Application不應該直接訪問硬件,通常的軟件框架是(從上到下):Application<---->Service<---->Driver<---->Hardware。這樣考慮的原因主要有二:安全性和共享硬件資源(例如顯示設備只有一個,卻有多個應用想要顯示)。

對稍微有經驗的軟件開發人員(特別是系統工程師和驅動工程師)來說,這種理念就像殺人償命、欠債還錢一樣天經地義。但直到X server+3D出現之后,一切都不好了。因為X server大喊的着:“讓我來!”,給出了這樣的框架:

x_window_indirect_render

先不考慮上面的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就應運而生了,如下:

x_window_direct_render

上面好像講的都是Rendering有關的內容,那送顯呢?還是由display server統一處理比較好,因為顯示設備是有限的,多個應用程序的多個界面都要爭取這有限的資源,server會統一管理、疊加並顯示到屏幕上。而這里疊加的過程,通常稱作合成(Compositor),后續文章會重點說明。

3. 軟件架構

DRI是因3D而生,但它卻不僅僅是為3D而存在,這背后涉及了最近Linux圖形系統設計思路的轉變,即:

從以前的:X serve是宇宙的中心,其它的接口都要和我對話。

轉變為:Linux kernel及其組件為中心,X server(如Wayland compositor等)只是角落里的一員,可有可無。

最終,基於DRI的linux圖形系統如下(參考自[4][5]):

Direct_Rendering_Infrastructure

該框架以基於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)模塊,該模塊會控制顯示控制器將圖像顯示到具體的顯示設備上。

4. DRM和KMS

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。

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM