接前一篇文章:libdrm全解析三十 —— 源码全解析(27)
本文参考以下博文:
特此致谢!
前一篇文章讲解完了drmIoctl(DRM_IOCTL_MODE_CREATE_DUMB)以及其封装函数drmModeCreateDumbBuffer(),本篇文章继续讲解DRM一般流程的下一步。为了便于理解,再次贴出一般流程示例:
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);
}
下一步是drmModeAddFB()。
74. DRM_IOCTL_MODE_ADDFB
第74个宏是DRM_IOCTL_MODE_ADDFB,相应代码如下:
#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd)
结合之前文章中的_IOWR(type,nr,size)的最终定义,得到如下代码:
#define DRM_IOCTL_MODE_ADDFB ( ((3) << 30) | (('d') << 8) | ((0xAE) << 0) | ((sizeof(struct drm_mode_fb_cmd)) << 16) )
struct drm_mode_fb_cmd在同文件(include/drm/drm.h)中定义,代码如下:
struct drm_mode_fb_cmd {
__u32 fb_id;
__u32 width;
__u32 height;
__u32 pitch;
__u32 bpp;
__u32 depth;
/* driver specific handle */
__u32 handle;
};
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;
}
函数的作用是向DRM驱动注册一个framebuffer object。
对于drmModeAddFB函数的详细解析,将在下篇文章中进行。