Android圖形系統概述

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

概述

官方提供了一個圖形系統的關鍵組件協做圖,以下所示:
Android官方圖形架構
這幅圖大體描述了圖形數據的流轉:OpenGL ES、MediaPlayer等生產者生產圖形數據到Surface,Surface經過IGraphicBufferProducerGraphicBuffer跨進程傳輸給消費者SurfaceFlingerSurfaceFlinger根據WMS提供的窗口信息合成全部的Layer(對應於Surface),具體的合成策略由hwcomposerHAL模塊決定並實施,最後也是由該模塊送顯到Display,而Gralloc模塊則負責分配圖形緩衝區。不過該圖缺少層次感,經過下圖咱們詳細分析整個流程。
圖形系統架構segmentfault

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

  • Canvas
  • OpenGL ES

Canvas是一個2D圖形API,是Android View樹實際的渲染者。Canvas又可分爲Skia軟件繪製和hwui硬件加速繪製。
Android4.0以前默認是Skia繪製,該方式徹底經過CPU完成繪圖指令,而且所有在主線程操做,在複雜場景下單幀容易超過16ms致使卡頓。
從Android4.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,而後經過IGraphicBufferProducerGraphicBuffer提交到BufferQueue,讓SurfaceFlinger進行後續的合成顯示工做。併發

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

  • OpenGL ES:把這些圖層合成到FrameBuffer,而後把FrameBuffer提交給hwcomposer完成剩餘合成和顯示工做。
  • hwcomposer:經過HWC模塊合成部分圖層和FrameBuffer,並顯示到Display。

BufferQueue

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

  1. CanvasOpenGL ES生產圖形數據,SurfaceFlinger消費圖形數據。
  2. SurfaceFlinger合成全部圖層的圖形數據,Display顯示合成結果。

Surface屬於APP進程,Layer屬於系統進程,若是它們之間只用一個Buffer,那麼必然存在顯示和性能問題,因此圖形系統引入了BufferQueue,一個Buffer用於繪製,一個Buffer用於顯示,雙方處理完以後,交換一下Buffer,這樣效率就高不少了。BufferQueue的通訊流程以下所示:
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的生產者,起到了承上啓下的做用。官方提供了一個架構圖,以下所示:
Android圖形管道函數

該圖可能較抽象,咱們經過一個實例理解下這層關係,下圖是微信添加朋友的彈窗界面:
<img src="https://ltlovezh.oss-cn-beiji...; width="300" />
咱們能夠經過adb shell dumpsys SurfaceFlinger查看該界面包含幾個窗口(Surface):
微信多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實例。

相關文章
相關標籤/搜索