第三板块:Android 图形渲染与窗口体系 | 第十三篇:SurfaceFlinger 与 VSYNC 信号机制

47 阅读5分钟

第三板块:Android 图形渲染与窗口体系 | 第十三篇:SurfaceFlinger 与 VSYNC 信号机制

所属板块:第三板块 — Android 图形渲染与窗口体系

前置知识:第十二篇中的 System Server 架构、Binder IPC、Surface 概念、屏幕刷新原理

本篇定位:这是 Android 图形系统的心脏。如果说 View 的绘制是“画家在画板上作画”,那么 SurfaceFlinger 就是**“美术馆的策展人将画作挂上墙”**。本篇将彻底拆解 SurfaceFlinger 的合成算法VSYNC 信号的产生与分发Triple Buffering(三重缓冲)机制HWC (Hardware Composer) 的硬件叠加原理。我们将深入 HAL 层Kernel 驱动SurfaceFlinger 进程的源码级逻辑,揭示 Android 如何实现 60/90/120 FPS 的流畅体验


1. 核心结论先行(Thesis Statement)

Android 的图形渲染是一个生产者-消费者模型

  • SurfaceFlinger 的本质:一个系统服务,也是一个合成引擎。它运行在 System Server 之外的独立进程(有时是 Root 进程),负责接收所有应用提交的 Buffer,并根据 Z-order(深度顺序)透明度(Alpha)裁剪区域(Crop) 将它们合成为一幅最终的 Frame,发送给 Display(显示屏)
  • VSYNC 的本质垂直同步信号。由硬件(Display Panel)或软件模拟产生,频率为屏幕的刷新率(60Hz/90Hz/120Hz)。它告诉系统:“屏幕准备好了,可以换下一帧了”。
  • BufferQueue 的本质连接生产者(App)和消费者(SurfaceFlinger)的管道。它是一个 FIFO(先进先出) 的环形缓冲区,通常包含 3 个 Buffer(Triple Buffering)。

2. 图形架构全景图

2.1 从 View 到屏幕的数据流

graph LR
    %% LR = Left to Right 横向排列
    subgraph AppProc [应用进程]
        direction LR
        View["View.draw()"]
        Canvas["Canvas"]
        Bitmap["SkBitmap (CPU 内存)"]
        GL["OpenGL ES / Vulkan"]
        Surface["Surface"]
    end

    subgraph SFProc [SurfaceFlinger 进程]
        direction LR
        BufferQueue["BufferQueue"]
        SF["SurfaceFlinger"]
        HWC["HWC (Hardware Composer)"]
    end

    subgraph Display [显示硬件]
        direction LR
        Panel["LCD / OLED Panel"]
    end

    %% 核心渲染流程
    View -->|"绘制指令"| Canvas
    Canvas -->|"光栅化"| Bitmap
    Bitmap -->|"GPU 上传"| GL
    GL -->|"渲染到"| Surface
    Surface -->|"dequeueBuffer"| BufferQueue
    BufferQueue -->|"queueBuffer"| SF
    SF -->|"合成"| HWC
    HWC -->|"Present"| Panel

2.2 核心角色定义

角色职责学术定义
Producer (生产者)应用进程通过 Surface 接口向 BufferQueue 填充图像数据。
BufferQueue缓冲区队列管理 GraphicBuffer 的申请、归还和流转。
Consumer (消费者)SurfaceFlingerBufferQueue 中取出 GraphicBuffer,进行合成。
HWC硬件合成器硬件芯片(Display Controller),负责将多个图层物理叠加。

3. BufferQueue 与 Triple Buffering

3.1 Buffer 的生命周期(Ring Buffer)

BufferQueue 中的每个 Buffer 都经历以下状态流转:

stateDiagram-v2
    [*] --> Free: 初始化
    Free --> Dequeued: dequeueBuffer() (App 申请)
    Dequeued --> Queued: queueBuffer() (App 提交)
    Queued --> Acquired: acquireBuffer() (SF 获取)
    Acquired --> Free: releaseBuffer() (SF 释放)

学术定义

  • Free: 空闲状态,可被申请。
  • Dequeued: 已被应用申请,正在填充数据。
  • Queued: 数据填充完毕,等待 SurfaceFlinger 消费。
  • Acquired: 已被 SurfaceFlinger 获取,正在合成。

3.2 Triple Buffering(三重缓冲)

为什么需要 3 个 Buffer?

缓冲数量场景结果
Single Buffering只有 1 个 Buffer屏幕正在读时,App 不能写,导致卡顿。
Double Buffering2 个 Buffer (Front/Back)理想情况流畅,但如果 App 渲染慢于 VSYNC,会导致 Jank(掉帧)。
Triple Buffering3 个 BufferApp 即使慢一帧,也有第三个 Buffer 可以准备下一帧,极大减少 Jank。
graph LR
    subgraph DoubleBuffer ["双缓冲 (容易卡顿)"]
        A1["VSYNC 1"] -->|"显示"| F1["Front Buffer"]
        A1 -->|"渲染"| B1["Back Buffer"]
        A2["VSYNC 2"] -->|"显示"| F1
        A2 -->|"等待"| B1
    end

    subgraph TripleBuffer ["三缓冲 (抗抖动)"]
        B_V1["VSYNC 1"] -->|"显示"| F2["Buffer A"]
        B_V1 -->|"渲染"| B2["Buffer B"]
        B_V2["VSYNC 2"] -->|"显示"| F2
        B_V2 -->|"渲染"| C2["Buffer C"]
        B_V3["VSYNC 3"] -->|"显示"| B2
        B_V3 -->|"渲染"| C2
    end

4. VSYNC 信号机制

4.1 VSYNC 的产生与分发

