当前位置: 首页 > news >正文

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. 调用流程图

相关文章:

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. 调用流程图 书接上回&#xff0c;使…...

mysql的date_format()函数格式月份的坑

问题背景 我表中有个字段存的是“年-月”格式的字符串&#xff0c;格式是这样的&#xff1a;‘2023-08’ 在查询这个表数据时&#xff0c;我使用了如下sql语句&#xff1a; select * from car where date_format(car_start_month,%Y-%m)<2023-08 意思是查询 car_start_mo…...

保姆级式教程:教你制作电子画册

在这个数字化时代&#xff0c;电子画册成为了展示和分享作品的一种流行方式。制作一个精美的电子画册不仅可以展示你的创意和才华&#xff0c;还可以吸引更多人的关注和欣赏。下面告诉大家一些小步骤&#xff0c;带你一步步学习如何制作电子画册。 1.收集和整理作品 接下来&am…...

探究Nginx应用场景

1 静态资源 Nginx是一个流行的Web服务器和反向代理服务器&#xff0c;它可以用于托管静态资源。下面是一个简单的案例&#xff0c;展示了如何使用Nginx来提供静态资源。 假设你有一个名为example.com的域名&#xff0c;并且你希望使用Nginx来托管位于/var/www/html目录下的静…...

sklearn中的数据集使用

导库 from sklearn.datasets import load_iris 实现 # 加载数据集 iris load_iris() print(f查看数据集&#xff1a;{iris}) print(f查看数据集的特征&#xff1a;{iris.feature_names}) print(f查看数据集的标签&#xff1a;{iris.target_names}) print(f查看数据集的描述…...

LLM在电商推荐系统的探索与实践

本文对LLM推荐的结合范式进行了梳理和讨论&#xff0c;并尝试将LLM涌现的能力迁移应用在推荐系统之中&#xff0c;利用LLM的通用知识来辅助推荐&#xff0c;改善推荐效果和用户体验。 背景 电商推荐系统&#xff08;Recommend System&#xff0c;RecSys&#xff09;是一种基于用…...

Linux 文本操作指令

Linux操作系统提供了许多用于处理文本文件的命令和工具。以下是一些常用的Linux文本命令&#xff1a; cat&#xff1a; 用于查看文本文件的内容&#xff0c;也可以用于合并多个文件。 cat 文件名more和less&#xff1a; 用于逐页查看文本文件&#xff0c;特别是对于大型文件。 …...

GIS地图服务数据可视化

GIS地图服务数据可视化 OSM&#xff08;Open Street Map&#xff0c;开放街道地图&#xff09;Bing地图&#xff08;必应地图&#xff09;Google地图&#xff08;谷歌地图&#xff09; 地图服务数据可视化是根据调用的地图服务请求Web服务器端的地图数据&#xff0c;实现地图数…...

java 获取实体类的反射 Field用法(获取对象的字段名和属性值) 包含注解值 - 如何用枚举类映射获取数据库字段名

实体类映射数据库字段的设计思路 初始思路: 使用 java 的反射 Field 通过注解方法获取实体类属性的注解值,但是如果遇到不是标准的数据库映射的注解方法,那么就无法拿到对应的数据库映射字段名,所以这一点被笔者舍弃了。 什么是标准的映射注解方法,即导入方法后带 anno…...

日志平台搭建第六章:logstash通过kafka通道采集日志信息

1.修改文件/opt/app/elk/logstash-7.5.1/config.d/config1.conf&#xff0c;在input下添加kafka采集配置 #192.168.128.130:9103:kafka地址 #topics:主题 kafka {bootstrap_servers > ["192.168.128.130:9103"]group_id > "logstash"topics > [&…...

mysql的索引分类

索引分类 在 MySQL 数据库&#xff0c;将索引的具体类型主要分为以下几类&#xff1a;主键索引、唯一索引、常规索引、全文索引。 分类 含义 特点 关键字 主键 索引 针对于表中主键创建的索引 默认自动创建 , 只能 有一个 PRIMARY 唯一 索引 避免同一个表中某数据列中…...

【校招VIP】java语言考点之并发相关

考点介绍&#xff1a; 并发在操作系统中是指一个时间段中有几个程序都处于已启动运行到运行完毕之间&#xff0c;且这几个程序都是在同一个处理机上运行&#xff0c;但任一个时刻点上只有一个程序在处理机上运行。并发相关问题在校招面试中出现频次很高。 java语言考点之并发相…...

