Android 图形系统(10)---- libdrm 基本API

DRM 框架基础

drm_object.jpg

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,858评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,372评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,282评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,842评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,857评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,679评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,406评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,311评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,767评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,945评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,090评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,785评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,420评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,988评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,101评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,298评论 3 372
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,033评论 2 355

推荐阅读更多精彩内容