Linux graphic subsytem(1)_概述
1. 前言
圖形子系統是linux系統中比較復雜的子系統之一:對下,它要管理形態各異的、性能各異的顯示相關的器件;對上,它要向應用程序提供易用的、友好的、功能強大的圖形用戶界面(GUI)。因此,它是linux系統中少有的、和用戶空間程序(甚至是用戶)息息相關的一個子系統。
本文是圖形子系統分析文章的第一篇,也是提綱挈領的一篇,將會從整體上,對linux顯示子系統做一個簡單的概述,進而羅列出顯示子系統的軟件構成,后續的文章將會圍繞這些軟件一一展開分析。
注1:本文所有的描述將以原生linux系統為例(如Ubuntu、Debian等),對其它基于linux的系統(如Android),部分內容會不適用。
注2:本文很多圖片都是從網上搜集而來的(很多是從維基百科)。雖然蝸窩的宗旨是用自己的語言表述,盡量自己畫圖,但是linux圖形子系統太復雜了,蝸蝸的理解有限,而老外的圖畫的實在太好,蝸蝸覺得,再怎么努力,也畫不出更好的了,因此本著為讀者負責的態度,就直接copy了。
2. 概念介紹
2.1 GUI(Graphical User Interface,圖形用戶界面)
linux圖形子系統的本質,是提供圖形化的人機交互(human-computer interaction)界面,也即常說的GUI(Graphical User Interface)。而人機交互的本質,是人腦通過人的輸出設備(動作、聲音等),控制電腦的輸入設備,電腦經過一系列的處理后,經由電腦的輸出設備將結果輸出,人腦再通過人的輸入設備接收電腦的輸出,最終實現“人腦<-->電腦”之間的人機交互。下面一幅摘自維基百科的圖片(可從“這里”查看比較清晰的SVG格式的原始圖片),對上述過程做了很好的總結:
該圖以一個非常前衛的應用場景----虛擬現實(VR,Virtual Reality)游戲,說明了以圖形化為主的人機交互過程:
1)人腦通過動作、聲音(對人腦而言,是output),控制電腦的輸入設備,包括鍵盤、鼠標、操作桿、麥克風、游戲手柄(包含加速度計、陀螺儀等傳感器)。
2)電腦通過輸入設備,接收人腦的指令,這些指令經過kernel Input subsystem、Middleware Gesture/Speech recognition等軟件的處理,轉換成應用程序(Game)可以識別的、有意義的信息。
3)應用程序(Game)根據輸入信息,做出相應的反饋,主要包括圖像和聲音。對VR游戲而言,可能需要3D rendering,這可以借助openGL及其相應的用戶空間driver實現。
4)應用程序的反饋,經由kernel的Video subsystem(如DRM/KMS)、audio subsystem(如ALSA),輸出到電腦的輸出設備上,包括顯示設備(2D/3D)、揚聲器/耳機(3D Positional Audio)、游戲手柄(力的反饋)等。
5)輸出到顯示設備上時,可能會經過圖形加速模塊(Graphics accelerator)。
注3:圖中提到了VR場景的典型幀率(1280×800@95fps?for VR),這是一個非常龐大的信息輸出,要求圖形子系統能10.5ms的時間內,生成并輸出一幀,以RGBA的數據格式為例,每秒需要處理的數據量是1280x800x95x4x8=3.11296Gb,壓力和挑戰是相當大的(更不用提1080P了)。
有關GUI更為詳細的解釋,請參考:https://en.wikipedia.org/wiki/Graphical_user_interface。
2.2 Windowing system(窗口系統)
窗口系統,是GUI的一種(也是當前計算機設備、智能設備廣泛使用的一種),以WIMP (windows、icons、menus、pointer) 的形式,提供人機交互接口。Linux系統中有很多窗口系統的實現,如X Window System、Wayland、Android SurfaceFlinger等,雖然形態各異,但思路大致相同,包含如下要點:
1)一般都使用client-server架構,server(稱作display server,或者windows server、compositor等等)管理所有輸入設備,以及用于輸出的顯示設備。
2)應用程序作為display server的一個client,在自己窗口(window)中運行,并繪制自己的GUI。
3)client的繪圖請求,都會提交給display server,display server響應并處理這些請求,以一定的規則混合、疊加,最終在有限的輸出資源上(屏幕),顯示多個應用程序的GUI。
3)display server和自己的client之間,通過某種類型的通信協議交互,該通信協議通常稱作display server protocol。
4)display server protocol可以是基于網絡的,甚至是網絡透明的(network transparent),如X Window System所使用的。也可以是其它類型的,如Android SurfaceFlinger所使用的binder。
有關Windowing system的詳細解釋,請參考:https://en.wikipedia.org/wiki/Windowing_system。
2.3 X Window System
似乎終于要進入正題了。
X Window System是Windowing System一種實現,廣泛使用于UNIX-like的操作系統上(當然也包括Linux系統),由MIT(Massachusetts Institute of Technology,麻省理工學院)在1984年發布。下圖(可從“這里”查看比較清晰的SVG格式的原始圖片)是它的典型架構:
1)X Window System簡稱X,或者X11,或者X-Windows。之所以稱作X,是因為在字母表中X位于W之后,而W是MIT在X之前所使用的GUI系統。之所以稱作X11,是因為在1987年的時候,X Window System已經進化到第11個版本了,后續所有的X,都是基于X11版本發展而來的(變動不是很大)。為了方便,后續我們都以X代指X Window System。
2)X最初是由X.org(XOrg Foundation)維護,后來基于X11R6發展出來了最初專門給Intel X86架構PC使用的X,稱作XFree86(提供X服務,它是自由的,它是基于Intel的PC平臺)。而后XFree86發展成為幾乎適用于所有類UNIX操作系統的X Window系統,因此在相當長的一段時間里,XFree86也是X的代名詞。再后來,從2004年的時候,XFree86不再遵從GPL許可證發行,導致許多發行套件不再使用XFree86,轉而使用Xorg,再加上Xorg在X維護工作上又趨于活躍,現在Xorg由成為X的代名詞(具體可參考“http://www.x.org/”)。
3)X設計之初,制定了很多原則,其中一條----"It is as important to decide what a system is not as to decide what it is”,決定了X的“性格”,即:X只提供實現GUI環境的基本框架,如定義protocol、在顯示設備上繪制基本的圖形單元(點、線、面等等)、和鼠標鍵盤等輸入設備交互、等等。它并沒有實現UI設計所需的button、menu、window title-bar styles等元素,而是由第三方的應用程序提供。這就是Unix的哲學:只做我應該做、必須做的事情。這就是這么多年來,X能保持穩定的原因。也是Linux OS界面百花齊放(不統一)的原因,各有利弊吧,后續文章會展開討論。
4)X包括X server和X client,它們之間通過X protocol通信。
5)X server接收X clients的顯示請求,并輸出到顯示設備上,同時,會把輸入設備的輸入事件,轉遞給相應的X client。X server一般以daemon進程的形式存在。
6)X protocol是網絡透明(network-transparently)的,也就是說,server和client可以位于同一臺機器上的同一個操作系統中,也可以位于不同機器上的不同操作系統中(因此X是跨平臺的)。這為遠端GUI登錄提供了便利,如上面圖片所示的運行于remote computer 的terminal emulator,但它卻可以被user computer的鼠標鍵盤控制,以及可以輸出到user computer的顯示器上。?
注4:這種情況下,user computer充當server的角色,remote computer是client,有點別扭,需要仔細品味一下(管理輸入設備和顯示設備的是server)。
7)X將protocol封裝為命令原語(X command primitives),以庫的形式(xlib或者xcb)向client提供接口。X client(即應用程序)利用這些API,可以向X server發起2D(或3D,通過GLX等擴展,后面會介紹)的繪圖請求。
有關X更為詳細的介紹,請參考:https://en.wikipedia.org/wiki/X_Window_System,后續蝸蝸可能會在單獨的文章中分析它。
2.4 窗口管理器、GUI工具集、桌面環境及其它
前面講過,X作為Windowing system中的一種,只提供了實現GUI環境的基本框架,其它的UI設計所需的button、menu、window title-bar styles等基本元素,則是由第三方的應用程序提供。這些應用程序主要包括:窗口管理器(window manager)、GUI工具集(GUI widget toolkit)和桌面環境(desktop environment)。
窗口管理器負責控制應用程序窗口(application windows)的布局和外觀,使每個應用程序窗口盡量以統一、一致的方式呈現給用戶,如針對X的最簡單的窗口管理程序--twm(Tab Window Manager)。
GUI工具集是Windowing system之上的進一步的封裝。還是以X為例,它通過xlib提供給應用程序的API,僅僅可以繪制基本的圖形單元(點、線、面等等),這些基本的圖形單元,要組合成復雜的應用程序,還有很多很多細碎、繁雜的任務要做。因此,一些特定的操作系統,會在X的基礎上,封裝出一些更為便利的GUI接口,方便應用程序使用,如Microwindows、GTK+、QT等等。
桌面環境是應用程序級別的封裝,通過提供一系列界面一致、操作方式一致的應用程序,使系統以更為友好的方式向用戶提供服務。Linux系統比較主流的桌面環境包括GNOME、KDE等等。
2.5 3D渲染、硬件加速、OpenGL及其它
渲染(Render)在電腦繪圖中,是指:用軟件從模型生成圖像的過程。模型是用嚴格定義的語言或者數據結構對于三維物體的描述,它包括幾何、視點、紋理以及照明信息。圖像是數字圖像或者位圖圖像。
上面的定義摘錄自“百度百科”,它是著重提及“三維物體”,也就是我們常說的3D渲染。其實我們在GUI編程中習以為常的點、線、矩形等等的繪制,也是渲染的過程中,只不過是2D渲染。2D渲染面臨的計算復雜度和性能問題沒有3D厲害,因此渲染一般都是指3D渲染。
在計算機中,2D渲染一般是由CPU完成(也可以由專門的硬件模塊完成)。3D渲染也可以由CPU完成,但面臨性能問題,因此大多數平臺都會使用單獨硬件模塊(GPU或者顯卡)負責3D渲染。這種通過特定功能的硬件模塊,來處理那些CPU不擅長的事務的方法,稱作硬件加速(Hardware acceleration),相應的硬件模塊,就是硬件加速模塊。
眾所周知,硬件設備是多種多樣的,為了方便應用程序的開發,需要一個穩定的、最好是跨平臺的API,定義渲染有關的行為和動作。OpenGL(Open Graphics Library)就是這類API的一種,也是最為廣泛接納的一種。
雖然OpenGL只是一個API,但由于3D繪圖的復雜性,它也是相當的復雜的。不過,歸根結底,它的目的有兩個:
1)對上,屏蔽硬件細節,為應用程序提供相對穩定的、平臺無關的3D圖像處理API(當然,也可以是2D)。
2)對下,指引硬件相關的驅動軟件,實現3D圖像處理相關的功能。
另外,openGL的一個重要特性,是獨立于操作系統和窗口系統而存在的,具體可以參考后面軟件框架相關的章節。
3. 軟件框架
通過第2章的介紹,linux系統中圖形有關的軟件層次已經呼之欲出,具體如下:
該層次圖中大部分的內容,已經在第2章解釋過了,這里再補充說明一下:
1)該圖片沒有體現3D渲染、硬件加速等有關的內容,而這些內容卻是當下移動互聯、智能化等產品比較關注的地方,也是linux平臺相對薄弱的環節。后續會在軟件框架有關的內容中再著重說明。
2)從層次結構的角度看,linux圖形子系統是比較清晰的,但牽涉到每個層次上的實現的時候,就比較復雜了,因為有太多的選擇了,這可歸因于“提供機制,而非策略”的Unix軟件準則。該準則為類Unix平臺軟件的多樣性、針對性做出了很大的貢獻,但在今天這種各類平臺趨于整合的大趨勢下,過多的實現會導致用戶體驗的不一致、開發者開發精力分散等弊端,值得我們思考。
3)雖然圖形子系統的層次比較多,但不同的人可能關注的內容不太一樣。例如對Linux系統工程師(驅動&中間件)而言,比較關注hardware、kernel和display server這三個層次。而對Application工程師來說,可能更比較關心GUI Toolkits。本文以及后續display subsystem的文章,主要以Linux系統工程師的視角,focus在hardware、kernel和display server(可能包括windows manager)上面。
以X window為例,將hardware、kernel和display server展開如下(可從“這里”查看比較清晰的SVG格式的原始圖片):
From:?https://upload.wikimedia.org/wikipedia/commons/c/c2/Linux_Graphics_Stack_2013.svg
對于軟件架構而言,這張來自維基百科的圖片并不是特別合適,因為它包含了太多的細節,從而顯得有些雜亂。不過瑕不掩瑜,對本文的描述,也足夠了。從向到下,圖中包括如下的軟件的軟件模塊:
1)3D-game engine、Applications和Toolkits,應用軟件,其中3D-game engine是3D application的一個特例。
2)Display Server
圖片給出了兩個display server:Wayland compositor和X-Server(X.Org)。X-Server是linux系統在PC時代使用比較廣泛的display server,而Wayland compositor則是新設計的,計劃在移動時代取代X-Server的一個新的display server。
3)libX/libXCB和libwayland-client
display server提供給Application(或者GUI Toolkits)的、訪問server所提供功能的API。libX/libXCB對應X-server,libwayland-client對已Wayland compositor。
4)libGL
libGL是openGL接口的實現,3D application(如這里的3D-game engine)可以直接調用libGL進行3D渲染。
libGL可以是各種不同類型的openGL實現,如openGL(for PC場景)、openGL|ES(for嵌入式場景)、openVG(for Flash、SVG矢量圖)。
libGL的實現,既可以是基于軟件的,也可以是基于硬件的。其中Mesa 3D是OpenGL的一個開源本的實現,支持3D硬件加速。
5)libDRM和kernel DRM
DRI(Direct Render Infrastructure)的kernel實現,及其library。X-server或者Mesa 3D,可以通過DRI的接口,直接訪問底層的圖形設備(如GPU等)。
6)KMS(Kernel Mode Set)
一個用于控制顯示設備屬性的內核driver,如顯示分辨率等。直接由X-server控制。
4. 后續工作
本文有點像一個大雜燴,丟進去太多的東西,每個東西又不能細說。覺得說了很多,又覺得什么都沒有說。后續蝸蝸將有針對性的,focus在某些點上面,更進一步的分析,思路如下:
1)將會把顯示框架限定到某個確定的實現上,初步計劃是:Wayland client+Wayland compositor+Mesa+DRM+KMS,因為它們之中,除了Mesa之外,其它的都是linux系統中顯示有關的比較前沿的技術。當然,最重要的,是比較適合移動端的技術。
2)通過單獨的一篇文章,更詳細的分析Wayland+Mesa+DRM+KMS的軟件框架,著重分析圖像送顯、3D渲染、Direct render的過程,以此總結出DRM的功能和工作流程。
3)之后,把重心拉回kernel部分,主要包括DRM和KMS,當然,也會順帶介紹framebuffer。
4)kernel部分分析完畢后,回到Wayland,主要關心它的功能、使用方式等等。
5)其它的,邊學、邊寫、邊看吧。
?
原創文章,轉發請注明出處。蝸窩科技,www.wowotech.net
總結
以上是生活随笔為你收集整理的Linux graphic subsytem(1)_概述的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何手动完成一次APK打包?----AP
- 下一篇: 【译】X Server-Client!!