Android 图形系统---- libdrm 基本API

DRM 框架基础

drm 驱动使用的基本概念:

drm_概念.jpg

libdrm API 调用栈

使用 atomic 方法显示画面的调用方法如下:

  • 初始化设备,获取所有Object 的 id 和 prop id 信息
    open(/dev/dri/card0) //open drm device
    –> drmSetClientCap(DRM_CLIENT_CAP_UNIVERSAL_PLANES)
    –> drmSetClientCap(DRM_CLIENT_CAP_ATOMIC)
    –> drmModeGetResources() // connector,encoder,crtc count 和 id 信息
    –> drmModeGetConnector() // 获取 connector 的 id 和 prop 信息
    –> drmModeObjectGetProperties()
    –> drmModeGetEncoder()
    –> drmModeGetCrtc() //获取crtc id 和 fb id 信息
    –> drmGetPlaneByType(DRM_PLANE_TYPE_PRIMARY)
    –> drmModeObjectGetProperties(plane_id,DRM_MODE_OBJECT_PLANE)
    –> drmModeGetProperty() //get drm info like crtc_id,fb_id and so on,they be used for commit

drmIoctl(DRM_IOCTL_MODE_CREATE_DUMB) //创建dumb buffer(只支持连续物理内存,基于kernel中通用CMA API实现)
–> drmIoctl(DRM_IOCTL_MODE_MAP_DUMB) //获取dumb buffer的映射偏移值
–> mmap() //通过mmap映射内核空间到应用层
–> drmPrimeHandleToFD(fd,handle,0,&fd2) //handle已和fd绑定,在此将fd2与handle绑定,即fd2同fd相同
–> drmModeAddFB2() //添加framebuffer

drmModeAtomicAlloc //申请Atomic结构
–> drmModeAtomicAddProperty() //将前面获取的crtc_id,fb_id等参数都传入申请的Atomic结构中
–> drmModeAtomicCommit() //提交数据到display

drmModeRmFB(fb_id) //删除drmModeAddFB2()添加的framebuffer,不然会造成shmem泄露
–> munmap() //释放mmap映射的内存
–> close() //关闭打开的drm句柄

DRM 相关API解析

android 下代码路径:
external/libdrm/xf86drmMode.h
external/libdrm/xf86drm.h
API 和相应的 IOCTL CMD 对应关系如下

libdrm_interface.jpg

drmSetClientCap

extern int drmSetClientCap(int fd, uint64_t capability, uint64_t value);
设置 drm 的capability 属性,可以选择的属性如下:
#define DRM_CLIENT_CAP_STEREO_3D 1
#define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2
#define DRM_CLIENT_CAP_ATOMIC 3

一般需要设置的属性:DRM_CLIENT_CAP_UNIVERSAL_PLANES 和 DRM_CLIENT_CAP_ATOMIC
drmSetClientCap(dev->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
drmSetClientCap(dev->fd, DRM_CLIENT_CAP_ATOMIC, 1);

drmGetVersion

获取drm_driver 的major version,minor version 和name 相关信息,name是char 类型的数组,空间是 libdrm 分配的
extern drmVersionPtr drmGetVersion(int fd);

typedef struct _drmVersion {
    int     version_major;        /**< Major version */
    int     version_minor;        /**< Minor version */
    int     version_patchlevel;   /**< Patch level */
    int     name_len;             /**< Length of name buffer */
    char    *name;            /**< Name of driver */
    int     date_len;             /**< Length of date buffer */
    char    *date;                /**< User-space buffer to hold date */
    int     desc_len;             /**< Length of desc buffer */
    char    *desc;                /**< User-space buffer to hold desc */
} drmVersion, *drmVersionPtr;

drmModeGetResources

drmModeResPtr drmModeGetResources(int fd)
获取 connector,encoder,crtc 的数量和ID信息,注意不包含 plane 的相关信息

typedef struct _drmModeRes {
    int count_fbs;
    uint32_t *fbs;

    int count_crtcs;
    uint32_t *crtcs;

    int count_connectors;
    uint32_t *connectors;

    int count_encoders;
    uint32_t *encoders;

    uint32_t min_width, max_width;
    uint32_t min_height, max_height;
} drmModeRes, *drmModeResPtr;

通过 void drmModeFreeResources(drmModeResPtr ptr) Free

drmModeGetPlaneResources

drmModePlaneResPtr drmModeGetPlaneResources(int fd)
返回plane 的数量和id 信息

typedef struct _drmModePlaneRes {
    uint32_t count_planes;
    uint32_t *planes;
} drmModePlaneRes, *drmModePlaneResPtr;

通过 void drmModeFreePlaneResources(drmModePlaneResPtr ptr) free

drmModeGetPlane

drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id)
传入 plane id 的值,获取plane 的详细信息,注意没有包含 plane 的 prop 信息

