Android 顯示系統

來源:互聯網
上載者:User

 

Android display system introduce(Qualcomm 8x60 platform)(二、SW架構--1)2010-12-31 11:17

一、Overview

    的原型取自高通的文檔,由於原圖無法描述現有的架構,我在原圖的基礎了做了些修改,主要是增加了overlay部分,另外其他部分根據現有的軟體也做了些許改動。下面先對做個大概的介紹,後面會針對重點部分做詳細的分析。

         最上面一層為應用程式,根據資料類型以及應用的不同可以分為幾種。

第一種是最普通的應用,如UI介面的顯示,這部分通常資料類型為RGB格式,資料無須再經過特殊的處理。該應用可以說遍布各個應用程式,幾乎是即時存在的。

第二種是針對大塊YUV資料的應用,如camera的preview、視頻的播放等。該應用只針對特定的應用程式,開啟時通過overlay直接把大塊的YUV資料送到kernel顯示。

        第三種其實和第一種類似,只不過由於應用的需求在顯示之前需要對資料進行2D、3D的處理(使用OpenGL、OpenVG、SVG、SKIA),處理之後的流程和普通的顯示就沒什麼差別了。一般在Game、地圖、Flash等應用中會用到。

        應用之下是framework,其中最核心的就是surfaceflinger了,它為所有的應用程式的顯示提供服務。由於overlay的介面掛在surfaceflinger裡面(雖然2者在功能上不相干),所有使用overlay的AP需要通過surfaceflinger才可以訪問overlay;另外,由於surfaceflinger需要使用OpenGL來compose
surface,這也就是為什麼surfacelfinger會調用EGL wrapper了,EGL wrapper是對Graphics HAL的封裝,除了surfaceflinger會調用它來compose
surface外,上層的2D、3D應用也會調用它來進行圖形處理。

        再下一層就是HAL了。

首先一個是overlay模組,對上提供control channel和data channel;對下則通過系統調用到kernel中的MDP driver。

再一個是Gralloc模組,注意它是和overlay並列的,它包含2個部分,一部分是為上層提供pmem的介面,另一部分則是對framebuffer進行重新整理,這裡的framebuffer其實就是UI的資料。由此可見上層有2個通道把顯示資料送到kernel中,framebuffer是傳統的方式,overlay是android(éclair以後)後增加的。

         紅色及右邊部分是OpenGL的HAL,其中紅色部分代表HW solution,高通提供的,這部分是沒有源碼的;右邊的software graphics library是SW
solution,android自身的。HW和SW solution可以同時存在也可以只有一個,後面會講解。

        再往下就是kernel中的driver了,最主要的就是fb裝置驅動以及MDP4 overlay的驅動,從硬體上看2者是並列的,framebuffer最終也是通過overlay方式送入MDP的。PMEM和KGSL分別對應kernel中pmem的driver(/dev/pmem)和Adreno220的driver。

二、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開始看,surface的JNI檔案路徑如下:

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

C實現的檔案路徑如下:

frameworks/base/libs/ui/Surface.cpp

        我們來看看JNI中一些重要的介面:

        SurfaceSession_init:本介面只會被調用一次,負責建立surfacecomposerclient,主要為處理序間通訊做準備。對應的銷毀函數有SurfaceSession_destroy和SurfaceSession_kill。

Surface_init:負責建立surface,最終會調用到surfaceflinger中的createSurface,對應的銷毀函數有Surface_destroy和Surface_release。

Surface_lockCanvas:當對一個surface進行繪圖之前要調用的,將該surface鎖定,並且得到surface的back 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的一些屬性,如大小、位置、方位、截取範圍,Z-order等。其最終改變的都是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.JNI與Surfaceflinger的串連通訊

由於JNI及C函數實現與surfaceflinger不在同一個進程(一個在應用端-用戶端,另一個在服務端),android中通過IPC(Binder)方式實現處理序間通訊,來源於網上,不過我修改了裡面的一些錯誤,它示範了JNI和surfaceflinger建立串連以及建立surface的流程。

JNI和C函數實現我們看作是一個部分

這裡看到一個比較重要的部分——SurfaceComposerClient,它是surfacelinger的用戶端,通過它上層才可以和surfaceflinger使用Binder聯絡到一起,IsurfaceComposer和IsurfaceFlingerClient都是用來實現Binder通訊的。具體流程講解 如下:

應用程式通過JNI介面SurfaceSession_init建立SurfaceComposerClient。通過SurfaceComposerClient函數中調用getComposerService獲得IsurfaceComposer的IBinder對象,然後通過這個對象的createConnection又獲得IsurfaceFlingerClient的IBinder,通過這個IBinder,JNI就可以調用Surfaceflinger中的介面了,如createSurface。由於採用Binder方式,代碼部分稍微複雜一些,需要多看幾遍才能把流程理清楚。

4.Surfaceflinger與libui、OpenGL、顯示裝置的串連

這裡不得不提到android對媒體架構中一個很重要的部分,那就是libui,它是一個架構庫提供對底層操作的介面,比如會調用Gralloc、Overlay等HAL層介面。其他的庫類繼承的方式來調用libui,surfaceflinger就是這樣和顯示裝置串連的(包括寫顯存和對pmem的使用)

Surfaceflinger使用OpenGL來合成surface,所以surfaceflinger會直接調用到OpenGL的介面。

它們的架構如下:

 

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

Surfaceflinger在設計時考慮到支援多個螢幕,但目前的版本只支援一個,在surfaceflinger當中一個顯示裝置對應一個圖中的DisplayHardware,surfaceflinger在初始化時會建立Displayhardware(請參考surfaceflinger.cpp中的readyToRun函數),它完成的主要任務一個是建立FramebufferNativeWindow,確定資料輸出裝置介面(請參考FramebufferNativeWindow.cpp),再一個就是初始化OpenGL,並建立main
surface,後續surfaceflinger中所有的layer最終都將被畫到這個main surface上(請參考displayhardware.cpp的init函數)。這樣main surface、OpenGL和libui中的FramebufferNativeWindow介面就綁定在一起。

由於libEGL負責所有layer的最終合成,所以最後資料送往HAL一定要libEGL來觸發,對應的函數流程是:

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

另外圖中的GraphicBuffer是libui中提供的對pmem的操作介面,它會直接調用gralloc模組。關於OpenGL和Gralloc後面會有單獨的章節來介紹。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.