Android應用程式與SurfaceFlinger服務的關係概述和學習計劃 .

來源:互聯網
上載者:User

標籤:

轉自:http://blog.csdn.net/luoshengyang/article/details/7846923

SurfaceFlinger服務:負責繪製Android應用程式的UI,

        SurfaceFlinger服務運行在Android系統的System進程中,它負責管理Android系統的框架緩衝區(Frame Buffer)。Android系統的框架緩衝區的相關知識,

Android應用程式為了能夠將自己的UI繪製在系統的框架緩衝區上,它們就必須要與SurfaceFlinger服務進行通訊,1所示:


圖1 Android應用程式與SurfaceFlinger服務的關係

  注意,Android應用程式與SurfaceFlinger服務是運行在不同的進程中的,因此,它們採用Binder處理序間通訊機制來進行通訊。

        在圖1中,每一個Android應用程式與SurfaceFlinger服務都有一個串連,這個串連都是通過一個類型為Client的Binder對象來描述的。這些Client對象是Android應用程式串連到SurfaceFlinger服務的時候由SurfaceFlinger服務建立的,

而當Android應用程式成功串連到SurfaceFlinger服務之後,就可以獲得一個對應的Client對象的Binder代理介面了。有了這些Binder代理介面之後,Android應用程式就可以通知SurfaceFlinger服務來繪製自己的UI了。

 

        Android應用程式在通知SurfaceFlinger服務來繪製自己的UI的時候,需要將UI中繼資料傳遞給SurfaceFlinger服務,例如,要繪製UI的地區、位置等資訊。一個Android應用程式可能會有很多個視窗,而每一個視窗都有自己的UI中繼資料,

因此,Android應用程式需要傳遞給SurfaceFlinger服務的UI中繼資料是相當可觀的。在這種情況下,通過Binder處理序間通訊機制來在Android應用程式與SurfaceFlinger服務之間傳遞UI中繼資料是不合適的,

這時候Android系統的匿名共用記憶體機制(Anonymous Shared Memory)就派上用場了。

 

       在每一個Android應用程式與SurfaceFlinger服務之間的串連上加上一塊用來傳遞UI中繼資料的匿名共用記憶體,我們就得到了圖2,如下所示:

 

 

 

圖2 用來在Android應用程式與SurfaceFlinger服務之間傳遞UI中繼資料的匿名共用記憶體

 

        在Application和Client這兩個高富帥看來,它們之間的原生匿名共用記憶體塊就一個活脫脫的土肥圓。因此,Application和Client是看不上這塊原生的匿名共用記憶體的。於是,這塊原生的匿名共用記憶體當時就怒了,立志要逆襲變成白富美,3所示:

 

 

圖3 結構化後的用來傳遞UI中繼資料的匿名共用記憶體塊

 

       土肥圓逆襲後,就變成了一個名字為SharedClient的白富美,從此,它就和Application、Client過上幸福的啪啪啪生活了。

 

       SharedClient到底有多白多富多美?參見圖4:

 

 

圖4 用來描述Android應用程式的UI中繼資料的SharedClient

 

        在每一個SharedClient裡面,有至多31個SharedBufferStack。字面上來看,SharedBufferStack就是共用緩衝區堆棧。怎麼理解呢?首先,Shared表明這個堆棧共用的。那麼由誰來共用呢?當然就是Android應用程式和SurfaceFlinger服務了。其次,Buffer表明這個堆棧的內容是緩衝區。什麼樣的緩衝區呢?當然就是用來描述UI中繼資料的緩衝區了。再者,Stack表明用來描述UI中繼資料的緩衝區是需要按照一定的規則來訪問的。綜合起來,我們就可以認為每一個SharedBufferStack就是用來描述一系列需要按照一定規則來訪問的緩衝區。

 

        好像還是不能理解SharedBufferStack?好吧,回憶一下,一般我們就繪製UI的時候,都會採用一種稱為“雙緩衝”的技術。雙緩衝意味著要使用兩個緩衝區,其中一個稱為Front Buffer,另外一個稱為Back Buffer。

