3. PLANE核心概念:PLANE的作用、帧缓冲绑定、像素格式、Alpha混合、Z-order排序
在DRM/KMS显示子系统中,PLANE(图层/平面)是构成最终显示画面的基本元素。理解PLANE的核心概念,是掌握多图层显示驱动开发的基石。本章将深入剖析PLANE的作用、与帧缓冲(FB)的绑定关系、像素格式、Alpha混合机制以及Z-order排序规则。
3.1 PLANE的作用与分类
PLANE在硬件上对应显示控制器中的一个独立图层。每个PLANE可以承载一个独立的帧缓冲(Framebuffer),并拥有自己的位置、尺寸、像素格式和透明度属性。CRTC(显示控制器定时器)负责将多个PLANE按照特定的顺序(Z-order)叠加混合,最终生成一帧完整的画面输出到显示器。
根据功能和性能,PLANE通常分为以下几类:
| 类型 | 硬件特性 | 典型用途 | 数量 |
|---|---|---|---|
| 主图层 (Primary Plane) | 必须存在,通常支持扫描输出,与CRTC直接关联 | 桌面背景、视频播放、游戏主画面 | 至少1个 |
| 光标图层 (Cursor Plane) | 硬件光标,尺寸小(通常64x64),更新快,无需重新配置整个管线 | 鼠标指针、光标 | 0或1个 |
| 覆盖图层 (Overlay Plane) | 可选的额外图层,支持独立缩放、旋转、色彩空间转换 | 画中画、字幕、UI元素、摄像头预览 | 0或多个 |
3.2 帧缓冲绑定(Framebuffer Binding)
PLANE本身不存储像素数据,它只是一个“窗口”。PLANE通过绑定一个帧缓冲(Framebuffer,FB)来获取实际的像素内容。帧缓冲是内存中的一块区域,存储了渲染好的图像数据。
绑定过程通过drmModeSetPlane或atomic接口完成,核心参数包括:
- plane_id:目标PLANE的ID。
- fb_id:要绑定的帧缓冲的ID。
- crtc_id:目标CRTC的ID。
- src_x, src_y, src_w, src_h:源裁剪区域(以16.16固定点格式表示)。
- crtc_x, crtc_y, crtc_w, crtc_h:目标显示区域(以像素为单位)。
// 用户空间通过libdrm调用示例
int ret = drmModeSetPlane(fd, plane_id, crtc_id, fb_id, flags,
crtc_x, crtc_y, crtc_w, crtc_h,
src_x << 16, src_y << 16, src_w << 16, src_h << 16);
if (ret) {
// 错误处理
printf("Failed to set plane: %s\n", strerror(errno));
}
3.3 像素格式(Pixel Format)
像素格式定义了帧缓冲中每个像素的数据排列方式。DRM子系统通过四字符码(FourCC)来标识像素格式。PLANE支持的像素格式列表是驱动初始化时注册的,用户空间必须查询并选择PLANE支持的格式。
常见的像素格式分类如下:
| 分类 | FourCC | 描述 | 位深 |
|---|---|---|---|
| RGB 打包格式 | DRM_FORMAT_XRGB8888 | 32位,无Alpha通道,RGB各8位 | 32 |
| RGB 打包格式 | DRM_FORMAT_ARGB8888 | 32位,含Alpha通道,RGB各8位 | 32 |
| RGB 打包格式 | DRM_FORMAT_RGB565 | 16位,R:5 G:6 B:5 | 16 |
| YUV 半平面格式 | DRM_FORMAT_NV12 | Y平面 + UV交错平面,视频编码常用 | 12 |
| YUV 平面格式 | DRM_FORMAT_YUV420 | Y、U、V三个独立平面 | 12 |
| 压缩格式 | DRM_FORMAT_MODIFIER | 通过修饰符(Modifier)指定压缩方式,如AFBC、DCC | 可变 |
plane->format_modifiers中正确声明支持的格式列表,否则用户空间的合成器(如Weston、Wayland)将无法正确使用该PLANE。
3.4 Alpha混合(Alpha Blending)
当多个PLANE叠加时,Alpha混合决定了上层像素如何与下层像素融合。DRM/KMS支持两种主要的Alpha模式:
- 全局Alpha(Plane Alpha):整个PLANE使用一个统一的Alpha值,对所有像素生效。
- 逐像素Alpha(Per-Pixel Alpha):每个像素使用其自身的Alpha通道值(如ARGB8888格式中的A分量)。
混合公式(使用预乘Alpha):
// 假设上层像素为 S(源),下层像素为 D(目标),Alpha值为 A
// 预乘Alpha混合公式
Output = S + D * (1 - A)
// 如果S是预乘Alpha格式(Premultiplied Alpha),则直接使用上述公式。
// 如果S是直通Alpha格式(Straight Alpha),则需要先进行预乘:
// S_premultiplied = S * A
// Output = S_premultiplied + D * (1 - A)
PLANE的Alpha属性通过以下属性控制:
| 属性名 | 类型 | 说明 |
|---|---|---|
alpha |
范围 [0, 0xffff] | 全局Alpha值,0为完全透明,0xffff为完全不透明 |
pixel blend mode |
枚举 | None(禁用混合)、Pre-multiplied(预乘)、Coverage(直通/覆盖) |
DRM_FORMAT_XRGB8888(无Alpha通道)并设置alpha为0xffff,这样硬件可以跳过Alpha混合计算,降低带宽消耗。
3.5 Z-order排序(Z-order Ordering)
Z-order决定了多个PLANE在垂直方向上的叠加顺序。Z-order值越小,图层越靠近“底部”(离观察者越远);Z-order值越大,图层越靠近“顶部”(离观察者越近)。
在DRM/KMS中,Z-order通常通过PLANE的ID或显式的Z-order属性来控制:
- 隐式Z-order(基于ID):某些硬件按照PLANE注册的顺序或ID大小决定叠加顺序。这种方式不够灵活,已逐渐被淘汰。
- 显式Z-order(基于属性):现代驱动通过
zpos属性来显式控制Z-order。用户空间可以动态调整每个PLANE的zpos值。
// 内核驱动中注册zpos属性的示例
struct drm_plane *plane;
drm_object_attach_property(&plane->base,
config->plane_zpos_property,
plane->base.id); // 默认zpos等于plane ID
// 用户空间通过atomic ioctl设置zpos
drmModeAtomicReq *req = drmModeAtomicAlloc();
drmModeAtomicSetProperty(req, plane_id, zpos_prop_id, 10); // 设置zpos为10
drmModeAtomicCommit(fd, req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
drmModeAtomicFree(req);
下图展示了三个PLANE(背景、视频、UI)通过Z-order叠加的典型场景:
3.6 核心数据结构与驱动接口
在内核驱动中,PLANE由struct drm_plane结构体表示。驱动开发者需要实现一系列回调函数来支持PLANE的操作。
// 内核中 drm_plane 结构体(简化版)
struct drm_plane {
struct drm_device *dev;
struct drm_crtc *crtc; // 当前绑定的CRTC
struct drm_framebuffer *fb; // 当前绑定的帧缓冲
struct drm_plane_state *state; // 当前状态
uint32_t possible_crtcs; // 位掩码,表示该PLANE可以绑定到哪些CRTC
uint32_t format_count; // 支持的像素格式数量
const uint32_t *format_types; // 支持的像素格式列表
// 核心回调函数
int (*update_plane)(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb, int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
uint32_t src_x, uint32_t src_y,
uint32_t src_w, uint32_t src_h,
struct drm_modeset_acquire_ctx *ctx);
int (*disable_plane)(struct drm_plane *plane,
struct drm_modeset_acquire_ctx *ctx);
void (*destroy)(struct drm_plane *plane);
};
- possible_crtcs:必须正确设置,否则用户空间无法将PLANE绑定到目标CRTC。
- format_types:必须包含硬件支持的所有格式,包括带修饰符的格式。
- atomic_check:在atomic模式下,驱动应实现
atomic_check回调,验证状态变更的合法性(如检查缩放比例是否在硬件限制内)。
3.7 本章小结
PLANE是DRM/KMS多图层合成的核心抽象。理解PLANE的作用、帧缓冲绑定机制、像素格式选择、Alpha混合原理以及Z-order排序规则,是开发高效、灵活的显示驱动的关键。在实际项目中,驱动开发者需要根据硬件能力,合理暴露PLANE的属性,并确保用户空间能够通过标准接口(如libdrm、Wayland)充分利用硬件图层功能,实现低功耗、高性能的显示合成。