xorg 硬件

已經轉型不做Xorg了,現在做android了,還是市場決定的吧。

不過xorg本身是一個很大的體系,所以本來自己有一些理解也不到位的地方,所以這裏的答案並非最終答案
只供大家參謀,要是商業資訊要收諮詢費的哦,1000美元一天啊。不過現在不做xorg可,應該可以寫寫了

1:什麼是xorg的驅動
恩,這裏簡單來分吧,我說一下以前大體從事過的一些
1)輸入設備的驅動,這個比較容易理解,之前的文章當中也有描述,比如鼠標,鍵盤,touchpad
touchscreen的驅動等等。xorg的inputinit(有點記不太清了)
2)圖形驅動,這裏實際上是輸出設備的驅動,也就是xorg裏面的outputinit(有點記不太清了)
圖形驅動分的部分也比較多,但是大體上分爲2D和3D兩個部分。

xorg的大邏輯,開始的時候會進行各種初始化,輸入部分,輸出部分。事件隊列,各種extention,等等


輸入部分的邏輯相對來說比較簡單,之前也有講過這裏的邏輯,所以不再贅述。
無非是從設備文件裏面讀消息,然後post消息到xorg的事件隊列裏面。不過實際要做好這裏並不容易
xorg本身是bug很多的,另外就是之前也說到xorg本身的設計問題。還有就是會經常遇到一些
莫名其妙的bug,如果同時碰到圖形驅動也出問題。有時候是kernel裏面掛掉,有時候是xorg的邏輯
掛掉,有時候是其他驅動block住,總之多調試,就有經驗了,希望國內的工程師多起來。

不過就xorg來說,沒有商業的支持發展非常的緩慢,sun又死掉了,xorg就更不好過了。

android發展的不錯,市場上要做的也多,所以需求大了,人都要轉了。

下面主要描述一下圖形部分的。

首先要說明的是xorg是pc用的,雖然n810?沒記錯的話,就是nokia的用maemo系統那個手機。
開始用的是kdrive。問題來了,

什麼是kdrive?
之前已經有文章描述,這裏再說一次,
kdrive是xserver的一種。看xorg的代碼樹下面就知道有多種xserver,他們的大體邏輯是一樣的。
mi目錄下面是最核心的抽象,抱歉這裏都是憑腦袋寫的,不能回去翻代碼了。各種不同的xserver
設計的目的不一樣,但是上面自然都是支持xlib,再往上就是支持gtk,qt這些widget了,
簡單的說一些xserver
dmx分佈式的x,大家可以man 一下就知道了,每個server目錄下面都有說明的
xfree86就是我們通常說的xorg了。
kdrive就是kdrive了。也就是以前的tinyx,那個某某覺得xfree86的代碼過於複雜,
(抱歉我實在是記不住名字了,對明星實在是不上心)
大家可以去翻翻以前的xserver的代碼,極其混亂。後來做了很多工作,包括模塊化,這個
工作對後來者來說是非常有作用的。kdrive的設計是非常簡單有效的,大家可以去翻翻
High Performance X Servers in the Kdrive Architecture

好了,這裏再說說kdrive的缺陷。自然就是很多擴展都不支持了。
最早的時候還支持kaa,之前有文章講述什麼是kaa了,之前也支持xvideo,
後來乾脆都去掉了,好像就是去年還是前年的事情,所以現在kdrive是完全沒有硬件加速框架了。
還有就是很多邏輯處理有問題,比如輸入事件,輸出事件,xorg現在更新完全有點傷筋動骨了。但是
kdrive維護的人就很少。所以nokia的maemo也該成了xorg了,後來nokia和intel把maemo改名
叫meego了。

本文恐怕比較長,吃飯去回來再寫。


插播一段郵件,會有問題嗎?
-------------------------------------------------------------------------

上面5點這裏解釋一下
Xorg和opengl有關係,但是和opengles並沒有任何直接的關係,目前只有eglx和egl/opengles有一點關係,但是這個東西並沒有
標準化的,所以並不推薦使用。我們之前給別人做東西的時候倒是用過,但是那個是所有的3D應用都是用clutter來做的,後端
是eglx。驅動是基於glx/dri的。當然kernel裏面也是有drm的,這個工作量來說太大了,而且當時是跟高通合作做的。需要各個
方面的專家來協同工作。

