iT邦幫忙

2025 iThome 鐵人賽

DAY 14
0

SurfaceFlinger and RenderThread

intro

在 Android 系統中,畫面呈現是使用者體驗的核心。從應用程式呼叫 Canvas.drawXXX() 或 OpenGL ES API 開始,到最終畫面被顯示在螢幕上,這個過程涉及 應用層 → Framework → HAL → Kernel → Display 的完整鏈路。
其中,兩個極為重要的角色是:

  1. RenderThread —— 應用程式內部的專屬渲染執行緒,負責將 UI 或 GPU 指令轉換為圖形緩衝區 (Buffer)。
  2. SurfaceFlinger —— Android 系統層的合成服務 (System Service),負責將多個應用的圖層 (Surface) 合成,並送往螢幕。

簡單來說:

  • RenderThread 負責「畫出一張張圖片」(per-surface rendering)。
  • SurfaceFlinger 負責「把所有圖片拼在一起」(global composition)。

圖形系統總覽

Android 的圖形系統包含以下幾個層級:

  1. 應用層
  • Java/Kotlin 程式呼叫 UI API (如 View.invalidate())。
  • 或使用 OpenGL / Vulkan 直接繪製。
  1. 渲染層
  • RenderThread 處理應用的渲染邏輯。
  • 將畫面繪製到 GraphicBuffer,並交給 Surface。
  1. 合成層
  • SurfaceFlinger 收集各應用的 Surface,決定畫面合成策略 (OpenGL / Hardware Composer)。
  • 最終合成單一 FrameBuffer。
  1. 顯示層
  • HWComposer (HWC) 與 Display Driver,將畫面送到螢幕。
應用層 (App)
   |
   v
RenderThread (繪製至 Surface)
   |
   v
SurfaceFlinger (全域合成)
   |
   v
HWComposer (硬體合成)
   |
   v
Display (螢幕)

RenderThread:應用內的渲染執行緒

  1. RenderThread 的角色
  • 在 Android 5.0 (Lollipop) 引入,目的是 減少 UI 延遲。
  • 將渲染任務從 UI Thread (主執行緒) 分離,避免因 GC 或主執行緒卡頓而影響流暢度。
  • 使用 OpenGL ES / Skia / Vulkan 進行 GPU 加速繪製。
  1. RenderThread 運作流程
  • 應用呼叫 invalidate() → Framework 標記需要重繪。
  • Choreographer 在下一個 VSync 信號到來時,通知 RenderThread 準備繪製。
  • RenderThread 收集繪製命令 (DisplayList)。
  • 執行 Skia/OpenGL 指令,繪製到 GraphicBuffer。
  • Buffer 透過 BufferQueue 傳送給 SurfaceFlinger。
UI Thread (事件/邏輯) → DisplayList
                         |
                         v
                   RenderThread
                         |
                GPU/Skia 繪製 → GraphicBuffer
                         |
                         v
                    Surface (BufferQueue)
  1. RenderThread 的優勢
  • 降低延遲:渲染與 UI 邏輯並行。
  • 更穩定的幀率:避免 UI Thread 卡住影響畫面更新。
  • 靈活性:支援 Skia、OpenGL、Vulkan 等不同後端。

SurfaceFlinger:系統級合成服務

  1. SurfaceFlinger 的角色
  • Android 的 System Service,運行在 system_server。
  • 職責是 合成所有應用的 Surface,並輸出到螢幕。
  • 相當於「全域畫布管理者」。
  1. Surface 與 BufferQueue
  • 每個應用的視窗 (Activity) 對應一個 Surface。
  • Surface 內部透過 BufferQueue 與 SurfaceFlinger 溝通:
    • 應用 RenderThread → 生產者 (Producer)
    • SurfaceFlinger → 消費者 (Consumer)
  1. SurfaceFlinger 的核心工作
  • 收集 Buffer
  • 從不同應用的 BufferQueue 收取最新的 GraphicBuffer。
  • 決定合成策略
    • 軟體合成:使用 OpenGL ES。
    • 硬體合成:交由 HWComposer。
  • 合成圖層
    • 依照 Z-Order、透明度、Clip 等屬性,疊加多個圖層。
  • 輸出到螢幕
    • 通知 Display HAL 更新 FrameBuffer。
