19. 屏幕显示(DRM)介绍¶
19.1. 前言¶
本章节基于 《DRM(Direct Rendering Manager)》 进行DRM的应用开发的讲解, 该专栏还具有GPU,DRM驱动开发等图形学的相关教程及理论分析
19.2. DRM介绍¶
DRM是Linux目前主流的图形显示框架,相比FB架构,DRM更能适应当前日益更新的显示硬件。 比如FB原生不支持多层合成,不支持VSYNC,不支持DMA-BUF,不支持异步更新,不支持fence机制等等, 而这些功能DRM原生都支持。同时DRM可以统一管理GPU和Display驱动,使得软件架构更为统一,方便管理和维护。
可以看到DRM的图像系统可以分为两部分
应用层– libdrm
内核驱动层— GEM, KMS
libdrm: 对底层接口进行封装,向上层提供通用的API接口,主要是对各种IOCTL接口进行封装。
KMS(Kernel Mode Setting): 即Mode setting:更新画面和设置显示参数。
更新画面:显示buffer的切换,多图层的合成方式,以及每个图层的显示位置。
设置显示参数:包括分辨率、刷新率、电源状态(休眠唤醒)等。
GEM(Graphic Execution Manager): 主要负责显示buffer的分配和释放,内存管理与同步。
19.3. DRM显示¶
本小节主要引用下列文章进行讲解 《drm-kms.pdf》
19.3.1. DRM与framebuffer的区别¶
framebuffer的使用十分简单,只需要在用户空间定义一个framebuffer的内存空间, 只要直接操作这块内存就可以轻易的改变屏幕的显示
对于DRM而言,在framebuffer与显示器之间有四个部件, framebuffer的数据经过几个部件的联合处理最终把图像输出到显示器中
除此之外,DRM相比framebuffer而言有更多的优势:
DRM具有更多的社区维护者
DRM为显示提供更多的设置
DRM在用户空间能够享受更广泛的运用
不过framebuffer在图像并不复杂的场景下的开发难度小于DRM显示系统开发
19.3.2. DRM显示系统分析¶
让我们分析一下绿框中的五个部件,以及他们的联动
19.3.2.1. DRM Framebuffer¶
与上一章节的framebuffer一样,DRM Framebuffer也是一片存放图像的内存区域, 且需要设置图像的格式(RGB888,YUV,C8等)以及画布的大小
19.3.2.2. CRTC¶
CRTC的名字来源于Cathode Ray Tube Controller,中文名为阴极射线显像管控制器
世界上第一台彩色电视正是CRT显示器, 取这个名字的主要原因这个部件很像阴极射线显像管控制器, 电子枪打出的电子撞击到屏幕上的荧光物质使其发光。只要控制电子枪从左到右扫完一行(也就是扫描一行),然后 从上到下扫描完所有行,这样一帧图像就显示出来了。也就是说,显示一帧图像时电子枪是按照‘Z’形在运动,当扫描速度足够快的时候看起来就是一幅完成的画面了。
在DRM显示系统中CRTC会配置display timings和显示分辨率(Planes提供)来扫描framebuffer上的内容,传给Encoder。
display timings: 扫描framebuffer的时序,因为LCD屏的显示并不像0.96寸的屏幕那样, 直接把所有的显示数据写进去就可以显示东西,LCD屏需要一定的时序才能正确显示东西, 因此,CRTC在这里就有着很重要的作用,生成视频模式定时信号,输出内容到Encoder中,Encoder和Connector则只作为数据的转换和传输
关于LCD屏幕时序,下面这篇文章有详细介绍 《LCD基础概念(一):LCD timing 时序参数总结》
19.3.2.3. Planes¶
普遍翻译为平面,我觉得译为图层更合适,Planes是一个包含向CRTC发送数据的缓存块的内存对象, 每个CRTC必须关联一个Planes,它是CRTC决定采用哪种视频模式的根据—显示分辨率(宽度和高度),像素大小,像素格式,刷新率等
Planes会分为三种类型:
DRM_PLANE_TYPE_PRIMARY: 主要图层,显示背景或者图像内容,每个CRTC中含一个
DRM_PLANE_TYPE_OVERLAY: 用于显示叠加、缩放,每个CRTC中含一个以上
DRM_PLANE_TYPE_CURSOR: 用于显示鼠标,每个CRTC中含0-N个
通常驱动会把framebuffer绑定到 DRM_PLANE_TYPE_PRIMARY
上。
LubanCat-RK系列板卡图层包含三个,一个 DRM_PLANE_TYPE_PRIMARY
和两个 DRM_PLANE_TYPE_OVERLAY
(其中一个无法正常使用)
Planes叠加的现象如下
19.3.2.4. Encoder¶
译为编码器。它的作用就是将 pixel 像素编码(转换)为显示器所需要的信号。
如果我们要把图像输出到不同的显示器上显示,需要将其转化为不同的电信号,比如 DVID、VGA、YPbPr、CVBS、Mipi、eDP 等。
所以它的作用:负责将帧转换为适当的格式,通过连接器传输。
比如说:HDMI connector 需要使用TMDS格式的数据才能驱动,因此需要一个能够把像素格式转换为TMDS的编码器。
19.3.2.5. Connector¶
译为连接器。Connector 常常对应于物理连接器 (VGA, DVI, FPD-Link, HDMI, DisplayPort, S-Video …) 他会连接将一个物理显示输出设备 (monitor, laptop panel, …) 。 与当前物理连接的输出设备相关的信息(如连接状态,EDID数据,DPMS状态或支持的视频模式)也存储在 Connector 内。
19.3.2.6. 总结¶
到此,你就会发现DRM显示框架并不是十分复杂,理解之后就会对显示框架有大概的了解, 通过后面的DRM应用编程后,我们对它的理解会更深。
19.3.3. LubanCat-RK系列drm分析¶
采用RK3566的板卡仅支持单屏显示,多屏幕接入会无法实现多屏异显的功能,当接入一个屏幕时具有3个planes(第三个图层Cluster仅支持AFBC格式的图像)
采用RK3568的板卡支持多屏异显,最大可支持3屏异显,RK3568总plane数量为6个
当开启一个屏幕时,屏幕会分配3个图层(第三个图层Cluster仅支持AFBC格式的图像)
当开启两个屏幕时,两个屏幕均会分配3个图层(第三个图层Cluster仅支持AFBC格式的图像)
当开启三个屏幕时,第一个屏幕分配3个图层,第二个屏幕分配两个图层, 最后屏幕分配一个图层 (第一个屏幕的第三个图层Cluster以及第二个屏幕的第二个图层Cluster仅支持AFBC格式的图像)
注意
因此在后面的指南中,我们是无法对Cluster图层进行操作, 我们使用的图像格式为RGB,而Cluster图层需要AFBC格式
注解
The Arm Frame Buffer Compression (AFBC) 是ARM 制定的一种无损图像压缩格式, 主要用于Arm GPU/DPU/VPU 和图形视频内存之间的数据传输; 最大优点是可以显著降低带宽和功耗,提供了对图形像素的更加细粒度的访问。
vp是rk356x系列的显示单元,总共有三个显示单元,分别是VP0,VP1,VP2,对于图层的分配具有优先级,VP1>VP0>VP2
开启三个屏幕时的分配
VP0–》 HDMI 可插拔 -》 二个(最大支持 4096x2304@60Hz)
VP1–》 MIPI 主屏幕 -》 三个 (最大支持 1920x1080@60Hz)
VP2–》 DP转VGA,可插拔 -》 一个 (最大支持 1920x1080@60Hz)
可以在内核内分配图层
19.3.3.1. 查看drm的相关信息¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | #安装测试工具
sudo apt install libdrm-tests
#以双屏异显为例
modetest
cat@lubancat:~/lubancat-test/base_linux$ modetest
trying to open device 'rockchip'...done
Encoders:
id crtc type possible crtcs possible clones
149 0 Virtual 0x00000003 0x00000000
151 71 TMDS 0x00000001 0x00000000
162 87 DSI 0x00000002 0x00000000
Connectors:
id encoder status name size (mm) modes encoders
152 151 connected HDMI-A-1 600x340 32 151
modes:
index name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot
#0 1920x1080 60.00 1920 2008 2052 2200 1080 1084 1089 1125 148500 flags: phsync, pvsync; type: preferred, driver
(省略.........)
props:
(省略.........)
163 162 connected DSI-1 0x0 1 162
modes:
index name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot
#0 720x1280 60.00 720 730 736 756 1280 1290 1294 1314 59603 flags: nhsync, nvsync; type: preferred, driver
props:
(省略.........)
CRTCs:
id fb pos size
71 167 (0,0) (1920x1080)
#0 1920x1080 60.00 1920 2008 2052 2200 1080 1084 1089 1125 148500 flags: phsync, pvsync; type: preferred, driver
props:
(省略.........)
87 164 (0,0) (720x1280)
#0 720x1280 60.00 720 730 736 756 1280 1290 1294 1314 59603 flags: nhsync, nvsync; type: preferred, driver
props:
(省略.........)
Planes:
id crtc fb CRTC x,y x,y gamma size possible crtcs
57 71 167 0,0 0,0 0 0x00000001
formats: XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 1
63 NAME:
flags: immutable bitmask
values: Smart1-win0=0x2
value: 2
(省略.........)
73 87 164 0,0 0,0 0 0x00000002
formats: XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 1
79 NAME:
flags: immutable bitmask
values: Smart0-win0=0x1
value: 1
(省略.........)
89 0 0 0,0 0,0 0 0x00000001
formats: XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16 NV12 NV16 NV24 NA12 NA16 NA24 YVYU VYUY
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 0
95 NAME:
flags: immutable bitmask
values: Esmart1-win0=0x4
value: 4
(省略.........)
103 0 0 0,0 0,0 0 0x00000002
formats: XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16 NV12 NV16 NV24 NA12 NA16 NA24 YVYU VYUY
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 0
109 NAME:
flags: immutable bitmask
values: Esmart0-win0=0x8
value: 8
(省略.........)
117 0 0 0,0 0,0 0 0x00000002
formats: XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16 NV12 NV16 NV24 NA12 NA16 NA24 YUYV
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 0
123 NAME:
flags: immutable bitmask
values: Cluster0-win0=0x10
value: 16
(省略.........)
131 0 0 0,0 0,0 0 0x00000001
formats: XR24 AR24 XB24 AB24 RG24 BG24 RG16 BG16 NV12 NV16 NV24 NA12 NA16 NA24 YUYV
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 0
137 NAME:
flags: immutable bitmask
values: Cluster1-win0=0x40
value: 64
(省略.........)
|
id为151的TMDS为HDMI
id为162的DSI为MIPI屏幕
可以看到CRTC Planes Connectors都有列举,省略的部分包含部分绑定信息,可以查看源码分析。