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);
这行代码调用了 SurfaceComposerClient 的 createSurface 方法,该方法用于创建一个新的 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函数的工作主要有两个:
- 通过
mClient调用createSurface服务来创建一个Surface,结果保存在传入的result中; - 使用
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。以上过程可以总结成如下示意图: