Linux内核4.14版本——drm框架分析(13)——DRM_IOCTL_MODE_SETPLANE(drm_mode_setplane)

news2025/1/21 21:31:38

目录

1. drm_mode_setplane

1.1 根据应用的plane_req->plane_id找到plane

1.2 根据应用的plane_req->fb_id找到struct drm_framebuffer

1.3 调用setplane_internal

2. setplane_internal->__setplane_internal

2.1 struct drm_framebuffer是否为空

2.2 判断此plane是否有合适的crtc

2.3 检查plane是否支持该fb的pix format

2.4 一些越界检查

2.5 检查对齐情况

2.6 调用plane->funcs->update_plane(drm_atomic_helper_update_plane)

3. drm_atomic_helper_update_plane

3.1 drm_atomic_set_fb_for_plane 把framebuffer引用给plane

4. 流程图


     本文分析一下drm_mode_setplane函数。

1. drm_mode_setplane

1.1 根据应用的plane_req->plane_id找到plane

int drm_mode_setplane(struct drm_device *dev, void *data,
		      struct drm_file *file_priv)
{
	struct drm_mode_set_plane *plane_req = data;
	struct drm_plane *plane;
	struct drm_crtc *crtc = NULL;
	struct drm_framebuffer *fb = NULL;

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

	/*
	 * First, find the plane, crtc, and fb objects.  If not available,
	 * we don't bother to call the driver.
	 */
	plane = drm_plane_find(dev, plane_req->plane_id);
	if (!plane) {
		DRM_DEBUG_KMS("Unknown plane ID %d\n",
			      plane_req->plane_id);
		return -ENOENT;
	}

1.2 根据应用的plane_req->fb_id找到struct drm_framebuffer

	if (plane_req->fb_id) {
		fb = drm_framebuffer_lookup(dev, plane_req->fb_id);
		if (!fb) {
			DRM_DEBUG_KMS("Unknown framebuffer ID %d\n",
				      plane_req->fb_id);
			return -ENOENT;
		}

		crtc = drm_crtc_find(dev, plane_req->crtc_id);
		if (!crtc) {
			drm_framebuffer_put(fb);
			DRM_DEBUG_KMS("Unknown crtc ID %d\n",
				      plane_req->crtc_id);
			return -ENOENT;
		}
	}

1.3 调用setplane_internal

	/*
	 * setplane_internal will take care of deref'ing either the old or new
	 * framebuffer depending on success.
	 */
	return setplane_internal(plane, crtc, fb,
				 plane_req->crtc_x, plane_req->crtc_y,
				 plane_req->crtc_w, plane_req->crtc_h,
				 plane_req->src_x, plane_req->src_y,
				 plane_req->src_w, plane_req->src_h);
}

2. setplane_internal->__setplane_internal

2.1 struct drm_framebuffer是否为空

static int __setplane_internal(struct drm_plane *plane,
			       struct drm_crtc *crtc,
			       struct drm_framebuffer *fb,
			       int32_t crtc_x, int32_t crtc_y,
			       uint32_t crtc_w, uint32_t crtc_h,
			       /* src_{x,y,w,h} values are 16.16 fixed point */
			       uint32_t src_x, uint32_t src_y,
			       uint32_t src_w, uint32_t src_h,
			       struct drm_modeset_acquire_ctx *ctx)
{
	int ret = 0;

	/* No fb means shut it down */
	if (!fb) {
		plane->old_fb = plane->fb;
		ret = plane->funcs->disable_plane(plane, ctx);
		if (!ret) {
			plane->crtc = NULL;
			plane->fb = NULL;
		} else {
			plane->old_fb = NULL;
		}
		goto out;
	}

2.2 判断此plane是否有合适的crtc

	/* Check whether this plane is usable on this CRTC */
	if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) {
		DRM_DEBUG_KMS("Invalid crtc for plane\n");
		ret = -EINVAL;
		goto out;
	}

