2. KMS核心概念:CRTC、Encoder、Connector、Plane、Framebuffer的角色与数据流

在DRM/KMS框架中,显示管道被抽象为五个核心对象:CRTC、Encoder、Connector、Plane和Framebuffer。理解这五个对象的角色及其数据流关系,是掌握atomic提交机制的基础。本章将逐一剖析每个对象的功能定位,并通过数据流图展示它们如何协同工作,将应用程序的像素数据最终呈现在物理显示器上。

核心要点:KMS的五个核心对象构成了从内存到显示器的完整数据管道。CRTC是管道的控制中枢,Plane负责图层合成,Framebuffer承载像素数据,Encoder和Connector负责信号传输与物理连接。atomic提交的本质是原子性地更新这五个对象的状态组合。

2.1 五对象角色定义与职责

下表从功能定位、核心属性和典型操作三个维度,对比了五个KMS核心对象的差异:

对象 功能定位 核心属性 典型操作
CRTC 显示控制器,驱动时序生成 模式(mode)、扫描位置、背景色 设置显示模式、开启/关闭显示
Plane 图层合成单元,叠加多个Framebuffer 源矩形、目标矩形、Z序、alpha 关联Framebuffer、设置位置与大小
Framebuffer 内存中的像素数据缓冲区 宽度、高度、像素格式、dma-buf句柄 创建/销毁、映射、导出dma-buf
Encoder 信号编码器,将CRTC输出转为物理信号 编码类型(HDMI/DP/LVDS)、可能克隆 绑定CRTC、设置编码参数
Connector 物理连接器,检测显示器状态 连接状态、EDID、物理类型 热插拔检测、读取EDID
实战提示:在atomic提交中,CRTC和Plane是状态更新的主要目标。一个典型的atomic commit会同时更新CRTC的显示模式、Plane关联的Framebuffer以及Plane的显示位置,确保所有变化在同一个vblank周期内生效。

2.2 数据流全景:从Framebuffer到显示器

下图展示了KMS五对象之间的数据流关系。像素数据从用户空间应用程序开始,经过Framebuffer、Plane、CRTC、Encoder,最终通过Connector到达物理显示器:

KMS五对象数据流全景图 用户空间应用 Framebuffer Plane CRTC Encoder Connector 物理显示器 drmModeAddFB set_plane 合成后像素流 时序信号 编码后信号 物理链路 数据流说明: 1. 用户空间通过DRM IOCTL创建Framebuffer,填充像素数据。 2. Plane从Framebuffer读取像素,进行缩放/裁剪/alpha混合等合成操作。 3. CRTC按照设定的显示模式(分辨率/刷新率)生成时序,从Plane读取合成后的像素流。 4. Encoder将CRTC输出的并行像素信号编码为HDMI/DP等串行信号。 5. Connector通过物理线缆将信号传输到显示器,并负责热插拔检测和EDID读取。

2.3 各对象深度解析

2.3.1 Framebuffer:像素数据的载体

Framebuffer是KMS中最接近内存的对象。它不直接参与显示时序,而是作为像素数据的存储容器。每个Framebuffer对应一个或多个内存缓冲区(支持立体/多层缓冲),通过dma-buf机制与GPU或显示控制器共享物理内存。

// Framebuffer创建示例(用户空间)
struct drm_mode_fb_cmd2 fb_cmd = {
    .width = 1920,
    .height = 1080,
    .pixel_format = DRM_FORMAT_XRGB8888,
    .handles[0] = gem_handle,   // GEM对象句柄
    .pitches[0] = 1920 * 4,     // 每行字节数
};
int ret = drmIoctl(fd, DRM_IOCTL_MODE_ADDFB2, &fb_cmd);
// fb_cmd.fb_id 即为创建的Framebuffer ID
常见误区:Framebuffer本身不包含显示位置信息。同一个Framebuffer可以被多个Plane引用,显示在不同的屏幕位置。Framebuffer的生命周期独立于Plane和CRTC,需要显式调用drmModeRmFB销毁。

2.3.2 Plane:图层合成引擎

Plane是KMS中实现硬件图层叠加的核心。现代显示控制器通常支持多个硬件图层(主层、光标层、视频层等),每个Plane对应一个硬件图层。Plane负责从Framebuffer读取像素,进行缩放、裁剪、旋转等变换,然后按照Z序与其它Plane合成。

Plane类型 典型用途 硬件特性
Primary Plane 主显示层,通常显示桌面背景 必须存在,支持全屏显示
Cursor Plane 鼠标光标层 尺寸小(通常64x64),更新快
Overlay Plane 视频播放、画中画 支持YUV格式、硬件缩放

