一、Android 显示系统架构总览
1. 核心组件全景图(按职责划分)
组件 | 职责 | 所属层级 |
---|
App (ViewRootImpl) | 接收输入事件 → 触发 View 测量/布局/绘制 | Java Framework |
SurfaceFlinger | 合成所有 Layer 图层 → 输出到 FrameBuffer | Native Service |
DisplayManagerService (DMS) | 管理显示设备生命周期(如亮灭屏)→ 连接 SurfaceFlinger | Java 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
源码位置:
frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
关键调用链:
private void registerDefaultDisplay(int displayId, IBinder displayToken) {
SurfaceControl.setDisplayToken(displayToken);
}
2. SurfaceFlinger
核心职责:
- 接收并缓存多个 Layer(来自 App 的 Surface)
- 根据 Z-order 合成图层 → 通过 HWC 或 OpenGL 渲染
- 管理帧缓冲区(FrameBuffer)
源码位置:
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
启动流程:
int main() {
sp<SurfaceFlinger> flinger = new SurfaceFlinger();
flinger->init();
sp<ISurfaceFlinger> iFlinger = flinger;
defaultServiceManager()->addService(String16("SurfaceFlinger"), iFlinger);
runLoop();
}
3. BufferQueue:生产者-消费者模型
工作机制:
- 应用侧(Producer)通过
dequeueBuffer
获取空缓冲区 - 绘制完成后调用
queueBuffer
提交 - SurfaceFlinger(Consumer)消费缓冲区进行合成
核心状态机:
[ FREE ] --dequeue--> [ DEQUEUED ]
^ |
| queue
+----<<acquire<<-----+
源码位置:
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);
scheduleFrameLocked(now);
}
}
三、显示流程全链路跟踪
1. App 侧 View 绘制到 BufferQueue
ViewRootImpl.setView() {
mSurface = new Surface();
mWindowSession.addToDisplay(...);
requestLayout();
}
Surface.unlockCanvasAndPost(Canvas canvas) {
nativeUnlockCanvasAndPost(mNativeObject, canvas);
}
2. BufferQueue 本地提交流程(C++ 层)
virtual status_t queueBuffer(...) {
mCore->signalCondition();
bufferState[b].status = BufferSlot::DEQUEUED;
}
3. SurfaceFlinger 合成逻辑
void onMessageReceived(int32_t what) {
switch (what) {
case MessageQueue::INVALIDATE:
handleRepaint();
break;
}
}
void handleRepaint() {
for (size_t i=0 ; i<mLayers.size() ; i++) {
Layer* layer = mLayers[i];
layer->beginFrame();
layer->prepare(SurfaceFlinger::eNextAnimationFrame);
}
}
四、必看调试命令与工具
adb shell dumpsys SurfaceFlinger --latency
adb shell service call SurfaceFlinger 1013
python systrace.py --time=10 -o trace.html gfx view wm
adb shell dumpsys display
五、推荐动手实验
- 修改 VSync 周期
static const nsecs_t vsyncPeriod = 16666666;
- 打印 BufferQueue 状态
在 BufferQueueProducer::queueBuffer()
添加日志输出 - 强制软件合成
adb shell setprop debug.sf.force_gpu false