還有就是EGL在不同的平臺上面差別是很大的,比如差不多兩年前大家的EGL都是隻支持fbdev的。後來的才慢慢出現支持xserver
的版本。這個區別主要是底下的nativewindow系統不同。比如android下面直接使用framebuffer,xorg下面使用的是xwindow

不知道你們具體的需求是什麼,單純的egl/opengles的應用是比較少的,沒法支持多個window,單個應用佔全屏幕的,這樣來說
對系統限制很大,應用本身的限制也很大。gui的程序開發限制就多了。如果沒有圖形framework的話,開發應用也難度太高。

你說的3D的窗口管理器,窗口管理器是和圖形系統緊密相關的,看你這裏的意思是,你們已經定了xserver這個圖形系統?


做2D的加速需要有2D芯片的資料,做3D,大多數情況下你們拿到的OPENGLES的,都是一個比較簡單的版本,比如底下的圖形系統
是專有的,而不是xwindow作爲nativewindow的。目前支持比較多的兩種nativewindow一個就是fbdev,另外一個就是xwindow的

這裏有一個困難就是,這個東西都是和本地的圖形系統相關的,比如你如果使用的是xwindow的話,首先你是要把buffer放到
顯存裏面的,xwindow要能夠管理這個。但是現在你們的opengles和xorg是完全獨立的兩套系統,xwindow是要管理最後的輸出的
但是你們的opengles會直接把swapbuffer輸出到屏幕上面去。


也就是說實際上xwindow必須管理顯卡的資源無論你通過什麼接口,dri也好,或者私有的接口也好,實際dri的接口就是爲了
2D和3D共享資源,3D畫完了之後是需要輸出到2D平面的。



> 6、我不太熟悉DRI,也不太熟悉EXA,如果不考慮太複雜的情況下,如何用 SDK 完成一個,帶硬件加速功能的驅動,讓我編譯出來的 XORG
> 可以使用?最起碼我可以先完成一個,支持 2D 加速的XSERVER,具體我應該怎麼做呢?


不知道你們是否已經把xorg跑起來了,把xorg跑起來本身也需要做很多工作,你需要交叉編譯這個系統,xorg本身依賴的庫也是
很多的。如果沒有的話你們可以先跑一個軟的,也就是使用fbdev驅動的,不過這個需要系統能夠提供framebuffer的設備。是純軟
的方案,

不知道你們是否有2D的芯片,還是說只有一個gpu,對方只提供了opengles/eg/openvg這樣的東西給你們。
如果是隻有後面的東西,2D加速時沒有辦法的,因爲後面的3D加速的東西沒法放到2D這邊來。是兩套完全不同的東西。
至於xgl,是用opengl來實現xrender方案的,但是一個問題是,它已經死掉了,現在應該是已經無法運行了。還有就是這個方案
本身是需要有opengl的驅動也就是opengl的應用能完全跑起來的,還有就是它依賴幾個特殊的opengl的擴展,否則極慢,
不過opengles實際比opengl還是差很多的,opengles實際不需要glx的,除非你需要實現eglx

從現在已有的嵌入式的方案來說(開源的)一般他們會先實現xvideo的加速,因爲多媒體這邊對性能要求是最高的。實現也
相對簡單一些。前提還是你們有2D的芯片,用opengles是不行的,除非能讓opengles和xwindow的輸出能夠統一起來,也就是
把opengles的輸出讓xwindow來管理。xvideo主要是解決視頻顯示中顏色空間轉換和視屏縮放的。


至於你說的把opengles整合到xorg裏面,看你的意思是想用opengles/openvg來加速xorg。
arm曾經想讓我們在他們的gpu(mali)這麼幹來,沒答應他們。
如果你要給個確定的答覆,我覺得是不可能了。
如果技術能力許可,可以實現的方案是這樣的。
1)實現eglx的支持(主要是讓opengles的輸出能夠被xwindow管理起來,就是clip等等的問題)
2)有了上面的之後就可以實現xorg+eglx+opengles的框架了,在這個框架之上可以使用一些eglx的框架,比如clutter。
這個時候只需要使用clutter來開發應用即可,不過這個東西主要是用來做比較酷炫的效果的,消費類產品比較適合.

