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:更新画面和设置显示参数。

  1. 更新画面:显示buffer的切换,多图层的合成方式,以及每个图层的显示位置。

  2. 设置显示参数:包括分辨率、刷新率、电源状态(休眠唤醒)等。

GEM(Graphic Execution Manager): 主要负责显示buffer的分配和释放,内存管理与同步。

19.3. DRM显示

本小节主要引用下列文章进行讲解 《drm-kms.pdf》

19.3.1. DRM与framebuffer的区别

未找到图片
  • framebuffer的使用十分简单,只需要在用户空间定义一个framebuffer的内存空间, 只要直接操作这块内存就可以轻易的改变屏幕的显示

  • 对于DRM而言,在framebuffer与显示器之间有四个部件, framebuffer的数据经过几个部件的联合处理最终把图像输出到显示器中

除此之外,DRM相比framebuffer而言有更多的优势:

  1. DRM具有更多的社区维护者

  2. DRM为显示提供更多的设置

  3. 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会分为三种类型:

  1. DRM_PLANE_TYPE_PRIMARY: 主要图层,显示背景或者图像内容,每个CRTC中含一个

  2. DRM_PLANE_TYPE_OVERLAY: 用于显示叠加、缩放,每个CRTC中含一个以上

  3. 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

开启三个屏幕时的分配

可以在内核内分配图层

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都有列举,省略的部分包含部分绑定信息,可以查看源码分析。