当前位置: 首页 > 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 模型结果 多语言…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...

FFmpeg avformat_open_input函数分析

函数内部的总体流程如下&#xff1a; avformat_open_input 精简后的代码如下&#xff1a; int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...

客户案例 | 短视频点播企业海外视频加速与成本优化:MediaPackage+Cloudfront 技术重构实践

01技术背景与业务挑战 某短视频点播企业深耕国内用户市场&#xff0c;但其后台应用系统部署于东南亚印尼 IDC 机房。 随着业务规模扩大&#xff0c;传统架构已较难满足当前企业发展的需求&#xff0c;企业面临着三重挑战&#xff1a; ① 业务&#xff1a;国内用户访问海外服…...