libdrm全解析三十 —— 源码全解析(27)

接前一篇文章:libdrm全解析二十九 —— 源码全解析(26)

本文参考以下博文:

DRM 驱动程序开发(VKMS)

特此致谢!

本文开始对drmIoctl(DRM_IOCTL_MODE_CREATE_DUMB)以及其封装函数drmModeCreateDumbBuffer()进行解析。再次贴出该函数源码,在xf86drmMode.c中,如下:

drm_public int
drmModeCreateDumbBuffer(int fd, uint32_t width, uint32_t height, uint32_t bpp,
                        uint32_t flags, uint32_t *handle, uint32_t *pitch,
                        uint64_t *size)
{
	int ret;
	struct drm_mode_create_dumb create = {
		.width = width,
		.height = height,
		.bpp = bpp,
		.flags = flags,
	};

	ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create);
	if (ret != 0)
		return ret;

	*handle = create.handle;
	*pitch = create.pitch;
	*size = create.size;
	return 0;
}

实际使用中,可以使用drmModeCreateDumbBuffer函数,但更一般地是直接使用drmIoctl(DRM_IOCTL_MODE_CREATE_DUMB)函数。

实际调用的代码示例片段为:

    struct drm_mode_create_dumb create = {};

	/* create a dumb-buffer, the pixel format is XRGB888 */
	create.width = bo->width;
	create.height = bo->height;
	create.bpp = 32;
	drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create);

另一实力片段:

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函数传入的参数就是上一步通过_drmModeGetConnector函数得到的connector的相关信息。为了便于理解,再次贴出struct _drmModeConnector的定义,在xf86drmMode.h中,如下:

扫描二维码关注公众号,回复: 16396620 查看本文章
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;

drmModeModeInfoPtr的定义也在xf86drmMode.h中,代码如下:

typedef struct _drmModeModeInfo {
	uint32_t clock;
	uint16_t hdisplay, hsync_start, hsync_end, htotal, hskew;
	uint16_t vdisplay, vsync_start, vsync_end, vtotal, vscan;

	uint32_t vrefresh;

	uint32_t flags;
	uint32_t type;
	char name[DRM_DISPLAY_MODE_LEN];
} drmModeModeInfo, *drmModeModeInfoPtr;

来看drmIoctl(DRM_IOCTL_MODE_CREATE_DUMB)以及其封装函数drmModeCreateDumbBuffer()中的关键结构体struct drm_mode_create_dumb,其定义在include/drm/drm_mode.h中,代码如下:

/* create a dumb scanout buffer */
struct drm_mode_create_dumb {
	__u32 height;
	__u32 width;
	__u32 bpp;
	__u32 flags;
	/* handle, pitch, size will be returned */
	__u32 handle;
	__u32 pitch;
	__u64 size;
};

实际上drmIoctl(DRM_IOCTL_MODE_CREATE_DUMB)这一步不难理解,就是根据之前获得的相关信息,然后以获取的宽度和高度信息,通过ioctl系统调用创建一个dumb buffer对象。

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

猜你喜欢

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