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()这一步就讲解完了。

相关推荐
轻松Ai享生活6 小时前
5 节课深入学习Linux Cgroups
linux
christine-rr7 小时前
linux常用命令(4)——压缩命令
linux·服务器·redis
三坛海会大神5557 小时前
LVS与Keepalived详解(二)LVS负载均衡实现实操
linux·负载均衡·lvs
東雪蓮☆7 小时前
深入理解 LVS-DR 模式与 Keepalived 高可用集群
linux·运维·服务器·lvs
乌萨奇也要立志学C++8 小时前
【Linux】进程概念(二):进程查看与 fork 初探
linux·运维·服务器
獭.獭.9 小时前
Linux -- 信号【上】
linux·运维·服务器
hashiqimiya9 小时前
centos配置环境变量jdk
linux·运维·centos
hashiqimiya9 小时前
权限更改centos中系统文件无法创建文件夹,使用命令让普通用户具备操作文件夹
linux
逆小舟14 小时前
【Linux】人事档案——用户及组管理
linux·c++
青草地溪水旁14 小时前
pthread_mutex_lock函数深度解析
linux·多线程·pthread