VSYNC 是图形系统的节拍器。

sequenceDiagram
    participant HW as 硬件 (Display)
    participant DispSync as DispSync (软件模型)
    participant SF as SurfaceFlinger
    participant Choreo as Choreographer
    participant App as 应用进程

    HW->>DispSync: 硬件 VSYNC 脉冲 (60Hz)
    DispSync->>DispSync: 校准相位 (Phase Offset)
    par 分发至合成器
        DispSync->>SF: Signal (SF VSYNC)
        SF->>SF: 开始合成 (doComposition)
    and 分发至应用
        DispSync->>Choreographer: Signal (App VSYNC)
        Choreographer->>App: doFrame()
        App->>App: 执行 Input/Animation/Traversal
        App->>SF: queueBuffer()
    end

学术定义

  • HW VSYNC: 显示器硬件产生的物理信号。
  • SW VSYNC (DispSync): Android 在软件层模拟的 VSYNC,用于同步 HWComposer。
  • Phase Offset (相位偏移): 为了让 App 的渲染和 SF 的合成错开,避免同时抢占 CPU/GPU 资源。

4.2 Choreographer(编舞者)

Choreographer 运行在应用进程的主线程,它是 VSYNC 信号的接收者

源码解析

// Choreographer.java
void doFrame(long frameTimeNanos, int frame) {
    // 1. 处理输入事件
    doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos);
    // 2. 执行动画
    doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);
    // 3. 执行 Traversal (measure/layout/draw)
    doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);
    // 4. 提交帧
    doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos);
}

5. SurfaceFlinger 的合成算法

5.1 合成策略:Client Composition vs Device Composition

SurfaceFlinger 面临一个选择:是用 GPU 合成,还是用硬件叠加?

合成方式执行者适用场景性能
Device Composition (HWC)硬件叠加器 (Display Controller)不透明图层、无复杂变换极高 (零拷贝)
Client Composition (GPU)GPU (OpenGL ES)透明图层、复杂变换、旋转较低 (需要渲染)

5.2 HWC (Hardware Composer) 的工作流程

HWC 是 SurfaceFlinger 的“硬件助手”。

graph TB
    subgraph SF ["SurfaceFlinger"]
        A["Layer 1 (Status Bar)"]
        B["Layer 2 (Wallpaper)"]
        C["Layer 3 (App Window)"]
        D["Layer 4 (Navigation Bar)"]
    end

    subgraph HWC ["Hardware Composer"]
        H1["Overlay 1 (Status Bar)"]
        H2["Overlay 2 (Wallpaper)"]
        H3["Overlay 3 (App Window)"]
        H4["Overlay 4 (Nav Bar)"]
    end

    A -->|"不透明"| H1
    B -->|"不透明"| H2
    C -->|"半透明"| SF_GPU["GPU 合成"]
    D -->|"不透明"| H4
    SF_GPU -->|"合成结果"| H3

学术定义

  • Overlay Planes: 硬件支持的物理图层。每个 Plane 可以直接显示一块内存,无需拷贝。
  • GPU Fallback: 如果图层太多(超过 HWC 支持的 Overlay 数量)或者有复杂特效,SurfaceFlinger 会强制使用 GPU 将所有图层合成到一个 Buffer 中,再由 HWC 显示。

6. 关键源码解析

6.1 SurfaceFlinger 的主循环

SurfaceFlinger 是一个典型的 Event Loop 模型。

// frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::run() {
    while (true) {
        waitForEvent(); // 等待 VSYNC 或 Buffer 提交
        handleMessageRefresh(); // 处理刷新
    }
}

void SurfaceFlinger::handleMessageRefresh() {
    preComposition();    // 准备合成
    rebuildLayerStacks(); // 重建图层堆栈
    setUpHWComposer();   // 配置 HWC
    doComposition();    // 执行合成
    postComposition();   // 提交到显示
}

6.2 BufferQueue 的核心逻辑

// frameworks/native/libs/gui/BufferQueueProducer.cpp
status_t BufferQueueProducer::dequeueBuffer(...) {
    // 1. 查找 Free Buffer
    // 2. 如果没有,等待
    // 3. 返回 Buffer 的 Slot
}

status_t BufferQueueProducer::queueBuffer(...) {
    // 1. 标记 Buffer 为 Queued
    // 2. 通知 Consumer (SurfaceFlinger)
    listener->onFrameAvailable();
}

7. 掉帧(Jank)的学术成因

7.1 掉帧的数学模型

假设屏幕刷新率为 60Hz,每帧时间约为 16.67ms

阶段耗时结果
App 渲染20ms掉帧。超过了 16.67ms,下一帧 VSYNC 到来时还没画完。
SurfaceFlinger 合成10ms正常。
HWC 显示1ms正常。

学术定义

  • Deadline Miss: 未能在 VSYNC 信号到来前完成渲染或合成。
  • Buffer Stuffing: 由于 App 太慢,BufferQueue 被填满,App 必须等待 SurfaceFlinger 消费后才能继续渲染。

8. 本篇总结(Knowledge Closure)

关键点纯学术定义
SurfaceFlinger 的本质系统级合成服务,负责将多个应用的 Surface 合成为单一帧。
VSYNC 的作用同步软件渲染与硬件刷新的节拍器,防止画面撕裂。
BufferQueue 机制基于 Triple Buffering 的环形缓冲区,解耦生产者与消费者。
HWC 的价值利用硬件叠加器(Overlay)实现零拷贝合成,是流畅度的关键。
Choreographer 的角色应用进程的 VSYNC 接收者,协调 Input、Animation 和 Drawing。

下一篇预告第三板块:Android 图形渲染与窗口体系 | 第十四篇:View 绘制体系与 RenderThread 异步渲染