fwrite

fwrite

好好生活
twitter
github
email

Android 圖形系統

概覽#

官方簡介:Android-Graphics

2022-06-30-11-44-47

  • Image Stream Producers:圖形生產者,用來生成圖形緩衝區,以供圖形消費者使用。例如 OpenGL ES、Canvas 2D 和 mediaserver 視頻解碼器。

  • Native Framework:Libgui 庫,包含了圖形系統底層的基本元素,例如 Surface、BufferQueue、GraphicBufferConsumer、GraphicBufferProducer、SurfaceComposer 等等。

  • Window Positioning:WindowManager,用來控制 window 對象,window 為一組 view 對象的集合。它為 SurfaceFlinger 提供緩衝區和窗口元數據,而 SurfaceFlinger 可使用這些信息將 Surface 合成到屏幕。

  • Image Stream Consumers:圖形消費者,包括 SurfaceFlinger 和一些圖形應用。

    • 圖形流的最常見消費者是 SurfaceFlinger,該系統服務會消耗當前可見的 Surface,並使用 WindowManager 中提供的信息將它們合成到顯示部分。SurfaceFlinger 使用 OpenGL 和 Hardware Composer 來合成一組 Surface。
    • 一些 OpenGL ES 應用也可以做為消費者,例如相機應用會消費相機預覽圖像流。非 GL 應用也可以是消費者,例如 ImageReader 類。
  • HAL:顯示子系統的硬體抽象實現,包括 Hardware Composer 和 Gralloc。

    • SurfaceFlinger 可以將某些合成工作委託給 Hardware Composer,以分擔 OpenGL 和 GPU 上的工作量。這時,SurfaceFlinger 只是充當另一個 OpenGL ES 客戶端,Hardware Composer 則進行圖形渲染的工作。Hardware Composer 必須支持事件,其中之一是 VSYNC(另一個是支持即插即用 HDMI 的熱插拔)。
    • Gralloc 用來分配圖形生產方請求的內存。

2022-06-30-11-32-42

BufferQueue#

官方簡介:Android-BufferQueue

2022-06-30-11-39-08

左側的對象是生成圖形緩衝區的渲染器,如主屏幕、狀態欄和系統界面。SurfaceFlinger 是合成器,而 Hardware Composer 是製作器。BufferQueue 是 Android 圖形系統很重要的組成部分,它負責數據的傳遞:

2022-06-30-11-39-36

圖中的 producer 和 consumer 運行在不同的進程裡,BufferQueue 是將緩衝區池與隊列相結合的數據結構,它使用 Binder IPC 在進程之間傳遞緩衝區。幾個重要函數如下:

  • producers 透過 BufferQueue 請求一塊空閒的緩存區 (GraphicBuffer): IGraphicBufferProducer.dequeueBuffer 方法
  • 往緩存區 (GraphicBuffer) 填充了數據 (繪製等) 後,producers 將緩存區 (GraphicBuffer) 入隊列到 BufferQueue 中: IGraphicBufferProducer.queueBuffer 方法
  • consumer 從 BufferQueue 中出隊列一塊緩存區 (GraphicBuffer): IGraphicBufferConsumer.acquireBuffer 方法
  • consumer 消費完畢後 (典型的是 SurfaceFlinger 合成數據) 將緩存區 (GraphicBuffer) 返回給隊列: IGraphicBufferConsumer.releaseBuffer 方法

其中 IGraphicBufferProducer 是 BufferQueue 的生產者接口,實現類是 BufferQueueProducer 生產者類;IGraphicBufferConsumer 是 BufferQueue 的消費者接口,實現類是 BufferQueueConsumer 消費者類。

2022-06-30-11-39-58

SurfaceFlinger#

SurfaceFlinger 用來管理消費當前可見的 Surface, 所有被渲染的可見 Surface 都會被 SurfaceFlinger 透過 WindowManager 提供的信息合成 (使用 OpenGL 和 HardWare Composer) 提交到屏幕的後緩衝區,等待屏幕的下個 Vsync 信號到來,再顯示到屏幕上。SufaceFlinger 透過屏幕後緩衝區與屏幕建立聯繫,同時透過 Surface 與上層建立聯繫,起到了一个承上启下的作用。

2022-06-30-11-40-23

SurfaceFlinger 工作流程

2022-06-30-11-40-40

SurfaceFlinger 的 registerCallback 時的this就是 SurfaceFlinger 對 ComposerCallback 接口的實現。

  • onHotplugReceived

    熱插拔事件,顯示屏幕連接或者斷開時回調

  • onRefreshReceived

    接收底層 HWComposer 的刷新請求,實現方法如下:

    
    void SurfaceFlinger::onRefreshReceived(int sequenceId,
    
                                           hwc2_display_t /*display*/) {
    
        Mutex::Autolock lock(mStateLock);
    
        if (sequenceId !=getBE().mComposerSequenceId) {
    
            return;
    
        }
    
        repaintEverythingLocked();
    
    }
    
    
    void SurfaceFlinger::repaintEverythingLocked() {
    
        android_atomic_or(1, &mRepaintEverything);
    
        //觸發刷新,重新合成顯示
    
        signalTransaction();
    
    }
    
    
  • onVsyncReceived

    Vsync 事件上報,接收底層硬體上報的垂直同步信號。

為什麼需要垂直同步信號,參考https://juejin.cn/post/6863756420380196877#heading-1

合成方式#

  • Client 合成

將各個 Layer 的內容用 GPU 渲染到暫存緩衝區中,最後將暫存緩衝區傳送到顯示硬體,Client 合成,採用 RenderEngine 進行合成

  • Device 合成

硬體合成器進行合成 HWComposer,其合成方式是將各個 Layer 的數據全部傳給顯示硬體,並告知它從不同的緩衝區讀取屏幕不同部分的數據

HWC 相關圖表#

2022-06-30-11-41-18

合成圖表#

2022-06-30-11-41-30

Dump 信息#

adb shell dumpsys SurfaceFlinger

2022-06-30-11-41-46

圖層#

圖層(Layer)是合成的最重要單元;每個圖層都有一組屬性,用於定義它與其他層的交互方式。Layer 在每一層中的代碼的實現不一樣,基本上 Layer 的理念都是一樣的。


frameworks/native/services/surfaceflinger

├── Layer.h

├── Layer.cpp

├── ColorLayer.h

├── ColorLayer.cpp

├── BufferLayer.h

└── BufferLayer.cpp

總結#

整個圖形顯示系統可以簡單地分為圖形和顯示兩個系統理解。

  • 圖形系統,提供繪圖和圖形處理的支持。無論是 2D 的 Skia,還是 3D 的 OpenGLES,還有各種圖片解碼庫
  • 顯示系統,圖形繪製好後,需要顯示,就需要合併窗口,這個時候就需要用到 Surfaceflinger,上層的顯示系統有 View、ActivityManagerService 和 WindowManagerService 組成。一個窗口就是一個 Surface,Surfacedlinger 使用 Layer 去描述一個窗口。

2022-06-30-11-42-11

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。