libdrm全解析三十五 —— 源码全解析(32)

接前一篇文章:libdrm全解析三十四 ------ 源码全解析(31)

本文参考以下博文:

DRM 驱动程序开发(VKMS)

特此致谢!

前一篇文章讲解完了drmIoctl(DRM_IOCTL_MODE_MAP_DUMB)以及其封装函数drmModeMapDumbBuffer(),本篇文章继续讲解DRM一般流程的下一步。为了便于理解,再次贴出一般流程示例:

cpp 复制代码
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);
}

下一步是mmap。实际使用中调用的代码示例片段如下:

cpp 复制代码
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函数中,在上一步通过drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map)将dumb buffer与fd绑定,并根据handle返回offset后,在此调用了mmap函数,将通过offset得到的对应dumb buffer映射到用户空间。

在映射完成后,写入用户空间内存vaddr的访问(读写),实际上就是对于显存的访问了。

struct framebuffer是示例代码中自定义的结构,如下:

cpp 复制代码
struct framebuffer{
	uint32_t size;
	uint32_t handle;	
	uint32_t fb_id;
	uint32_t *vaddr;	
};

至此,mmap()这一步就讲解完了。

相关推荐
赵民勇7 小时前
fuse-overlayfs命令详解
linux·容器
sulikey7 小时前
个人Linux操作系统学习笔记6 - 操作系统与进程初识
linux·笔记·学习·操作系统·进程
杨云龙UP9 小时前
Oracle RAC / ODA 生产环境指定 PDB 启动 SOP
linux·运维·数据库·oracle
Shingmc39 小时前
【Linux】多路转接之select
linux·网络
木古古1810 小时前
搞一个高效的c/c++开发环境,工具VIm+自研vim插件+Shell脚本
linux·编辑器·vim
茫忙然11 小时前
U 盘搭建免驱 Linux 便携系统教程
linux·服务器
一起逃去看海吧12 小时前
dify-03
java·linux·开发语言
fengyehongWorld12 小时前
Linux 根据端口进行的相关查询
linux
lihao lihao12 小时前
linux匿名管道
linux·运维·服务器
うちは止水12 小时前
weston出图调试
linux·wayland·weston