图像显示框架七——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了

相关推荐
聆风吟º3 小时前
【Spring Boot 报错已解决】Spring Boot项目启动报错 “Main method not found“ 的全面分析与解决方案
android·spring boot·后端
Rysxt_4 小时前
Kotlin前景深度分析:市场占有、技术优势与未来展望
android·开发语言·kotlin
莫白媛4 小时前
Android开发之Kotlin 在 Android 开发中的全面指南
android·开发语言·kotlin
broadview_java14 小时前
使用 ConstraintLayout 构建自适应界面
android
wy31362282117 小时前
android——开发中的常见Bug汇总与解决方案(闪退)
android·bug
小小测试开发18 小时前
实战派SQL性能优化:从语法层面攻克项目中的性能瓶颈
android·sql·性能优化
QuantumLeap丶19 小时前
《Flutter全栈开发实战指南:从零到高级》- 26 -持续集成与部署
android·flutter·ios
StarShip20 小时前
从Activity.setContentView()开始
android
千里马学框架21 小时前
重学SurfaceFlinger之Layer显示区域bounds计算剖析
android·智能手机·sf·安卓framework开发·layer·surfaceflinger·车载开发