UI總是先在Back Buffer中繪製,然後再和Front Buffer交換,渲染到顯示裝置中。這下就可以理解SharedBufferStack的含義了吧?SurfaceFlinger服務只不過是將傳統的“雙緩衝”技術升華和抽象為了一個SharedBufferStack。

可別小看了這個升華和抽象,有了SharedBufferStack之後,SurfaceFlinger服務就可以使用N個緩衝區技術來繪製UI了。N值的取值範圍為2到16。例如,在Android 2.3中,N的值等於2,而在Android 4.1中,據說就等於3了。

 

        我們還可以再進一步地理解SharedBufferStack。在SurfaceFlinger服務中,每一個SharedBufferStack都對應一個Surface,即一個視窗。這樣,我們就可以知道為什麼每一個SharedClient裡麵包含的是一系列SharedBufferStack而不是單個SharedBufferStack:一個SharedClient對應一個Android應用程式,而一個Android應用程式可能包含有多個視窗,即Surface。從這裡也可以看出,一個Android應用程式至多可以包含31個Surface。

 

        SharedBufferStack長什麼樣子呢?看圖5:

 

 

 

圖 5 SharedBufferStack的結構

 

       在圖5中,為了方便描述,我們假設圖中的SharedBufferStack有5個Buffer,其中,Buffer-1和Buffer-2是已經使用了的,而Buffer-3、Buffer-4和Buffer-5是閒置。指標head和tail分別指向空閑緩衝區列表的頭部和尾部,而指標queue_head指向已經使用了的緩衝區列表的頭部。從這裡就可以看出,從指標tail到head之間的Buffer即為空白閑緩衝區表,而從指標head到queue_head之間的Buffer即為已經使用了的緩衝區列表。注意,圖中的5個Buffer是迴圈使用的。

 

       空閑緩衝區比較好理解,接下來我們重點解釋一下那些已經被使用了的緩衝區,即圖5中的Buffer-1和Buffer-2。

 

       前面我們說過,SharedBufferStack中的緩衝區只是用來描述UI中繼資料的,這意味著它們不包含真正的UI資料。真正的UI資料儲存在GraphicBuffer中,後面我們再描述GaphicBuffer。

因此,為了完整地描述一個UI,SharedBufferStack中的每一個已經使用了的緩衝區都對應有一個GraphicBuffer,用來描述真正的UI資料。當SurfaceFlinger服務緩制Buffer-1和Buffer-2的時候,就會找到與它們所對應的GraphicBuffer,這樣就可以將對應的UI繪製出來了。

 

       當Android應用程式需要更新一個Surface的時候,它就會找到與它所對應的SharedBufferStack,並且從它的空閑緩衝區列表的尾部取出一個閒置Buffer。我們假設這個取出來的空閑Buffer的編號為index。接下來Android應用程式就請求SurfaceFlinger服務為這個編號為index的Buffer分配一個圖形緩衝區GraphicBuffer。SurfaceFlinger服務分配好圖形緩衝區GraphicBuffer之後,會將它的編號設定為index,然後再將這個圖形緩衝區GraphicBuffer返回給Android應用程式訪問。Android應用程式得到了SurfaceFlinger服務返回的圖形緩衝區GraphicBuffer之後,就在裡面寫入UI資料。寫完之後,就將與它所對應的緩衝區,即編號為index的Buffer,插入到對應的SharedBufferStack的已經使用了的緩衝區列表的頭部去。這一步完成了之後,Android應用程式就通知SurfaceFlinger服務去繪製那些儲存在已經使用了的緩衝區所描述的圖形緩衝區GraphicBuffer了。用圖5的例子來說,SurfaceFlinger服務需要繪製的是編號為1和2的Buffer所對應的圖形緩衝區GraphicBuffer。由於SurfaceFlinger服務知道編號為1和2的Buffer所對應的圖形緩衝區GraphicBuffer在哪裡,因此,Android應用程式只需要告訴SurfaceFlinger服務要繪製的Buffer的編號就OK了。當一個已經被使用了的Buffer被繪製了之後,它就重新變成一個閒置Buffer了。

 

        上面描述的過程比較複雜,後面我們再用幾篇文章來詳細描述。

 

        SharedBufferStack是在Android應用程式和SurfaceFlinger服務之間共用的,但是,Android應用程式和SurfaceFlinger服務使用SharedBufferStack的方式是不一樣的,具體來說,就是Android應用程式關心的是它裡面的空閑緩衝區列表,而SurfaceFlinger服務關心的是它裡面的已經使用了的緩衝區列表。從SurfaceFlinger服務的角度來看,儲存在SharedBufferStack中的已經使用了的緩衝區其實就是在排隊等待渲染。

 

        為了方便SharedBufferStack在Android應用程式和SurfaceFlinger服務中的訪問,Android系統分別使用SharedBufferClient和SharedBufferServer來描述SharedBufferStack,其中,SharedBufferClient用來在Android應用程式這一側訪問SharedBufferStack的空閑緩衝區列表,而SharedBufferServer用來在SurfaceFlinger服務這一側訪問SharedBufferStack的排隊緩衝區列表。

 

         在SharedBufferClient看來,SharedBufferStack的樣子6所示:

 

 

