Android display system introduce(Qualcomm 8x60 platform)(2、SW架構--1)

1、Overviewjava

 

  

  上圖的原型取自高通的文檔,因爲原圖沒法描述現有的架構,我在原圖的基礎了作了些修改,主要是增長了overlay部分,另外其餘部分根據現有的軟件也作了些許改動。下面先對上圖作個大概的介紹,後面會針對重點部分作詳細的分析。android

         最上面一層爲應用程序,根據數據類型以及應用的不一樣能夠分爲幾種。c++

第一種是最普通的應用,如UI界面的顯示,這部分一般數據類型爲RGB格式,數據無須再通過特殊的處理。該應用能夠說遍及各個應用程序,幾乎是實時存在的。api

第二種是針對大塊YUV數據的應用,如camerapreview、視頻的播放等。該應用只針對特定的應用程序,開啓時經過overlay直接把大塊的YUV數據送到kernel顯示。架構

        第三種其實和第一種相似,只不過因爲應用的需求在顯示以前須要對數據進行2D3D的處理(使用OpenGLOpenVGSVGSKIA),處理以後的流程和普通的顯示就沒什麼差異了。通常在Game、地圖、Flash等應用中會用到。app

        應用之下是framework,其中最核心的就是surfaceflinger了,它爲全部的應用程序的顯示提供服務。因爲overlay的接口掛在surfaceflinger裏面(雖然2者在功能上不相干),全部使用overlayAP須要經過surfaceflinger才能夠訪問overlay;另外,因爲surfaceflinger須要使用OpenGLcompose surface,這也就是爲何surfacelfinger會調用EGL wrapper了,EGL wrapper是對Graphics HAL的封裝,除了surfaceflinger會調用它來compose surface外,上層的2D3D應用也會調用它來進行圖形處理。composer

        再下一層就是HAL了。框架

首先一個是overlay模塊,對上提供control channeldata channel;對下則經過系統調用到kernel中的MDP driveride

再一個是Gralloc模塊,注意它是和overlay並列的,它包含2個部分,一部分是爲上層提供pmem的接口,另外一部分則是對framebuffer進行刷新,這裏的framebuffer其實就是UI的數據。因而可知上層有2個通道把顯示數據送到kernel中,framebuffer是傳統的方式,overlayandroidéclair之後)後增長的。函數

         紅色及右邊部分是OpenGLHAL,其中紅色部分表明HW solution,高通提供的,這部分是沒有源碼的;右邊的software graphics librarySW solutionandroid自身的。HWSW solution能夠同時存在也能夠只有一個,後面會講解。

        再往下就是kernel中的driver了,最主要的就是fb設備驅動以及MDP4 overlay的驅動,從硬件上看2者是並列的,framebuffer最終也是經過overlay方式送入MDP的。PMEMKGSL分別對應kernelpmemdriver/dev/pmem)和Adreno220driver

2、Surfaceflinger詳解

1.overview

        Surfaceflinger能夠說是Android顯示系統中的核心,在android當中它是一個service提供系統範圍內的surface composer 功能,它可以將各類應用程序的2D 3D surface 進行組合,合併最終獲得的一個main surface數據會送入顯存。簡單的說,surfaceflinger就像是畫布,它不關心畫上去的內容,只是一味的執行合成功能,固然要根據畫的位置、大小以及效果等參數。這很像Photoshop中的各個Layer,你能夠在不一樣的layer畫任意的內容,每一個layer能夠設置位置、大小、效果參數等,最終經過merge合成一個layer

        從應用的角度看,每一個應用程序可能對應一個或多個圖形界面,每一個界面能夠看做是一個surface。首先每一個surface有它的位置、大小、內容等元素,這些元素是能夠隨便變化的;另外不一樣的surface的位置會有重疊,會涉及到透明度等效果處理問題,這些都是經過surfaceflinger來完成的。固然了,surfaceflinger擔任是一個管理的職責,對於效果處理及合成它是經過OpenGL來作的,但前提是surfaceflinger須要把相關參數計算好,如重疊的位置等。

2.Surfaceflinger在系統中的位置

Android中的圖形系統採用Client/Server架構。服務端負責Surface的合成等處理工做,客戶端提供接口給上層操做本身的Surface,並向服務端發送消息完成實際處理工做服務端 (SurfaceFlinger)主要由c++代碼編寫而成。客戶端端代碼分爲兩部分,一部分是由Java提供的供應用使用的api,另外一部分則是由c++寫成的底層實現。以下圖所示:

 

除去最上層的應用不算,surface最上層的接口就是java surface了,文件路徑以下:

frameworks/base/core/java/android/view/Surface.java,該文件中的接口會被應用間接調用。

咱們從JNI開始看,surfaceJNI文件路徑以下:

frameworks/base/core/jni/android_view_Surface.cpp,裏面的接口大概分爲2類,一類是負責管理ibinder通訊的;另外一類纔是和顯示控制相關的,第二類接口會直接調用C實現函數。

