Android 圖形系統概述

圖形系統是 Android 中很是重要的子系統,與其餘子系統相互協做,完成圖形界面的渲染和顯示。shell


概述


官方提供了一個圖形系統的關鍵組件協做圖,以下所示:緩存


這幅圖大體描述了圖形數據的流轉:OpenGL ES、MediaPlayer 等生產者生產圖形數據到 Surface,Surface 經過 IGraphicBufferProducer把 GraphicBuffer 跨進程傳輸給消費者SurfaceFlinger。微信


SurfaceFlinger 根據 WMS 提供的窗口信息合成全部的 Layer(對應於 Surface ),具體的合成策略由 hwcomposerHAL 模塊決定並實施,最後也是由該模塊送顯到 Display,而 Gralloc 模塊則負責分配圖形緩衝區。架構


不過該圖缺少層次感,經過下圖咱們詳細分析整個流程。併發



大致上,應用開發者能夠經過兩種方式將圖像繪製到屏幕上:app


  • Canvascomposer

  • OpenGL ES框架


Canvas 是一個2D圖形 API ,是 Android View 樹實際的渲染者。Canvas 又可分爲Skia 軟件繪製和 hwui 硬件加速繪製。異步


Android 4.0 以前默認是 Skia 繪製,該方式徹底經過 CPU 完成繪圖指令,而且所有在主線程操做,在複雜場景下單幀容易超過16ms致使卡頓。編輯器


從 Android 4.0 開始,默認開啓硬件加速渲染,並且 5.0 開始把渲染操做拆分到了兩個線程:主線程和渲染線程,主線程負責記錄渲染指令,渲染線程負責經過 OpenGL ES 完成渲染,兩個線程能夠併發執行。


除了Canvas,開發者還能夠在異步線程直接經過 OpenGL ES 進行渲染,通常適用於遊戲、視頻播放等獨立場景。


從應用側來看,不論是 Canvas ,仍是 OpenGL ES,最終渲染到的目標都是 Surface ,如今比較流行的跨平臺UI框架 Flutter 在 Android 平臺上也是直接渲染到 Surface 。


Surface是一個窗口,例如:一個Activity是一個Surface、一個Dialog也是一個Surface,承載了上層的圖形數據,與SurfaceFlinger側的Layer相對應。


Native層Surface實現了ANativeWindow結構體,在構造函數中持有一個IGraphicBufferProducer,用於和 BufferQueue 進行交互。


BufferQueue 是鏈接 Surface 和 Layer 的紐帶,當上層圖形數據渲染到 Surface 時,實際是渲染到了BufferQueue中的一個GraphicBuffer,而後經過IGraphicBufferProducer 把 GraphicBuffer 提交到 BufferQueue ,讓 SurfaceFlinger 進行後續的合成顯示工做。


SurfaceFlinger 負責合成全部的 Layer 並送顯到 Display ,這些Layer主要有兩種合成方式:


  • OpenGL ES:把這些圖層合成到 FrameBuffer,而後把FrameBuffer提交給hwcomposer 完成剩餘合成和顯示工做。

  • hwcomposer:經過HWC模塊合成部分圖層和FrameBuffer,並顯示到Display。


BufferQueue


Android 圖形系統包含了兩對生產者和消費者模型,它們都經過 BufferQueue 進行鏈接:

  • Canvas 和 OpenGL ES 生產圖形數據,SurfaceFlinger消 費圖形數據。

  • SurfaceFlinger合成全部圖層的圖形數據,Display顯示合成結果。


Surface屬於APP進程,Layer屬於系統進程,若是它們之間只用一個Buffer,那麼必然存在顯示和性能問題,因此圖形系統引入了BufferQueue,一個Buffer用於繪製,一個Buffer用於顯示,雙方處理完以後,交換一下Buffer,這樣效率就高不少了。


BufferQueue的通訊流程以下所示:



  • 生產者從BufferQueue出隊一個空閒GraphicBuffer,交給上層填充圖形數據;

  • 數據填充後,生產者把裝載圖形數據的GraphicBuffer入隊到BufferQueue,也能夠丟棄這塊Buffer,直接cancelBuffer送回到BufferQueue;

  • 消費者經過acquireBuffer獲取一個有效緩存;

  • 完成內容消費後(好比上屏),消費者調用releaseBuffer把Buffer交還給BufferQueue。

  • GraphicBuffer表明的圖形緩衝區是由Gralloc模塊分配的,而且能夠跨進程傳輸(實際傳輸的只是一個指針)。

  • 一般而言,APP端使用的是BufferQueue的IGraphicBufferProducer接口(在Surface類裏面),用於生產;SurfaceFlinger端使用的是BufferQueue的IGraphicBufferConsumer接口(在GLConsumer類裏面),用於消費。

Surface 與 SurfaceFlinger


Surface 表示 APP 進程的一個窗口,承載了窗口的圖形數據,SurfaceFlinger 是系統進程合成全部窗口(Layer)的系統服務,負責合成全部 Surface 提供的圖形數據,而後送顯到屏幕


SurfaceFlinger 既是上層應用的消費者,又是 Display 的生產者,起到了承上啓下的做用。官方提供了一個架構圖,以下所示:



該圖可能較抽象,咱們經過一個實例理解下這層關係,下圖是微信添加朋友的彈窗界面:



咱們能夠經過adb shell dumpsys SurfaceFlinger查看該界面包含幾個窗口(Surface):



從SurfaceFlinger的dump信息能夠看到:


  • com.tencent.mm/com.tencent.mm.ui.LauncherUI#0是微信的主窗口,而且鋪滿了整個屏幕(0,0,1080,2340)。

  • PopupWindow:7020633#0是彈起的 PopupWindow,它是一個獨立的窗口(Surface),屏幕座標範圍是(599,210,1058,983)。

  • StatusBar#0 表示系統狀態欄,由系統進程負責繪製,屏幕座標範圍是(0,0,1080,80),即此狀態欄高80像素。

  • NavigationBar#0 表示系統導航欄,由系統進程負責繪製,屏幕座標範圍是(0,2214,1080,2340),即此導航欄高126像素。

  • 最後兩個窗口也是系統窗口,具體做用不知。

  • 上述全部圖層的合成類型都是Device,即HWC硬件模塊負責合成這些Layer。

  • SurfaceFlinger會合成上述全部圖層(Layer),並送顯到內嵌的Display 0。


總結


本篇文章從上到下簡述了 Android 圖形系統的流轉流程,以及承載圖形數據流轉的重要結構:BufferQueue ,最後經過dump信息論證了多 Surface 實例。


做者:ltlovezh
連接:https://juejin.im/post/6844903955709820936


-- END --


進技術交流羣,掃碼添加個人微信:Byte-Flow



獲取視頻教程和源碼



推薦:

Android OpenGL 渲染圖像讀取哪家強?

字節流動 OpenGL ES 技術交流羣來啦

FFmpeg + OpenGL ES 實現 3D 全景播放器

FFmpeg + OpenGLES 實現視頻解碼播放和視頻濾鏡

一文掌握 YUV 圖像的基本處理

Android OpenGL ES 從入門到精通系統性學習教程

OpenGL ES 實現動態(水波紋)漣漪效果


以爲不錯,點個在看唄~

本文分享自微信公衆號 - 字節流動(google_developer)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索