typedef struct _drmModePlane {
    uint32_t count_formats;
    uint32_t *formats;
    uint32_t plane_id;

    uint32_t crtc_id;
    uint32_t fb_id;

    uint32_t crtc_x, crtc_y;
    uint32_t x, y;

    uint32_t possible_crtcs;
    uint32_t gamma_size;
} drmModePlane, *drmModePlanePtr;

通过 void drmModeFreePlane(drmModePlanePtr ptr) Free

drmModeGetConnector

drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
根据connector ID获取到 connector 的相关信息,包含 connector 的prop信息,prop 的值;encoder 的数量和 encoder 的 ID信息
connector 相应的信息如下:

typedef struct _drmModeConnector {
    uint32_t connector_id;
    uint32_t encoder_id; /**< Encoder currently connected to */
    uint32_t connector_type;
    uint32_t connector_type_id;
    drmModeConnection connection;
    uint32_t mmWidth, mmHeight; /**< HxW in millimeters */
    drmModeSubPixel subpixel;

    int count_modes;
    drmModeModeInfoPtr modes;

    int count_props;
    uint32_t *props; /**< List of property ids */
    uint64_t *prop_values; /**< List of property values */

    int count_encoders;
    uint32_t *encoders; /**< List of encoder ids */
} drmModeConnector, *drmModeConnectorPtr;

通过 void drmModeFreeConnector(drmModeConnectorPtr ptr) Free

drmModeGetEncoder

drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id)
获取encoder 的详细信息,注意没有包含prop 的 id 信息

typedef struct _drmModeEncoder {
    uint32_t encoder_id;
    uint32_t encoder_type;
    uint32_t crtc_id;
    uint32_t possible_crtcs;
    uint32_t possible_clones;
} drmModeEncoder, *drmModeEncoderPtr;

通过void drmModeFreeEncoder(drmModeEncoderPtr ptr) Free

drmModeGetCrtc

drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
获取Crtc 的详细信息,注意不包含 prop相关信息

typedef struct _drmModeCrtc {
    uint32_t crtc_id;
    uint32_t buffer_id; /**< FB id to connect to 0 = disconnect */

    uint32_t x, y; /**< Position on the framebuffer */
    uint32_t width, height;
    int mode_valid;
    drmModeModeInfo mode;

    int gamma_size; /**< Number of gamma stops */

} drmModeCrtc, *drmModeCrtcPtr;


通过 void drmModeFreeCrtc(drmModeCrtcPtr ptr) free

drmModeObjectGetProperties

drmModeObjectPropertiesPtr drmModeObjectGetProperties(int fd, uint32_t object_id, uint32_t object_type)
获取 crtc,plane,Encoder 和 connector 所有的prop信息

typedef struct _drmModeObjectProperties {
    uint32_t count_props;
    uint32_t *props;
    uint64_t *prop_values;
} drmModeObjectProperties, *drmModeObjectPropertiesPtr;

其中的 uint32_t object_id, uint32_t object_typ 需要相互对应,可以选择的组合如下:

#define DRM_MODE_OBJECT_CRTC 0xcccccccc
#define DRM_MODE_OBJECT_CONNECTOR 0xc0c0c0c0
#define DRM_MODE_OBJECT_ENCODER 0xe0e0e0e0
#define DRM_MODE_OBJECT_MODE 0xdededede
#define DRM_MODE_OBJECT_PROPERTY 0xb0b0b0b0
#define DRM_MODE_OBJECT_FB 0xfbfbfbfb
#define DRM_MODE_OBJECT_BLOB 0xbbbbbbbb
#define DRM_MODE_OBJECT_PLANE 0xeeeeeeee
#define DRM_MODE_OBJECT_ANY 0

void drmModeFreeObjectProperties(drmModeObjectPropertiesPtr ptr)

drmModeGetProperty

drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id)
针对 drmModeObjectGetProperties 获取到的 prop id,获取到更加详细的 prop 信息,获取到每个prop 的name 和 value 信息

typedef struct _drmModeProperty {
    uint32_t prop_id;
    uint32_t flags;
    char name[DRM_PROP_NAME_LEN];
    int count_values;
    uint64_t *values; /* store the blob lengths */
    int count_enums;
    struct drm_mode_property_enum *enums;
    int count_blobs;
    uint32_t *blob_ids; /* store the blob IDs */
} drmModePropertyRes, *drmModePropertyPtr;

通过接口 void drmModeFreeProperty(drmModePropertyPtr ptr) free

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
在这里插入图片描述
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

全套视频资料:

一、面试合集

在这里插入图片描述
二、源码解析合集
在这里插入图片描述

三、开源框架合集
在这里插入图片描述
欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值