2019年3月26日

Linux Graphics Study

前言:
這篇是我以前針對Linux X-Window和Qt寫的Study文件。

Linux GUI架構:
下圖是Linux Qt視窗系統的最簡架構圖:


對Qt來說,根據不同的下層和硬體,區分為:
  • Qt/Embedded
  • Qt/X11
  • Qt/Windows(針對Microsoft Windows環境)
  • Qt/Mac(針對MacOS環境)


Qt/Embedded:
Qt/Embedded主要是用於嵌入式系統的環境,Qt/Embedded本身包含了類似X-window的視窗處理,
它的下層直接界接驅動程式,驅動程式部份可以有3種,分別是:
  • Qt直接操作FrameBuffer(VGA模式)
  • Qt透過DirectFB操作FrameBuffer
  • Qt直接操作DirectFB


Qt直接操作FrameBuffer是Qt最早的作法,但缺點是,FrameBuffer是以VGA模式直接處理,
因此FrameBuffer沒有提供和使用任何的顯示晶片加速器
因為這原因,德國一家公司提供DirectFB,號稱能夠透過一個中間層,
來統一Embedded的圖形開發,並使用顯示晶片的硬體加速能力,
但後來細看後得知,DirectFB的硬體加速能力,
事實上是需要顯示晶片的廠商撰寫DirectFB的顯示晶片驅動程式
這樣一來,上層應用程式(包括Qt)直接呼叫DirectFB即可使用顯示晶片的硬體加速能力。
如果沒有DirectFB的顯示晶片驅動程式,那麼DirectFB還是只能用FrameBuffer,
像是Intel就沒有提供DirectFB的驅動程式


Qt/X11:
Qt/X11是針對X-window的環境,Qt/X11中,Qt使用X-window來進行視窗操作,
X-window則透過X-window的顯示晶片驅動程式來操作顯示晶片硬體。


Linux X-window驅動程式簡單架構圖:


X-window本身架構龐大且複雜,但從驅動程式的角度來看,可以將架構簡化。
在目前的X-window中,針對2D和3D的加速,
Intel提供了X-window 2D的顯示驅動程式和X-window 3D的顯示驅動程式
其中2D的驅動程式為(xf86-video-intel Driver),
3D的驅動程式的部份,Intel則提供了X-window專用的mesa介面的Driver,
Intel沒有另外提供它名稱,就叫做mesa driver。

X-window和Driver對應架構圖:


X-window的2D:
顯示晶片針對2D的驅動程式,其實是在VGA模式之上加入了許多圖像處理的加速器,
像是圖像重繪(redraw)、圖像縮放(resize)、旋轉(rotation)…等。
X-window本身提供了XLib來和X-window溝通,
而X-window提供了許多所謂的Extension來針對不同的需要進行處理,
在這裡我只看了XRender、XVideo(XV)、DGA這三種Extension。
選擇這三種Extension的原因和它們和Qt的關係,再之後說明。


X-window的3D:
X-window針對3D的處理,提供了一個稱為DRI(Direct Rendering Infrastructure)的介面,
上面提供給3D Library(OpenGL)操作顯示晶片的3D驅動程式,
下面則透過mesa這個驅動程式介面提供給顯示晶片廠商開發3D加速的驅動程式。

Qt/X11和X-win Extension/3D OpenGL關係架構圖:


在Qt中,目前我已經看到針對顯示相關的Class有3個,分別是:
  • QPainter
  • QX11EmbedWidget
  • QGL Module


QPainter:
QPainter是Qt中最基本的繪圖Class,Qt中所有的視窗繪製行為都是透過QPainter。
而在X-window中,QPainter事實上是透過了XLib操作XRender Extension來讓顯示晶片顯示,
XRender Extension實際上就是X-Window基本的Render(繪製器),
它和Microsoft Windows的GDI地位雷同。


QX11EmbedWidget:
QX11EmbedWidget事實上可以說是Qt針對X-window直接操作提供的洞,
QX11EmbedWidget讓GUI應用程式能夠透過QX11EmbedWidget直接和XLib溝通和操作
我們可以透過QX11EmbedWidget來操作X-window其他的Extension。


  • XVideo(XV) Extension:
XVideo(XV) Extension是X-window針對影片播放提供的Extension,
目前在Linux上主流的播放器,包括vlc、mplayer、gstream,
預設的Video Output都是使用XVideo(XV) Extension。
從XV的說明來看,它使用了顯示晶片上圖片縮放、旋轉、重繪的加速器,
讓播放器在播放時,可以直接利用顯示晶片進行影片的縮放和重繪。


  • DGA Extension:
