Surfacefinger——threadLoop主迴圈

來源:互聯網
上載者:User

1 Surfaceflinger線程


 Surfaceflinger是一個類,同時又是線程,該線程通過迴圈,不斷計算並重新整理當前螢幕需要的顯示內容。Surfaceflinger線程屬於SystemServer進程,也就是在SystemServer進程中啟動了Surfaceflinger線程。

 Surfaceflinger中儲存著各種layer,其主要工作就是負責各種layer的融合,因此可看做一個用於維護各種layer的線程。

 啟
動Android線程需要提供兩個介面,一是readyToRun(),該函數定義了線程迴圈前需要初始化的內容;二是threadLoop(),每個線
程都必須實現,該函數定義了線程執行的內容,如果該函數返回true,線程會繼續調用threadLoop(),如果返回false,線程將退出。

2 初始化


 Surfaceflinger類的建構函式會執行init(),該函數輸出Surfaceflinger啟動資訊,並配置一些調試資訊。接著執行readyToRun(),初始化整個顯示系統。

 readyToRun()調用過程如下:

 (1)執行new DisplayHardware(this, dpy),通過DisplayHardware初始化Framebuffer、EGL並擷取OpenGL ES資訊。

 (2)建立共用的記憶體控制塊。

 (3)將EGL與當前螢幕綁定。

 (4)初始化共用記憶體控制塊。

 (5)初始化OpenGL ES。

 (6)顯示開機動畫。

3 核心資料結構


 State           mCurrentState;  

 當前更新的狀態

State           mDrawingState; 

正在螢幕上繪製的狀態

LayerVector     layersSortedByZ; 

儲存layer的列表,類似於Z軸,mCurrentState和mDrawingState分別擁有一個列表。

4 主迴圈threadLoop()


 通過流程圖可以看到threadLoop()都做了哪些操作。

 



4.1 waitForEvent函數


 waitForEvent函數將逾時時間設定為5秒鐘,並等待系統事件發生。在逾時前若有事件發生則立即返回,若發生逾時將輸出警告資訊,上層一般會處理這個問題。

4.2 handleConsoleEvents函數


 該函數被執行的幾率較低,主要用於處理控制台事件。

4.3 handleTransaction函數


 該函數將遍曆Surfaceflinger擁有的每一個layer,檢查是否有layer的屬性改變,主要執行以下工作:

 (1)擷取mCurrentState.layersSortedByZ及layer的數目。

 (2)遍曆所有layer,擷取layer對應的參數,判斷是否有layer的屬性改變和是否有需要顯示的layer。

 (3)更新主畫面參數:

  如果螢幕需要旋轉,則需更新所有可見地區和共用控制塊,並計算旋轉參數;

  判斷主畫面是否需要被凍結;

  判斷是否有新加入的layer;

  去除不再需要的layer,通過ditchedLayers.add(layer)釋放資源;

 (4)通過廣播更新所有改變。

4.4 handlePageFlip函數


 該函數主統計所有layer的資訊,針對需要的layer進行重繪,並計算螢幕實際可顯示地區。

 (1)調用lockPageFlip(currentLayers)

 遍
曆currentLayers包含的所有layer,依次調用每層layer對應的lockPageFlip函數。首先通過retireAndLock函
數取得新的frontbuffer,然後擷取並計算髒的地區,最後調用reloadTexture函數更新這些地區。

 (2)
如果有需要顯示的layer,調用computeVisibleRegionsFunction Compute經過混合後每個layer的顯示地區。每一個layer擁有三片區
域,分別為opaqueRegion、visibleRegion和coveredRegion,主畫面則擁有aboveOpaqueLayers、
aboveCoveredLayers。在遍曆每一層layer時,要計算沒個layer對應的地區,同時同步更新主畫面的
aboveOpaqueLayers和aboveCoveredLayers。

 (3)調用unlockPageFlip(currentLayers)

 遍曆currentLayers包含的所有layer,依次調用每層layer對應的unlockPageFlip函數,完成layer到螢幕的座標變換。

4.5 handleRepaint函數


 handlePageFlip更新並計算每一個獨立layer的顯示地區,handleRepaint則負責將每一個layer經過計算的顯示地區資料搬運至螢幕的顯存中。

 (1)根據不同的螢幕類型,設定更新模式,有部分更新、緩衝更新、矩形框交換和全屏更新。

 (2)調用composeSurfaces(mDirtyRegion)

 該函數將遍曆每一層layer,調用layer對應的onDraw介面,將資料從layer的緩衝搬運至螢幕的顯存中。

4.6 hw.compositionComplete函數


 該函數會調用到gralloc模組的fb_compositionComplete介面,是提供給螢幕的回調介面,目前並沒有實現任何功能,根據採用螢幕的不同可能需要填充相應操作。

4.7 unlockClients函數


 unlockClients函數將遍曆每一層layer,調用finishPageFlip釋放layer用於的共用控制塊。

4.8 postFramebuffer函數


 handleRepaint函數執行的搬運操作實際將顯示資料搬運至螢幕的後緩衝中,postFramebuffer最終將調用到eglSwapBuffers(dpy, surface),交換螢幕的後緩衝和前緩衝,實現顯示更新。

4.9 另一條路線


 如果hw.canDraw返回錯誤或者螢幕此時被凍結,那麼將無法進行資料更新,此時將都另外一條路線,直接調用unlockClients,並休眠16667微秒。如果顯示出現問題,16667微秒將保證每秒最多執行60次threadLoop函數。

聯繫我們

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