原文出處——>[Android系統Surface機制的SurfaceFlinger服務簡要介紹和學習計劃](http://blog.csdn.net/luoshengyang/article/details/8010977)
前面我們從Android應用程序與SurfaceFlinger服務的關系出發,從側面簡單學習了SurfaceFlinger服務。有了這些預備知識之后,我們就可以從正面來分析SurfaceFlinger服務的實現原理了。SurfaceFlinger服務負責管理系統的幀緩沖區設備,并且負責渲染系統的UI,即各個應用程序的UI。在本文中,我們就簡要介紹SurfaceFlinger服務,并且制定學習計劃。
在前面Android應用程序與SurfaceFlinger服務的關系概述和學習計劃一系列的文章中提到,SurfaceFlinger服務運行在System進程中,用來統一管理系統的幀緩沖區設備。由于SurfaceFlinger服務運行在System進程中,因此,Android應用程序就需要通過Binder進程間通信機制來請求它來渲染自己的UI。Android應用程序請求SurfaceFlinger服務渲染自己的UI可以分為三步曲:首先是創建一個到SurfaceFlinger服務的連接,接著再通過這個連接來創建一個Surface,最后請求SurfaceFlinger服務渲染該Surface。
由于SurfaceFlinger服務需要與Android應用程序執行Binder進程間通信,因此,它本身就是一個Binder本地對象,如圖1所示:

圖1 SurfaceFlinger服務的類關系圖
理解這個圖需要學習Binder進程間通信機制,具體可以參考Android進程間通信(IPC)機制Binder簡要介紹和學習計劃這一系列的文章。
SurfaceFlinger服務實現的接口為ISurfaceComposer,后者定義在文件frameworks/base/include/surfaceflinger/ISurfaceComposer.h中,如下所示:
~~~
class ISurfaceComposer : public IInterface
{
public:
DECLARE_META_INTERFACE(SurfaceComposer);
......
/* create connection with surface flinger, requires
* ACCESS_SURFACE_FLINGER permission
*/
virtual sp<ISurfaceComposerClient> createConnection() = 0;
/* create a client connection with surface flinger
*/
virtual sp<ISurfaceComposerClient> createClientConnection() = 0;
/* retrieve the control block */
virtual sp<IMemoryHeap> getCblk() const = 0;
/* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */
virtual void openGlobalTransaction() = 0;
virtual void closeGlobalTransaction() = 0;
/* [un]freeze display. requires ACCESS_SURFACE_FLINGER permission */
virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags) = 0;
virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags) = 0;
/* Set display orientation. requires ACCESS_SURFACE_FLINGER permission */
virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags) = 0;
/* signal that we're done booting.
* Requires ACCESS_SURFACE_FLINGER permission
*/
virtual void bootFinished() = 0;
/* Capture the specified screen. requires READ_FRAME_BUFFER permission
* This function will fail if there is a secure window on screen.
*/
virtual status_t captureScreen(DisplayID dpy,
sp<IMemoryHeap>* heap,
uint32_t* width, uint32_t* height, PixelFormat* format,
uint32_t reqWidth, uint32_t reqHeight) = 0;
virtual status_t turnElectronBeamOff(int32_t mode) = 0;
virtual status_t turnElectronBeamOn(int32_t mode) = 0;
/* Signal surfaceflinger that there might be some work to do
* This is an ASYNCHRONOUS call.
*/
virtual void signal() const = 0;
};
~~~
ISurfaceComposer接口有13個成員函數,下面我們就簡單介紹一下:
* createConnection:Android應用程序通過它來請求SurfaceFlinger服務建立一個連接,具體可以參考Android應用程序與SurfaceFlinger服務的連接過程分析一文。
* createClientConnection:Android應用程序通過它來請求SurfaceFlinger服務創建一塊共享UI元數據緩沖區,具體可以參考Android應用程序與SurfaceFlinger服務之間的共享UI元數據(SharedClient)的創建過程分析一文。
* getCblk:Android應用程序通過它來請求SurfaceFlinger服務返回一塊匿名共享內存,返回的匿名共享內存包含了設備顯示屏的信息,例如,寬度和高度信息。
* openGlobalTransaction:Android應用程序通過它請求SurfaceFlinger服務來增加一個全局Transaction計數,用來批量修改UI屬性信息。注意,這些被修改的UI屬性信息會被緩存起來,不會馬上生效。要使得這些被修改的UI屬性信息生效,需要調用另外一個成員函數closeGlobalTransaction,如下所述。
* closeGlobalTransaction:Android應用程序通過它請求SurfaceFlinger服務來減少一個全局Transaction計數。當這個全局Transaction計數減少至0的時候,前面通過openGlobalTransaction來請求修改的UI屬性信息就會馬上生效。
* freezeDisplay:Android應用程序通過它來請求SurfaceFlinger服務來凍結屏幕。屏幕在被凍結期間,所有UI渲染操作都會被緩存起來,等待被執行。
* unfreezeDisplay:Android應用程序通過它來請求SurfaceFlinger服務來解凍屏幕。屏幕被解凍之后,SurfaceFlinger服務就可以執行UI渲染操作了。
* setOrientation:Android應用程序通過它來請求SurfaceFlinger服務設備屏幕的旋轉方向。
* bootFinished:WindowManagerService通過它來告訴SurfaceFlinger服務,系統啟動完成了,這時候SurfaceFlinger服務就會停止執行開機動畫,具體可以參考Android系統的開機畫面顯示過程分析一文。
* captureScreen:Android應用程序通過它來請求SurfaceFlinger服務截取屏幕圖像。
* turnElectronBeamOff:Android應用程序通過它來請求SurfaceFlinger服務關閉屏幕。
* turnElectronBeamOn:Android應用程序通過它來請求SurfaceFlinger服務點亮屏幕。
* signal:Android應用程序通過它來請求SurfaceFlinger服務渲染UI,具體可以參考Android應用程序請求SurfaceFlinger服務渲染Surface的過程分析一文。
理解了ISurfaceComposer接口的定義之后,我們再來看SurfaceFlinger服務的Binder代理對象BpSurfaceComposer的實現,如圖2所示:

圖2 SurfaceFlinger服務的Binder代理對象的類關系圖
理解這個圖同樣需要學習Binder進程間通信機制,具體可以參考Android進程間通信(IPC)機制Binder簡要介紹和學習計劃這一系列的文章。
Android應用程序獲得了SurfaceFlinger服務的一個Binder代理對象,即一個BpSurfaceComposer對象之后,就可以請求SurfaceFlinger服務來創建以及渲染自己的UI了。
接下來,我們再簡單介紹一下SurfaceFlinger類的定義,如圖3所示:

圖3 SurfaceFlinger類的定義
SurfaceFlinger類有兩個類型為State的成員變量mCurrentState和mDrawingState。其中,成員變量mCurrentState用來描述系統下一次要渲染的UI的狀態;而mDrawingState用來描述當前正要渲染的UI的狀態。
State類用來描述一個UI狀態,它有四個重要的成員變量layersSortedByZ、orientation、orientationType和freezeDisplay。其中,成員變量layersSortedByZ是一個類型為LayerVector的向量,里面保存的系統所包含的Surface,每一個Surface使用一個LayerBase對象來描述,并且它們按照 Z軸順序來排列;成員變量orientation和orientationType的類型均為uint8_t,它們用來描述屏幕的方向; 成員變量freezeDisplay的類型也是uint8_t,用來描述屏幕是否處于被凍結狀態。
SurfaceFlinger類的成員變量mVisibleLayerSortedByZ是一個類型為sp<LayerBase>的Vector,它是用來保存SurfaceFlinger服務下一次要渲染的、處于可見狀態的Surface的,它們是來自SurfaceFlinger類的成員變量mDrawingState所描述的一個State對象的成員變量layersSortedByZ的。
SurfaceFlinger類的成員變量mGraphicPlanes是一個類型為GraphicPlane的數組,它是用來描述系統所有的顯示設備的。從這個數組的大小等于1可以知道,當前Android系統只支持一個顯示設備。
GraphicPlane類有四個重要的成員變量mHw、mOrientation、mWidth和mHeight。其中,成員變量mHw指向一個DisplayHardware對象,用來描述一個硬件顯示設備;成員變量mOrientation、mWidth和mHeight的類型均為int,分別用來描述一個硬件顯示設備的旋轉方向、寬度和高度。我們可以通過調用GraphicPlane類的成員函數setDisplayHardware和displayHardware來設備和獲取一個GraphicPlane對象內部所包含的一個硬件顯示設備。
DisplayHardware類有一個重要的成員變量mNativeWindow,它是一個類型為FramebufferNativeWindow的強指針。FramebufferNativeWindow類是用來描述一個Android系統本地窗口,而這個窗口代表的是系統的硬件幀緩沖區。DisplayHardware類的成員函數flip是用來渲染系統UI的,即將后端的圖形緩沖區翻轉為前端的圖形緩沖區,并且渲染在硬件幀緩沖區去。
FramebufferNativeWindow類與在前面Android應用程序請求SurfaceFlinger服務創建Surface的過程分析一文中所介紹的Surface類的作用是一樣的,即它是OpenGL庫和Android的UI系統之間的一個橋梁。OpenGL庫正是通過它的成員函數dequeueBuffer來獲得一個用來填充UI數據的圖形緩沖區,而通過它的成員函數queueBuffer來將一個已經填充好UI數據的圖形緩沖區渲染到系統的幀緩沖區中去。
FramebufferNativeWindow類有三個重要的成員變量fbDev、grDev和buffers。其中,成員變量fbDev和grDev分別指向一個framebuffer_device_t設備和一個alloc_device_t設備。從前面Android幀緩沖區(Frame Buffer)硬件抽象層(HAL)模塊Gralloc的實現原理分析一文可以知道,framebuffer_device_t設備和一個alloc_device_t設備是由HAL模塊Gralloc來提供的,它們分別用來分配圖形緩沖區和渲染圖形緩沖區;成員變量buffers是一個類型為NativeBuffer的數組,這個數組用來描述一個圖形緩沖區堆棧,堆棧的大小為NUM_FRAME_BUFFERS,這些圖形緩沖區是直接在硬件幀緩沖區中分配的,有別于Surface類所使用的圖形緩沖區,因為后者所使用的圖形緩沖區是在匿名共享內存分配的。
了解了SurfaceFlinger類的重要成員變量之后,我們再來了解它的幾個重要成員函數threadLoop、waitForEvent、signalEvent、handleConsoleEvents、handleTransaction、handlePageFlip、handleRepaint和postFramebuffer。
SurfaceFlinger服務雖然是在System進程中啟動的,但是它在啟動的時候創建一個線程來專門負責渲染UI。為了方便描述,我們將這個線程稱為UI渲染線程。UI渲染線程的執行函數就為SurfaceFlinger類的成員函數threadLoop,同時它有一個消息隊列。當UI渲染線程不需要渲染UI時,它就會在SurfaceFlinger類的成員函數waitForEvent中睡眠等待,直到SurfaceFlinger服務需要執行新的UI渲染操作為止。
SurfaceFlinger服務什么時候會需要執行新的UI渲染操作呢?當系統顯示屏屬性發生變化,或者應用程序窗口發生變化時,它就需要重新渲染系統的UI。這時候SurfaceFlinger服務就會從SurfaceFlinger類的成員函數waitEvent中喚醒,并且依次執行SurfaceFlinger類的成員函數handleConsoleEvents、handleTransaction、handlePageFlip、handleRepaint和postFramebuffer來具體執行渲染UI的操作。其中,成員函數handleConsoleEvents用來處理控制臺事件;成員函數handleTransaction用來處理系統顯示屏屬性變化以及應用程序窗口屬性變化;成員函數handlePageFlip用來獲得應用程序窗口下一次要渲染的圖形緩沖區,即設置應用程序窗口的活動圖形緩沖區;成員函數handleRepaint用來重繪應用程序窗口;成員函數postFramebuffer用來將系統UI渲染到硬件幀緩沖區中去。
我們知道,應用程序是運行在與SurfaceFlinger服務不同的進程中的,而從前面Android應用程序請求SurfaceFlinger服務渲染Surface的過程分析一文又可以知道,每當應用程序需要更新自己的UI時,它們就會通過Binder進程間通信機制來通知SurfaceFlinger服務。SurfaceFlinger服務接到這個通知之后,就會調用SurfaceFlinger類的成員函數signalEvent來喚醒UI渲染線程,以便它可以執行渲染UI的操作。注意,SurfaceFlinger服務是通過Binder線程來獲得應用程序的請求的,因此,這時候SurfaceFlinger服務的UI渲染線程實際上是被Binder線程喚醒的。SurfaceFlinger類的成員函數signalEvent實際上是通過向UI渲染線程的消息隊列發送一個類型為INVALIDATE的消息來喚醒UI渲染線程的。
前面提到, SurfaceFlinger服務在在執行UI渲染操作時,需要調用SurfaceFlinger類的成員函數handleConsoleEvents來處理控制臺事件。這怎么理解呢?原來,SurfaceFlinger服務在啟動的時候,還會創建另外一個線程來監控由內核發出的幀緩沖區硬件事件。為了方便描述,我們將這個線程稱為控制臺事件監控線程。每當幀緩沖區要進入睡眠狀態時,內核就會發出一個睡眠事件,這時候SurfaceFlinger服務就會執行一個釋放屏幕的操作;而當幀緩沖區從睡眠狀態喚醒時,內核就會發出一個喚醒事件,這時候SurfaceFlinger服務就會執行一個獲取屏幕的操作。
這樣,我們就簡要介紹完了SurfaceFlinger類的定義。從這些介紹可以知道:
1. SurfaceFlinger服務通過一個GraphicPlane對象來管理系統的顯示設備;
2. SurfaceFlinger服務有三種類型的線程,它們分別是Binder線程、控制臺事件監控線程和UI渲染線程;
3. SurfaceFlinger服務是在UI渲染線程中執行渲染系統UI的操作的。
圍繞上述三個內容,再結合SurfaceFlinger服務的啟動過程,接下來我們再通過以下四篇文章來系統地學習SurfaceFlinger服務的實現原理:
1. SurfaceFlinger服務是如何啟動的?
2. SurfaceFlinger服務是如何通過GraphicPlane、DisplayHardware和FramebufferNativeWindow三個類來管理系統的顯示設備的?
3. SurfaceFlinger服務的三個線程的協作模型是如何的?
4. SurfaceFlinger服務是如何在UI渲染線程中執行UI渲染操作的?
結合前面Android應用程序與SurfaceFlinger服務的關系概述和學習計劃的一系列文章,以及上述四篇文章,相信我們就可以對SurfaceFlinger服務有一個清晰的認識了,敬請關注!
- 前言
- Android組件設計思想
- Android源代碼開發和調試環境搭建
- Android源代碼下載和編譯
- Android源代碼情景分析法
- Android源代碼調試分析法
- 手把手教你為手機編譯ROM
- 在Ubuntu上下載、編譯和安裝Android最新源代碼
- 在Ubuntu上下載、編譯和安裝Android最新內核源代碼(Linux Kernel)
- 如何單獨編譯Android源代碼中的模塊
- 在Ubuntu上為Android系統編寫Linux內核驅動程序
- 在Ubuntu上為Android系統內置C可執行程序測試Linux內核驅動程序
- 在Ubuntu上為Android增加硬件抽象層(HAL)模塊訪問Linux內核驅動程序
- 在Ubuntu為Android硬件抽象層(HAL)模塊編寫JNI方法提供Java訪問硬件服務接口
- 在Ubuntu上為Android系統的Application Frameworks層增加硬件訪問服務
- 在Ubuntu上為Android系統內置Java應用程序測試Application Frameworks層的硬件服務
- Android源代碼倉庫及其管理工具Repo分析
- Android編譯系統簡要介紹和學習計劃
- Android編譯系統環境初始化過程分析
- Android源代碼編譯命令m/mm/mmm/make分析
- Android系統鏡像文件的打包過程分析
- 從CM刷機過程和原理分析Android系統結構
- Android系統架構概述
- Android系統整體架構
- android專用驅動
- Android硬件抽象層HAL
- Android應用程序組件
- Android應用程序框架
- Android用戶界面架構
- Android虛擬機之Dalvik虛擬機
- Android硬件抽象層
- Android硬件抽象層(HAL)概要介紹和學習計劃
- Android專用驅動
- Android Logger驅動系統
- Android日志系統驅動程序Logger源代碼分析
- Android應用程序框架層和系統運行庫層日志系統源代碼分析
- Android日志系統Logcat源代碼簡要分析
- Android Binder驅動系統
- Android進程間通信(IPC)機制Binder簡要介紹和學習計劃
- 淺談Service Manager成為Android進程間通信(IPC)機制Binder守護進程之路
- 淺談Android系統進程間通信(IPC)機制Binder中的Server和Client獲得Service Manager接口之路
- Android系統進程間通信(IPC)機制Binder中的Server啟動過程源代碼分析
- Android系統進程間通信(IPC)機制Binder中的Client獲得Server遠程接口過程源代碼分析
- Android系統進程間通信Binder機制在應用程序框架層的Java接口源代碼分析
- Android Ashmem驅動系統
- Android系統匿名共享內存Ashmem(Anonymous Shared Memory)簡要介紹和學習計劃
- Android系統匿名共享內存Ashmem(Anonymous Shared Memory)驅動程序源代碼分析
- Android系統匿名共享內存Ashmem(Anonymous Shared Memory)在進程間共享的原理分析
- Android系統匿名共享內存(Anonymous Shared Memory)C++調用接口分析
- Android應用程序進程管理
- Android應用程序進程啟動過程的源代碼分析
- Android系統進程Zygote啟動過程的源代碼分析
- Android系統默認Home應用程序(Launcher)的啟動過程源代碼分析
- Android應用程序消息機制
- Android應用程序消息處理機制(Looper、Handler)分析
- Android應用程序線程消息循環模型分析
- Android應用程序輸入事件分發和處理機制
- Android應用程序鍵盤(Keyboard)消息處理機制分析
- Android應用程序UI架構
- Android系統的開機畫面顯示過程分析
- Android幀緩沖區(Frame Buffer)硬件抽象層(HAL)模塊Gralloc的實現原理分析
- SurfaceFlinger
- Android系統Surface機制的SurfaceFlinger服務
- SurfaceFlinger服務簡要介紹和學習計劃
- 啟動過程分析
- 對幀緩沖區(Frame Buffer)的管理分析
- 線程模型分析
- 渲染應用程序UI的過程分析
- Android應用程序與SurfaceFlinger服務的關系
- 概述和學習計劃
- 連接過程分析
- 共享UI元數據(SharedClient)的創建過程分析
- 創建Surface的過程分析
- 渲染Surface的過程分析
- Android應用程序窗口(Activity)
- 實現框架簡要介紹和學習計劃
- 運行上下文環境(Context)的創建過程分析
- 窗口對象(Window)的創建過程分析
- 視圖對象(View)的創建過程分析
- 與WindowManagerService服務的連接過程分析
- 繪圖表面(Surface)的創建過程分析
- 測量(Measure)、布局(Layout)和繪制(Draw)過程分析
- WindowManagerService
- WindowManagerService的簡要介紹和學習計劃
- 計算Activity窗口大小的過程分析
- 對窗口的組織方式分析
- 對輸入法窗口(Input Method Window)的管理分析
- 對壁紙窗口(Wallpaper Window)的管理分析
- 計算窗口Z軸位置的過程分析
- 顯示Activity組件的啟動窗口(Starting Window)的過程分析
- 切換Activity窗口(App Transition)的過程分析
- 顯示窗口動畫的原理分析
- Android控件TextView的實現原理分析
- Android視圖SurfaceView的實現原理分析
- Android應用程序UI硬件加速渲染
- 簡要介紹和學習計劃
- 環境初始化過程分析
- 預加載資源地圖集服務(Asset Atlas Service)分析
- Display List構建過程分析
- Display List渲染過程分析
- 動畫執行過程分析
- Android應用程序資源管理框架
- Android資源管理框架(Asset Manager)
- Asset Manager 簡要介紹和學習計劃
- 編譯和打包過程分析
- Asset Manager的創建過程分析
- 查找過程分析
- Dalvik虛擬機和ART虛擬機
- Dalvik虛擬機
- Dalvik虛擬機簡要介紹和學習計劃
- Dalvik虛擬機的啟動過程分析
- Dalvik虛擬機的運行過程分析
- Dalvik虛擬機JNI方法的注冊過程分析
- Dalvik虛擬機進程和線程的創建過程分析
- Dalvik虛擬機垃圾收集機制簡要介紹和學習計劃
- Dalvik虛擬機Java堆創建過程分析
- Dalvik虛擬機為新創建對象分配內存的過程分析
- Dalvik虛擬機垃圾收集(GC)過程分析
- ART虛擬機
- Android ART運行時無縫替換Dalvik虛擬機的過程分析
- Android運行時ART簡要介紹和學習計劃
- Android運行時ART加載OAT文件的過程分析
- Android運行時ART加載類和方法的過程分析
- Android運行時ART執行類方法的過程分析
- ART運行時垃圾收集機制簡要介紹和學習計劃
- ART運行時Java堆創建過程分析
- ART運行時為新創建對象分配內存的過程分析
- ART運行時垃圾收集(GC)過程分析
- ART運行時Compacting GC簡要介紹和學習計劃
- ART運行時Compacting GC堆創建過程分析
- ART運行時Compacting GC為新創建對象分配內存的過程分析
- ART運行時Semi-Space(SS)和Generational Semi-Space(GSS)GC執行過程分析
- ART運行時Mark-Compact( MC)GC執行過程分析
- ART運行時Foreground GC和Background GC切換過程分析
- Android安全機制
- SEAndroid安全機制簡要介紹和學習計劃
- SEAndroid安全機制框架分析
- SEAndroid安全機制中的文件安全上下文關聯分析
- SEAndroid安全機制中的進程安全上下文關聯分析
- SEAndroid安全機制對Android屬性訪問的保護分析
- SEAndroid安全機制對Binder IPC的保護分析
- 從NDK在非Root手機上的調試原理探討Android的安全機制
- APK防反編譯
- Android視頻硬解穩定性問題探討和處理
- Android系統的智能指針(輕量級指針、強指針和弱指針)的實現原理分析
- Android應用程序安裝過程源代碼分析
- Android應用程序啟動過程源代碼分析
- 四大組件源代碼分析
- Activity
- Android應用程序的Activity啟動過程簡要介紹和學習計劃
- Android應用程序內部啟動Activity過程(startActivity)的源代碼分析
- 解開Android應用程序組件Activity的"singleTask"之謎
- Android應用程序在新的進程中啟動新的Activity的方法和過程分析
- Service
- Android應用程序綁定服務(bindService)的過程源代碼分析
- ContentProvider
- Android應用程序組件Content Provider簡要介紹和學習計劃
- Android應用程序組件Content Provider應用實例
- Android應用程序組件Content Provider的啟動過程源代碼分析
- Android應用程序組件Content Provider在應用程序之間共享數據的原理分析
- Android應用程序組件Content Provider的共享數據更新通知機制分析
- BroadcastReceiver
- Android系統中的廣播(Broadcast)機制簡要介紹和學習計劃
- Android應用程序注冊廣播接收器(registerReceiver)的過程分析
- Android應用程序發送廣播(sendBroadcast)的過程分析