C實現的文件路徑以下:

frameworks/base/libs/ui/Surface.cpp

        咱們來看看JNI中一些重要的接口:

        SurfaceSession_init:本接口只會被調用一次,負責建立surfacecomposerclient,主要爲進程間通訊作準備。對應的銷燬函數有SurfaceSession_destroySurfaceSession_kill

Surface_init負責建立surface,最終會調用到surfaceflinger中的createSurface,對應的銷燬函數有Surface_destroySurface_release

Surface_lockCanvas:當對一個surface進行繪圖以前要調用的,將該surface鎖定,而且獲得surfaceback buffer,應用能夠繪圖。

Surface_unlockCanvasAndPost:當上層繪圖完畢後,經過該函數通知底層back buffer已繪製完畢,能夠更新到顯存中。

Surface_setLayer/

Surface_setPosition/

Surface_setSize/

Surface_hide/

Surface_show/

Surface_setOrientation/

Surface_freeze/

Surface_unfreeze

Surface_setFlags/

Surface_setAlpha/

Surface_setMatrix:設置surface的一些屬性,如大小、位置、方位、截取範圍,Zorder等。其最終改變的都是surface的結構體屬性,以下:

            uint32_t        what;//哪一項屬性改變

            int32_t         x;//顯示位置

            int32_t         y; //顯示位置

            uint32_t        z; //layer順序

            uint32_t        w;//寬度

            uint32_t        h;//高度

            float           alpha;//透明度

            uint32_t        tint;//色彩,未使用

            uint8_t         flags;// 標誌

            uint8_t         mask;//屏蔽命令

            uint8_t         reserved;

            matrix22_t      matrix;//截取範圍

            Region          transparentRegion;//透明度設置

3.JNISurfaceflinger的鏈接通信

因爲JNIC函數實現與surfaceflinger不在同一個進程(一個在應用端-客戶端,另外一個在服務端),android中經過IPCBinder)方式實現進程間通訊,下圖來源於網上,不過我修改了裏面的一些錯誤,它演示了JNIsurfaceflinger創建鏈接以及建立surface的流程。

 

JNIC函數實現咱們看做是一個部分

這裏看到一個比較重要的部分——SurfaceComposerClient,它是surfacelinger的客戶端,經過它上層才能夠和surfaceflinger使用Binder聯繫到一塊兒,IsurfaceComposerIsurfaceFlingerClient都是用來實現Binder通訊的。具體流程講解 以下:

應用程序經過JNI接口SurfaceSession_init建立SurfaceComposerClient。經過SurfaceComposerClient函數中調用getComposerService得到IsurfaceComposerIBinder對象,而後經過這個對象的createConnection又得到IsurfaceFlingerClientIBinder,經過這個IBinderJNI就能夠調用Surfaceflinger中的接口了,如createSurface。因爲採用Binder方式,代碼部分稍微複雜一些,須要多看幾遍才能把流程理清楚。

4.SurfaceflingerlibuiOpenGL、顯示設備的鏈接

這裏不得不提到android對媒體框架中一個很重要的部分,那就是libui,它是一個框架庫提供對底層操做的接口,好比會調用GrallocOverlayHAL層接口。其餘的庫類繼承的方式來調用libuisurfaceflinger就是這樣和顯示設備鏈接的(包括寫顯存和對pmem的使用)

Surfaceflinger使用OpenGL來合成surface,因此surfaceflinger會直接調用到OpenGL的接口。

它們的架構以下:

 

 

這部分的流程比較複雜,主要是各個類的繼承繞的比較多,我也是看了不少遍代碼以及參考了些資料才理出來,下面來詳細解釋下這個圖:

Surfaceflinger在設計時考慮到支持多個屏幕,但目前的版本只支持一個,在surfaceflinger當中一個顯示設備對應一個圖中的DisplayHardwaresurfaceflinger在初始化時會新建Displayhardware(請參考surfaceflinger.cpp中的readyToRun函數),它完成的主要任務一個是創建FramebufferNativeWindow,肯定數據輸出設備接口(請參考FramebufferNativeWindow.cpp),再一個就是初始化OpenGL,並建立main surface,後續surfaceflinger中全部的layer最終都將被畫到這個main surface上(請參考displayhardware.cppinit函數)。這樣main surfaceOpenGLlibui中的FramebufferNativeWindow接口就綁定在一塊兒。

因爲libEGL負責全部layer的最終合成,因此最後數據送往HAL必定要libEGL來觸發,對應的函數流程是:

postFrameBuffer(surfaceflinger)>Flip(displayhardware)> eglSwapBuffers(OpenGL)-> queueBuffer(libui)->fbpost(gralloc)

另外圖中的GraphicBufferlibui中提供的對pmem的操做接口,它會直接調用gralloc模塊。關於OpenGLGralloc後面會有單獨的章節來介紹。