這裏可以不用考慮dri的問題,原因上面已經描述。私有的接口也可以,只要能實現就可以。
但是實際上你要實現的也是和dri類似的東西,就是窗口覆蓋之後讓egl只輸出該輸出的部分等等。


2D加速不知道你們有多大的需求,實際上比如android等等系統2D繪圖的部分也是純軟件的,
還有就是2D加速(exa)部分也是要把東西放在顯存裏面才能加速的。這個部分並不是使用的egl/openges
這種框架的。

2D加速現在也有使用dri的了,沒記錯的話intel的驅動就是。
不過後來intel的驅動七改八改(kms,gallium)現在也不知道什麼狀態了。
回到正文。

kdrive的缺陷很多,這裏說的很多擴展,比如xrandr,一般用來設置屏幕分辨率,旋轉,多個屏幕的
輸出選擇等等,比如你要輸出到DVI,或者HDMI。還有就是xinerama,多個屏幕組成一個屏幕。
還有一個根本的缺陷就是沒有3D,因爲沒有glx dri等等支持而喪失了3D能力支持。
另外的根本缺陷就是驅動不能動態加載了。驅動支持的種類有限,對比xorg這邊頻繁的bug修改來說
kdrive本身已經缺乏更新,kdrive裏面自帶的驅動也是更缺乏更新了,大家還在不斷的刪除不被
維護的驅動,所以kdrive自身的能力就很有限了。還有不支持XKB(沒記錯的話),多國鍵盤的支持
也會有問題,這些很多限制在後期擴展的時候問題就很麻煩。
可能最大的限制還是大家移除了kdrive的硬件加速機制。


好,回來圖形加速部分

我們已經不再討論kdrive了,使用xorg取代kdrive,包括在嵌入式系統裏面,前提是圖形系統選型時選擇了
xserver,那麼xorg就是唯一之選了,

xorg的加速,我們這裏講到的加速暫時不提3D加速,實際上3D加速和xorg本身並沒什麼關係
3D只是給大家提供一種機制來創建3D的應用,比如遊戲等等,所以3D部分是相對獨立的。
3D之所以和xorg有關,是因爲我們屏幕只有一個,所有的應用都要往屏幕上面輸出,2D的部分要輸出
3D的部分也要輸出,所以需要有人來管理這個事情,比如說一個window蓋住了3D遊戲的一部分
那個3D遊戲應當只輸出沒有被覆蓋的那個部分。只有這個地方xorg和3D纔有交集。glx就是用來幹這個的
了。3D部分要使用glx來和xorg交流。


好下面,確定了加速目前只指2D加速,至於軟3D和硬3D的區別後面會講到
2D的加速,目前對於xorg來說exa是官方的方案,至於其他的衍生方案,比如intel的uxa什麼的
暫時不提。

exa加速方案

exa的由來。

最早的xfree86的加速方案目前可以查到的使用的是xaa的方案,
提供了衆多的接口。後來有上面那個論文說了,我們只要加速少數的接口就可以了,
還有就是我們的顯存管理要更加有效纔可以。細節可參考上面的論文,(相關的論文衆多,需要抱着
洋人們的論文多看看才行)
價值xfree86過於臃腫,後來直接就有了tinyx,後來變爲kdrive,kdrive設計的加速框架
本稱之爲kaa。這裏還是有必要提一下kaa的顯存劃分,這個之前的文章略掉了。
kaa的顯存劃分在上面的論文也有,時間長了有點記不住了,大體上是有對應屏幕的部分。
還有就是離屏的部分,也就是offscreen的部分,但是這些都是一個線性的空間。
以最常見的狀況來說,比如我們在kernel裏面fb0的分辨率是1024x768,這個一般我們指的是
第一個page,也就是屏幕可見的部分,這裏熟悉framebuffer driver的朋友們知道
fbinfo裏面還有一個virtual_size比如可能是1024x1536(沒算錯吧)這個代表fb0這個設備有兩個
page,一個對應屏幕,一個對應offscreen。當你cat這個設備的時候,會輸出兩個屏幕分辨率那麼
大的區域。當然一般都是兩個page。不過也有4個的,就是看你對顯存有多大的需求了。
這個地方如果有4個,也始終只有一個是對應屏幕的。剩下的三個page都是offscreen的。
我們爲什麼要這麼多offscreen的空間呢?

