图像显示框架七——createSurface的流程(基于Android 15源码分析)

目录

1.背景

[2. createSurface流程](#2. createSurface流程)


1.背景

前面的文章已经讲述了应用层如何调用图像显示的api,以及应用如何与SurfaceFlinger建立连接和通信,接下来我们就来讲述下如何创建Surface。

本文涉及的代码

/frameworks/native/libs/gui/SurfaceComposerClient.cpp /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp /frameworks/native/services/surfaceflinger/Client.cpp /frameworks/native/libs/gui/ISurfaceComposer.cpp

首先大家回忆下之前说的与SurfaceFlinger通信过程中有两个重点的成员变量,大家是否还记得?这个同样在这里也有关键作用:

1. ComposerServiceAIDL中有成员mComposerService,它代表了SurfaceFlinger服务的代理客户端;

2. SurfaceComposerClient中有成员mClient,它代表了SurfaceFlinger服务进程中的Client的代理客户端

2. createSurface流程

由于createSurface流程涉及到之前的应用层与SurfaceFlinger通信过程,所以把之前的时序图贴一下,方便后续理解:

应用进程 (Application) ServiceManager SurfaceFlingerAIDL进程

| | |

|---1. new SurfaceComposerClient()------------------------>|

| (应用进程内部创建) | |

| | |

|<--2. onFirstRef()回调-------------------------------------|

| (应用进程内部回调) | |

| | |

|---3. ComposerServiceAIDL.getComposerService()----------->|

| | |

|---4. ServiceManager.getService("SurfaceFlingerAIDL")--->|

| |---5. 查询服务注册表------>|

|<--6. 返回ISurfaceComposer代理----------------------------|

| (应用进程内部) | |

| | |

|---7. ISurfaceComposer.createConnection()---------------->|

| | |

| |---8. SurfaceFlingerAIDL.createConnection()|

| | |

| |---9. new ClientAIDL()---->|

| | (SurfaceFlinger进程内部) |

|<--10. 返回ISurfaceComposerClient代理---------------------|

| (应用进程内部) | |

| | |

|---11. 保存到mClient成员--------------------------------->|

| (应用进程内部) | |

| | |

SurfaceComposerClient::createSurface

添加注释后代码如下,主要参数是传递一个名字name,指定宽高,指令格式format等,返回一个个SurfaceControl的指针,这个方法中调用了createSurfaceChecked

cpp 复制代码
/**
 * 创建一个新的图形层(Surface)。
 * 该方法用于在显示系统中创建一个新的图层,该图层可以用于绘制UI、视频渲染或作为其他图层的容器。
 * 创建的Surface将成为显示层级树的一部分,其属性(如大小、格式)和行为由参数定义。
 *
 * @param name 图层标识符(String8类型)。为创建的Surface分配一个可读的名称,
 *              便于在调试或系统工具(如dumpsys SurfaceFlinger)中识别此图层。
 * 
 * @param w 图层宽度(uint32_t类型)。指定Surface的初始宽度,单位为像素。
 * 
 * @param h 图层高度(uint32_t类型)。指定Surface的初始高度,单位为像素。
 * 
 * @param format 像素格式(PixelFormat类型)。定义缓冲区颜色的存储格式,
 *               例如PIXEL_FORMAT_RGBA_8888(常用,带透明度)或PIXEL_FORMAT_RGB_565(节省内存)。
 * 
 * @param flags 行为控制标志(int32_t类型)。通过位掩码组合定义Surface的类型和特性:
 *              - eFXSurfaceNormal / eFXSurfaceBufferState: 创建标准带缓冲区的Surface
 *              - eFXSurfaceEffect: 创建特效层(如纯色背景)
 *              - eFXSurfaceContainer: 创建容器层(用于管理子图层)
 *              - eOpaque: 表示表面不透明(可优化渲染)
 * 
 * @param parentHandle 父图层句柄(sp<IBinder>类型)。指定父图层的Binder句柄,
 *                     新创建的Surface将作为其子节点,用于构建图层树和确定Z序。
 *                     传入nullptr表示不指定父图层。
 * 
 * @param metadata 图层元数据(LayerMetadata类型)。用于传递附加的键值对信息,
 *                 例如窗口类型,可供SurfaceFlinger或HWC(硬件合成器)进行特定处理。
 * 
 * @param outTransformHint 变换提示(uint32_t*类型,输出参数)。方法执行成功后,
 *                         会写入一个提示值,指示显示设备当前的旋转或镜像状态,
 *                         应用可据此优化渲染流程。
 * 
 * @return sp<SurfaceControl> 返回SurfaceControl对象的智能指针。
 *         该对象是应用进程中控制Surface的核心句柄,可用于:
 *         - 通过Transaction设置Surface的位置、大小、透明度等属性
 *         - 调用getSurface()获取关联的Surface对象,用于渲染绘制
 * 
 * @note 该方法实际调用createSurfaceChecked完成核心创建逻辑。
 * @see createSurfaceChecked, SurfaceControl, Transaction
 */
sp<SurfaceControl> SurfaceComposerClient::createSurface(
    const String8& name,       // 图层标识符
    uint32_t w,                 // 宽度(像素)
    uint32_t h,                 // 高度(像素)  
    PixelFormat format,         // 像素格式
    int32_t flags,              // 行为控制标志
    const sp<IBinder>& parentHandle, // 父图层句柄
    LayerMetadata metadata,     // 图层元数据
    uint32_t* outTransformHint  // 变换提示(输出参数)
) {
    sp<SurfaceControl> s;
    // 调用实际的创建方法,执行参数验证和Surface创建
    createSurfaceChecked(name, w, h, format, &s, flags, parentHandle, 
                        std::move(metadata), outTransformHint);
    return s;  // 返回新创建的SurfaceControl对象
}

然后再来看下createSurfaceChecked方法

cpp 复制代码
status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,
                                                     PixelFormat format,
                                                     sp<SurfaceControl>* outSurface, int32_t flags,
                                                     const sp<IBinder>& parentHandle,
                                                     LayerMetadata metadata,
                                                     uint32_t* outTransformHint) {
    status_t err = mStatus;

    if (mStatus == NO_ERROR) {
        gui::CreateSurfaceResult result; // 用于接收SurfaceFlinger返回的创建结果
        
        // 关键步骤:通过Binder IPC跨进程调用SurfaceFlinger服务创建图层
        // mClient是ISurfaceComposerClient的代理,实际调用会发送到SurfaceFlinger进程[1,3](@ref)
        binder::Status status = mClient->createSurface(std::string(name.c_str()), flags,
                                                       parentHandle, std::move(metadata), &result);
        err = statusTFromBinderStatus(status);
        
        // 处理返回的显示变换提示信息
        if (outTransformHint) {
            *outTransformHint = result.transformHint;
        }
        
        ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
        
        // 创建成功后的处理
        if (err == NO_ERROR) {
            // 使用SurfaceFlinger返回的创建结果构造SurfaceControl对象
            // result.handle是SurfaceFlinger中Layer的标识句柄[1](@ref)
            // result.layerId是图层的唯一标识符
            *outSurface = new SurfaceControl(this, result.handle, result.layerId,
                                             toString(result.layerName), w, h, format,
                                             result.transformHint, flags);
        }
    }
    return err; // 返回操作状态
}

