美文网首页
【转】DRM(三)libdrm库

【转】DRM(三)libdrm库

作者: RonZheng2010 | 来源:发表于2020-10-22 09:51 被阅读0次

1. DRM driver 与 libdrm库

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

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

2. 打开设备

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

card0
controlD64
renderD128

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

// 打开DRM设备
int drmOpen(const char *name, const char *busid);

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

int fd;
fd = open ("/dev/dri/card0", O_RDWR, 0);

3. Capability

得到、设置capability。

// 得到指定的capability
int drmGetCap(int fd, uint64_t capability, uint64_t *value);

// 设置指定的capability
int drmSetClientCap(int fd, uint64_t capability, uint64_t value);

4. DRM组件

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

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

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

4. 得到资源

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

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

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

// 得到资源集
drmModeResPtr drmModeGetResources(int fd);

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

// 得到connector
drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id);
// 得到encoder
drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id);
// 得到crtc
drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId);

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

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

drmModeGetPlaneResources()得到plane资源集。

// 得到plane资源集
drmModePlaneResPtr drmModeGetPlaneResources(int fd);

drmModeGetPlane() 根据Plane ID得到Plane。

// 根据plane ID得到Plane资源
drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id);

5. 资源Property

drmModeProperty结构保存属性。

  • 成员prop_id是属性的唯一标识值,
  • 成员name是属性名。

drmModeObjectProperties保存资源的属性集。

  • 成员props是变长数组,保存属性的prop_id。数组长度保存在count_props中。
  • 成员prop_values是与props等长的数组。保存与props数组对应的属性值。其中有标准属性,也可能有厂商自定义属性,比如Plane类型DRM_PLANE_TYPE。

drmModeObjectGetProperties()得到资源属性集。

drmModeObjectPropertiesPtr drmModeObjectGetProperties(int fd,
                              uint32_t object_id,
                              uint32_t object_type);

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

drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id);

int drmModeObjectSetProperty(int fd, uint32_t object_id, uint32_t object_type,
                 uint32_t property_id, uint64_t value);

5. framebuffer ioctl操作

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

// requests
#define DRM_IOCTL_MODE_CREATE_DUMB ...   // 创建framebuffer
#define DRM_IOCTL_MODE_MAP_DUMB    ...      // 映射framebuffer

int drmIoctl(int fd, unsigned long request, void *arg)

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

void *mmap(void *addr, size_t length, int prot, int flags,
                  int fd, off_t offset);

5. 加入framebuffer

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

int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
                  uint32_t pixel_format, // framebuffer图像格式
                  uint32_t bo_handles[4], 
                  uint32_t pitches[4], uint32_t offsets[4],
                  uint32_t *buf_id,  // framebuffer ID
                  uint32_t flags);

5. 提交DRM请求

drmModeAtomicReq保存DRM请求。

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

int drmModeAtomicCommit(int fd,
                   drmModeAtomicReqPtr req,
                   uint32_t flags,
                   void *user_data);

5. 绑定framebuffer到Plane

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

// 将framebuffer绑定到plane
int drmModeSetPlane(int fd, 
            uint32_t plane_id, // plane id
            uint32_t crtc_id,
            uint32_t fb_id, // frambuffer id
            uint32_t flags,
            int32_t crtc_x, int32_t crtc_y, uint32_t crtc_w, uint32_t crtc_h, // 目标区域RECT
            uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h); // 源区域RECT

参考资料

Linux DRM API - NVIDIA
DRM示例工程 zizimumu/DRM_test

相关文章

  • 【转】DRM(三)libdrm库

    1. DRM driver 与 libdrm库 DRM是Linux内核层的显示驱动框架。它把显示功能封装成 ope...

  • EGL和opengles2在开发板上实现无窗口3D显示--App

    继上一篇使用meson自己编译libdrm及修改example代码--Apple的学习笔记成功验证了drm的显示框...

  • GNU Binutils之readelf命令

    在调试libdrm时,查看libdrm.so依赖哪些库,用到了readelf命令,简单记录下该命令的用法。 1、显...

  • Linux DRM那些事-libdrm调试准备

    本文主要介绍libdrm的代码下载、编译和调试前的准备工作。 一、代码下载 libdrm下载网址:https://...

  • 【转】DRM (一)历史

    1. 背景 1.1. XClient / XServer X Windows窗口系统提供GUI环境的基本框架:在显...

  • OMA DRM

    DRM Digital Rights Management 数字版权管理 OMA DRM OMA DRM是OMA(...

  • linux drm

    Linux DRM(一)Display Server Linux DRM(二)基本概念和特性 Linux DRM ...

  • [转]DRM显示驱动开发

    本篇博客摘自CSDN博主「何小龙」的原创文章,很好的DRM学习进阶,也省的亲自写了! 1. 最简单的DRM应用程序...

  • Linux DRM那些事-RockPI DRM

    一、DRM基本组件 Linux内核DRM框架包括:GEM和KMS。引用网络图片,展示DRM大体框架: 1、GEM ...

  • Oracle安装

    安装 创建数据库用户 执行数据库脚本 执行DRM的建表脚本。 要求: 1、Oracle 11g及以上版本; 2、实...

网友评论

      本文标题:【转】DRM(三)libdrm库

      本文链接:https://www.haomeiwen.com/subject/gsfemktx.html