DGA全名是Direct Graphics Architecture,
它主要的能力是能夠讓程式透過DGA跨過整個X-window直接操作顯示驅動程式上的FrameBuffer。
我認為在X-window架構上,如果要像嵌入式系統一樣直接處理FrameBuffer,
DGA Extension應該是個不錯的選擇。


選擇瞭解XRender、XVideo(XV)、DGA這三種Extension的原因是:
  • XRender是Qt QPainter使用的Extension,整個視窗介面都透過它來進行繪製
  • XV是目前幾個主流播放器預設使用的Video Output
  • DGA具有能最直接操作顯示晶片上FrameBuffer的能力


QGL Module:
QGL Module是Qt針對OpenGL提供的一整組Class,透過QGL Module,Qt可以使用OpenGL Library。
OpenGL Library在X-window中,它會透過DRI介面和mesa Driver直接溝通,
雖然DRI是X-window架構中的一部分,但目前我的理解,它事實上是獨立的一塊,
並沒有和XLib界接。

X-win基本架構:
X-win的基本架構如下圖:


所有的應用程式都是X Client,而所有的操作和螢幕顯示則是透過X Server,
因為X-win的設計是以TCP/IP為基礎的設計,X Client和X Server的溝通都是透過TCP/IP,
就算是在本機,也同樣需要透過TCP/IP溝通。
前面提到的Extension,都是在X Server上用來顯示使用的,
而XLib,實際上是將整個X-win的X Server、X Client溝通(X Protocol)封裝隱藏起來。

X-win繪圖與影片播放:
X-win的基本繪圖顯示,就如前面提到的,是使用XRender進行繪圖,使用格式為BGRA。
流程如下:


首先,在應用程式(X Client)中使用XImage結構建立圖片,接著將圖片送到X Server端並顯示。
Qt的繪圖模式相同,在Qt中,QImage Class其實就是在X Client上建立圖片,
QPixmap Class則是在X Server端的顯示晶片記憶體中放置圖片。
X-win的這種繪圖方式,會有load(負載)在X Client和X Server的溝通以及TCP/IP的資料交換。


XVideo(XV) Extension前面提到過,它能加快X-win的影片播放,
Wiki的說明裡面寫得很詳細,XVideo(XV) Extension實際上是使用顯示晶片的加速能力,
來達成以下幾件事情:
  1. 影片播放時,由顯示晶片處理圖片的縮放或全螢幕顯示
  2. 由顯示晶片處理Color Space的轉換(主要是YUV的處理)
  3. 由顯示晶片來處理影片播放時,圖片的飽和度、亮度、彩度…等設定的處理


XVideo(XV) Extension的支援性,是相依在顯示晶片上的,
顯示晶片是否支援XVideo(XV) Extension?
顯示晶片的XVideo(XV) Extension支援哪些Color Space操作?
都由顯示晶片決定。
以例子中的Intel GMA 3100來說,這顆顯示晶片支援XVideo(XV) Extension,
支援的Color Space轉換包括:
  1. YUY2
  2. YV12
  3. I420
  4. UYVY
  5. XvMC


其中XvMC(Wiki)是類似Windows上Microsoft的DirectX Video Acceleration (DxVA) API,
主要是能透過它使用顯示卡上的GPU運算,這部份我沒有再進一步下去看。
其他幾個Color Space轉換都是支援YUV。
因此如果圖片原始格式是YUV的,建議直接使用XVideo(XV) Extension,
如果圖片原始格式是RGB的,建議使用XRender。

X-win的XSHM Extension:
前面提到過X-win的繪圖流程,
會需要用TCP/IP在X Client和X Server之間溝通(X Protocol)和傳遞資料,
其中用TCP/IP進行圖片資料(XImage)的傳遞會消耗很多系統資源,
因此提出XSHM Extension來解決這問題。
XSHM Extension流程如下:


和原始的流程相比,X Protocol通訊的部份不變,
但圖片部份的操作改用Share Memory進行圖片交換,
因此省去了XImage在X Client與X Server間傳遞的消耗,減輕負載。
目前XSHM Extension提供了XRender和XVideo(XV) Extension的操作的加速,
其他方式它都不支援。


幾種方式的測試:
環境:Intel Q35晶片組主機板
圖片:480x640圖片(XV使用UYVY、XRender使用RGBA、QT使用BMP)
圖片:1920x1080圖片(XRender使用RGBA)
速度:每秒30張循環



Qt
(直接讀圖到QPixmap Class)
XRender
XRender
(XSHM)
XVideo(XV)
XVideo(XV)
(XSHM)
CPU
13%~18%
2%~6%
1%~4%
2%~5%
2%~4%
1920x1080圖片
11%~22%


沒有留言: