Android图形框架之SurfaceControl 构建过程分析

368 阅读5分钟

0 引言

在前面Android图形框架之SurfaceComposerClient初始化过程分析的分析过程中我们知道SurfaceComposerClient对象初始化过程中,我们了解到,SurfaceComposerClient 对象在初始化过程中,会内部初始化一个 mClient 指针,该指针指向 SurfaceFlinger 进程内部的 Client 类。通过这个指针,SurfaceComposerClient 可以访问并调用 SurfaceFlinger 提供的服务。

下面继续分析这样一段代码:

sp<SurfaceControl> surfaceControl =
            surfaceComposerClient->createSurface(name, resolution.getWidth(),
                                                 resolution.getHeight(), PIXEL_FORMAT_RGBA_8888,
                                                 ISurfaceComposerClient::eFXSurfaceBufferState,/*parent*/ nullptr);

这行代码调用了 SurfaceComposerClientcreateSurface 方法,该方法用于创建一个新的 SurfaceControl 对象。我们进入源码里面仔细分析SurfaceControl的构建过程。

1 SurfaceComposerClient::createSurface函数

首先调用的是SurfaceComposerClient的createSurface函数,从函数名字看是创建一个Surface,但是实际返回的是一个指向SurfaceControl的智能指针。

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;
    createSurfaceChecked(name, w, h, format, &s, flags, parentHandle, std::move(metadata),
                         outTransformHint);
    return s;
}

首先解析一下传入的参数:name表示创建的 Surface 的名称。它通常用于调试、日志记录等目的,帮助识别或区分不同的Surface。w和h分别指定了Surface的宽度和高度,通常传入的是显示屏幕的分辨率。flags指定了Surface的缓冲区类型(例如,是否是透明的、是否是一个虚拟显示等)。metadata是与表面相关的元数据(例如,层级信息、显示效果等)。outTransformHint是返回的表面变换提示,指示表面可能需要的变换(如旋转或缩放)。

接着创建了一个指向SurfaceControl的指针,然后继续调用createSurfaceChecked函数:

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) {
    sp<SurfaceControl> sur;
    status_t err = mStatus;

    if (mStatus == NO_ERROR) {
        gui::CreateSurfaceResult result;
        binder::Status status = mClient->createSurface(std::string(name.string()), 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) {
            *outSurface = new SurfaceControl(this, result.handle, result.layerId,
                                             toString(result.layerName), w, h, format,
                                             result.transformHint, flags);
        }
    }
    return err;
}

createSurfaceChecked函数的工作主要有两个:

  1. 通过mClient调用createSurface服务来创建一个Surface,结果保存在传入的result中;
  2. 使用result的数据new 一个SurfaceControl

我们前面一篇博客分析了,mClient就是一个指向Client类的指针,所以我们找到Client的createSurface方法:

binder::Status Client::createSurface(const std::string& name, int32_t flags,
                                     const sp<IBinder>& parent, const gui::LayerMetadata& metadata,
                                     gui::CreateSurfaceResult* outResult) {
    // We rely on createLayer to check permissions.
    sp<IBinder> handle;
    LayerCreationArgs args(mFlinger.get(), sp<Client>::fromExisting(this), name.c_str(),
                           static_cast<uint32_t>(flags), std::move(metadata));
    args.parentHandle = parent;
    const status_t status = mFlinger->createLayer(args, *outResult);
    return binderStatusFromStatusT(status);
}

createSurface函数主要是通过Surface的参数构造一个创建Layer的参数,然后通过它和mFlinger的createLayer服务创建一个新的Layer。因此在这里多了一个新的概念Layer。Surface是定义在应用程序接口层,它用于存储应用程序绘制内容Surface定义在SurfaceFlinger内部,它用于显示内容并参与图形合成。

2 SurfaceFlinger::createLayer函数

