Android 15 Surface 与 SurfaceControl 关系梳理

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 关键变化

  1. 移除 gbp 参数createSurfaceChecked 不再返回 IGraphicBufferProducer,统一使用 BLASTBufferQueue

  2. BLAST 架构

    • Android 12 前:BufferQueue 在 SurfaceFlinger 中创建
    • Android 12+:BufferQueue 在应用进程的 BLASTBufferQueue 中创建
  3. 一一对应关系

    • 一个 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?

  1. surfacesp<SurfaceControl>(强智能指针)
  2. 函数返回时 sp 会自动析构,导致引用计数 -1
  3. 如果引用计数降为 0,对象会被销毁
  4. 但我们要把这个对象返回给 Java 层继续使用!
  5. 手动 incStrong +1,抵消 sp 析构时的 -1

生命周期变化:

创建时 +1 → sp析构 -1 → 手动incStrong +1 = 最终 +1(对象存活)

参数 (void *)nativeCreate:引用计数的 cookie(标识符),用于调试追踪引用来源。


八、参考链接

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容