接前一篇文章:libdrm全解析三十二 —— 源码全解析(29)
本文参考以下博文:
特此致谢!
前一篇文章讲解完了DRM_IOCTL_MODE_ADDFB以及对应Userspace API drmModeAddFB(),本篇文章继续讲解DRM一般流程的下一步。为了便于理解,再次贴出一般流程示例:
int main(int argc, char **argv)
{
/* open the drm device */
open("/dev/dri/card0");
/* get crtc/encoder/connector id */
drmModeGetResources(...);
/* get connector for display mode */
drmModeGetConnector(...);
/* create a dumb-buffer */
drmIoctl(DRM_IOCTL_MODE_CREATE_DUMB);
/* bind the dumb-buffer to an FB object */
drmModeAddFB(...);
/* map the dumb buffer for userspace drawing */
drmIoctl(DRM_IOCTL_MODE_MAP_DUMB);
mmap(...);
/* start display */
drmModeSetCrtc(crtc_id, fb_id, connector_id, mode);
}
下一步是drmIoctl(DRM_IOCTL_MODE_MAP_DUMB)。
79. DRM_IOCTL_MODE_MAP_DUMB
第79个宏是DRM_IOCTL_MODE_MAP_DUMB,相应代码如下:
#define DRM_IOCTL_MODE_MAP_DUMB DRM_IOWR(0xB3, struct drm_mode_map_dumb)
结合之前文章中的_IOWR(type,nr,size)的最终定义,得到如下代码:
#define DRM_IOCTL_MODE_MAP_DUMB ( ((3) << 30) | (('d') << 8) | ((0xB3) << 0) | ((sizeof(struct drm_mode_map_dumb)) << 16) )
struct drm_mode_map_dumb在同文件(include/drm/drm.h)中定义,代码如下:
/* set up for mmap of a dumb scanout buffer */
struct drm_mode_map_dumb {
/** Handle for the object being mapped. */
__u32 handle;
__u32 pad;
/**
* Fake offset to use for subsequent mmap call
*
* This is a fixed-size type for 32/64 compatibility.
*/
__u64 offset;
};
drm_mode_map_dumb结构中各成员的意义代码注释描述得很清楚了,在此无需赘述。
DRM_IOCTL_MODE_MAP_DUMB对应的Userspace API为:drmModeMapDumbBuffer()。该函数在xf86drmMode.c中,代码如下:
drm_public int
drmModeMapDumbBuffer(int fd, uint32_t handle, uint64_t *offset)
{
int ret;
struct drm_mode_map_dumb map = {
.handle = handle,
};
ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_MAP_DUMB, &map);
if (ret != 0)
return ret;
*offset = map.offset;
return 0;
}
函数的作用是将dumb buffer与fd绑定,并根据handle返回offset。
对于drmModeMapDumbBuffer函数的详细解析,将在下篇文章中进行。