DRM_DrmLayer - SweerItTer/utilsCore GitHub Wiki
DrmLayer 是 utilsCore DRM 模块的核心类,提供 DRM 图层管理功能,包括图层属性设置、缓冲区更新和 framebuffer 缓存管理。
- 管理 DRM 图层属性
- 处理缓冲区更新
- Framebuffer 缓存管理
- Fence 同步机制
- 图层生命周期管理
- 多图层合成
- 硬件加速显示
- 视频渲染
- UI 渲染
- 依赖: DRM 库、DMA-BUF
- 被依赖: DisplayManager、UIRenderer 等模块
DrmLayer 是 DRM 图层的封装类,提供:
- 图层属性管理(位置、大小、透明度等)
- 缓冲区绑定和更新
- Framebuffer 缓存管理(避免频繁创建/销毁)
- Fence 同步
- 回调通知机制
- 观察者模式: 回调通知图层状态
- RAII: 自动管理资源
- 缓存模式: Framebuffer 复用
enum class planeType {
overlay = 0, // 覆盖层
primary = 1, // 主层
cursor = 2 // 光标层
};LayerProperties 定义 DRM 图层的所有属性。
struct LayerProperties {
int type_ = 0; // 图层类型 (0=overlay, 1=primary, 2=cursor)
uint32_t plane_id_ = -1; // DRM plane ID
uint32_t crtc_id_ = -1; // 绑定的 CRTC ID
uint32_t fb_id_ = 0; // 绑定的 framebuffer ID
// 源图像区域
uint32_t srcX_ = 0; // 源图像 X 坐标
uint32_t srcY_ = 0; // 源图像 Y 坐标
uint32_t srcwidth_ = 0; // 源图像宽度
uint32_t srcheight_ = 0; // 源图像高度
// 显示区域 (CRTC 空间)
uint32_t crtcX_ = 0; // 显示区域 X 坐标
uint32_t crtcY_ = 0; // 显示区域 Y 坐标
uint32_t crtcwidth_ = 0; // 显示区域宽度
uint32_t crtcheight_ = 0; // 显示区域高度
uint32_t zOrder_ = 0; // 图层 Z 顺序
float alpha_ = 1.0f; // 透明度
};| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
type_ |
int |
0 | 图层类型 (0=overlay, 1=primary, 2=cursor) |
plane_id_ |
uint32_t |
-1 | DRM plane ID |
crtc_id_ |
uint32_t |
-1 | 绑定的 CRTC ID |
fb_id_ |
uint32_t |
0 | 绑定的 framebuffer ID |
srcX_ |
uint32_t |
0 | 源图像 X 坐标 |
srcY_ |
uint32_t |
0 | 源图像 Y 坐标 |
srcwidth_ |
uint32_t |
0 | 源图像宽度 |
srcheight_ |
uint32_t |
0 | 源图像高度 |
crtcX_ |
uint32_t |
0 | 显示区域 X 坐标 |
crtcY_ |
uint32_t |
0 | 显示区域 Y 坐标 |
crtcwidth_ |
uint32_t |
0 | 显示区域宽度 |
crtcheight_ |
uint32_t |
0 | 显示区域高度 |
zOrder_ |
uint32_t |
0 | 图层 Z 顺序 |
alpha_ |
float |
1.0f | 透明度 (0.0-1.0) |
using PropertyValue = SimpleVariant<int, uint32_t, float>;用于设置和获取单个属性值。
using updateLayerCallback = std::function<void(const std::shared_ptr<DrmLayer>&, uint32_t)>;图层更新回调函数类型。
explicit DrmLayer(std::vector<DmaBufferPtr> buffers, size_t cacheSize);
DrmLayer() = default;
~DrmLayer();参数说明:
-
buffers(输入): DmaBuffer 指针列表 -
cacheSize(输入): Framebuffer 缓存大小
返回值: 无
所有权归属:
- DrmLayer 拥有 DRM 资源的所有权
- buffers 的所有权由调用者管理
注意事项:
- 构造时初始化图层和 framebuffer 缓存
- cacheSize 控制 framebuffer 的复用数量
- 析构时自动清理所有资源
使用例程:
// 创建图层
std::vector<DmaBufferPtr> buffers;
buffers.push_back(dmaBufferY);
buffers.push_back(dmaBufferUV);
auto layer = std::make_shared<DrmLayer>(buffers, 2);void setUpdateCallback(updateLayerCallback updatelayer)参数说明:
-
updatelayer(输入): 回调函数
返回值: 无
所有权归属: 无
注意事项:
- 图层更新时会触发回调
- 回调参数:图层指针和 framebuffer ID
void setProperty(const LayerProperties& props)参数说明:
-
props(输入): 图层属性结构体
返回值: 无
所有权归属: 无
注意事项:
- 更新整个图层属性
- 需要调用 commit 才能生效
void setProperty(const std::string& name, PropertyValue value)参数说明:
-
name(输入): 属性名称 -
value(输入): 属性值
返回值: 无
注意事项:
- 支持的属性名称:type, planeId, crtcId, fbId, x, y, w, h, crtcX, crtcY, crtcW, crtcH, zOrder, alpha
- 未知属性会抛出 std::invalid_argument
使用例程:
layer->setProperty("width", static_cast<uint32_t>(1920));
layer->setProperty("alpha", 0.8f);PropertyValue getProperty(const std::string& name) const参数说明:
-
name(输入): 属性名称
返回值: 属性值
注意事项:
- 使用 std::get() 提取具体类型
- 未知属性会抛出 std::invalid_argument
使用例程:
auto width = std::get<uint32_t>(layer->getProperty("width"));
auto alpha = std::get<float>(layer->getProperty("alpha"));void updateBuffer(std::vector<DmaBufferPtr> buffers)参数说明:
-
buffers(输入): 新的 DmaBuffer 列表
返回值: 无
所有权归属:
- buffers 的所有权由调用者管理
注意事项:
- 更新显示缓冲区
- 会触发 setUpdateCallback 回调
void onFenceSignaled()参数说明: 无
返回值: 无
注意事项:
- Fence 信号到达时调用
- 回收旧的 framebuffer
- 采用多级缓冲避免直接销毁 framebuffer
- 使用
std::deque<uint32_t>缓存 framebuffer ID - 通过
cacheSize_控制缓存大小 -
recycleOldFbs(size_t keep)回收旧的 framebuffer - 避免频繁创建/销毁 framebuffer
-
propertySetters_: 属性设置器映射表 -
propertyGetters_: 属性获取器映射表 - 支持通过字符串名称访问属性
// 准备缓冲区
std::vector<DmaBufferPtr> buffers;
buffers.push_back(dmaBufferY);
buffers.push_back(dmaBufferUV);
// 创建图层,缓存 2 个 framebuffer
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.zOrder_ = 0;
props.alpha_ = 1.0f;
layer->setProperty(props);// 准备新缓冲区
std::vector<DmaBufferPtr> newBuffers;
newBuffers.push_back(newDmaBufferY);
newBuffers.push_back(newDmaBufferUV);
// 更新缓冲区
layer->updateBuffer(newBuffers);// Fence 信号到达时
FenceWatcher::instance().watchFence(drmFence, [layer]() {
layer->onFenceSignaled();
// 通知继续
});- Framebuffer 缓存: cacheSize 应根据使用情况设置
- 属性映射: 属性名称需要映射到正确的字段
- Fence 同步: onFenceSignaled() 由外部调用
- 内存管理: DmaBuffer 的所有权由调用者管理
- 线程安全: Framebuffer 缓存操作使用互斥锁保护
- 回调机制: setUpdateCallback() 需要在使用前设置
- DeviceController - DRM 设备控制器
- PlanesCompositor - DRM 平面合成
- DmaBuffer - DMA-BUF 缓冲区
- DRM 模块总览