接前一篇文章:libdrm全解析三十一 —— 源码全解析(28)
本文参考以下博文:
特此致谢!
本文开始对于DRM_IOCTL_MODE_ADDFB对应的Userspace API drmModeAddFB()进行解析。再次贴出该函数源码,在xf86drmMode.c中,如下:
drm_public int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
uint32_t *buf_id)
{
struct drm_mode_fb_cmd f;
int ret;
memclear(f);
f.width = width;
f.height = height;
f.pitch = pitch;
f.bpp = bpp;
f.depth = depth;
f.handle = bo_handle;
if ((ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_ADDFB, &f)))
return ret;
*buf_id = f.fb_id;
return 0;
}
实际使用中调用的代码示例片段如下:
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_CREATE_DUMB, &create)根据之前调用_drmModeGetConnector函数获得的宽高信息创建显存后,调用drmModeAddFB(fd, create.width, create.height, 24, 32, create.pitch,create.handle, &fb_id)向DRM驱动注册一个framebuffer object。
drmModeAddFB函数本身很简单,就是根据函数的入参设置struct drm_mode_fb_cmd f。设置好之后调用DRM_IOCTL(fd, DRM_IOCTL_MODE_ADDFB, &f),这就是核心功能:向DRM驱动注册一个framebuffer对象(object)。成功后将framebuffer对象的id返回。
drmModeAddFB函数的核心结构体struct drm_mode_fb_cmd在include/libdrm/drm_mode.h中定义,代码如下:
struct drm_mode_fb_cmd {
__u32 fb_id;
__u32 width;
__u32 height;
__u32 pitch;
__u32 bpp;
__u32 depth;
/* driver specific handle */
__u32 handle;
};
至此,drmModeAddFB()这一步就讲解完了。