KWin、libdrm、DRM从上到下全过程 —— drmModeAddFBxxx(2)

本文继续探讨KWin、libdrm和DRM框架下,drmModeAddFB系列函数的整合过程。文章详细阐述了从drmModeAddFB到drmModeAddFB2的转变,以及如何通过drm_mode_addfb2函数实现内核层的统一。通过对合并过程的回顾,特别是同级函数差异的分析,帮助读者深入理解这一关键操作。下一部分将揭示如何通过drm_mode_fb_cmd到drm_mode_fb_cmd2的转换完成最后的统一。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接前一篇文章:KWin、libdrm、DRM从上到下全过程 —— drmModeAddFBxxx(1)

上回书说到drmModeAddFB、drmModeAddFB2和drmModeAddFB2WithModifiers函数最终“三分归一统”,在内核层统一调用到drm_mode_addfb2函数。

这里我们先不急于往下分析drm_mode_addfb2函数,而是再来回顾一下之前的逐步合并统一的过程,以加深理解。如下图所示:

重点关注函数两次合并过程中同级函数的差异:

第1次合并

  • DRM <——> libdrm

drmModeAddFB2(buffer->gpu()->fd(), size.width(), size.height(), buffer->format(), handles.data(), strides.data(), offsets.data(), &framebufferId, 0);

drmModeAddFB2WithModifiers(buffer->gpu()->fd(), size.width(), size.height(), buffer->format(), handles.data(), strides.data(), offsets.data(), modifier, &framebufferId, DRM_MODE_FB_MODIFIERS);

drm_public int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
		uint32_t pixel_format, const uint32_t bo_handles[4],
		const uint32_t pitches[4], const uint32_t offsets[4],
		uint32_t *buf_id, uint32_t flags)
{
	return drmModeAddFB2WithModifiers(fd, width, height,
					  pixel_format, bo_handles,
					  pitches, offsets, NULL,
					  buf_id, flags);
}
drm_public int drmModeAddFB2WithModifiers(int fd, uint32_t width,
		uint32_t height, uint32_t pixel_format, const uint32_t bo_handles[4],
		const uint32_t pitches[4], const uint32_t offsets[4],
		const uint64_t modifier[4], uint32_t *buf_id, uint32_t flags)
{
    ……
}
  •  libdrm <——> DRM
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_public int drmModeAddFB2WithModifiers(int fd, uint32_t width,
		uint32_t height, uint32_t pixel_format, const uint32_t bo_handles[4],
		const uint32_t pitches[4], const uint32_t offsets[4],
		const uint64_t modifier[4], uint32_t *buf_id, uint32_t flags)
{
	struct drm_mode_fb_cmd2 f;
	int ret;

	memclear(f);
	f.width  = width;
	f.height = height;
	f.pixel_format = pixel_format;
	f.flags = flags;
	memcpy(f.handles, bo_handles, 4 * sizeof(bo_handles[0]));
	memcpy(f.pitches, pitches, 4 * sizeof(pitches[0]));
	memcpy(f.offsets, offsets, 4 * sizeof(offsets[0]));
	if (modifier)
		memcpy(f.modifier, modifier, 4 * sizeof(modifier[0]));

	if ((ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_ADDFB2, &f)))
		return ret;

	*buf_id = f.fb_id;
	return 0;
}

第2次合并

int drm_mode_addfb_ioctl(struct drm_device *dev,
			 void *data, struct drm_file *file_priv)
{
	return drm_mode_addfb(dev, data, file_priv);
}
int drm_mode_addfb(struct drm_device *dev, struct drm_mode_fb_cmd *or,
		   struct drm_file *file_priv)
{
	struct drm_mode_fb_cmd2 r = {};
	int ret;

	……

	/* convert to new format and call new ioctl */
	r.fb_id = or->fb_id;
	r.width = or->width;
	r.height = or->height;
	r.pitches[0] = or->pitch;
	r.handles[0] = or->handle;

	ret = drm_mode_addfb2(dev, &r, file_priv);
	if (ret)
		return ret;

	or->fb_id = r.fb_id;

	return 0;
}
int drm_mode_addfb2_ioctl(struct drm_device *dev,
			  void *data, struct drm_file *file_priv)
{
#ifdef __BIG_ENDIAN
	……
#endif
	return drm_mode_addfb2(dev, data, file_priv);
}

由代码可以看到,drm_mode_addfb函数中存在由drm_mode_fb_cmd结构向drm_mode_fb_cmd2结构的转换,这样两者才能最终统一起来。

欲知后事如何,且看下回分解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝天居士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值