2.3 检查plane是否支持该fb的pix format

	/* Check whether this plane supports the fb pixel format. */
	ret = drm_plane_check_pixel_format(plane, fb->format->format);
	if (ret) {
		struct drm_format_name_buf format_name;
		DRM_DEBUG_KMS("Invalid pixel format %s\n",
		              drm_get_format_name(fb->format->format,
		                                  &format_name));
		goto out;
	}

2.4 一些越界检查

	/* Give drivers some help against integer overflows */
	if (crtc_w > INT_MAX ||
	    crtc_x > INT_MAX - (int32_t) crtc_w ||
	    crtc_h > INT_MAX ||
	    crtc_y > INT_MAX - (int32_t) crtc_h) {
		DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n",
			      crtc_w, crtc_h, crtc_x, crtc_y);
		ret = -ERANGE;
		goto out;
	}

2.5 检查对齐情况

	ret = drm_framebuffer_check_src_coords(src_x, src_y, src_w, src_h, fb);
	if (ret)
		goto out;

2.6 调用plane->funcs->update_plane(drm_atomic_helper_update_plane)

	plane->old_fb = plane->fb;
	ret = plane->funcs->update_plane(plane, crtc, fb,
					 crtc_x, crtc_y, crtc_w, crtc_h,
					 src_x, src_y, src_w, src_h, ctx);
	if (!ret) {
		plane->crtc = crtc;
		plane->fb = fb;
		fb = NULL;
	} else {
		plane->old_fb = NULL;
	}
static const struct drm_plane_funcs malidp_de_plane_funcs = {
	.update_plane = drm_atomic_helper_update_plane,
	.disable_plane = drm_atomic_helper_disable_plane,
	.destroy = malidp_de_plane_destroy,
	.reset = malidp_plane_reset,
	.atomic_duplicate_state = malidp_duplicate_plane_state,
	.atomic_destroy_state = malidp_destroy_plane_state,
	.atomic_print_state = malidp_plane_atomic_print_state,
};

3. drm_atomic_helper_update_plane

int drm_atomic_helper_update_plane(struct drm_plane *plane,
				   struct drm_crtc *crtc,
				   struct drm_framebuffer *fb,
				   int crtc_x, int crtc_y,
				   unsigned int crtc_w, unsigned int crtc_h,
				   uint32_t src_x, uint32_t src_y,
				   uint32_t src_w, uint32_t src_h,
				   struct drm_modeset_acquire_ctx *ctx)
{
	struct drm_atomic_state *state;
	struct drm_plane_state *plane_state;
	int ret = 0;

	state = drm_atomic_state_alloc(plane->dev);
	if (!state)
		return -ENOMEM;

	state->acquire_ctx = ctx;
	plane_state = drm_atomic_get_plane_state(state, plane);
	if (IS_ERR(plane_state)) {
		ret = PTR_ERR(plane_state);
		goto fail;
	}

	ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
	if (ret != 0)
		goto fail;
	drm_atomic_set_fb_for_plane(plane_state, fb);
	plane_state->crtc_x = crtc_x;
	plane_state->crtc_y = crtc_y;
	plane_state->crtc_w = crtc_w;
	plane_state->crtc_h = crtc_h;
	plane_state->src_x = src_x;
	plane_state->src_y = src_y;
	plane_state->src_w = src_w;
	plane_state->src_h = src_h;

	if (plane == crtc->cursor)
		state->legacy_cursor_update = true;

	ret = drm_atomic_commit(state);
fail:
	drm_atomic_state_put(state);
	return ret;
}

        drm_atomic_helper_update_plane最终也会调用drm_atomic_commit,而且其参数都是struct drm_atomic_state。后面我们单独分析。

3.1 drm_atomic_set_fb_for_plane 把framebuffer引用给plane

void
drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state,
			    struct drm_framebuffer *fb)
{
	if (fb)
		DRM_DEBUG_ATOMIC("Set [FB:%d] for plane state %p\n",
				 fb->base.id, plane_state);
	else
		DRM_DEBUG_ATOMIC("Set [NOFB] for plane state %p\n",
				 plane_state);

	drm_framebuffer_assign(&plane_state->fb, fb);
}

4. 流程图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1007229.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Cesium对WMS地图服务进行查询并弹框展示信息

一、简介 Cesium加载WMS地图服务,然后调用接口GetFeatureInfo对要素信息进行查询 二、测试接口 {type: "Point | MultiPoint | LineString | MultiLineString | Polygon | MultiPolygon",coordinates: 数组 } 查询点 http://123.56.67.147:8080/geoserve…

智慧公厕构建城市公共厕所中枢网络,民生服务更高效,城市管理更精准

随着城市化进程的加快,城市人口的不断增长,城市公共厕所问题愈发凸显。大量的人口涌入,公厕资源的不足、管理的不到位,已经成为困扰城市发展的一大难题。然而,智慧公厕的出现,为解决这一问题提供了新的思路…

2023-09-12 LeetCode每日一题(课程表 IV)

2023-03-29每日一题 一、题目编号 1462. 课程表 IV二、题目链接 点击跳转到题目位置 三、题目描述 你总共需要上 numCourses 门课,课程编号依次为 0 到 numCourses-1 。你会得到一个数组 prerequisite ,其中 prerequisites[i] [ai, bi] 表示如果你…

这泼天的富贵,轮到数字化转型升级的企业了

数字化转型是建立在现代信息技术上,利用数字化的一切相关技术创建一种新的、或者对已有的商业模式进行重塑,以此来满足时代变化中传统的业务和市场进行变革。 数字化转型 - 派可数据BI可视化分析平台 出现这种变革是因为经过几十年的经济发展&#xff0…

怎么合并pdf文件到一起?快点过来尝试一下吧

怎么合并pdf文件到一起?pdf文件的使用越来越频繁,相信每个小伙伴都有这样的感受,不管是网上下载到的文件资料,还是合作伙伴发送过来的合作意向书,基本上都会做成pdf格式的文件,因为pdf文件具有更强的稳定性…

记账app排行榜前十名,第2个开店必备!

工欲善其事必先利其器,不管是开店做生意的老板还是个人,想要管理好自己的财富,第一步就是要坚持记账。 现在市面上的记账App有很多,我们选取了秦丝进销存、随手记、智慧记等10款比较有代表性的记账APP,其中有几个是专…

webpack自定义loader解析指定后缀名文件

案例&#xff1a; webpack自定义loader解析.chenjiang后缀名的文件 整体目录&#xff1a; chenjiangLoader.js文件代码 // 正则匹配script标签中的内容 const REG /<script>([\s\S]*)<\/script>/;module.exports function (source) {const __source source.…

拼多多手势验证

国内的好像并没有出现这种&#xff0c;一般都是在海外注册&#xff0c;或者发信才会有。各位大哥想研究的话得需要挂vpn了。 拼多多手势的轨迹其实咋说&#xff0c;难倒是不难&#xff0c;反正要你准确按这个线条描绘出不间断的数据。 它这识别的话&#xff0c;跟狗东的那个还…

运维学习之部署Grafana

sudo nohup wget https://dl.grafana.com/oss/release/grafana-10.1.1.linux-amd64.tar.gz &后台下载压缩包&#xff0c;然后按一下回车键。 ps -aux | grep 15358发现有两条记录&#xff0c;就是还在下载中。 ps -aux | grep 15358发现有一条记录&#xff0c;并且tail …

【03】Charles_ mock服务端返回数据Maplocal

目录 1.适用场景 2.操作方法 3.实现效果 1.适用场景 功能描述&#xff1a; 拦截客户端发出的接口请求&#xff0c;使用本地文档内容&#xff0c;替代服务端返回值。可以使用断点方式&#xff0c;但是断点操作容易超时。 我们可以随时更改本地文档的内容&#xff0c;来模拟各…

提醒一个xampp启动mysql创建函数存在的坑

一直以来本地搭建的项目为了方便我都是使用xampp作为mysql的管理工具&#xff0c;比较简洁可视化比较好。但是最近程序的一个报错暴露了他与mysql之间的一些问题。 使用自增序列nextval函数时&#xff0c;突然抛出来一句&#xff1a; select nextval( SEQ_REGISTER_ID) > …

代码随想录 -- day50 -- 123.买卖股票的最佳时机III 、188.买卖股票的最佳时机IV

123.买卖股票的最佳时机III 动态规划&#xff1a; 关键在于至多买卖两次&#xff0c;这意味着可以买卖一次&#xff0c;可以买卖两次&#xff0c;也可以不买卖。 一天一共就有五个状态&#xff0c; 没有操作 &#xff08;其实我们也可以不设置这个状态&#xff09;第一次持…

微信怎么定时发圈?

定时发圈的妙用 在合适的时间点发布新的产品、促销活动&#xff0c;不仅能够及时提醒用户品牌的存在&#xff0c;还可以引发用户的兴趣&#xff0c;增加品牌的曝光率。 选择最佳的发朋友圈时间段&#xff0c;以确保推广内容得到最大的曝光和关注&#xff0c;提高广告投放的效果…

推进“数智+数治”,中期科技智慧公厕驱动城市公厕更新升级发展

随着城市化的快速发展和人口的不断增加&#xff0c;公共厕所这一基础设施的更新升级成为了亟待解决的问题。过去的传统公厕往往存在着环境脏乱差、无法保证使用者的舒适度等诸多问题。而智慧公厕则能够通过互联网和物联网的技术手段&#xff0c;实现智能化的运行管理&#xff0…

微信小程序 封装请求api

封装请求地址 https.js let baseUrlhttps://XX.XXX.com/index.php/; //自己得服务器地址export {baseUrl}结构目录 封装 request.js import { baseUrl } from ./https.jsmodule.exports {request : function(url, methodType, data){let fullUrl ${baseUrl}${url}// let tok…

mmap详解

想写一篇文章&#xff0c;详细的介绍一下mmap&#xff0c;主要是原理、用法、mmap泄露来进行介绍。说到mmap&#xff0c;首先得从堆空间说起。 申请堆空间 其实&#xff0c;不管是 32 位系统还是 64 位系统&#xff0c;内核都会维护一个变量 brk&#xff0c;指向堆的顶部&…

element-ui框架的el-dialog弹出框被遮罩层挡住了/el-drawer....会生成v-model元素的组件被遮罩层挡住

element-ui框架的el-dialog弹出框被遮罩层遮挡问题_前端李十三的博客-CSDN博客可以发现el-dialog 组件显示的时候被遮罩层挡住了。https://blog.csdn.net/weixin_64530670/article/details/131173159?ydrefereraHR0cHM6Ly9tcC5jc2RuLm5ldC9tcF9ibG9nL21hbmFnZS9hcnRpY2xlP3Nwb…

KubeSphere 在互联网医疗行业的应用实践

作者&#xff1a;宇轩辞白&#xff0c;运维研发工程师&#xff0c;目前专注于云原生、Kubernetes、容器、Linux、运维自动化等领域。 前言 2020 年我国互联网医疗企业迎来了“爆发元年”&#xff0c;越来越多居民在家隔离期间不方便去医院看诊&#xff0c;只好采取在线诊疗的手…

USB接口针式打印机

1 针式打印机原理 - 针式打印机16针是纵向排列&#xff0c;每次打印垂直的16bit&#xff0c;然后右移一bit&#xff0c;继续下列打印&#xff1b;字节的MSB表示最上面的点&#xff0c;字节LSB表示最下面的点 - 由于汉字字模的点阵是横向排列的&#xff0c;而提供给打印头的信息…

java.lang.NoSuchMethodError: java.lang.reflect.Field.trySetAccessible()Z

java.lang.NoSuchMethodError: java.lang.reflect.Field.trySetAccessible()Z 将JDK升级为11即可。 File --Project Structure – SDK Location --Gradle Setting --Gradle JDK 选择11