DRM 框架基础
drm_object.jpgdrm 驱动使用的基本概念:
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
网友评论