DRM 完全解析 - ADD_FB (2)

前回の記事:DRMの完全解析 - ADD_FB (1)の続きです。

この記事は次のブログ投稿を参照しています。

DRM ドライバー (4) ADD_FB

ありがとう!

前の章では、Linux カーネルの libdrm と DRM の間のインターフェイスに焦点を当てました。

DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb_ioctl, 0),

関連するマクロを拡張しました。この記事では、drm_mode_addfb_ioctl 関数の詳細な説明から始めます。drm_mode_addfb_ioctl 関数は drivers/gpu/drm/drm_framebuffer.c にあります。コードは次のとおりです。

int drm_mode_addfb_ioctl(struct drm_device *dev,
			 void *data, struct drm_file *file_priv)
{
	return drm_mode_addfb(dev, data, file_priv);
}

drm_mode_addfb_ioctl 関数は単純なカプセル化にすぎず、実際の作業は drm_mode_addfb 関数に任せられます。すぐ上にあり、コードは次のとおりです。

/**
 * drm_mode_addfb - add an FB to the graphics configuration
 * @dev: drm device for the ioctl
 * @or: pointer to request structure
 * @file_priv: drm file
 *
 * Add a new FB to the specified CRTC, given a user request. This is the
 * original addfb ioctl which only supported RGB formats.
 *
 * Called by the user via ioctl, or by an in-kernel client.
 *
 * Returns:
 * Zero on success, negative errno on failure.
 */
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;

	if (!drm_core_check_feature(dev, DRIVER_MODESET))
		return -EOPNOTSUPP;

	r.pixel_format = drm_driver_legacy_fb_format(dev, or->bpp, or->depth);
	if (r.pixel_format == DRM_FORMAT_INVALID) {
		drm_dbg_kms(dev, "bad {bpp:%d, depth:%d}\n", or->bpp, or->depth);
		return -EINVAL;
	}

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

この関数を説明する前に、ユーザー空間の一般的なプロセスでこのステップ (ioctl システム コール) を呼び出すコンテキストを見てみましょう。

    struct drm_mode_create_dumb create = {};
	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); 

libdrm 完全分析シリーズの記事と DRM 完全分析 - CREATE_DUMB シリーズの記事で述べたように、ユーザー空間では

drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create)

最後に、カーネル内で異なるグラフィックスドライバーに対応する関数内でダムバッファオブジェクトが作成され(実際には struct drm_gem_object *gobj が割り当てられます)、割り当てられた struct drm_gem_object *gobj にバインドされたハンドルが返されます。

drm_gem_object を作成した後、それを drm_framebuffer にバインドする必要があります。これは、fb が最終的な描画に使用されるためです。したがって、drmModeAddFB インターフェイスを使用して drm_framebuffer を作成し、それを以前に作成した struct drm_gem_object *gobj にバインドします。

ユーザー モードとカーネル モードでの DRM_IOCTL_MODE_ADDFB マクロの上下の呼び出しプロセスは、次の図に示すようになります。

drm_mode_addfb 関数の詳細な分析は次の記事に残しておきます。

おすすめ

転載: blog.csdn.net/phmatthaus/article/details/132646813