Full analysis of libdrm 30 - full analysis of source code (27)

Continued from the previous article: Full analysis of libdrm twenty-nine -- full analysis of source code (26)

This article refers to the following blog posts:

DRM driver development (VKMS)

Thank you very much!

This article begins to analyze drmIoctl(DRM_IOCTL_MODE_CREATE_DUMB) and its package function drmModeCreateDumbBuffer(). Post the source code of this function again, in xf86drmMode.c, as follows:

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;
}

In actual use, you can use the drmModeCreateDumbBuffer function, but more generally use the drmIoctl(DRM_IOCTL_MODE_CREATE_DUMB) function directly.

The code sample snippet that is actually called is:

    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);

Another piece of strength:

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]);

In the second instance, the parameter passed in by the create_fb function is the information about the connector obtained through the _drmModeGetConnector function in the previous step. For ease of understanding, post the definition of struct _drmModeConnector again, in xf86drmMode.h, as follows:

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;

The definition of drmModeModeInfoPtr is also in xf86drmMode.h, the code is as follows:

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;

Let’s look at drmIoctl(DRM_IOCTL_MODE_CREATE_DUMB) and the key structure struct drm_mode_create_dumb in its package function drmModeCreateDumbBuffer(), which is defined in include/drm/drm_mode.h, and the code is as follows:

/* 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;
};

In fact, the drmIoctl (DRM_IOCTL_MODE_CREATE_DUMB) step is not difficult to understand. It is to create a dumb buffer object through the ioctl system call based on the relevant information obtained before, and then use the obtained width and height information.

So far, the drmIoctl(DRM_IOCTL_MODE_CREATE_DUMB) step has been explained.

Guess you like

Origin blog.csdn.net/phmatthaus/article/details/132565224