SDV Media 使用 Linux DRM API 向 OEM 应用公开可用显示屏。
帧缓冲 是像素数据的来源,由一些外部分配的内存缓冲区提供支持。
平面 是 CRTC 使用的图片来源。它与帧缓冲相关联,可能表示帧缓冲的裁剪视图。
CRTC 表示整体显示流水线。它可能会组合多个平面来创建最终视频输出,并将输出分派给多个 编码器。
编码器 将 CRTC 的视频输出转换为适合特定连接器的形式。
连接器 表示可用的显示连接器。例如,HDMI 端口。
如需更深入的说明,请参阅:
API Surface
SDV Media 提供 Linux DRM 接口。虽然可以使用 ioctl 系统调用直接使用这些接口,但对于应用开发,建议使用用户空间帮助程序库。例如:
drm-rs适用于 Rust 的 crate(推荐),libdrm适用于 C/C++。drm-kms手册页 提供了 API 及其用法的全面 概览。
设置渲染到单个显示屏
打开 DRM 设备 (
/dev/dri/card*),并使用其文件描述符上的 Linux DRM API(例如通过libdrm)选择显示屏及其模式。通常,主机系统只会公开一个虚拟 GPU 设备,该设备将显示为
/dev/dri/card0。使用 Linux DRM API 分配前缓冲和后缓冲。
建议使用
minigbm'sgbm_bo_create(),并通过gbm_bo_get_fd()获取 DMA-BUF 文件描述符。创建由分配的缓冲区支持的 GL 帧缓冲。
使用
eglCreateImageKHR和EGL_LINUX_DMA_BUF_EXT(来自EGL_EXT_image_dma_buf_import扩展程序)从 DRM 缓冲区创建EGLImage。创建 GL 纹理,并使用
glEGLImageTargetTexture2DOES(来自GL_OES_EGL_image扩展程序)将纹理的存储空间设置为上一步中的EGLImage。创建 GL 帧缓冲,并使用
glFramebufferTexture2D将其 支持纹理设置为上一步中创建的纹理。
如需渲染帧,请执行以下操作:
绑定其中一个创建的 GL 帧缓冲。
使用常用的 GLES API 绘制帧。
在屏幕上显示帧:使用 Linux DRM API (
drmModeAtomicCommit()) 发送DRM_MODE_PAGE_FLIP_EVENT,其中包含绑定 GL 帧缓冲使用的 DMA-BUF 文件描述符。
组合来自多个图层的视频输出
对于硬件加速的多层(多平面)组合,我们依赖于主机系统将每个图层公开为单独的 DRM 连接器(虚拟显示屏),并将它们映射到正确的硬件位置 / 流水线。
如需了解详情,请参阅设置渲染到多个显示屏。
设置渲染到多个显示屏
打开
/dev/dri/card*DRM 设备,就像在单显示屏流程中一样。列出可用的显示连接器。
每个显示屏都公开为 DRM 设备的单独 DRM 连接器。
对于每个显示连接器:
选择与连接器兼容的 CRTC。每个连接器都有一个可用编码器列表,每个编码器都指明了它可以与哪些 CRTC 搭配使用。始终至少有一个兼容的 CRTC。
选择与 CRTC 兼容的平面。
创建由 GPU 缓冲区支持的 DRM 帧缓冲。此过程与单显示屏变体相同。
连接平面、CRTC 和连接器,并在 CRTC 上设置视频模式。
您可以使用原子 API 同时设置多个显示屏的模式,以便为每个连接器、CRTC 和平面集设置以下 DRM 属性。
必要属性的完整列表:
目标 属性 类型 说明 连接器 CRTC_IDCRTC ID 要分配给连接器的 CRTC 的 ID CRTC MODE_IDblob ID 使用 drmModeCreatePropertyBlob创建的 属性 blob 的 ID,其中包含所选视频模式的drmModeModeInfo结构体CRTC ACTIVEbool true,用于将 CRTC 标记为有效平面 FB_ID帧缓冲 ID 要在屏幕上显示的 DRM 帧缓冲的 ID 平面 SRC_X像素 帧缓冲源图片矩形的 X 坐标 平面 SRC_Y像素 帧缓冲源图片矩形的 Y 坐标 平面 SRC_W16.16 定点数 帧缓冲源图片矩形的宽度(像素左移 16 位) 平面 SRC_H16.16 定点数 帧缓冲源图片矩形的高度(像素左移 16 位) 平面 CRTC_X像素 CRTC 目标图片矩形的 X 坐标 平面 CRTC_Y像素 CRTC 目标图片矩形的 Y 坐标 平面 CRTC_W像素 CRTC 目标图片矩形的宽度 平面 CRTC_H像素 CRTC 目标图片矩形的高度 输入渲染循环:
在渲染下一帧之前,等待 CRTC 上的页面翻转事件。
通过为给定的 CRTC+帧缓冲安排页面翻转,渲染帧并在屏幕上显示该帧。