DRM_DrmLayer - SweerItTer/utilsCore GitHub Wiki

DrmLayer API 文档

概述

DrmLayer 是 utilsCore DRM 模块的核心类,提供 DRM 图层管理功能,包括图层属性设置、缓冲区更新和 framebuffer 缓存管理。

职责

  • 管理 DRM 图层属性
  • 处理缓冲区更新
  • Framebuffer 缓存管理
  • Fence 同步机制
  • 图层生命周期管理

适用场景

  • 多图层合成
  • 硬件加速显示
  • 视频渲染
  • UI 渲染

依赖关系

  • 依赖: DRM 库、DMA-BUF
  • 被依赖: DisplayManager、UIRenderer 等模块

类分析

DrmLayer 类

职责与用途

DrmLayer 是 DRM 图层的封装类,提供:

  • 图层属性管理(位置、大小、透明度等)
  • 缓冲区绑定和更新
  • Framebuffer 缓存管理(避免频繁创建/销毁)
  • Fence 同步
  • 回调通知机制

设计模式

  • 观察者模式: 回调通知图层状态
  • RAII: 自动管理资源
  • 缓存模式: Framebuffer 复用

枚举类型

planeType

enum class planeType {
    overlay = 0,  // 覆盖层
    primary = 1,  // 主层
    cursor  = 2   // 光标层
};

结构体分析

LayerProperties 结构体

职责与用途

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)

类型定义

PropertyValue

using PropertyValue = SimpleVariant<int, uint32_t, float>;

用于设置和获取单个属性值。

updateLayerCallback

using updateLayerCallback = std::function<void(const std::shared_ptr<DrmLayer>&, uint32_t)>;

图层更新回调函数类型。


公共 API 方法

构造函数

explicit DrmLayer(std::vector<DmaBufferPtr> buffers, size_t cacheSize);
DrmLayer() = default;
~DrmLayer();

参数说明:

  • buffers (输入): DmaBuffer 指针列表
  • cacheSize (输入): Framebuffer 缓存大小

返回值: 无

所有权归属:

  • DrmLayer 拥有 DRM 资源的所有权
  • buffers 的所有权由调用者管理

注意事项:

  1. 构造时初始化图层和 framebuffer 缓存
  2. cacheSize 控制 framebuffer 的复用数量
  3. 析构时自动清理所有资源

使用例程:

// 创建图层
std::vector<DmaBufferPtr> buffers;
buffers.push_back(dmaBufferY);
buffers.push_back(dmaBufferUV);

auto layer = std::make_shared<DrmLayer>(buffers, 2);

setUpdateCallback() - 设置更新回调

void setUpdateCallback(updateLayerCallback updatelayer)

参数说明:

  • updatelayer (输入): 回调函数

返回值: 无

所有权归属: 无

注意事项:

  1. 图层更新时会触发回调
  2. 回调参数:图层指针和 framebuffer ID

setProperty() - 设置图层属性(整个结构体)

void setProperty(const LayerProperties& props)

参数说明:

  • props (输入): 图层属性结构体

返回值: 无

所有权归属: 无

注意事项:

  1. 更新整个图层属性
  2. 需要调用 commit 才能生效

setProperty() - 设置单个属性

void setProperty(const std::string& name, PropertyValue value)

参数说明:

  • name (输入): 属性名称
  • value (输入): 属性值

返回值: 无

注意事项:

  1. 支持的属性名称:type, planeId, crtcId, fbId, x, y, w, h, crtcX, crtcY, crtcW, crtcH, zOrder, alpha
  2. 未知属性会抛出 std::invalid_argument

使用例程:

layer->setProperty("width", static_cast<uint32_t>(1920));
layer->setProperty("alpha", 0.8f);

getProperty() - 获取属性

PropertyValue getProperty(const std::string& name) const

参数说明:

  • name (输入): 属性名称

返回值: 属性值

注意事项:

  1. 使用 std::get() 提取具体类型
  2. 未知属性会抛出 std::invalid_argument

使用例程:

auto width = std::get<uint32_t>(layer->getProperty("width"));
auto alpha = std::get<float>(layer->getProperty("alpha"));

updateBuffer() - 更新缓冲区

void updateBuffer(std::vector<DmaBufferPtr> buffers)

参数说明:

  • buffers (输入): 新的 DmaBuffer 列表

返回值: 无

所有权归属:

  • buffers 的所有权由调用者管理

注意事项:

  1. 更新显示缓冲区
  2. 会触发 setUpdateCallback 回调

onFenceSignaled() - Fence 信号处理

void onFenceSignaled()

参数说明: 无

返回值: 无

注意事项:

  1. Fence 信号到达时调用
  2. 回收旧的 framebuffer
  3. 采用多级缓冲避免直接销毁 framebuffer

内部实现

Framebuffer 缓存管理

  • 使用 std::deque<uint32_t> 缓存 framebuffer ID
  • 通过 cacheSize_ 控制缓存大小
  • recycleOldFbs(size_t keep) 回收旧的 framebuffer
  • 避免频繁创建/销毁 framebuffer

属性访问器

  • propertySetters_: 属性设置器映射表
  • propertyGetters_: 属性获取器映射表
  • 支持通过字符串名称访问属性

典型使用场景

场景 1: 创建图层

// 准备缓冲区
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);

场景 2: 更新缓冲区

// 准备新缓冲区
std::vector<DmaBufferPtr> newBuffers;
newBuffers.push_back(newDmaBufferY);
newBuffers.push_back(newDmaBufferUV);

// 更新缓冲区
layer->updateBuffer(newBuffers);

场景 3: Fence 同步

// Fence 信号到达时
FenceWatcher::instance().watchFence(drmFence, [layer]() {
    layer->onFenceSignaled();
    // 通知继续
});

注意事项

  1. Framebuffer 缓存: cacheSize 应根据使用情况设置
  2. 属性映射: 属性名称需要映射到正确的字段
  3. Fence 同步: onFenceSignaled() 由外部调用
  4. 内存管理: DmaBuffer 的所有权由调用者管理
  5. 线程安全: Framebuffer 缓存操作使用互斥锁保护
  6. 回调机制: setUpdateCallback() 需要在使用前设置

相关文档


参考资料

⚠️ **GitHub.com Fallback** ⚠️