答案是,我們的offscreen是用來加速用的。注意這裏的4個page都是顯存。所有的加速都是必須在
顯存裏面完成的。gpu只能在顯存裏面計算的,不過如果說嵌入式,因爲都是內存,通過內核裏面實現
一定的機制,gpu和cpu是都可以訪問這個空間的。

那麼比如我有一個surface,要加速怎麼辦,自然是先要倒到顯存裏面,然後繪圖,然後再顯示出去。
但是顯存的大小始終是有限的,總有用完的時候,用完了怎麼辦,這個時候需要就要發生交換,
把顯存裏面踢出一些東西到系統內存,然後把要加速的東西放到這個被釋放出來的空間。
一個簡單的例子,比如xvideo,我們從mp4文件裏面先要demux,分離出視頻,音頻,字幕等等數據,
對於視頻,然後是解碼,解碼出來是一幀一幀的圖片,對於pc來說,純cpu解碼的來說,這一切都是發生
在內存裏面的,最後解碼完的數據自然是一個buffer,也是在內存裏面,可能是i420的格式,分辨率是
1280x720.然後我們要把這個數據倒到顯存裏面去,這個是xvideo自身提供的框架來自己做的。
然後剩下的就是大家做的xvideo加速來做的事情了,這個東西已經在顯存裏面,我們首先要轉換成RGB
然後縮放成窗口大小,比如當前的window可能只有300x200.這個地方xvideo一般來說是直接顯示
到屏幕上面去了。可以使用overlay的。但是overlay的缺點就是如果有窗口蓋住了這個mediaplayer
但是mediaplay還是按照原始的大小輸出的。也就是說這個window並沒有被xwindow管理,xvideo
直接輸出到了framebuffer了,注意這個framebuffer並不一定指fb0的第一個page。所以後來
大家用texture的video輸出。也就是輸出到一個buffer,然後由xwindow的窗口管理機制來剪切這個區域

當然芯片越多,這裏就越複雜,比如一般都有dsp了,這個解碼完的數據可能就不是在內存裏面了
可能是一塊特殊的區域,需要使用特殊的機制才能取出來。還有就是顯示的時候可能是2D的芯片操作
也可能是3D的芯片去操作,也可能是cpu去操作,這個要看soc上面到底有多少加速芯片,和這個加速框架
具體是怎麼實現的,整個加速的框架是必須放在整個系統裏面來考慮的,這樣才能發揮芯片本身應該有的性能,pc則又不同具體情況具體對待。


回到kaa的顯存部分,2個page很多時候可能並不夠用,一個簡單的例子就是,比如我們的屏幕是720p
1280x720的。我當前本來有很多window,會佔用一部分顯存。然後我們還要解碼視頻。如果解碼的輸出
是直接放在顯存裏面,這本身就會佔用顯存,我們假定是720p的i420的數據,這會佔用很多顯存,然後
我們轉換格式,縮放的時候還需要差不多同樣的顯存。

今天天氣很好,適合看書,少更新點

我也是用拼音打字的,別字較多,希望不太影響閱讀

上面說了kaa的顯存管理機制了。
要加速的話,硬件是要能夠訪問這個offscreen的區域的,也就是說那個2D的芯片(用kdrive的一般
只能用2D加速了)要能夠訪問這個offscreen的區域和onlinescreen的區域。並在這個區域裏面計算。



exa,composite, composite manager, xgl

這幾個東西本來沒有太直接的關聯,但是還是放在一起說了吧。

xgl之前有解釋,上面也有解釋,實際是用opengl來實現了xrender的接口,實際也是實現了exa
用opengl來實現的,具體的操作的時候使用的庫叫做glitz,不過現在已經死了。
composite extension是xorg比較新的擴展,和damage extention一樣,是算出來最晚的幾個
extension之一了。不過也出來很久了。這裏說說它的作用。
我們默認的情況下,創建window的時候都是可見的,也就是Xcreatewindow,這個是libx11,也就是xlib
的函數,就可以創建一個window,這裏實際上是走socket到了xserver裏面,然後window是在xserver
這邊創建的。這個就是cs架構了,客戶端是請求操作,xserver這邊分配實際的資源。至於大家說用
gtk,qt,底下實際還是要走xlib的。當然,gtk和qt都有其他的後端,比如fbdev,但是用的最廣泛
的還是x11的後端了。我們不討論用的極少,又沒有成熟的東西。以免大家混淆。
創建window都是可見的,我們要繪圖的時候就直接顯示到屏幕上面的,