这个方法的关键步骤是mClient->createSurface,mClient这是之前说过的是SurfaceFlinger的Client代理客户端,最终调用到服务端 Client::createSurface中

这里result做了一个统一的封装,里面包含了handle(是SurfaceFlinger中Layer的标识句柄),layerId(是图层的唯一标识符)等,可以看出来这里移除了Android 13版本中的sp<IGraphicBufferProducer> gbp;参数,说明从Android 14版本开始直接默认使用BLASTBufferQueue了

相关推荐
QING61810 小时前
Kotlin inline 实战详解 —— 新手须知
android·kotlin·android jetpack
ElevenS_it18810 小时前
MySQL慢查询监控与告警实战:从slow_log采集到分钟级定位慢SQL的完整链路配置
android·sql·mysql
沐言人生10 小时前
ReactNative 源码分析12——Native View创建流程onBatchComplete
android·react native
caicai_xiaobai10 小时前
QT搭建安卓开发环境
android
YF021110 小时前
Android 异形屏与横屏全屏沉浸式适配技术方案
android·app
2501_9419820511 小时前
通过 API 实时监听企业微信外部群变更事件并同步本地数据库
android·自动化·企业微信·rpa
白雪落青衣12 小时前
buuoj course 1详细解析
android
恋猫de小郭12 小时前
Android 发布全新性能分析器,实用性和性能大升级
android·前端·flutter
Kapaseker12 小时前
为什么 Java 的数组需要 new 出来
android·java·kotlin
黄林晴12 小时前
颠覆开发!Google AI Studio 一句话生成原生 Android App
android·google io