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:
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.