2.3.3 CRTC:显示时序的指挥官

CRTC(Cathode Ray Tube Controller,历史名称沿用)是KMS管道的控制核心。它负责:

  • 时序生成:根据设定的显示模式(如1920x1080@60Hz)生成行同步、场同步、消隐等时序信号。
  • 扫描控制:决定从哪个Plane读取像素,以及读取的起始位置和扫描顺序。
  • 背景处理:当所有Plane都不覆盖某个像素时,显示CRTC设置的背景色。
// CRTC模式设置示例(用户空间)
drmModeCrtcPtr crtc = drmModeGetCrtc(fd, crtc_id);
drmModeSetCrtc(fd, crtc_id, fb_id, x, y, connectors, connector_count, mode);
// 该调用会同时设置CRTC的模式、关联Framebuffer和Connector

2.3.4 Encoder:信号编码的桥梁

Encoder将CRTC输出的并行像素数据转换为特定接口标准的串行信号。常见的Encoder类型包括:

  • TMDS Encoder:用于HDMI/DVI接口,将RGB数据编码为TMDS差分信号。
  • LVDS Encoder:用于嵌入式显示屏,将并行数据转换为低压差分信号。
  • DisplayPort Encoder:将数据打包为DP微包,支持更高带宽和辅助通道。

2.3.5 Connector:物理世界的接口

Connector是KMS中唯一与物理世界直接交互的对象。它的核心职责包括:

  • 连接检测:通过硬件引脚或辅助通道检测显示器是否连接。
  • EDID读取:通过I2C或DP辅助通道读取显示器的EDID数据,获取支持的分辨率列表。
  • 物理类型标识:标识连接器类型(HDMI、DP、eDP、VGA等),驱动据此选择合适的Encoder。

2.4 对象间的绑定关系

KMS五对象之间存在严格的绑定约束,这些约束在atomic提交中必须满足:

KMS对象绑定关系 Framebuffer Plane CRTC Encoder Connector 绑定 绑定 绑定 绑定 约束规则:1个CRTC可绑定多个Plane;1个CRTC绑定1个Encoder;1个Encoder绑定1个Connector

2.5 atomic提交中的数据流整合

在atomic提交模式下,上述五个对象的状态更新被封装为一个原子事务。以下是一个典型的atomic提交数据流步骤:

  1. 创建Framebuffer:用户空间分配GEM缓冲区,通过DRM_IOCTL_MODE_ADDFB2创建Framebuffer对象。
  2. 准备Plane状态:设置Plane关联的Framebuffer ID、源矩形(裁剪区域)、目标矩形(显示位置)和Z序。
  3. 准备CRTC状态:设置显示模式(分辨率、刷新率)、背景色,以及是否启用显示。
  4. 准备Encoder/Connector状态:设置Encoder的编码参数,确认Connector的连接状态。
  5. 提交atomic commit:将所有对象的状态打包为drm_atomic_state,通过DRM_IOCTL_MODE_ATOMIC一次性提交。
  6. 硬件生效:驱动在下一个vblank时刻原子性地切换所有硬件寄存器,完成显示更新。
// atomic提交核心代码片段(用户空间)
struct drm_mode_atomic atomic = {0};
// 准备对象属性
atomic.flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
atomic.count_objs = 3;  // CRTC + Plane + Connector
atomic.objs_ptr = (uint64_t)obj_ids;
atomic.count_props_ptr = (uint64_t)count_props;
atomic.props_ptr = (uint64_t)prop_ids;
atomic.values_ptr = (uint64_t)prop_values;
int ret = drmIoctl(fd, DRM_IOCTL_MODE_ATOMIC, &atomic);
关键理解:atomic提交的核心价值在于,它将Framebuffer、Plane、CRTC、Encoder、Connector五个对象的状态变更捆绑为一个不可分割的操作。要么所有对象的状态同时生效,要么全部回滚,彻底避免了传统模式设置中出现的画面撕裂、闪烁或中间态问题。

2.6 本章小结

KMS五对象构成了Linux显示子系统的核心抽象层:

  • Framebuffer是像素数据的物理载体,通过dma-buf实现零拷贝共享。
  • Plane是硬件图层合成单元,支持缩放、裁剪和alpha混合。
  • CRTC是显示时序的生成器,控制整个管道的扫描节奏。
  • Encoder将并行像素信号编码为接口标准信号。
  • Connector是物理世界的接口,负责连接检测和EDID读取。