文章目录
- 前言: Linux 的两种显示方案
- FrameBuffer
- DRM
- 1、GEM
- 2、KMS
参考:RK3399 探索之旅 / Display 子系统 / 基础概念
参考:DRM架构介绍(一)
前言: Linux 的两种显示方案
包括:
-
FBDEV: Framebuffer Device
-
DRM/KMS: Direct Rendering Manager / Kernel Mode Setting
它们有什么区别?
FBDEV:
- 传统的显示框架;
- 简单,但是只能提供最基础的显示功能;
- 无法满足当前上层应用和底层硬件的显示需求;
DRM/KMS:
- 目前主流的显示方案;
- 为了适应当前日益更新的显示硬件;
- 软件上能支持更多高级的控制和特性;
DRM 是 Linux 目前主流的图形显示框架,相比 FrameBuffer 架构,DRM 更能适应当前日益更新的显示硬件。比如 FB 原生不支持多层合成,不支持 VSYNC,不支持 DMA-BUF,不支持异步更新,不支持 fence 机制等等,而这些功能 DRM 原生都支持。同时 DRM 可以统一管理 GPU 和 Display 驱动,使得软件架构更为统一,方便管理和维护。
DRM 全称是 Direct Rendering Manager,进行显示输出管理、buffer 分配、帧缓冲。对应 userspace 库 为 libdrm,,libdrm 库提供了一系列友好的控制封装,使用户可以方便的进行显示的控制和 buffer 申请。DRM 的设备节点为 “/dev/dri/cardX”, X 为 0-15 的数值,默认使用的是/dev/dri/card0
从驱动的视角看:
传统linux显示设备驱动开发时,通常使用FB驱动架构,随着显卡性能升级:显示覆盖(菜单层级)、GPU加速、硬件光标,传统FB架构无法很好支持,此外,对于多应用的访问冲突也无法很好控制。在这样的背景下,DRM应用而生。
DRM是linux内核中负责与显卡交互的管理架构,用户空间很方便的利用DRM提供的API,实现3D渲染、视频解码和GPU计算等工作。
FrameBuffer
DRM
目前大多数厂商已经抛弃fb框架,使用drm驱动来管理显示。其中的优点是芯片厂商不必重复造轮子,只需将自己显示处理器的配置流程实现为函数,由drm驱动调用即可。同时drm也为用户提供同一接口,方便使用。
DRM驱动模块
了解过drm的可能都看过下面这张图
DRM subsystem图:
虽然经常用 DRM/KMS 来指代整个 DRM subsystem,但是 KMS 和 DRM driver 只是 整个 DRM subsystem 的其中 2 个部分。
KMS (Kernel Mode Setting) 是内核提供给应用层的 DRM API 的其中一部分,应用层一般通过 libdrm 来访问这些 API。
对于驱动工程师而言,重点关注 DRM driver,这里负责使能 Display engine,可以理解为加强版的 FBDEV。
Linux内核DRM框架包括:GEM和KMS。展示DRM大体框架:
1、GEM
GEM(Graphic Execution Manager):图形执行管理器,主要是对 FrameBuffer 的管理,如内存的申请、释放、共享和同步(GPU和CPU之间内存)机制等。
GEM常用的Buffer包括:
1)Dumb Buffer:基于cma api实现,只支持连续物理内存,用于小分辨率简单场景。
2)Prime Buffer:基于dma-buf实现的buffer共享机制,支持连续、非连续物理内存,用于大内存复杂场景。
2、KMS
KMS(Kernel Mode Setting):内核显示模式设置,主要元素:Framebuffer、Plane、CRTC、Encoder、Connector。见下图:
1)Framebuffer:单个图层的显示内容,应用层和内核都可访问。
2)Plane:硬件图层,可实现多层合成显示,连接FB和CRTC。包括:Primary、Overlay和Cursor,驱动中至少实现1个Plane。
3)CRTC:对内存Buffer进行扫描,并转换成LCDC Timing信号。
4)Encoder:将CRTC输出的LCDC Timing时序转换成显示屏所需要的接口时序。
5)Connector:对应显示屏接口(HDMI、MIPI DSI、LVDS等)驱动和输出设备的相关状态信息(EDID、热插拔等)。