Android 15 Surface 与 SurfaceControl 关系梳理
一、核心概念
┌─────────────────────────────────────────────────────────────────┐
│ 应用进程 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │SurfaceControl│─────▶│BLASTBufferQueue│─────▶│ Surface │ │
│ │ (图层句柄) │ │ (缓冲队列适配) │ │ (绘图窗口) │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ │ handle │ Producer │ │
│ ▼ ▼ ▼ │
└─────────┼─────────────────────┼─────────────────────┼──────────┘
│ │ │
│ Binder IPC │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────┐
│ SurfaceFlinger 进程 │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Layer │◀─────│ Client │ │
│ │ (显示图层) │ │ (客户端代理) │ │
│ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────┘
| 类 | 职责 | 所在进程 |
|---|---|---|
| SurfaceControl | Layer 的句柄,控制图层属性(位置、透明度等) | 应用进程 |
| Surface | 绘图窗口,提供 ANativeWindow 接口供绘图 |
应用进程 |
| BLASTBufferQueue | 缓冲队列适配器,连接 Surface 和 Layer | 应用进程 |
| Layer | SurfaceFlinger 中的实际图层对象 | SF 进程 |
二、初始化流程
1. SurfaceControl 创建(先创建)
应用调用 SurfaceComposerClient::createSurface()
│
▼
mClient->createSurface() ────── Binder IPC ──────▶ SurfaceFlinger::createLayer()
│ │
│ ▼
│ 创建 Layer 对象
│ (BufferStateLayer/EffectLayer等)
│ │
│ ▼
│ 返回 handle + layerId
│
▼
new SurfaceControl(this, handle, layerId, ...)
关键代码:
// frameworks/native/libs/gui/SurfaceComposerClient.cpp
status_t SurfaceComposerClient::createSurfaceChecked(...) {
// Binder 调用到 SurfaceFlinger
mClient->createSurface(name, flags, parentHandle, metadata, &result);
// 创建 SurfaceControl 封装返回结果
*outSurface = new SurfaceControl(this, result.handle, result.layerId, ...);
}
2. Surface 创建(从 SurfaceControl 获取)
应用调用 SurfaceControl::getSurface()
│
▼
generateSurfaceLocked()
│
├─▶ mClient->createSurface("bbq-wrapper", ...) // 创建子图层
│
├─▶ new BLASTBufferQueue("bbq-adapter", mBbqChild, ...)
│ │
│ └─▶ createBufferQueue() 创建 Producer/Consumer
│
└─▶ mBbq->getSurface() → new BBQSurface(mProducer, ...)
关键代码:
// frameworks/native/libs/gui/SurfaceControl.cpp
sp<Surface> SurfaceControl::generateSurfaceLocked() {
// 1\. 创建 bbq-wrapper 子图层
mBbqChild = mClient->createSurface(String8("bbq-wrapper"), ...);
// 2\. 创建 BLASTBufferQueue(核心!)
mBbq = sp<BLASTBufferQueue>::make("bbq-adapter", mBbqChild, mWidth, mHeight, mFormat);
// 3\. 从 BLASTBufferQueue 获取 Surface
mSurfaceData = mBbq->getSurface(true);
return mSurfaceData;
}
3. BLASTBufferQueue 构造(Android 12+ 核心机制)
BLASTBufferQueue::BLASTBufferQueue(...) {
// 1\. 创建 BufferQueue 三元组
createBufferQueue(&mProducer, &mConsumer);
// - BufferQueueCore:状态机,管理 Buffer 生命周期
// - Producer:应用持有,dequeueBuffer/queueBuffer
// - Consumer:BLAST 持有,监听 Buffer 并转为 Transaction
// 2\. 创建 BLAST 专用消费者
mBufferItemConsumer = new BLASTBufferItemConsumer(mConsumer, ...);
// 3\. 设置帧可用监听器
// 当应用 queueBuffer 时触发 onFrameAvailable()
mBufferItemConsumer->setFrameAvailableListener(this);
}
三、关系图总结
┌────────────────────────────────────────────────────────────────────┐
│ 类关系图 │
├────────────────────────────────────────────────────────────────────┤
│ │
│ SurfaceControl │
│ ├── mHandle ──────────────────▶ Layer (在 SurfaceFlinger 中) │
│ ├── mClient ──────────────────▶ SurfaceComposerClient │
│ ├── mBbq ────────────────────▶ BLASTBufferQueue │
│ │ ├── mProducer ──▶ IGraphicBufferProducer
│ │ ├── mConsumer ──▶ IGraphicBufferConsumer
│ │ └── mSurfaceControl ──▶ mBbqChild │
│ └── mSurfaceData ────────────▶ Surface (BBQSurface) │
│ └── mGraphicBufferProducer │
│ (指向 mProducer) │
│ │
└────────────────────────────────────────────────────────────────────┘
四、数据流向
应用绘图
│
▼
Surface (ANativeWindow 接口)
│ dequeueBuffer()
▼
BBQBufferQueueProducer ──────────────────┐
│ │
│ queueBuffer() │ BufferQueueCore
▼ │ (状态机管理)
BLASTBufferQueue::onFrameAvailable() ◀────┘
│
│ 打包成 Transaction
▼
SurfaceComposerClient::Transaction
│
│ apply()
▼
SurfaceFlinger
│
▼
Layer 合成 ──▶ 显示
五、Android 15 关键变化
移除 gbp 参数:
createSurfaceChecked不再返回IGraphicBufferProducer,统一使用 BLASTBufferQueue-
BLAST 架构:
- Android 12 前:BufferQueue 在 SurfaceFlinger 中创建
- Android 12+:BufferQueue 在应用进程的 BLASTBufferQueue 中创建
-
一一对应关系:
- 一个
SurfaceControl↔ 一个Layer - 一个
Surface↔ 一个BLASTBufferQueue - 一个
BLASTBufferQueue↔ 一个Layer
- 一个
六、关键源码路径
| 文件 | 路径 |
|---|---|
| SurfaceComposerClient | frameworks/native/libs/gui/SurfaceComposerClient.cpp |
| SurfaceControl | frameworks/native/libs/gui/SurfaceControl.cpp |
| BLASTBufferQueue | frameworks/native/libs/gui/BLASTBufferQueue.cpp |
| Surface | frameworks/native/libs/gui/Surface.cpp |
| SurfaceFlinger | frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp |
| Layer | frameworks/native/services/surfaceflinger/Layer.cpp |
| Client | frameworks/native/services/surfaceflinger/Client.cpp |
七、JNI 层关键函数
nativeCreate(创建 SurfaceControl)
static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
jstring nameStr, jint w, jint h, jint format, jint flags, jlong parentObject,
jobject metadataParcel) {
ScopedUtfChars name(env, nameStr);
sp<SurfaceComposerClient> client;
if (sessionObj != NULL) {
client = android_view_SurfaceSession_getClient(env, sessionObj);
} else {
client = SurfaceComposerClient::getDefault();
}
SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject);
sp<SurfaceControl> surface;
LayerMetadata metadata;
Parcel* parcel = parcelForJavaObject(env, metadataParcel);
if (parcel && !parcel->objectsCount()) {
status_t err = metadata.readFromParcel(parcel);
if (err != NO_ERROR) {
jniThrowException(env, "java/lang/IllegalArgumentException",
"Metadata parcel has wrong format");
}
}
sp<IBinder> parentHandle;
if (parent != nullptr) {
parentHandle = parent->getHandle();
}
status_t err = client->createSurfaceChecked(String8(name.c_str()), w, h, format, &surface,
flags, parentHandle, std::move(metadata));
if (err == NAME_NOT_FOUND) {
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
return 0;
} else if (err != NO_ERROR) {
jniThrowException(env, OutOfResourcesException, statusToString(err).c_str());
return 0;
}
// 关键:增加引用计数,防止 sp 析构时销毁对象
surface->incStrong((void *)nativeCreate);
// 返回裸指针给 Java 层保存
return reinterpret_cast<jlong>(surface.get());
}
引用计数管理解释
surface->incStrong((void *)nativeCreate);
return reinterpret_cast<jlong>(surface.get());
为什么需要 incStrong?
-
surface是sp<SurfaceControl>(强智能指针) - 函数返回时
sp会自动析构,导致引用计数 -1 - 如果引用计数降为 0,对象会被销毁
- 但我们要把这个对象返回给 Java 层继续使用!
- 手动
incStrong+1,抵消sp析构时的 -1
生命周期变化:
创建时 +1 → sp析构 -1 → 手动incStrong +1 = 最终 +1(对象存活)
参数 (void *)nativeCreate:引用计数的 cookie(标识符),用于调试追踪引用来源。