图解Linux DRM框架:手把手带你理解plane结构体与API(以4.14内核为例)

张开发
2026/4/8 4:14:59 15 分钟阅读

分享文章

图解Linux DRM框架:手把手带你理解plane结构体与API(以4.14内核为例)
图解Linux DRM框架从图层管理视角理解plane结构体与API想象一下你正在使用一款专业的视频编辑软件。当你将多个视频轨道、文字标题和特效叠加在一起时软件是如何确保它们正确合成最终画面的这与Linux内核中的DRMDirect Rendering Manager框架处理图形平面的方式惊人地相似。本文将带你从图层管理器的视角深入理解DRM框架中plane结构体的设计哲学与实现细节。1. DRM Plane图形世界的图层管理系统在图形显示系统中plane平面可以理解为独立的图像层。就像Photoshop中的图层每个plane可以承载不同的图像内容如视频、UI元素、光标拥有独立的格式和分辨率ARGB8888、NV12等被动态组合到显示管道CRTC上支持变换操作旋转、缩放、alpha混合// 典型的plane类型定义include/drm/drm_plane.h enum drm_plane_type { DRM_PLANE_TYPE_OVERLAY, // 叠加层如视频播放 DRM_PLANE_TYPE_PRIMARY, // 主显示层桌面环境 DRM_PLANE_TYPE_CURSOR, // 光标层 };提示现代GPU通常支持多个overlay plane这能显著降低合成操作的功耗。1.1 plane与显示管道的关联plane不是孤立存在的它必须通过CRTC显示控制器最终输出到屏幕。possible_crtcs字段用位掩码表示该plane可以绑定到哪些CRTCuint32_t possible_crtcs; // 例如0x3表示可绑定到CRTC 0和1这种设计带来了硬件资源管理的灵活性多显示器支持一个plane可以在不同时间被不同显示器使用热插拔处理当某个CRTC不可用时plane可以快速切换到备用CRTC性能优化避免将过多plane绑定到同一个CRTC导致带宽瓶颈2. 解码plane的核心数据结构2.1 格式支持plane的语言能力就像翻译需要掌握多种语言plane需要声明支持的像素格式。format_types和format_count字段定义了这种能力uint32_t *format_types; // 格式数组指针 unsigned int format_count; // 支持的格式数量常见的DRM格式定义include/uapi/drm/drm_fourcc.h格式宏描述典型用途DRM_FORMAT_ARGB888832位带alpha通道UI元素、窗口管理DRM_FORMAT_NV12YUV420半平面格式视频解码DRM_FORMAT_RGB56516位RGB压缩格式嵌入式设备2.2 状态管理atomic与legacy模式对比DRM框架经历了从legacy到atomic的架构演进这在plane结构体中体现明显// Legacy模式直接访问的字段 struct drm_crtc *crtc; // 当前绑定的CRTC struct drm_framebuffer *fb; // 当前显示的帧缓冲 // Atomic模式使用的状态容器 struct drm_plane_state *state; // 包含所有原子状态关键区别Legacy模式直接修改字段可能导致中间状态不一致Atomic模式先准备完整的状态集合再原子提交注意现代驱动都应实现atomic APIlegacy字段仅用于向后兼容。3. 实战初始化一个DRM plane3.1 drm_universal_plane_init详解这是创建plane的核心API我们拆解其关键步骤int drm_universal_plane_init( struct drm_device *dev, // 所属DRM设备 struct drm_plane *plane, // 要初始化的plane uint32_t possible_crtcs, // 可绑定的CRTC掩码 const struct drm_plane_funcs *funcs, // 操作函数集 const uint32_t *formats, // 支持的格式数组 unsigned int format_count, // 格式数量 const uint64_t *format_modifiers, // 格式修饰符 enum drm_plane_type type, // plane类型 const char *name, ...) // 可定制的名称 { // 1. 分配模式对象ID ret drm_mode_object_add(dev, plane-base, DRM_MODE_OBJECT_PLANE); // 2. 初始化互斥锁 drm_modeset_lock_init(plane-mutex); // 3. 复制格式信息 plane-format_types kmalloc_array(format_count, sizeof(uint32_t), GFP_KERNEL); memcpy(plane-format_types, formats, format_count * sizeof(uint32_t)); // 4. 设置基本属性 plane-possible_crtcs possible_crtcs; plane-type type; // 5. 添加到全局plane列表 list_add_tail(plane-head, config-plane_list); // 6. 为atomic模式创建属性 if (drm_core_check_feature(dev, DRIVER_ATOMIC)) { drm_object_attach_property(plane-base, config-prop_fb_id, 0); // ...其他属性初始化 } }关键内存管理点格式数组需要动态分配kmalloc_array修饰符数组可选用于支持压缩/平铺格式名称字符串使用kvasprintf实现可变参数格式化3.2 操作函数集plane的技能表drm_plane_funcs定义了驱动需要实现的核心操作struct drm_plane_funcs { int (*update_plane)(...); // 更新plane内容 int (*disable_plane)(...); // 禁用plane void (*destroy)(...); // 资源清理 // Atomic模式专用 struct drm_plane_state *(*atomic_duplicate_state)(...); void (*atomic_destroy_state)(...); int (*atomic_set_property)(...); };典型实现模式基础函数直接操作硬件寄存器Atomic函数通常通过drm_atomic_helper_*辅助函数实现4. 深入plane状态管理4.1 drm_plane_state解析这是atomic模式下的核心数据结构包含完整的plane状态struct drm_plane_state { struct drm_plane *plane; // 所属plane // 显示属性 struct drm_crtc *crtc; // 目标CRTC struct drm_framebuffer *fb; // 要显示的帧缓冲 // 源/目标矩形 uint32_t src_x, src_y; // 源区域偏移 uint32_t src_w, src_h; // 源区域尺寸 int32_t crtc_x, crtc_y; // 显示位置 uint32_t crtc_w, crtc_h; // 显示尺寸 // 变换属性 unsigned int rotation; // 旋转角度 uint16_t alpha; // 透明度 };状态流转示例应用准备新的帧缓冲和参数创建或复制现有的plane状态修改状态中的各个字段通过atomic commit提交所有变更内核验证并应用新状态4.2 辅助函数drm_plane_helper_funcs这些函数填补了核心框架与硬件操作之间的空白struct drm_plane_helper_funcs { int (*prepare_fb)(...); // 显示前的准备工作 void (*cleanup_fb)(...); // 清理工作 int (*atomic_check)(...); // 状态验证 void (*atomic_update)(...);// 实际硬件更新 };prepare_fb的典型任务建立DMA映射等待缓冲区可用fence同步缓存管理如颜色空间转换表在RK3399平台的实现中prepare_fb会处理ARM Mali GPU的特定需求static int rockchip_drm_plane_prepare_fb(...) { // 1. 等待DMA缓冲区就绪 if (new_state-fence) ret dma_fence_wait(new_state-fence, true); // 2. 为Mali GPU准备缓存 if (rk_obj-flags ROCKCHIP_BO_CACHABLE) drm_gem_cma_sync_data(new_state-fb-obj[0]); // 3. 处理AFBC压缩格式 if (modifier_is_afbc(modifier)) setup_afbc_headers(...); }理解DRM plane的工作机制就像掌握了一个高性能图形合成引擎的核心原理。从简单的帧缓冲显示到复杂的多层视频合成这套系统支撑着现代Linux图形栈的方方面面。

更多文章