但是後來大家有一個需求,就是說我們要做透明窗口的效果。那首先我們要把所有的window離屏畫好,
然後再挨個做alpha blending到rootwindow,這樣我們就可以看到一個窗口透過另外一個窗口的效果了
所以overlay是被拒絕的,overlay以後可能用的也會很少吧。實際窗口系統要的是規範性,性能是
可以放在其次的,比如我們應該看到該看到的區域,不該看到的區域不要被看到。這個是最基本的,但是
overlay就破壞了這種規範。

好,說多了,那麼要怎麼實現呢,這裏就是composite extension了。具體用是在什麼地方用呢?
以linux pc來說,是window manager來用的。一般都是實現在windowmanager裏面的,實現一個
composite manager,具體的做法就是windowmanager去調用composite extension來實現的
composite manager,這裏有點拗口,不過就是這樣的。他會把window redirect到pixmap去。
函數是在libxcomposite裏面提供的,請求時發送到xserver的。所有的實際處理都是xserver處理
外面只是簡單調用一個api而已。這裏所有window的操作都被“翻譯”成了pixmap的請求。
createwindow實際上是變成了createpixmap。這裏再xserver裏面可以給每個screen註冊createwindow
的回調,這個時候變成了pixmap。也就是上層的應用實際上沒有任何改變,但是實際上底下的東西是變化的
這個東西畫好了之後windowmanager要負責把每個該顯示的部分顯示到屏幕上面去。大家可以簡單
看看metacity的裏面XrenderComposite調用的地方,這個就是了。我們要把window composite到
rootwindow上面去。

那麼這裏和exa有什麼關係呢?exa可以註冊CreatePixmap的callback。簡單描述一下調用如下
應用調用了Xcreatewindow,這個是libx11的函數,然後請求走socket到了xserver,xserver這邊
由於metacity(window manager)做了composite的請求,這個請求變成了CreatePixmap,然後這個
請求被exa給註冊了callback,也就是說調用到驅動的exa裏面的CreatePixmap了。這樣就從顯存
裏面分配了一個pixmap了。這樣的好處是什麼呢?

exa加速的時候首先要判斷一下,這個被計算的src和dst是否在顯存裏面,如果本身就在顯存裏面
那麼我們就開始計算了,否則我們要先拿到顯存裏面去,然後再計算。所以如果我們所有的東西如果
都是分配在顯存裏面的話,倒騰數據就少了。

不過這裏要說一下,註冊了這個回調之後,默認我們是從顯存裏面分配,對於pc來說顯存稍稍大一些。
這個機制是可以的。但是對於嵌入式來說,默認從顯存裏面分配,很快就用光的。所以
默認從什麼地方分配的是講決策的,如果沒有的話,默認是從內存裏面分配,計算的時候放到顯存。
也就是說看我們讓大多數的buffer默認在什麼地方,如果顯存極小,我們默認就放在內存裏面,保證
顯存夠計算我們足夠大的window,缺點是我們每個buffer都是要倒到顯存裏面才能計算的。
如果顯存夠大,我們默認就放在顯存裏面,減少數據倒騰。但是如果估計失誤,我們可能就很多時間在把
顯存裏面的東西往內存裏面倒。

上面不知道說明白沒有。
然後就是xgl,這裏會什麼要提是因爲這個技術本身來說還可以吧,但是novel/suse不夠google那麼
有錢來支持這個項目。
簡單說一下吧
xgl這個實際用的是render to texture (不過有可能我也理解錯誤的)
另外大家並不太看好用opengl來加速2D的操作,一個是本身這個不合適。另外一個就是gpu有很多計算
沒法完成。不夠cpu靈活,還有就是顯存本來就小,跑遊戲還不一定夠呢,還要把2D的東西放到texture裏面
底下都是用glitz來做繪圖的,再底下就是opengl了,這個xgl並不是構建在opengl之上的,
因爲opengl本身是依賴xserver/glx的,所以兩個本身是雜合在一起的。
關於依賴的擴展,有一個比較重要的就是opengl需要提供texture_from_pixmap,如果沒記錯的話。
因爲之前我們分配buffer是pixmap的,這個東西如果直接分配在顯存裏面,然後texture_from_pixmap
的時候就簡單了,和EGL_KHR的擴展差不多,這個地方極其有用,我們不用再texture2D了。
本質在於數據傳輸量太大,紋理太多。反覆倒騰的時間已經抵消了gpu的計算性能提高了。

