GUI系統總結

GUI系統之SurfaceFlinger
一、整體架構
1. Linux內核提供了framebuffer的顯示驅動,fb0表示第一個顯示屏;
2. Android的HAL層提供了Gralloc,包括fb和gralloc兩個設備。前者負責打開內核中的framebuffer、初始化配置、並提供了post,setSwapInterval等操作接口;後者則管理幀緩衝區的分配和釋放;
3. HAL層的另一個重要模塊是“Composer”,它的直接使用者是SurfaceFlinger中的HWComposer,它出了管理Composer的HAL模塊外,還負責VSync信號的產生和控制;


二、Gralloc和FramebufferNativeWindow
1. FramebufferNativeWindow繼承了ANativeWindow,提供了setSwapInterval,dequeueBuffer和queueBuffer等函數;
1. Gralloc的加載是在FramebufferNativeWindow的構造函數中;
2. FramebufferNativeWindow申請的緩衝區保存在buffers數組中,每個元素是一個NativeBuffer,它繼承了ANativeWindosBuffer;
3. dequeueBuffer方法是FramebufferNativeWindow的核心,主要是從buffers數組中找到一個空閒的緩衝區,返回給客戶端(生產者)使用;


三、應用程序端的本地窗口Surface
1. Surface和FramebufferNativeWindow一樣,也繼承了ANativeWindow;
2. Surface是面向Android系統中所有UI應用程序的,即它承擔着應用進程中的UI顯示需求;
3. 通過mGraphicBufferProducer來獲取GraphicBuffer,而這些緩衝區會被記錄在mSlots數組中;
4. ViewRootImpl持有一個Java層的空Surface對象mSurface,之後ViewRootImpl向WMS發起relayout請求,WMS會讓WindowStateAnimator生成一個SurfaceControl,通過Surface的copyFrom函數,複製到mSurface中;
5. ISurfaceComposer是SF的實名Binder,調用它的createConnection得到ISurfaceComposerClient,ISurfaceComposerClient的對象命名爲mClient,調用它的createSurface函數的到IGraphicBufferProducer對象,再由IGraphicBufferProducer創建出SurfaceControl;
6. IGraphicBufferProducer提供了requestBuffer、dequeueBuffer和queueBuffer等操作;
7. FramebufferNativeWindow是專門爲SF服務的,它由Gralloc提供支持;Surface是爲應用程序服務的,由SF統一管理的;
8. 爲應用程序服務的本地窗口Surface,它依賴的IGraphicBufferProducer在Server端的實現是BufferQueue;


四、BufferQueue
1. BufferQueue重載了queueBuffer,requestBuffer,dequeueBuffer等,還有mSlots數組,保存着BufferSlot對象;
2. BufferSlot對象包含了GraphicBuffer和BufferState,State的週期是FREE->DEQUEUED->QUEUED->ACQUIRED->FREE;
3. 當應用程序即Producer需要使用一塊Buffer時,就會向BufferQueue發起dequeue申請,操作完成後再調用queue接口;SF即消費者在收到BufferQueue的onFrameAvailable回調後,就會調用acquire獲取buffer;
4. 當mGraphicBufferProducer的dequeueBuffer得到mSlots中可用的數組成員序號buf後,因爲客戶端和BufferQueue運行在不同的進程中,所以雙方的mSlots[buf]不是指向同一塊物理內存,所以需要調用requestBuffer,複製服務器端的mSlots[buf].GraphicBuffer到客戶端(因爲GraphicBuffe實現了Flattenable接口,通過ashmem共享內存);
5. 服務器端的GraphicBuffer是在BufferQueue的dequeueBuffer的最後,調用mGraphicBufferAlloc的createGraphicBuffer函數分配的;


五、開機啓動動畫BootAnimation
1. BootAnimation繼承了Thread,在它的構造函數中創建了SurfaceComposerClient的對象mSession;SurfaceComposerClient是UI應用程序與SF間的紐帶,不過SurfaceComposerClient只是一個殼,真正起作用的是其內部的ISurfaceComposerClient,通過它獲得IGraphicBufferProducer;ISurfaceComposerClient代表SF,IGraphicBufferProducer代表BufferQueue;
2. 在BootAnimation的readyToRun函數中,調用mSession的createSurface創建SurfaceControl對象,內含Surface,又內含了IGraphicBufferProducer,在SF的Client類的createSurface中,通過消息調到SF的createLayer,生成了IGraphicBufferProducer對象gbp和Layer對象;
3. Layer對象是SF中的層,最終物理屏幕上的顯示結果就是通過對系統中同時存在的所有畫面進行處理而得到的;
4. 當EGL想通過Surface這個Native Window完成某些功能時,後者實際上又利用了ISurface和IGraphicBufferProducer來取得遠程服務端的對應服務,已完成EGL請求;
5. 詳見P262的時序圖《深入理解Android內核設計思想》


六、應用程序與BufferQueue的關係
1. 應用程序通過ISurfaceComposerClient::createSurface()發起創建Surface的請求時,SF會創建一個Layer,並返回Handle和IGraphicBufferProducer
2. 應用程序可以通過createSurface來建立多個Layer,它們是一對多的關係,爲應用程序申請的Layer,一方面需要告知SF,另一方面記錄到各Client內部中;
3. 對於SF,它需要對系統中當前所有的Layer進行ZOrder排序,對於Client則利用內部的mLayers來逐一紀錄新增的attachLayer和移除detachLayer的Layer;
4. 每個Layer對應一個BufferQueue,一個應用程序對應多個BufferQueue;


