Linux内核4.14版本——drm框架分析(11)——DRM_IOCTL_MODE_ADDFB2(drm_mode_addfb2)

目录

1. drm_mode_addfb2

2. drm_internal_framebuffer_create

3. drm_fb_cma_create->drm_gem_fb_create->drm_gem_fb_create_with_funcs

4. drm_gem_fb_alloc

 4.1 drm_helper_mode_fill_fb_struct

4.2 drm_framebuffer_init

5. 调用流程图


        书接上回,使用drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create)接口创建了一块内存放在了gem cma的对象里。

        gem obj创建之后需要与一块drm_framebuffer进行绑定使用,因为最终刷图使用的是fb。使用下面接口会创建drm_framebuffer并与上节创建的gem obj进行绑定。

        目前使用较多的就是drm_mode_addfb2接口,该接口完成了下面的功能。

1. drm_mode_addfb2

int drm_mode_addfb2(struct drm_device *dev,void *data, struct drm_file *file_priv)
{struct drm_mode_fb_cmd2 *r = data;struct drm_framebuffer *fb;if (!drm_core_check_feature(dev, DRIVER_MODESET))return -EINVAL;fb = drm_internal_framebuffer_create(dev, r, file_priv);if (IS_ERR(fb))return PTR_ERR(fb);DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);r->fb_id = fb->base.id;/* Transfer ownership to the filp for reaping on close */mutex_lock(&file_priv->fbs_lock);list_add(&fb->filp_head, &file_priv->fbs);mutex_unlock(&file_priv->fbs_lock);return 0;
}

       drm_mode_addfb2主要做了三件大事:

        (1)调用drm_internal_framebuffer_create创建一个drm_framebuffer。

        (2)把drm_framebuffer的struct drm_mode_object的ID返回给应用。

        (3)加到file_priv的fbs链表中。

下面我们看一下函数drm_internal_framebuffer_create。

2. drm_internal_framebuffer_create

struct drm_framebuffer *
drm_internal_framebuffer_create(struct drm_device *dev,const struct drm_mode_fb_cmd2 *r,struct drm_file *file_priv)
{........fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);if (IS_ERR(fb)) {DRM_DEBUG_KMS("could not create framebuffer\n");return fb;}return fb;
}

        检查参数,然后调用dev->mode_config.funcs->fb_create(dev, file_priv, r),可以自己实现,也可以使用内核现成的drm_fb_cma_create。

3. drm_fb_cma_create->drm_gem_fb_create->drm_gem_fb_create_with_funcs


struct drm_framebuffer *
drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,const struct drm_mode_fb_cmd2 *mode_cmd,const struct drm_framebuffer_funcs *funcs)
{const struct drm_format_info *info;struct drm_gem_object *objs[4];struct drm_framebuffer *fb;int ret, i;info = drm_get_format_info(dev, mode_cmd);if (!info)return ERR_PTR(-EINVAL);for (i = 0; i < info->num_planes; i++) {unsigned int width = mode_cmd->width / (i ? info->hsub : 1);unsigned int height = mode_cmd->height / (i ? info->vsub : 1);unsigned int min_size;objs[i] = drm_gem_object_lookup(file, mode_cmd->handles[i]);if (!objs[i]) {DRM_DEV_ERROR(dev->dev, "Failed to lookup GEM\n");ret = -ENOENT;goto err_gem_object_put;}min_size = (height - 1) * mode_cmd->pitches[i]+ width * info->cpp[i]+ mode_cmd->offsets[i];if (objs[i]->size < min_size) {// DRM_DEV_ERROR(dev->dev, "objs %d Size(%d %d) error\n",// 	i, objs[i]->size, min_size);drm_gem_object_put_unlocked(objs[i]);ret = -EINVAL;goto err_gem_object_put;}}fb = drm_gem_fb_alloc(dev, mode_cmd, objs, i, funcs);if (IS_ERR(fb)) {ret = PTR_ERR(fb);DRM_DEV_ERROR(dev->dev, "alloc error %d\n", ret);goto err_gem_object_put;}return fb;err_gem_object_put:for (i--; i >= 0; i--)drm_gem_object_put_unlocked(objs[i]);return ERR_PTR(ret);
}

        (1)通过应用提供的handle,使用drm_gem_object_lookup找到上次创建的gem obj。

        (2)调用drm_gem_fb_alloc,分配一个drm_framebuffer,将gem obj赋值给framebuffer中的obj。

4. drm_gem_fb_alloc

static struct drm_framebuffer *
drm_gem_fb_alloc(struct drm_device *dev,const struct drm_mode_fb_cmd2 *mode_cmd,struct drm_gem_object **obj, unsigned int num_planes,const struct drm_framebuffer_funcs *funcs)
{struct drm_framebuffer *fb;int ret, i;fb = kzalloc(sizeof(*fb), GFP_KERNEL);if (!fb)return ERR_PTR(-ENOMEM);drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);for (i = 0; i < num_planes; i++)fb->obj[i] = obj[i];ret = drm_framebuffer_init(dev, fb, funcs);if (ret) {DRM_DEV_ERROR(dev->dev, "Failed to init framebuffer: %d\n",ret);kfree(fb);return ERR_PTR(ret);}return fb;
}

 4.1 drm_helper_mode_fill_fb_struct

void drm_helper_mode_fill_fb_struct(struct drm_device *dev,struct drm_framebuffer *fb,const struct drm_mode_fb_cmd2 *mode_cmd)
{int i;fb->dev = dev;fb->format = drm_get_format_info(dev, mode_cmd);fb->width = mode_cmd->width;fb->height = mode_cmd->height;for (i = 0; i < 4; i++) {fb->pitches[i] = mode_cmd->pitches[i];fb->offsets[i] = mode_cmd->offsets[i];}fb->modifier = mode_cmd->modifier[0];fb->flags = mode_cmd->flags;
}

      将应用传入的长,宽,format,pitch,flag等填充framebuffer结构体。

4.2 drm_framebuffer_init

int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,const struct drm_framebuffer_funcs *funcs)
{int ret;if (WARN_ON_ONCE(fb->dev != dev || !fb->format))return -EINVAL;INIT_LIST_HEAD(&fb->filp_head);fb->funcs = funcs;ret = __drm_mode_object_add(dev, &fb->base, DRM_MODE_OBJECT_FB,false, drm_framebuffer_free);if (ret)goto out;mutex_lock(&dev->mode_config.fb_lock);dev->mode_config.num_fb++;list_add(&fb->head, &dev->mode_config.fb_list);mutex_unlock(&dev->mode_config.fb_lock);drm_mode_object_register(dev, &fb->base);
out:return ret;
}

        相关字段填充完成后会将fb添加进dev->mode_config.fb_list便于后面使用的时候通过id进行查找, drm的组件都是通过dev->mode_config中的链表进行管理的,只要拿到mode_config就可以拿到drm相关信息。

        至此drm_framebuffer已经创建完毕。通过r->fb_id = fb->base.id;将fb_id返回给用户。

5. 调用流程图

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

USB接口针式打印机

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

看板管理:以可视化方式确定任务优先级

确定工作的优先级是我们今天都要面对的挑战。若处理不当&#xff0c;我们就可能试图一心多用&#xff0c;从而严重损害工作效率。 使用看板方法来设定工作优先级是一种非常直观、快速的方法。 确定工作优先级的看板方法 看板工作流程管理方法的核心在于工作可视化。工作被划…

Docker基础入门

文章目录 前言一、什么是DockerDocker 安装Docker 镜像Docker 容器Docker 安装nginx 前言 在Linux上安装软件有三种方式&#xff1a; 在redhat系列下的发行版通过rpm包安装或者是在debian系列下的发行版通过deb包安装&#xff1b;通过工具安装&#xff0c;在redhat系列下的发…

Mybatis中动态SQL标签和内置参数介绍

Mybatis中动态SQL标签和内置参数 一、MyBatis动态SQL 1.1、sql标签 sql标签用于抽取公用的SQL代码&#xff0c;定义sql标签的时候需要通过【id】属性设置唯一标识。 <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapperPUBLIC "-…

【FAQ】视频监控管理平台/视频汇聚平台EasyCVR安全检查相关问题及解决方法3.0

智能视频监控系统/视频云存储/集中存储/视频汇聚平台EasyCVR具备视频融合汇聚能力&#xff0c;作为安防视频监控综合管理平台&#xff0c;它支持多协议接入、多格式视频流分发&#xff0c;视频监控综合管理平台EasyCVR支持海量视频汇聚管理&#xff0c;可应用在多样化的场景上&…

DHT11 温湿度传感器

目录 1.DHT11 温湿度传感器概述 2.检测DHT11温湿度传感器模块是否存在 3.通过编写代码读取温湿度数据​编辑 4.将读取到的温湿度数据通过串口上传 1.DHT11 温湿度传感器概述 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器&#xff0c;应用领域&am…

【资源推荐】一站式机器学习学习资料

我之前向大家推荐了许多关于人工智能数学原理与应用的资料&#xff0c;其中包括线性代数、机器学习和深度学习等方面的内容。 交互式线性代数学习网站 沉浸式线性代数学习网站 Kaggle大神教你机器学习 今天我将继续向大家推荐一个一站式学习机器学习的绝佳资源&#xff1a;《…

《TCP/IP网络编程》阅读笔记--多线程服务器端的实现

1--多线程的优点 多进程服务器的缺点&#xff1a; ① 创建进程的过程会带来一定的开销&#xff1b; ② 为了完成进程间的数据交换&#xff0c;需要特殊的 IPC 技术&#xff1b; ③ 进程间的上下文切换是创建进程时的最大开销&#xff1b; 多线程的优点&#xff1a; ① 线程的创…

C#类与类库调用注意事项

类 创建一个类文件&#xff0c;myfunction.cs //静态类&#xff1a;直接引用、无需实例化 static public int jiafa(int V) //普通类&#xff1a;引用时需要实例化 public int jiafa(int V)using System; using System.Collections.Generic; using System.Diagnostics; using …

无涯教程-JavaScript - ISNA函数

描述 如果指定的值为Excel&#xff03;N/A错误值,或者表达式返回Excel&#xff03;N/A错误,则ISNA函数将返回逻辑值TRUE。否则返回FALSE。当值不可用于您的公式时,将发生Excel&#xff03;N/A错误。 语法 ISNA (value)争论 Argument描述Required/OptionalvalueValue or exp…

《算法竞赛·快冲300题》每日一题:“点灯游戏”

《算法竞赛快冲300题》将于2024年出版&#xff0c;是《算法竞赛》的辅助练习册。 所有题目放在自建的OJ New Online Judge。 用C/C、Java、Python三种语言给出代码&#xff0c;以中低档题为主&#xff0c;适合入门、进阶。 文章目录 题目描述题解C代码Java代码Python代码 “ 点…

vue cli 打包、生产环境http-proxy-middleware代理

结构树 版本 1、创建vue.config.js const path require(path); const UglifyJsPlugin require(uglifyjs-webpack-plugin) //压缩 const CompressionWebpackPlugin require(compression-webpack-plugin) const isProduction process.env.NODE_ENV ! development;module.exp…

请求与响应以及REST风格

目录 请求与响应请求参数参数传递 五种类型参数传递普通参数POJO数据类型嵌套POJO类型参数数组类型参数集合类型参数 JSON数据传输参数JSON普通数组JSON对象数据JSON对象数组知识点1&#xff1a;EnableWebMvc知识点2&#xff1a;RequestBodyRequestBody与RequestParam区别日期类…

[SICTF 2023] webmisc

文章目录 webBaby_PHP涉及知识点 我全都要RCE你能跟得上我的speed吗 miscPixel_art攻破这个压缩包&#xff01; web Baby_PHP 涉及知识点 php解析特性apache换行解析漏洞无参RCE 源代码 <?php highlight_file(__FILE__); error_reporting(0);$query $_SERVER[QUERY_ST…

OpenCV Series : Target Box Outline Border

角点 P1 (255, 000, 000) P2 (000, 255, 000) P3 (000, 000, 255) P4 (000, 000, 000)垂直矩形框 rect cv2.minAreaRect(cnt)targetColor roi_colortargetThickness 1targetColor (255, 255, 255)if lineVerbose:if True:cv2.line(ph…

做机器视觉工程师,其实挺没意思的

3.康耐视VisionPro高级脚本系列教程-3.脚本编辑错误和运行错误调试方法&#xff0c;break和Contitinuee的差别_哔哩哔哩_bilibili 其实人生就是“有时有意思&#xff0c;有时没意思”。 心里有太多的不甘心&#xff0c;太多的苦水&#xff0c;是没法再吃学习的苦&#xff0c…

市场调查中的信度和效度分析原理及python实现示例

市场调查中的信度和效度分析 1.量表信度分析1.1 内部一致性信度&#xff1a;克朗巴赫α系数原理1.2 python实现示例 2.量表效度分析2.1 内容效度2.1.1 原理2.1.2 python实现示例 2.2 准则效度2.2.1 原理2.2.2 python实现示例 2.3 结构效度2.3.1 原理2.3.2 python实现示例 3.量表…

[PyTorch][chapter 54][GAN- 1]

前言&#xff1a; GAN playground: Experiment with Generative Adversarial Networks in your browser 生成对抗网络&#xff08;Generative Adversarial Nets&#xff0c;GAN&#xff09;是一种基于对抗学习的深度生成模型&#xff0c;最早由Ian Goodfellow于2014年在《Gener…

selenium.chrome怎么写扩展拦截或转发请求?

Selenium WebDriver 是一组开源 API&#xff0c;用于自动测试 Web 应用程序&#xff0c;利用它可以通过代码来控制chrome浏览器&#xff01; 有时候我们需要mock接口的返回&#xff0c;或者拦截和转发请求&#xff0c;今天就来实现这个功能。 代码已开源&#xff1a; https:/…

使用java连接Libvirtd

基于springboot web 一、依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId>&l…