libdrm全解析三十四 —— 源码全解析(31)

接前一篇文章:libdrm全解析三十三 —— 源码全解析(30)

本文参考以下博文:

DRM 驱动程序开发(VKMS)

特此致谢!

本文开始对于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;
}

实际使用中调用的代码示例片段如下:

static void create_fb(int fd,uint32_t width, uint32_t height, uint32_t color ,struct framebuffer *buf)
{
	struct drm_mode_create_dumb create = {};
 	struct drm_mode_map_dumb map = {};
	uint32_t i;
	uint32_t fb_id;
 
	create.width = width;
	create.height = height;
	create.bpp = 32;
	drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create);	//创建显存,返回一个handle
 
	drmModeAddFB(fd, create.width, create.height, 24, 32, create.pitch,create.handle, &fb_id); 
	
	map.handle = create.handle;
	drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map);	//显存绑定fd,并根据handle返回offset
 
	//通过offset找到对应的显存(framebuffer)并映射到用户空间
	uint32_t *vaddr = mmap(0, create.size, PROT_READ | PROT_WRITE,MAP_SHARED, fd, map.offset);	
 
	for (i = 0; i < (create.size / 4); i++)
		vaddr[i] = color;
 
	buf->vaddr=vaddr;
	buf->handle=create.handle;
	buf->size=create.size;
	buf->fb_id=fb_id;
 
	return;
}
 
create_fb(fd,connector->modes[0].hdisplay,connector->modes[0].vdisplay, 0xff0000, &buf[0]);	

create_fb函数中,在上一步通过drmModeAddFB(fd, create.width, create.height, 24, 32, create.pitch,create.handle, &fb_id)向DRM驱动注册一个framebuffer object后,直接调用drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map)将将dumb buffer与fd绑定,并根据handle返回offset。注意,这里并没有使用drmModeMapDumbBuffer函数,而是直接调用了drmIoctl函数,不过意思是一样的。

drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map)及其对应drmModeMapDumbBuffer函数的核心结构体struct drm_mode_map_dumb在include/libdrm/drm_mode.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;
};

至此,drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map)这一步就讲解完了。

猜你喜欢

转载自blog.csdn.net/phmatthaus/article/details/132580025