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函数的简单封装。

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;
}

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

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

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

相关文章

配置环境变量的作用

配置环境变量的作用 一般运行过程&#xff1a;寻找QQ.exe所在的目录&#xff0c;输入QQ.exe配置环境变量&#xff1a;把QQ所在的路径配给操作系统Path&#xff0c; 在任何路径下都能运行QQ.exe 举例&#xff1a; 定义变量&#xff1a;SCALA_HOME SCALA_HOME、JAVA_HOME 等这…

【论文精读】Learning Transferable Visual Models From Natural Language Supervision

Learning Transferable Visual Models From Natural Language Supervision 前言Abstract1. Introduction and Motivating Work2. Approach2.1. Creating a Sufficiently Large Dataset2.2. Selecting an Efficient Pre-Training Method2.3. Choosing and Scaling a Model2.4. P…

基于STM32的ADC采样及各式滤波实现(HAL库,含VOFA+教程)

前言&#xff1a;本文为手把手教学ADC采样及各式滤波算法的教程&#xff0c;本教程的MCU采用STM32F103ZET6。以HAL库的ADC采样函数为基础进行教学&#xff0c;通过各式常见滤波的实验结果进行分析对比&#xff0c;搭配VOFA工具直观的展示滤波效果。ADC与滤波算法都是嵌入式较为…

第十六章 ObjectScript - 日期和时间值

文章目录 第十六章 ObjectScript - 日期和时间值日期和时间值当地时间UTC Time日期和时间转换$H 格式的详细信息 第十六章 ObjectScript - 日期和时间值 日期和时间值 当地时间 要访问当前进程的日期和时间&#xff0c;可以使用 $HOROLOG 特殊变量。因此&#xff0c;在许多 …

【FreeRTOS】信号量的相关函数使用及示例解释

FreeRTOS中的信号量是一种用于任务间同步的机制。它可以用来实现任务之间的互斥访问共享资源或者等待某个事件发生。 文章目录 信号量类型1. 二进制信号量&#xff08;Binary Semaphore&#xff09;&#xff1a;2. 计数信号量&#xff08;Counting Semaphore&#xff09;&…

python in excel 如何尝鲜 有手就行

众所周知&#xff0c;微软在8月下旬放出消息python已入驻excel&#xff0c;可到底怎么实现呢。 今天我就将发布python in excel的保姆级教程&#xff0c;开始吧&#xff01; 获取office 365 账号 首先我们要有微软office365 这时候需要再万能的某宝去找一个账号&#xff0c;…

Android JNI系列详解之ndk-build工具的使用

一、Android项目中使用ndk-build工具编译库文件 之前介绍过CMake编译工具的使用&#xff0c;今天介绍一种ndk自带的编译工具ndk-build的使用。 ndk-build目前主要有两种配置使用方式&#xff1a; 如上图所示&#xff0c;第一种方式是Android.mkApplication.mkgradle的方式生成…

5.Redis-string

string 字符串 字符串类型是 Redis 最基础的数据类型&#xff0c;关于字符串需要特别注意&#xff1a; 1.⾸先Redis中所有 key 的类型都是字符串类型&#xff0c;⽽且其他⼏种数据结构也都是在字符串类似基础上构建的&#xff0c;例如 list 和 set 的元素类型是字符串类型。 2…

Web_单一视频文件mp4转换为m3u分段ts文件实现边下边播

