libdrm全解析四十 —— 源码全解析(37)

接前一篇文章:libdrm全解析三十九 —— 源码全解析(36)

本文参考以下博文:

DRM 驱动程序开发(VKMS)

特此致谢!

前一篇文章讲解完了资源的释放流程中的munmap()和drmIoctl(DRM_IOCTL_MODE_DESTROY_DUMB),本回讲解drmModeFreeConnector函数。drmModeFreeConnector()与drmModeGetConnector()是一对。

drmModeFreeConnector函数在xf86drmMode.c中,代码如下:

drm_public void drmModeFreeConnector(drmModeConnectorPtr ptr)
{
	if (!ptr)
		return;

	drmFree(ptr->encoders);
	drmFree(ptr->prop_values);
	drmFree(ptr->props);
	drmFree(ptr->modes);
	drmFree(ptr);
}

可见,drmModeFreeConnector函数并没有想象中与之专门对应的DRM_IOCTL_MODE_FREE_CONNECTOR宏,而是调用了drmFree函数释放了多个分配的空间。

前文讲过,drmFree函数在xf86drm.c中,代码如下

drm_public void drmFree(void *pt)
{
    free(pt);
}

就是free函数的简单封装。

扫描二维码关注公众号,回复: 16396153 查看本文章

drmModeFreeConnector函数的作用是释放drmModeGetConnector函数中分配的各个空间。

为了便于理解,再次贴出drmModeGetConnector函数代码,在xf86drmMode.c中,如下:

/*
 * Connector manipulation
 */
static drmModeConnectorPtr
_drmModeGetConnector(int fd, uint32_t connector_id, int probe)
{
	struct drm_mode_get_connector conn, counts;
	drmModeConnectorPtr r = NULL;
	struct drm_mode_modeinfo stack_mode;

	memclear(conn);
	conn.connector_id = connector_id;
	if (!probe) {
		conn.count_modes = 1;
		conn.modes_ptr = VOID2U64(&stack_mode);
	}

	if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn))
		return 0;

retry:
	counts = conn;

	if (conn.count_props) {
		conn.props_ptr = VOID2U64(drmMalloc(conn.count_props*sizeof(uint32_t)));
		if (!conn.props_ptr)
			goto err_allocs;
		conn.prop_values_ptr = VOID2U64(drmMalloc(conn.count_props*sizeof(uint64_t)));
		if (!conn.prop_values_ptr)
			goto err_allocs;
	}

	if (conn.count_modes) {
		conn.modes_ptr = VOID2U64(drmMalloc(conn.count_modes*sizeof(struct drm_mode_modeinfo)));
		if (!conn.modes_ptr)
			goto err_allocs;
	} else {
		conn.count_modes = 1;
		conn.modes_ptr = VOID2U64(&stack_mode);
	}

	if (conn.count_encoders) {
		conn.encoders_ptr = VOID2U64(drmMalloc(conn.count_encoders*sizeof(uint32_t)));
		if (!conn.encoders_ptr)
			goto err_allocs;
	}

	if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn))
		goto err_allocs;

	/* The number of available connectors and etc may have changed with a
	 * hotplug event in between the ioctls, in which case the field is
	 * silently ignored by the kernel.
	 */
	if (counts.count_props < conn.count_props ||
	    counts.count_modes < conn.count_modes ||
	    counts.count_encoders < conn.count_encoders) {
		drmFree(U642VOID(conn.props_ptr));
		drmFree(U642VOID(conn.prop_values_ptr));
		if (U642VOID(conn.modes_ptr) != &stack_mode)
			drmFree(U642VOID(conn.modes_ptr));
		drmFree(U642VOID(conn.encoders_ptr));

		goto retry;
	}

	if(!(r = drmMalloc(sizeof(*r)))) {
		goto err_allocs;
	}

	r->connector_id = conn.connector_id;
	r->encoder_id = conn.encoder_id;
	r->connection   = conn.connection;
	r->mmWidth      = conn.mm_width;
	r->mmHeight     = conn.mm_height;
	/* convert subpixel from kernel to userspace */
	r->subpixel     = conn.subpixel + 1;
	r->count_modes  = conn.count_modes;
	r->count_props  = conn.count_props;
	r->props        = drmAllocCpy(U642VOID(conn.props_ptr), conn.count_props, sizeof(uint32_t));
	r->prop_values  = drmAllocCpy(U642VOID(conn.prop_values_ptr), conn.count_props, sizeof(uint64_t));
	r->modes        = drmAllocCpy(U642VOID(conn.modes_ptr), conn.count_modes, sizeof(struct drm_mode_modeinfo));
	r->count_encoders = conn.count_encoders;
	r->encoders     = drmAllocCpy(U642VOID(conn.encoders_ptr), conn.count_encoders, sizeof(uint32_t));
	r->connector_type  = conn.connector_type;
	r->connector_type_id = conn.connector_type_id;

	if ((r->count_props && !r->props) ||
	    (r->count_props && !r->prop_values) ||
	    (r->count_modes && !r->modes) ||
	    (r->count_encoders && !r->encoders)) {
		drmFree(r->props);
		drmFree(r->prop_values);
		drmFree(r->modes);
		drmFree(r->encoders);
		drmFree(r);
		r = 0;
	}

err_allocs:
	drmFree(U642VOID(conn.prop_values_ptr));
	drmFree(U642VOID(conn.props_ptr));
	if (U642VOID(conn.modes_ptr) != &stack_mode)
		drmFree(U642VOID(conn.modes_ptr));
	drmFree(U642VOID(conn.encoders_ptr));

	return r;
}

资源释放流程中的其余函数将在后续文章中进行解析。

猜你喜欢

转载自blog.csdn.net/phmatthaus/article/details/132643707