status_t SurfaceFlinger::createLayer(LayerCreationArgs& args, gui::CreateSurfaceResult& outResult) {
    status_t result = NO_ERROR;

    sp<Layer> layer;

    switch (args.flags & ISurfaceComposerClient::eFXSurfaceMask) {
        case ISurfaceComposerClient::eFXSurfaceBufferQueue:
        case ISurfaceComposerClient::eFXSurfaceContainer:
        case ISurfaceComposerClient::eFXSurfaceBufferState:
            args.flags |= ISurfaceComposerClient::eNoColorFill;
            FMT_FALLTHROUGH;
        case ISurfaceComposerClient::eFXSurfaceEffect: {
            result = createBufferStateLayer(args, &outResult.handle, &layer);
            std::atomic<int32_t>* pendingBufferCounter = layer->getPendingBufferCounter();
            if (pendingBufferCounter) {
                std::string counterName = layer->getPendingBufferCounterName();
                mBufferCountTracker.add(outResult.handle->localBinder(), counterName,
                                        pendingBufferCounter);
            }
        } break;
        default:
            result = BAD_VALUE;
            break;
    }

    if (result != NO_ERROR) {
        return result;
    }

    args.addToRoot = args.addToRoot && callingThreadHasUnscopedSurfaceFlingerAccess();
    // We can safely promote the parent layer in binder thread because we have a strong reference
    // to the layer's handle inside this scope.
    sp<Layer> parent = LayerHandle::getLayer(args.parentHandle.promote());
    if (args.parentHandle != nullptr && parent == nullptr) {
        ALOGE("Invalid parent handle %p", args.parentHandle.promote().get());
        args.addToRoot = false;
    }

    uint32_t outTransformHint;
    result = addClientLayer(args, outResult.handle, layer, parent, &outTransformHint);
    if (result != NO_ERROR) {
        return result;
    }

    outResult.transformHint = static_cast<int32_t>(outTransformHint);
    outResult.layerId = layer->sequence;
    outResult.layerName = String16(layer->getDebugName());
    return result;
}

代码首先会根据不同的flag进入不同的case,根据引言部分的代码,我们传入的flag是eFXSurfaceBufferState,因此我们进入的case会将ISurfaceComposerClient::eNoColorFill 标志位添加到 args.flags中,使得后续创建的 Layer 具备 "禁用颜色填充" 的特性。

执行完该case后,由于没有break标记,意味着代码会继续执行后续的case。因此程序会执行createBufferStateLayer函数:

status_t SurfaceFlinger::createBufferStateLayer(LayerCreationArgs& args, sp<IBinder>* handle,
                                                sp<Layer>* outLayer) {
    args.textureName = getNewTexture();
    *outLayer = getFactory().createBufferStateLayer(args);
    *handle = (*outLayer)->getHandle();
    return NO_ERROR;
}

该函数首先调用SurfaceFlinger的getNewTexture方法,它会为新的Layer分配一个Texture(OpenGL里面的纹理的概念,也就是我们常说的贴图),然后把它的name保存到arg参数里面。

然后获取surfaceflinger::Factory类的实例。surfaceflinger::Factory是一个工厂类,专门用于创建不同类型的Layer。调用工厂方法createBufferStateLayer,根据传入的参数创建一个BufferStateLayer 实例,然后赋值给传入的outLayer参数。

sp<Layer> DefaultFactory::createBufferStateLayer(const LayerCreationArgs& args) {
    return sp<Layer>::make(args);
}

在SurfaceFlinger的初始化过程中使用的DefaultFactory,因此调用的也是DefaultFactory的createBufferStateLayer函数。该函数实际上就是根据参数创建一个Layer实例。

创建完Layer后,则开始获取其内部pending buffer counter 计数器指针,它是用于该Layer进行计数的。用于实现流式媒体的同步与调度(例如视频播放或屏幕刷新)。如果该Layer有未被处理的buffer,则将计数器名称和指针注册到 mBufferCountTracker,用于监控和管理。

switch-case部分代码分析完毕了,接下来继续往下看:

    // 检查是否需要添加到根Layer
    args.addToRoot = args.addToRoot && callingThreadHasUnscopedSurfaceFlingerAccess();
    
    // 获取父Layer以及验证其有效性
    sp<Layer> parent = LayerHandle::getLayer(args.parentHandle.promote());
    if (args.parentHandle != nullptr && parent == nullptr) {
        ALOGE("Invalid parent handle %p", args.parentHandle.promote().get());
        args.addToRoot = false;
    }

    // 将新创建的 Layer 添加到 Client 的 Layer 树中
    uint32_t outTransformHint;
    result = addClientLayer(args, outResult.handle, layer, parent, &outTransformHint);
    if (result != NO_ERROR) {
        return result;
    }

    // 构造Result
    outResult.transformHint = static_cast<int32_t>(outTransformHint);
    outResult.layerId = layer->sequence;
    outResult.layerName = String16(layer->getDebugName());
    return result;

根据上面的分析总结一下SurfaceFlinger::createLayer函数的工作就是创建一个新的Layer并且将其加入到Layer树中。

3 new SurfaceControl

这时候可以回到SurfaceComposerClient::createSurfaceChecked函数中了,我们将result作为参数new了一个新的SurfaceControl。

if (err == NO_ERROR) {
            *outSurface = new SurfaceControl(this, result.handle, result.layerId,
                                             toString(result.layerName), w, h, format,
                                             result.transformHint, flags);
        }

4 总结

从上面的分析中我们可以得出这样的结论:应用层创建一个Surface的过程中,会创建一个新的Layer,并且将该Layer加入到当前Clinet的Layer树中。最后根据Layer的创建结果构造一个SurfaceControl实例来专门管理这个Surface。以上过程可以总结成如下示意图:

image.png