一、下载ffmpeg: Builds - CODEX FFMPEG @ gyan.dev 二、转换视频文件: 先解压缩,会看到如下结构: 进入bin目录,把需要转换的视频文件复制过来,同时新建一个文件夹用来存放转换后的文件,然后按住Shift键同时单击鼠标右键,选择打开Powershell窗口: 输入以下命令(根据…

【管理运筹学】第 7 章 | 图与网络分析(1,图论背景以及基本概念、术语)

文章目录 引言一、图与网络的基本知识1.1 图与网络的基本概念1.1.1 图的定义1.1.2 图中相关术语1.1.3 一些特殊图类1.1.4 图的运算 写在最后 引言 按照正常进度应该学习动态规划了&#xff0c;但我想换换口味&#xff0c;而且动态规划听说也有一定难度&#xff0c;还不一定会考…

UE5- c++ websocket客户端写法

# 实现目标 ue5 c 实现socket客户端&#xff0c;读取服务端数据&#xff0c;并进行解析 #实现步骤 {projectName}.Build.cs里增加 "WebSockets","JsonUtilities", "Json"配置信息&#xff0c;最终输出如下&#xff1a; using UnrealBuildTool;…

IDEA 快捷键

方法参数顺序快速调整 参数顺序调整 交换参数位置 参数交换位置 编码过程中经常碰到函数调用的参数顺序需要调整的情况。 比如单元测试中&#xff0c;期望和实际值得参数顺序反了&#xff0c;就可以选中参数后或者光标放到要调整的参数位置&#xff0c;然后用 CTRL SHIFTA…

SpringBatch chunk详解

目录 一、Chunk基本概念 1. Chunk的概念: 2. 配置Chunk: 3. Chunk的示例配置: 4. Chunk的执行流程:

maven报错:[ERROR] 不再支持源选项 7。请使用 8 或更高版本。

解决方案 pom.xml文件中增加maven编译的java.version jdk版本设置&#xff0c;以及maven.compiler.source 资源编译jdk版本设置和maven.compiler.target 资源构建jdk版本设置 JDK&#xff1a;6~8 一般都是1.6&#xff0c;1.7&#xff0c;1.8的写法。 <properties><…

前端面试基础面试题——4

1.谈谈你对 ES6 的理解 2.说说你对 promise 的了解 3.解构赋值及其原理 4.Vue常用的修饰符及使用的场景 5.vue 中 key 值的作用 6.什么是 vue 的计算属性&#xff1f; 7.watch的作用是什么 8.计算属性的缓存和方法调用的区别 9.响应式系统的基本原理 10.vue-loader …

基于科大讯飞AIGC创作平台,构建数字人虚拟主播

笔者为体验目前数字人虚拟主播创作视频的质量&#xff0c;特意制作了一段测试视频。 基于讯飞智作创建 总体感受&#xff0c;数字人虚拟主播具有成本低、可定制性强等优点&#xff0c;但是也存在缺乏人情味、技术限制和法律问题等缺点。因此&#xff0c;在使用数字人虚拟主播时…

opencv 提取选中区域内指定hsv颜色的水印

基于《QT 插件化图像算法研究平台》做的功能插件。提取选中区域内指定hsv颜色的水印。 《QT 插件化图像算法研究平台》有个HSV COLOR PICK功能&#xff0c;可以很直观、方便地分析出水印 的hsv颜色&#xff0c;比如, 蓝色&#xff1a;100,180,0,255,100,255。 然后利用 opencv …

QtConcurrent和QFuture的使用

在Qt中&#xff0c;有时候我们会遇到这样一种情况&#xff0c;需要执行一个很长时间的操作&#xff0c;这时候我们的主界面就会卡住。我们的通常做法就是把这个很长时间的操作扔到线程里去处理&#xff0c;可以使用标准库中的线程也可以使用QThread。 如果我们要在这个很长时间…

C# 跨线程访问窗体控件

在不加任何修饰的情况下&#xff0c;C# 默认不允许跨线程访问控件&#xff0c;实际在项目开发过程中&#xff0c;经常使用跨线程操作控件属性&#xff0c;需要设置相关属性才能正确使用&#xff0c;两种方法设置如下&#xff1a; 方法1&#xff1a;告诉编译器取消跨线程访问检…

Springboot GET和POST请求的常用参数获取方式

GET 使用RequestParam注解 可以在控制器方法的参数上使用RequestParam注解来获取请求中的参数值。例如&#xff1a; GetMapping("/example") public String example(RequestParam String param) {// 使用param参数的值return "Value of param: " param…