【转】DRM(三)libdrm库

【转】DRM(三)libdrm库,第1张

DRM是Linux内核层的显示驱动框架。它把显示功能封装成 open/close/ioctl 等标准接口,用户空间的程序调用这些接口,驱动设备,显示数据。

libdrm库封装了DRM driver提供的这些接口。通过libdrm库,程序可以间接调用DRM Driver。

DRM驱动会在/dev/dri下创建3个设备节点:

使用drmOpen()打开设备。它根据指定的name和busid,在上述三个设备中选择匹配的节点。

也可以使用open(),直接打开指定设备。

得到、设置capability。

下图显示各个组件,以及组件之间的关联关系。在DRM的函数名中称作资源(Resource)。如drmModeGetResources()。

每种资源的结构都定义了一个成员,唯一标识这个资源。如drmModeCrtc的crtc_id、drmModeConnector的connector_id、drmModeEncoder的encoder_id、drmModePlane的plane_id。

显示设备的设置、状态,保存在若干结构、变量中,如下图。如drmModeModeInfo,保存设备大小,刷新率。drmModeConnection保存连接状态。

drmModeRes结构保存DRM设备的资源集。

drmModeRes的成员fbs、crtcs、connectors、encoders是变长数组,数组长度保存在对应的变量,如count_fbs中。数组中保存的是资源ID。

函数drmModeGetResources()用于得到资源集。

根据资源 ID 得到对应的资源,包括connector、encoder、crtc。

与其他资源不同,plane资源不在drmModeRes结构中,而是保存在drmModePlaneRes结构。

成员planes是变长数组,数组长度保存在count_planes中。这里保存是plane的资源ID。

drmModeGetPlaneResources()得到plane资源集。

drmModeGetPlane() 根据Plane ID得到Plane。

drmModeProperty结构保存属性。

drmModeObjectProperties保存资源的属性集。

drmModeObjectGetProperties()得到资源属性集。

drmModeGetProperty()得到属性,drmModeObjectSetProperty()设置属性。

使用drmIoctl()创建、映射framebuffer。

使用Linux API函数 mmap(),将framebuffer映射到用户空间。

加入framebuffer(不是提交显示!)。

drmModeAtomicReq保存DRM请求。

drmModeAtomicCommit()提交请求。比如,将framebuffer保存的图像提交显示。

将framebuffer绑定到plane。程序更新framebuffer,就是更新plane。

Linux DRM API - NVIDIA

DRM示例工程 zizimumu/DRM_test

如下是DRM Driver 所依赖的 Component Framework。

framebuffer是驱动和应用层都能访问的一块内存区域。

可以把它理解为一块画布。画画之前需要将它格式化,指定是画油画,还是国画(色彩模式,比如 RGB24,YUV 等),画布需要多大(分辨率)。

直译为阴极摄像管上下文。它读取当前扫描缓冲区的像素数据,借助于PLL电路,生成视频模式定时信号。

简单来说,它就是显示输出的上下文,对内连接 Framebuffer ,对外连接 Encoder。

可以把它理解为扫描仪。它扫描画布(framebuffer)上的内容,叠加 planes 的内容,传给 encoder。

直译为 编码器。它将内存的像素编码转换为显示器所需要的信号。

可以想象成,它将你的画在不同类型、型号的显示设备上显示,将其转换成不同的电信号,比如 DVID、VGA、YPbPr、CVBS、Mipi、eDP 等。

直译为 连接器。它常常对应于物理连接器 (VGA、DVI、FPD-Link、HDMI、DisplayPort、S-Video …) ,连接到一个显示输出设备 (monitor、laptop panel …) 。

与输出设备相关的信息(如连接状态、EDID数据、DPMS状态或支持的视频模式),也存储在 Connector 内。

直译为 平面。Plane和 framebuffer 一样是内存地址。

它的作用是干什么呢?想象这样一个场景,笔者正在很不专心地一边看动作大片,一边写文章。动作大片每一帧的变化都很大,需要全幅更新。写文章则可能半天挤不出一个字,基本上不需要更新。这是显卡使用的两个极端。一个是全幅高速更新的 Video Mode,一个是文字交互这种小范围更新的 Graphics Mode。此时轮到 Planes 出马,它给 Video 刷新提供了高速通道,使 Video 单独为一个图层,可以叠加在 Graphic 上面或下面,并具有缩放等功能。

Planes可以有多个。最后扫描仪(CRTC)扫描的画,实际上是framebuffer 和 若干planes 的组合(Blending)。

厂商可能会对planes的类型、用途做出规范。比如,

DRM_PLANE_TYPE_PRIMARY: 一定要有,由于显示背景或者图像内容

DRM_PLANE_TYPE_OVERLAY: 用于显示Overlay

DRM_PLANE_TYPE_CURSOR: 用于显示鼠标

Linux DRM(二)基本概念和特性

Display中的DRM模块介绍

DRM/KMS 基本组件介绍

DRM 是目前主流的图形显示框架,Linux 内核中已经有Framebuffer 驱动用于管理显示设备的 Framebuffer, Framebuffer 框架也可以实现Linux 系统的显示功能,但是缺点如下:

下面是Linux graphic system 的框架,基于Wayland的Windowing system,在DRI框架下,通过两条路径(DRM和KMS),分别实现Rendering和送显两个显示步骤,注意观察 DRM 框架在其中的作用

DRM 框架的基本流程框图如下:

软件角度框图:

DRM框架涉及到的元素很多,大致如下:

KMS: CRTC,ENCODER,CONNECTOR,PLANE,FB,VBLANK,property

GEM: DUMB、PRIME、Fence

下面一一介绍

libdrm:

应用层的一个动态链接库,对底层接口进行封装,向上层提供通用的API接口,主要是对各种IOCTL接口进行封装。

KMS:

Kernel mode setting 简而言之做两件事:更新画面 + 设置显示参数

更新画面: 显示buffer 的切换,多图层之间的合成方式,每个图层的显示位置

设置显示参数:包含 刷新率,分辨率,电源状态 休眠唤醒等等。

GEM:

Graphic Execution Manager,主要负责显示buffer的分配和释放,也是GPU唯一用到DRM的地方。

学习 drm 就是学习上面这些概念的用法和实现。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/7281995.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-03
下一篇 2023-04-03

发表评论

登录后才能评论

评论列表(0条)

保存