【FW】Android 显示系统核心架构与流程

一、Android 显示系统架构总览

1. 核心组件全景图(按职责划分)

组件职责所属层级
App (ViewRootImpl)接收输入事件 → 触发 View 测量/布局/绘制Java Framework
SurfaceFlinger合成所有 Layer 图层 → 输出到 FrameBufferNative Service
DisplayManagerService (DMS)管理显示设备生命周期(如亮灭屏)→ 连接 SurfaceFlingerJava Service
HWComposer HAL提供硬件合成能力(GPU/GPU混合渲染)→ 控制 VSync 中断Hardware Abstraction
BufferQueue生产消费模式管理 GraphicBuffer 缓冲区C++ Lib

2. 关键数据流

App draw() 
→ BufferQueue dequeue/queue 
→ SurfaceFlinger composeLayers 
→ HWComposer set(hal_module)
→ FrameBufferDevice (最终输出)

二、核心组件详解与协作机制

1. DisplayManagerService (DMS)

核心功能:
  • 监控显示设备插拔(如热插拔 HDMI)
  • 管理 DisplayDeviceInfo(分辨率/DPI/刷新率)
  • 创建 DisplayToken 并传递给 SurfaceFlinger
源码位置:
// Java 层入口
frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
关键调用链:
// DMS 初始化时注册显示设备
private void registerDefaultDisplay(int displayId, IBinder displayToken) {
    // 通过 SF 的 BootInitialize 设置主屏
    SurfaceControl.setDisplayToken(displayToken);
}

2. SurfaceFlinger

核心职责:
  • 接收并缓存多个 Layer(来自 App 的 Surface)
  • 根据 Z-order 合成图层 → 通过 HWC 或 OpenGL 渲染
  • 管理帧缓冲区(FrameBuffer)
源码位置:
// Native 入口
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
启动流程:
int main() {
    // Step1: 创建实例
    sp<SurfaceFlinger> flinger = new SurfaceFlinger();
    
    // Step2: 初始化硬件抽象层
    flinger->init();
    
    // Step3: 注册 Binder 接口
    sp<ISurfaceFlinger> iFlinger = flinger;
    defaultServiceManager()->addService(String16("SurfaceFlinger"), iFlinger);
    
    // Step4: 启动消息循环
    runLoop();
}

3. BufferQueue:生产者-消费者模型

工作机制:
  • 应用侧(Producer)通过 dequeueBuffer 获取空缓冲区
  • 绘制完成后调用 queueBuffer 提交
  • SurfaceFlinger(Consumer)消费缓冲区进行合成
核心状态机:
[ FREE ] --dequeue--> [ DEQUEUED ]
     ^                     |
     |                   queue
     +----<<acquire<<-----+ 
源码位置:
// BufferQueue 核心实现
frameworks/native/libs/gui/include/gui/BufferQueue.h
frameworks/native/libs/gui/BufferQueue.cpp

4. VSync 信号同步机制

原理图:
HWComposer.generateVSync()
      ↓
EventThread.dispatchVSync()
      ↓
SurfaceFlinger.onVSyncReceived()
      ↓
App.doTraversal() → 开始下一帧绘制
黄油计划改进(Android 4.1+):
  • 引入 Choreographer 实现 UI 渲染与 VSync 的同步
  • 支持多级 VSync offset(避免输入延迟)
源码片段(Choreographer):
public void postCallback(int callbackType, Runnable action, Object token) {
    synchronized (mLock) {
        // 计算下一帧时间戳
        long now = SystemClock.uptimeMillis();
        mCallbackQueues[callbackType].addCallbackLocked(now, action, token);
        
        // 请求下一次 VSync
        scheduleFrameLocked(now);
    }
}

三、显示流程全链路跟踪

1. App 侧 View 绘制到 BufferQueue

// Activity 启动后触发首次绘制
ViewRootImpl.setView() {
    // 创建 Surface 并关联到 WindowSession
    mSurface = new Surface();
    mWindowSession.addToDisplay(...);
    
    // 开始绘制循环
    requestLayout();
}

// Canvas 绘制完成提交缓冲区
Surface.unlockCanvasAndPost(Canvas canvas) {
    nativeUnlockCanvasAndPost(mNativeObject, canvas);
}

2. BufferQueue 本地提交流程(C++ 层)

// frameworks/native/libs/gui/BufferQueueProducer.cpp
virtual status_t queueBuffer(...) {
    // 通知 Consumer 可以消费
    mCore->signalCondition();
    
    // 更新缓冲区状态
    bufferState[b].status = BufferSlot::DEQUEUED;
}

3. SurfaceFlinger 合成逻辑

// SurfaceFlinger.cpp
void onMessageReceived(int32_t what) {
    switch (what) {
        case MessageQueue::INVALIDATE:
            // 触发合成
            handleRepaint();
            break;
    }
}

void handleRepaint() {
    // 遍历所有 Layer
    for (size_t i=0 ; i<mLayers.size() ; i++) {
        Layer* layer = mLayers[i];
        
        // 准备缓冲区
        layer->beginFrame();
        
        // 合成操作
        layer->prepare(SurfaceFlinger::eNextAnimationFrame);
    }
}

四、必看调试命令与工具

# 查看 SurfaceFlinger 当前负载
adb shell dumpsys SurfaceFlinger --latency

# 分析 BufferQueue 状态
adb shell service call SurfaceFlinger 1013

# 抓取 Systrace 分析 VSync
python systrace.py --time=10 -o trace.html gfx view wm

# 查看当前显示设备信息
adb shell dumpsys display

五、推荐动手实验

  1. 修改 VSync 周期
    // 修改 frameworks/native/services/surfaceflinger/EventThread.cpp
    static const nsecs_t vsyncPeriod = 16666666; // 默认 60Hz
    
  2. 打印 BufferQueue 状态
    BufferQueueProducer::queueBuffer() 添加日志输出
  3. 强制软件合成
    adb shell setprop debug.sf.force_gpu false
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值