App1 (RenderThread) → Surface1 (BufferQueue)
App2 (RenderThread) → Surface2 (BufferQueue)
App3 (RenderThread) → Surface3 (BufferQueue)
                           |
                           v
                     SurfaceFlinger
                 (決定 Z-Order / 合成策略)
                           |
                           v
                       HWComposer
                           |
                           v
                        Display

VSync 與幀同步

Android 的渲染必須與螢幕刷新同步,否則會出現 畫面撕裂 (Tearing) 或 掉幀 (Jank)。

  1. VSync 信號
  • 硬體每次刷新螢幕時發送信號。
  • Android Framework 透過 Choreographer 捕捉 VSync。
  1. 時間線
    T0:VSync 發送 → 通知 RenderThread 準備繪製。
    T1:RenderThread 完成繪製 → BufferQueue 交給 SurfaceFlinger。
    T2:SurfaceFlinger 在下一次 VSync 前完成合成 → 提交給 HWC。
    T3:螢幕刷新,顯示最新畫面。
|---VSync0---|---VSync1---|---VSync2---|
      ^             ^             ^
   應用繪製    SurfaceFlinger   螢幕刷新

SurfaceFlinger 與 HWComposer 的合作

  1. 軟體合成 (GL Composition)
  • SurfaceFlinger 使用 OpenGL 將各層合成到一個 FrameBuffer。
  • 適用於 GPU 效率較高的場景。
  1. 硬體合成 (HWC)
  • 將部分圖層交由 Display Controller 直接合成。
  • 節省 GPU 能耗。
  • 常用於播放影片、顯示系統 UI。
  1. 混合模式
  • 部分圖層 GPU 合成,部分圖層硬體合成。
  • SurfaceFlinger 動態選擇最優解。

Z-Order 與透明度管理

SurfaceFlinger 需要處理多層 Surface 疊加:

  • Z-Order:決定哪個視窗在前 (如 Dialog 蓋在 Activity 上)。
  • 透明度:支援半透明視窗、陰影效果。
  • 裁剪 (Clip):只顯示部分區域 (如系統狀態列)。
    這些資訊由 WindowManagerService (WMS) 提供,SurfaceFlinger 依此進行合成。

效能與挑戰

  1. 效能瓶頸
  • 應用渲染過慢 → Frame Miss。
  • SurfaceFlinger 合成過慢 → 掉幀。
  1. Triple Buffering
  • Android 採用 三重緩衝,減少等待時間。
  • 保證應用、SurfaceFlinger、Display 之間不卡住。
  1. 低延遲模式
  • 遊戲/VR 應用需要降低延遲,可能採用 Direct Composition。

Use case study

  1. 應用卡頓 (UI Thread 卡住)
  • RenderThread 無法及時接收繪製命令 → 畫面停頓。
  1. 視訊播放 (硬體合成)
  • 視訊 Surface 可直接交由 HWC,避免 GPU 重複合成,節能省電。
  1. 全螢幕遊戲
  • 使用 RenderThread + OpenGL 繪製,SurfaceFlinger 直接將單一 Surface 輸出,減少額外合成。

Summary

  • RenderThread:應用內部的渲染專用執行緒,降低延遲並提升幀率穩定性。
  • SurfaceFlinger:系統級的合成服務,負責將多應用的 Surface 合成,並輸出到螢幕。
  • VSync 與 BufferQueue:確保畫面更新與顯示同步,避免撕裂與掉幀。
  • HWComposer:降低 GPU 負擔,提高能效。

上一篇
#12
下一篇
#14
系列文
安豬複習16
  1. 12
    #11
  2. 13
    #12
  3. 14
    #13
  4. 15
    #14
  5. 16
    #15
完整目錄
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言