DRM_PlanesCompositor - SweerItTer/utilsCore GitHub Wiki
PlanesCompositor 是 utilsCore DRM 模块的核心类,提供 DRM Plane 的组合和原子提交功能,用于多图层合成显示。
- 管理 DRM Plane 的添加和移除
- 提供图层属性更新
- 执行原子提交(atomic commit)
- 支持 Fence 同步机制
- 多图层合成显示
- 视频叠加
- UI 层显示
- 硬件加速的图层合成
- 依赖: DeviceController, DrmLayer
- 被依赖: DisplayManager, VisionPipeline 等上层模块
PlanesCompositor 是 DRM Plane 组合器的封装类,提供:
- 图层管理(添加、移除、更新)
- 原子提交
- Fence 同步
- 属性配置
- 组合模式: 管理多个 DrmLayer
- 命令模式: 原子提交请求
static std::unique_ptr<PlanesCompositor> create();参数说明: 无
返回值:
- 成功: 返回 PlanesCompositor 的智能指针
- 失败: 抛出异常
所有权归属:
- 返回的 unique_ptr 持有 PlanesCompositor 的所有权
- PlanesCompositor 自身不持有 DeviceController 的所有权
注意事项:
- 静态工厂方法
- 每次调用创建新实例
- 单线程使用或外部同步
使用例程:
// 创建组合器
auto compositor = PlanesCompositor::create();bool addLayer(const DrmLayerPtr& layer);参数说明:
-
layer(输入): DrmLayer 智能指针(shared_ptr)
返回值:
-
true: 成功 -
false: 失败
所有权归属:
- DrmLayer 的所有权由调用者管理
- PlanesCompositor 不持有 DrmLayer 的所有权
注意事项:
- 使用 shared_ptr 引用(不转移所有权)
- 图层会被添加到组合器中
- 需要调用
commit()才能生效
使用例程:
// 创建图层
auto layer = std::make_shared<DrmLayer>(buffers, 2);
// 添加图层
if (compositor->addLayer(layer)) {
printf("Layer added successfully\n");
}
// 提交变更
int fence;
compositor->commit(fence);void removeLayer(const DrmLayerPtr& layer);参数说明:
-
layer(输入): DrmLayer 智能指针
返回值: 无
所有权归属:
- 无所有权转移
注意事项:
- 从组合器中移除图层
- 需要调用
commit()才能生效 - 如果图层不存在,不做任何操作
使用例程:
// 移除图层
compositor->removeLayer(layer);
// 提交变更
int fence;
compositor->commit(fence);void removeAllLayer();参数说明: 无
返回值: 无
注意事项:
- 移除所有图层
- 需要调用
commit()才能生效
bool updateLayer(const DrmLayerPtr& layer);参数说明:
-
layer(输入): DrmLayer 智能指针
返回值:
-
true: 成功 -
false: 失败
注意事项:
- 更新图层的属性
- 需要调用
commit()才能生效 - 如果图层不存在,返回 false
bool updatePropertyForLayer(const DrmLayerPtr& layer);参数说明:
-
layer(输入): DrmLayer 智能指针
返回值:
-
true: 成功 -
false: 失败
注意事项:
- 更新图层的 DRM 属性
- 需要调用
commit()才能生效
void updateLayer(const DrmLayerPtr& layer, const uint32_t fb_id);参数说明:
-
layer(输入): DrmLayer 智能指针 -
fb_id(输入): Framebuffer ID
返回值: 无
注意事项:
- 更新图层的 framebuffer ID
- 需要调用
commit()才能生效
int commit(int& fence);参数说明:
-
fence(输出): 输出参数,接收 fence 文件描述符
返回值:
- 成功: 返回 0
- 失败: 返回 -1
所有权归属:
- fence 的所有权由调用者管理
- 返回的 fence fd 可以传递给 FenceWatcher
注意事项:
- 执行 DRM 原子提交
- 所有变更一次性生效
- 返回的 fence 用于同步
- 阻塞操作,等待提交完成
使用例程:
// 添加图层
auto layer = std::make_shared<DrmLayer>(buffers, 2);
compositor->addLayer(layer);
// 更新图层属性
DrmLayer::LayerProperties props;
props.crtcwidth_ = 1920;
props.crtcheight_ = 1080;
props.srcwidth_ = 1920;
props.srcheight_ = 1080;
props.crtcX_ = 0;
props.crtcY_ = 0;
props.zOrder_ = 0;
props.alpha_ = 1.0f;
layer->setProperty(props);
// 提交所有变更
int fence;
int ret = compositor->commit(fence);
if (ret == 0) {
// 监控 fence
FenceWatcher::instance().watchFence(fence, [layer]() {
layer->onFenceSignaled();
});
}struct PlaneProperty {
uint32_t property_crtc_id = 0;
uint32_t property_fb_id = 0;
uint32_t property_crtc_x = 0;
uint32_t property_crtc_y = 0;
uint32_t property_crtc_w = 0;
uint32_t property_crtc_h = 0;
uint32_t property_src_x = 0;
uintuint32_t property_src_y = 0;
uint32_t property_src_w = 0;
uint32_t property_src_h = 0;
uint32_t property_zpos = 0;
};
struct LayerProperty {
uint32_t plane_id = 0;
uint32_t crtc_id = 0;
uint32_t fb_id = 0;
uint32_t crtc_x = 0;
uint32_t crtc_y = 0;
uint32_t crtc_w = 0;
uint32_t crtc_h = 0;
uint32_t src_x = 0;
uint32_t src_y = 0;
uint32_t src_w = 0;
uint32_t src_h = 0;
float alpha = 1.0f;
uint32_t zpos = 0;
int type = 0;
};
struct PropertyCache {
PlaneProperty planeProperty;
LayerProperty layerProperty;
};- 使用
std::unordered_map<DrmLayerPtr, PropertyCache, SharedPtrHash, SharedPtrEqual>管理图层 - 自定义哈希和比较函数,支持 shared_ptr 作为键
- 使用互斥锁保护图层操作
// 创建组合器
auto compositor = PlanesCompositor::create();
// 准备缓冲区
std::vector<DmaBufferPtr> buffers;
buffers.push_back(dmaBufferY);
buffers.push_back(dmaBufferUV);
// 创建图层
auto layer = std::make_shared<DrmLayer>(buffers, 2);
// 设置属性
DrmLayer::LayerProperties props;
props.type_ = 0; // overlay
props.crtcwidth_ = 1920;
props.crtcheight_ = 1080;
props.srcwidth_ = 1920;
props.srcheight_ = 1080;
props.crtcX_ = 0;
props.crtcY_ = 0;
props.zOrder_ = 0;
props.alpha_ = 1.0f;
layer->setProperty(props);
// 添加图层
compositor->addLayer(layer);
// 提交
int fence;
compositor->commit(fence);
// 监控 fence
FenceWatcher::instance().watchFence(fence, [layer]() {
layer->onFenceSignaled();
});// src/pipeline/displayManager.cpp:229
void DisplayManager::Impl::mainLoop() {
int drmFence{ -1 };
while (running.load()) {
// ...
// 合成并提交
drmFence = -1;
if (compositor) compositor->commit(drmFence);
FenceWatcher::instance().watchFence(drmFence, [this]() {
for (auto& pf : planesVector) {
pf.layer->onFenceSignaled();
}
cv.notify_one();
});
}
}-
构造方式: 使用静态工厂方法
create()创建,不是构造函数 -
图层引用: 使用
shared_ptr引用图层,不转移所有权 -
commit 必要性: 所有变更都需要调用
commit()才能生效 - Fence 同步: commit() 返回的 fence 需要使用 FenceWatcher 监控
- 线程安全: 多线程操作需要外部同步
- 图层复用: 同一个图层可以多次更新和提交
- 原子提交: commit() 是原子操作,所有变更一次性生效
- 错误处理: 失败时返回 -1,需要检查返回值
- DeviceController - DRM 设备控制器
- DrmLayer - DRM 图层管理
- FenceWatcher - Fence 监控
- DRM 模块总览