nginx实现路由重定向功能 避免服务器出现 404 Not Found

首先 到服务器上 vue react等项目路由的重定向已解决不了带后缀的访问 这个重定向需要 nginx 来实现 我们先执行 scp -r 用户名 如果没设置过就是root服务器公网地址:/etc/nginx/nginx.conf E:/拷贝地址这里 我将服务器上的nginx配置文件 拷贝到了本地的 E盘下的 拷贝地址目录…...

Flask+pyecharts+SQLAlchemy,统计图的数据存放在mysql中,综合版

ISEE小语 有人问:“世上最廉价的东西是什么?” 在网上看到这样一个回答说: “大概就是付出吧,一贫如洗的真心、一事无成的温柔、一厢情愿的等待。” 回顾上篇 此篇是在【Flask+pyecharts结合,html统计图呈现在前端页面】和【Flask+pyecharts结合,优化前端加导航栏显示】的…...

SQL注入类型判断

SQL注入的类型分为字符型和数字型&#xff0c;以sqli-labs靶场1、2关为例&#xff1a; 第一关 第一关注入一个1’&#xff0c;错误回显出下面内容&#xff0c;其中1’是注入的内容&#xff0c;0,1后面的单引号和最前面的单引号是一对&#xff0c;剩下的两个单引号是一对&#…...

ElasticSearch的安装部署-----图文介绍

文章目录 背景什么是ElasticSearch使用场景 ElasticSearch的在linux环境下的安装部署前期准备分配权限(正式实操)启动ElasticSearch创建用户组创建用户&#xff0c;并设置密码用户添加到elasticsearch用户组指定用户操作目录的一个操作权限切换用户 解压elasticsearch修改es的配…...

Unity粒子系统ParticleSystem各模块及其参数学习

粒子系统控制面板默认有4个模块&#xff1a;Particle System&#xff08;主模块&#xff09;&#xff0c;Emission&#xff08;发射模块&#xff09;&#xff0c; Shape&#xff08;形状模块&#xff09;&#xff0c;Renderer&#xff08;渲染器模块&#xff09; 1.Particle …...

vue3实现卡片翻牌

vue3实现塔罗牌翻牌 前言一、操作步骤1.布局2.操作3.样式 总结 前言 最近重刷诡秘之主&#xff0c;感觉里面的塔罗牌挺有意思&#xff0c;于是做了一个简单的塔罗牌翻牌动画&#xff08;vue3vitets&#xff09; 一、操作步骤 1.布局 首先我们定义一个整体的塔罗牌盒子&…...

算法训练营day45|动态规划 part07:完全背包 (LeetCode 70. 爬楼梯(进阶)、322. 零钱兑换、279.完全平方数)

文章目录 70. 爬楼梯(进阶)(求排列方法数)思路分析代码实现 322. 零钱兑换(求等于背包重量的最小物品数)思路分析代码实现思考总结 279.完全平方数 (求等于背包重量的最小物品数)思路分析代码实现 70. 爬楼梯(进阶)(求排列方法数) 题目链接&#x1f525; 假设你正在爬楼梯。需…...

【大模型】更强的开源可商用的中英文大语言模型baichuan2来了,从零开始搭建

【大模型】更强的开源可商用的中英文大语言模型baichuan2来了&#xff0c;从零开始搭建 Baichuan 2 介绍技术报告github 地址 模型下载开放协议协议 测试评估通用领域测试7B 模型结果13B 模型结果 法律、医疗7B 模型结果13B 模型结果 数学、代码7B 模型结果13B 模型结果 多语言…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...

Ubuntu系统复制(U盘-电脑硬盘)

所需环境 电脑自带硬盘&#xff1a;1块 (1T) U盘1&#xff1a;Ubuntu系统引导盘&#xff08;用于“U盘2”复制到“电脑自带硬盘”&#xff09; U盘2&#xff1a;Ubuntu系统盘&#xff08;1T&#xff0c;用于被复制&#xff09; &#xff01;&#xff01;&#xff01;建议“电脑…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践

在 Kubernetes 集群中&#xff0c;如何在保障应用高可用的同时有效地管理资源&#xff0c;一直是运维人员和开发者关注的重点。随着微服务架构的普及&#xff0c;集群内各个服务的负载波动日趋明显&#xff0c;传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...