關於dri的解釋。

dri這個是開源社區設計的一個框架了,做3D加速用的框架,但是實際上,私有的驅動,pc的比如
nvidia,嵌入式的私有的驅動就更多了,基本都不遵循dri的框架。目前看到只有高通的是dri的。
這裏簡單說一下dri和dri2的區別。
從應用來說的話,最大的區別應該說是dri2可以render to pixmap。
這個的好處主要就是composite manager打開的時候我們也能正常的看到opengl的程序的輸出,


關於EGL
是一個工業標註,之前的文章有簡單提到。這個會提供一個標準的接口給上面的應用。
可以理解爲是一箇中間層。簡單的流程如下
eglcreateContext
eglcreateWindowSurface
eglmakecurrent
然後我們就可以用opengles的api往這個surface繪圖了,
eglswapbuffers
輸出我們所繪圖的圖像。

EGL下面要顯示出來肯定是要和本地的圖形系統相關的。最簡單的就是fbdev的情況。直接全屏輸出到
framebuffer上面了。android就是這樣的。本地的圖形系統是會影響到EGL的實現的,EGL的實現
必須知道底下的windowing system,native window。android的比較簡單一點,只支持565.
所以egl也只需要支持565就可以了。另外android的EGL要求支持swaprect,也就是指刷新一小塊
不要全屏幕刷新

如果下面是xserver的話,因爲xserver是支持多window的,所以就複雜一些,egl是必須知道window 
的狀態的。比如只渲染到某個window區域的某個剪切域。還有就是xserver本身基本支持所有的
pixelformat,所以egl這邊也要支持了,否則createwindow的時候就會出問題了,createpixmapsurface也一樣
所以以xwindow爲native的EGL會比以framebuffer的要複雜的多了。

必須爲不同的window系統開發不同的EGL版本,不過一般來說,大家會開發一個LIBEGL.SO
然後下面動態的去裝載其他的so,比如egl_subfb.so,egl_subx11.so大概名字是類似這樣了,
有點記不住了。


關於軟3D和硬3D
最常見的軟3D就是mesa了。mesa已經遷移到了gallium了。
mesa是opengl的軟實現,好久沒看了,可能支持openvg和gles也說不定
android自帶的有一個軟3D的opengles 1.x的版本。

所謂軟3D,就是用cpu去算的
所有opengl的算法都用cpu來計算的。這個極慢。

硬3D就是廠家提供的,對應特定的gpu的了,
比如opengles的一般會提供
libegl13.so,opengles20.so,opengles11.so openvg11.so ,xxx_dri.so
名字憑記憶寫的,大概就是這些了。

opengl的比如nvidia的,
libglx.so, libGL.so,等等。

以opengles爲例來說明。
這裏不帶xorg的,他們直接會打開設備文件,比如/dev/hw3d等等,
用戶空間直接往裏面寫東西了。opengles的實現裏面會去和硬件打交道。

關於3D的xorg的框架,記得有4篇比較好的文章,都是洋人的文章了,他們的確是走在我們前面很多

算了,還是找個中文的給大家吧
http://www.linuxgraphics.cn/xwindow/dri_intro.html
這個也可以了。
http://dri.sourceforge.net/doc/DRIintro.html
http://dri.freedesktop.org/wiki/Documentation

抱歉,老文章實在不太好找了。先就這樣吧。

如果大家想要實現私有的gl,不使用dri的話,dri也是非常值得參考的。


exa加速的操作主要有,composite,copy, solid, uploadtoscreen,downloadfromscreen
這些接口大家都可以在exa.h(沒記錯的話),我現在翻不了代碼。

composite就是兩個buffer的composite運算,至於什麼是composite。wikipedia上面有解釋
copy,就是copy操作了,這個時候是有運算的。mask等等
solid是填充,同上,也是有運算的,不是單純的填充。
其他就是數據傳輸了,exa後來增加了一些接口。


關於XFT
下面用了fontconfig和freetype,所以只要用了xft的庫的,都是支持這些的。pango也是其中之一
pango有很多後端xft是其中一個。