七、SurfaceFlinger
1. 一旦VSync信號出現,CPU立刻開始執行Buffer的準備工作;
2. 如果CPU+GPU的執行時間超過了1/60秒,但是CPU的執行時間小於1/60秒,那麼在VSync信號到來時,CPU可以接着處理下一個緩衝區,而GPU繼續處理前一個緩衝區,此時屏幕上顯示的是第三個緩衝區的內容;
3. 應用程序的ISurfaceComposerClient對應的服務端類爲Client,主要提供createSurface和destroySurface兩個方法,Surface在服務器端對應的是Layer;
4. 同一個Activity中的UI佈局共用系統分配的Surface進行繪圖,但像SurfaceView這種UI組件卻是特例,它獨佔一個Surface進行繪製;
5. Client只是SF分派給應用程序的一個代表,真正的圖形層Layer需要另外申請,即調用Client提供的createSurface;
6. Client受到客戶端的請求後,把請求消息放到SF的隊列中,在SF執行過程中,Client所在的Binder線程會wait,直到SF完成後才被喚醒然後返回結果給客戶端;


八、VSync信號的產生和分發
1. 硬件源:HWComposer
2. 軟件源:VSyncThread模擬
3. SF內部的EventQueue監聽VSync消息,需要刷新UI的各進程也需要監聽;
4. VSync最終會被EventThread::threadLoop分發給各監聽者,如SF中就是MessageQueue;




九、VSync信號的處理
1. handleMessageTransaction()
2. handleMessageInvaliate()
3. signalRefresh(): preComposition, rebuildLayerStacks, setUpHWComposer, doDebugFlashRegions, doComposition, postComposition




GUI系統之WMS
一、概述
1. 從用戶角度講,窗口是一個界面,從SF角度講是一個Layer,承載着和界面相關的數據和屬性,從WMS的角度講是一個WindowState;
2. 當IMS收到一個按鍵或者觸摸消息時,它需要尋找一個合適的窗口來處理,WMS正是窗口管理者;
3. 主要包含功能:窗口的添加與刪除,起過度作用的啓動窗口,窗口動畫的設定,窗口大小的設定,窗口層級的設定,事件派發;
4. 工作方式:WMS爲SystemServer提供了wmHandlerThread,使得SystemServer中的其他Service可以往wmHandlerThread中投遞事件,方便WMS處理;
5. AMS和WMS在同一個進程中,可以相互調用;應用程序通過調用openSession獲得IWindowSession來訪問WMS的功能,WMS通過IWindow來回調應用程序的功能;
6. 應用程序調用IWindowSession::relayout(IWindow),用於WMS回調應用程序,IWindow的實現類是W,提供了resized,dispatchAppVisibility和dispatchScreenState等接口,用於WMS實時通知應用程序界面上的變化;
7. WMS利用WindowState來保存一個窗口相關信息,用AppWindowToken來對應AMS中的一個ActivityRecord;


二、窗口屬性
1. 類型與層級:普通窗口,系統窗口,子窗口
2. 窗口策略:PhoneWindow
3. 窗口屬性:WindowManager.LayoutParams中,包含Type,Flags,systemUiVisibility等;


三、窗口添加過程
1. mWindowManager.addView(view, WindowManager.LayoutParams),其中mWindowManager的實現是WindowManagerImpl,內部由WindowManagerGlobal單例實現的;
2. addView中創建了ViewRootImpl,並將ViewRoot、DecorView和wparams分別保存到數組中;
3. ViewRoot.setView(DecorView, wparams, panelParentView)中,調用了requestLayout,內部調用了scheduleTraversals,進行measure,layout和draw;
4. ViewRoot的setView中還調用了mWindowSession.addToDisplay(IWindow),講當前窗口註冊到WMS中;
5. 在WMS的addWindow中,創建了WindowState保存新的IWindow,還創建了WindowToken,保存當前的ActivityRecord,對所有Window進行排序;


四、Surface管理
1. WMS原則上只負責管理窗口的層級和屬性,而SF纔是真正講窗口數據合成並最終顯示到屏幕上的系統服務;WMS在對窗口大小或ZOrder做出調整後也必須通知SF;
2. ViewRoot進行performTraversals時,調用relayoutWindow,進而調用mWindowSession的relayout,向WMS申請一個Surface;
3. WMS中的relayoutWindow,根據窗口的可見性生成Surface,並分配層值;
4. WMS得到ISurfaceComposerClient,調用它的createSurface,獲得SurfaceControl,內含IGraphicBufferProducer;
5. WMS將SurfaceControl拷貝給應用程序,應用程序用其中內含的IGraphicBufferProducer建立一個C++層的Surface;
6. performLayoutAndPlaceSurfacesLocked,對窗口的變更進行計算,如計算大小,動畫等,並通過SurfaceControl應用到SurfaceFlinger中;


五、啓動窗口的添加與銷燬


六、窗口動畫


GUI系統之View體系


1. canvas = mSurface.lockCanvas(dirty)
2. mView.draw(canvas)
3. surface.unlockCanvasAndPost(canvas)
4. Bitmap, Canvas, Primitive, Paint
5. 其中lockCanvas的作用是調用dequeueBuffer,從buffer隊列中dequeue一個可用的buffer,並lock住防止別人使用;
6. unlockCanvasAndPost調用了unlock解除鎖定,並調用queueBuffer入隊;



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章