圖6 SharedBufferClient眼中的SharedBufferStack 

 

        只要SharedBufferStack中的available的buffer的數量大於0,SharedBufferClient就會將指標tail往前移一步,並且減少available的值,以便可以獲得一個閒置Buffer。當Android應用程式往這個閒置Buffer寫入好資料之後,它就會通過SharedBufferClient來將它添加到SharedBufferStack中的排隊緩衝區列表的尾部去,即指標queue_head的下一個位置上。

 

        在SharedBufferServer看來,SharedBufferStack的樣子7所示:

 

 

圖7 SharedBufferServer眼中的SharedBufferStack

 

        當Android代理程式更新SurfaceFlinger服務更新UI的時候,只要對應的SharedBufferStack中的queued的緩衝區的數量大於0,SharedBufferServer就會將指標head的下一個Buffer繪製出來,並且將指標head向前移一步,以及將queued的值減1。

 

        上面我們多次提到了圖形緩衝區GraphicBuffer,它是什麼東東呢?我們看圖8:

 

 

圖8 圖形緩衝區Graphic的結構

 

        每一個GraphicBuffer內部都包含有一塊用來儲存UI資料的緩衝區,這塊緩衝區使用一個buffer_handle_t對象來描述。看到buffer_handle_t,是不是有點眼熟?在前面Android框架緩衝區(Frame Buffer)硬體抽象層(HAL)模組Gralloc的實現原理分析一文中,我們說過,由HAL層的Gralloc模組分配的圖形緩衝區的是使用一個buffer_handle_t對象來描述的,而由buffer_handle_t對象所描述的圖形緩衝區要麼是在系統框架緩衝區(Frame Buffer)或者匿名共用記憶體(Anonymous Shared Memory)中分配的。這樣,我們就可以將SurfaceFlinger服務與HAL層中的Gralloc模組關聯起來了。

 

        至此,Android應用程式與SurfaceFlinger服務的關係就概述完畢了,但是我們的任務還沒有完成,我們還要進一步去具體地學習它,例如:

 

        1. Android應用程式是如何與SurfaceFlinger服務建立串連的?

 

        2. 用來描述Android應用程式的UI中繼資料的SharedClient是如何建立的?

 

        3. Android應用程式是如何請求SurfaceFlinger服務建立一個Surface的?

 

        4. Android應用程式是如何請求SurfaceFlinger服務渲染一個Surface的?

 

        回答了這4個問題之後,相信我們就可以對SurfaceFlinger服務有一個深刻的認識,進而可以協助我們從正面去分析SurfaceFlinger服務的實現。後面我們將以Android系統的開機動畫為例子,用4篇文章來回答這4個問題,敬請關注!

 

Android應用程式與SurfaceFlinger服務的關係概述和學習計劃 .

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.