關於CTL
qt和gtk用的是最廣泛的toolkit了。
CTL部分的代碼都是來自於最早的freetype,後來各自發展,後來兩大社區又謀劃再回到一起
這個就是halfbuzz,不知道我寫錯沒有,這個是國際化必須的,比如我們要橫排,豎排,
還有就是一些很特殊的字符的現實,幾個字符在一起的時候會要求按照規則組合成另外一個字符
這個是語法規則,這些東西有些在ttf裏面是要規定的,比如GSUB,GPOS等等信息。

感覺應該說的比較清楚了吧


好,關於留言的回覆
1:爲什麼要offscreen
這個比較容易理解,好比問,爲什麼opengl要支持doublebuffer一樣。我們要先離屏畫好了之後
然後搬運到屏幕上面,這樣我們就不會看到繪圖的過程,否則系統慢的時候我們會看到這個繪圖的過程
比如一個繪圖過程很複雜,我們又沒有double buffer的話我們就會看到這個圖形是怎麼繪製出來的,
pipe line的過程我們都要看到了。

2:爲什麼我們不直接畫到屏幕上面去
這個可以參考爲什麼不用overlay。是一樣的問題,我們必須只顯示我們該看到的區域。
overlay的機制是這樣的,我們使用overlay的輸出的時候硬件會直接輸出到屏幕上面指定的區域
而不管這個地方有沒有東西,一個簡單的例子,比如我們使用overlay來播放視頻的時候,這個時候
系統彈出一個警告框,需要在最前面顯示,但是overlay的畫面並不知道下面有什麼,這個時候overlay
會蓋住它。

android是如何使用這兩個buffer的,這裏簡單描述一下應該就比較清楚了。
android要求framebuffer支持flip也就是至少提供兩個page,這裏一個page作爲了frontbuffer
一個page作爲了backbuffer。當egl繪圖的時候都是在backbuffer裏面繪製的,等繪製完了之後
告訴hardware模塊說,請切換一下buffer,也就是fb_post,這裏默認情況下只要調用一個ioctl
就可以了,然後kernel裏面的驅動會把這個backbuffer給作爲輸出屏幕,從這裏搬運數據到lcd上面
注意這裏並沒有發生數據搬運,可以理解爲只是lcdc取數據的地址變了,當然不同的硬件是處理不一樣的。

這裏大家可能會問到Vsync的問題
這個文章可以解釋大家的疑問,還有爲什麼需要tripple buffer
http://hardforum.com/showthread.php?t=928593


3:有硬件加速的2D的模塊,要如何開發xorg的驅動。
個人看法,需要做如下的一些操作
a)如果要規範的話,需要做一個exa的驅動,可以參考其他嵌入式的exa的驅動。一般寫的比較簡單。
不要看pc顯卡的exa的驅動。推薦omap的 ,高通的,還有另外一家是哪家忘記了。都是開源的
b)最主要的問題是顯存管理的問題(因爲你們xorg已經可以啓動)
當exa判斷pixmap或者window不在顯存裏面時候需要倒騰到顯存裏面,這個時候需要先用平臺相關的
接口申請一下顯存,放到裏面,然後計算,如果有必要計算完了之後再倒出來(說的是顯存很小的情況)
倒到dst的buffer裏面,如果能夠所有的buffer都分配在顯存裏面自然好。
還要做顯存的swap的操作,顯存不夠的時候把存在顯存裏面的數據倒出來放到內存裏面,
這個地方有一個問題是exa目前是通過偏移地址來判斷是否在顯存裏面的,但是像你們的狀況肯定是不行
所以要實現exapixmapisoffscreen?我記得好像是有這個函數。可參考intel的驅動實現。
屏幕如果小的話,實際感覺沒什麼用。還有就是本身有些2D芯片很弱,能夠想象到的,說是支持2D
加速,但是支持的限制很大,比如copy,但是實際上xorg的copy過程中是每個像素都有運算的,可能是
mask,可能是or運算,等等。並非單純的copy操作,所以需要判斷滿足硬件配置的時候纔可以使用硬件
加速,但是這個判斷本身是需要時間的,被hit的概率太小的話,實際上比不做硬件加速還要慢。
因爲如果不支持,會返回fallback用軟件的實現。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章