自己做的网站微信pc端显示乱码/互联网项目推广
本系列文章基于linux 5.15
在上一篇文章DRM系列七:Drm之DRM_IOCTL_MODE_CREATE_DUMB获取buf的handle和pitch之后,接着使用ioctl(fd, DRM_IOCTL_MODE_ADDFB2, &fb_cmd)创建一个新的帧缓冲区对象(framebuffer object),并将帧缓冲区对象与显存关联起来。
一、整体流程
用户层提供width、height、piexel_format、handle和pitch,然后调用ioctl(fd, DRM_IOCTL_MODE_ADDFB2, &fb_cmd)进入kernel层,调用drm_mode_addfb2_ioctl创建新的帧缓冲区对象(framebuffer object),并将其与显存中的一块内存区域关联起来,返回fb_id供用户层使用。其关系如下图所示:
1.drm_mode_addfb2_ioctl
主要作用是为用户空间的应用程序创建一个新的帧缓冲区对象(framebuffer object),并将其与显存中的一块内存区域关联起来。
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2_ioctl, 0),int drm_mode_addfb2_ioctl(struct drm_device *dev,void *data, struct drm_file *file_priv)
{
#ifdef __BIG_ENDIANif (!dev->mode_config.quirk_addfb_prefer_host_byte_order) {DRM_DEBUG_KMS("addfb2 broken on bigendian");return -EOPNOTSUPP;}
#endifreturn drm_mode_addfb2(dev, data, file_priv);
}
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 -EOPNOTSUPP;fb = drm_internal_framebuffer_create(dev, r, file_priv);if (IS_ERR(fb))return PTR_ERR(fb);/*将新创建的 framebuffer 的 ID 存储到用户空间传递的 drm_mode_fb_cmd2 结构中,以便用户空间可以引用该 framebuffer*/DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);r->fb_id = fb->base.id;/* 帧缓冲区被添加到drm_file(file_priv)拥有的帧缓冲区列表中 */mutex_lock(&file_priv->fbs_lock);list_add(&fb->filp_head, &file_priv->fbs);mutex_unlock(&file_priv->fbs_lock);return 0;
}
1.1drm_internal_framebuffer_create
创建一个 drm_framebuffer 对象并初始化;接着会调用 framebuffer_check 函数对传入的参数进行检查,确保参数有效;最后调用dev->mode_config.funcs->fb_create回调,返回一个 drm_framebuffer 对象。
struct drm_framebuffer *drm_internal_framebuffer_create(struct drm_device *dev,const struct drm_mode_fb_cmd2 *r,struct drm_file *file_priv)
{struct drm_mode_config *config = &dev->mode_config;struct drm_framebuffer *fb;int ret;if (r->flags & ~(DRM_MODE_FB_INTERLACED | DRM_MODE_FB_MODIFIERS)) {DRM_DEBUG_KMS("bad framebuffer flags 0x%08x\n", r->flags);return ERR_PTR(-EINVAL);}/*mode_config的min_width和min_height和帧缓冲区对象的width和height的限制*/if ((config->min_width > r->width) || (r->width > config->max_width)) {DRM_DEBUG_KMS("bad framebuffer width %d, should be >= %d && <= %d\n",r->width, config->min_width, config->max_width);return ERR_PTR(-EINVAL);}if ((config->min_height > r->height) || (r->height > config->max_height)) {DRM_DEBUG_KMS("bad framebuffer height %d, should be >= %d && <= %d\n",r->height, config->min_height, config->max_height);return ERR_PTR(-EINVAL);}if (r->flags & DRM_MODE_FB_MODIFIERS &&!dev->mode_config.allow_fb_modifiers) {DRM_DEBUG_KMS("driver does not support fb modifiers\n");return ERR_PTR(-EINVAL);}/*对传入的参数进行检查,确保参数有效*/ret = framebuffer_check(dev, r);if (ret)return ERR_PTR(ret);/*调用mode_config func的fb_create回调*/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;
}
1.1.1framebuffer_check
对传入的参数进行检查,确保参数有效。
static int framebuffer_check(struct drm_device *dev,const struct drm_mode_fb_cmd2 *r)
{const struct drm_format_info *info;int i;/* check if the format is supported at all */if (!__drm_format_info(r->pixel_format)) {DRM_DEBUG_KMS("bad framebuffer format %p4cc\n",&r->pixel_format);return -EINVAL;}if (r->width == 0) {DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width);return -EINVAL;}if (r->height == 0) {DRM_DEBUG_KMS("bad framebuffer height %u\n", r->height);return -EINVAL;}/* 获取与之相关的像素格式信息 */info = drm_get_format_info(dev, r);for (i = 0; i < info->num_planes; i++) {unsigned int width = fb_plane_width(r->width, info, i);unsigned int height = fb_plane_height(r->height, info, i);unsigned int block_size = info->char_per_block[i];u64 min_pitch = drm_format_info_min_pitch(info, i, width);if (!block_size && (r->modifier[i] == DRM_FORMAT_MOD_LINEAR)) {DRM_DEBUG_KMS("Format requires non-linear modifier for plane %d\n", i);return -EINVAL;}if (!r->handles[i]) {DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i);return -EINVAL;}if (min_pitch > UINT_MAX)return -ERANGE;if ((uint64_t) height * r->pitches[i] + r->offsets[i] > UINT_MAX)return -ERANGE;if (block_size && r->pitches[i] < min_pitch) {DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i);return -EINVAL;}if (r->modifier[i] && !(r->flags & DRM_MODE_FB_MODIFIERS)) {DRM_DEBUG_KMS("bad fb modifier %llu for plane %d\n",r->modifier[i], i);return -EINVAL;}if (r->flags & DRM_MODE_FB_MODIFIERS &&r->modifier[i] != r->modifier[0]) {DRM_DEBUG_KMS("bad fb modifier %llu for plane %d\n",r->modifier[i], i);return -EINVAL;}/* modifier specific checks: */switch (r->modifier[i]) {case DRM_FORMAT_MOD_SAMSUNG_64_32_TILE:/* NOTE: the pitch restriction may be lifted later if it turns* out that no hw has this restriction:*/if (r->pixel_format != DRM_FORMAT_NV12 ||width % 128 || height % 32 ||r->pitches[i] % 128) {DRM_DEBUG_KMS("bad modifier data for plane %d\n", i);return -EINVAL;}break;default:break;}}for (i = info->num_planes; i < 4; i++) {if (r->modifier[i]) {DRM_DEBUG_KMS("non-zero modifier for unused plane %d\n", i);return -EINVAL;}/* Pre-FB_MODIFIERS userspace didn't clear the structs properly. */if (!(r->flags & DRM_MODE_FB_MODIFIERS))continue;if (r->handles[i]) {DRM_DEBUG_KMS("buffer object handle for unused plane %d\n", i);return -EINVAL;}if (r->pitches[i]) {DRM_DEBUG_KMS("non-zero pitch for unused plane %d\n", i);return -EINVAL;}if (r->offsets[i]) {DRM_DEBUG_KMS("non-zero offset for unused plane %d\n", i);return -EINVAL;}}return 0;
}
1.1.1.1drm_get_format_info
用于根据用户空间提供的 framebuffer 创建请求(drm_mode_fb_cmd2),获取与之相关的像素格式信息。在这里会使用dev->mode_config.funcs->get_format_info回调。
const struct drm_format_info *drm_get_format_info(struct drm_device *dev,const struct drm_mode_fb_cmd2 *mode_cmd)
{const struct drm_format_info *info = NULL;if (dev->mode_config.funcs->get_format_info)info = dev->mode_config.funcs->get_format_info(mode_cmd);if (!info)info = drm_format_info(mode_cmd->pixel_format);return info;
}
相关文章:

DRM系列八:Drm之DRM_IOCTL_MODE_ADDFB2
本系列文章基于linux 5.15 在上一篇文章DRM系列七:Drm之DRM_IOCTL_MODE_CREATE_DUMB获取buf的handle和pitch之后,接着使用ioctl(fd, DRM_IOCTL_MODE_ADDFB2, &fb_cmd)创建一个新的帧缓冲区对象(framebuffer object),并将帧缓冲区对象与显…...

软件测试用例篇
设计测试用例是测试面试的必考题,务必好好学 1. 测试用例 测试用例的概念 测试⽤例(Test Case)是为了实施测试而向被测试的系统提供的⼀组集合,这组集合包含:测试环境、操作步骤、测试数据、预期结果等要素。 设计测试⽤…...

PopupMenuButton组件的功能和用法
文章目录 1 概念介绍2 使用方法3 示例代码 我们在上一章回中介绍了Sliver综合示例相关的内容,本章回中将介绍PopupMenuButton组件.闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 我们在本章回中介绍的PopupMenuButton组件位于AppBar右侧,…...

Python进行模型优化与调参
在数据科学与机器学习领域,模型的优化与调参是提高模型性能的重要步骤之一。模型优化可以帮助提高模型的准确性和泛化能力,而合理的调参则能够充分发挥模型的潜力。这篇教程将重点介绍几种常用的模型优化与调参方法,特别是超参数调整和正则化技术的应用。这些技术能够有效地…...

vue2-组件通信
文章目录 vue2-组件通信1. 为什么需要组件通信2. props传递数据3. $emit触发自定义事件4.ref5. EventBus6. p a r e n t 和 parent和 parent和root7. a t t r s 和 attrs和 attrs和listeners8. provide和inject9. vuex10. 总结 vue2-组件通信 1. 为什么需要组件通信 在VUE中…...

20250205确认荣品RK3566开发板在Android13下可以使用命令行reboot -p关机
20250205确认荣品RK3566开发板在Android13下可以使用命令行reboot -p关机 2025/2/5 16:10 缘起:荣品RK3566开发板在Android13下,希望通过Native C语言程序来控制RK3566的关机。 通过ADB,很容易通过reboot -p命令关机。 最开始以为需要su/root…...

设计模式---观察者模式
设计模式—观察者模式 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 主要解决的问题:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,…...

初八开工!开启数字化转型新征程!
新年新气象,大年初八,我们斗志昂扬,共同奔赴充满希望的新一年! 2025 年意义非凡,这是广州市开利网络科技有限公司成立的第 18 个年头 。回首过往,我们一路拼搏,一路成长,积累了深厚的…...

文本分析NLP的常用工具和特点
1)非上下文感知型文本分析工具和特点 特性VADERTextBlob适合文本类型短文本、非正式语言(如评论、推文)中等长度、正式文本情感强度分析支持(正面、负面、中性)支持(极行、主观性)处理表情符号…...

DeepSeek 与 ChatGPT 对比分析
一、技术背景与研发团队 ChatGPT 由 OpenAI 开发,自 2015 年 OpenAI 成立以来,经过多年的技术积累和迭代,从 GPT-1 到 GPT-4o,每一次升级都带来了技术上的突破。OpenAI 拥有雄厚的技术实力和海量的数据、强大的算力支持ÿ…...

vite---依赖优化选项esbuildOptions详解
optimizeDeps.esbuildOptions vite.optimizeDeps.esbuildOptions 是 Vite 配置中的一个选项,它允许你在 Vite 启动时,给 esbuild(Vite 用来处理代码转换和优化的工具)传递额外的配置。通过这个配置项,你可以自定义 esb…...

ElasticSearch 学习课程入门(二)
引子 前文已经介绍了ES的增删改查基本操作,接下来,我们学习下高级点的用法。OK,那就让我们开始吧。 一、ES高级操作 1、条件查询 (1)GET https://127.0.0.1:9200/shopping/_search?qcategory:小米 (2&…...

使用 Redis Streams 实现高性能消息队列
1. 引言 在后端开发中,消息队列是一个常见的组件,主要用于解耦系统、提高吞吐量以及实现异步处理。常见的消息队列包括 Kafka、RabbitMQ 以及 ActiveMQ,但 Redis Streams 作为 Redis 5.0 引入的新特性,也提供了一种高效、轻量的消…...

深度学习|表示学习|卷积神经网络|DeconvNet是什么?|18
如是我闻: DeconvNet(反卷积网络)是一种可视化 CNN(卷积神经网络)内部特征的方法,用于理解 CNN 是如何提取图像特征的。这个方法由 Zeiler & Fergus(2013) 提出,目的…...

(优先级队列(堆)) 【本节目标】 1. 掌握堆的概念及实现 2. 掌握 PriorityQueue 的使用
优先级队列(堆) 1. 优先级队列1.1 概念 2. 优先级队列的模拟实现2.1 堆的概念2.2 堆的存储方式2.3 堆的创建2.3.1 堆向下调整2.3.2 堆的创建2.3.3 建堆的时间复杂度 【本节目标】 掌握堆的概念及实现掌握 PriorityQueue 的使用 1. 优先级队列 1.1 概念…...

优化数据库结构
MySQL学习大纲 一个好的数据库设计方案对于数据库的性能尝尝会起到事倍功半的效果,合理的数据库结构不仅使数据库占用更小的磁盘空间,而且使查询速度更快。数据库结构的设计需要考虑数据冗余、查询和更新速度、字段的数据类型是否合理等多方面的内容&…...

密云生活的初体验
【】在《岁末随笔之碎碎念》里,我通告了自己搬新家的事情。乙巳年开始,我慢慢与大家分享自己买房装修以及在新家的居住体验等情况。 跳过买房装修的内容,今天先说说这三个月的生活体验。 【白河】 潮白河是海河水系五大河之一,贯穿…...

图像分类与目标检测算法
在计算机视觉领域,图像分类与目标检测是两项至关重要的技术。它们通过对图像进行深入解析和理解,为各种应用场景提供了强大的支持。本文将详细介绍这两项技术的算法原理、技术进展以及当前的落地应用。 一、图像分类算法 图像分类是指将输入的图像划分为…...

计算机网络——流量控制
流量控制的基本方法是确保发送方不会以超过接收方处理能力的速度发送数据包。 通常的做法是接收方会向发送方提供某种反馈,如: (1)停止&等待 在任何时候只有一个数据包在传输,发送方发送一个数据包,…...

体验 DeepSeek 多模态大模型 Janus-Pro-7B
含有图片的链接: https://mp.weixin.qq.com/s/i6kuVcGU1CUMYRPDM-bKog?token2020918682&langzh_CN 继上篇文章下载了 Janus-Pro-7B 后,准备本地运行时发现由于电脑配置配置太低(显存小于24G),无法运行࿰…...

使用mockttp库模拟HTTP服务器和客户端进行单元测试
简介 mockttp 是一个用于在 Node.js 中模拟 HTTP 服务器和客户端的库。它可以帮助我们进行单元测试和集成测试,而不需要实际发送 HTTP 请求。 安装 npm install mockttp types/mockttp模拟http服务测试 首先导入并创建一个本地服务器实例 import { getLocal } …...

解决每次打开终端都需要source ~/.bashrc的问题(记录)
新服务器或者电脑通常需要设置一些环境变量,例如新电脑安装了Anaconda等软件,在配置环境变量后发现每次都需要重新source,非常麻烦,执行下面添加脚本实现一劳永逸 vim .bash_profile# .bash_profileif [ -f ~/.bashrc ]; then. ~…...

UE5 蓝图学习计划 - Day 14:搭建基础游戏场景
在上一节中,我们 确定了游戏类型,并完成了 项目搭建、角色蓝图的基础设置(移动)。今天,我们将进一步完善 游戏场景,搭建 地形、墙壁、机关、触发器 等基础元素,并添加角色跳跃功能,为…...

C++常用拷贝和替换算法
算法简介: copy // 容器内指定的元素拷贝到另一容器replace // 将容器内指定范围的旧元素改为新元素replace_if // 容器内指定范围满足条件的元素替换为新元素swap //互换两个容器的元素 1. copy 功能描述: 将容器内指定范围的数据拷贝到另一容器中函…...

取消和确认按钮没有显示的问题
取消和确认按钮没有显示的问题<template #footer> <template #footer> <!-- 使用插槽名称 #footer --> <span class"dialog-footer"> <el-button click"dialogVisible false">取消</el-button> …...

Python安居客二手小区数据爬取(2025年)
目录 2025年安居客二手小区数据爬取观察目标网页观察详情页数据准备工作:安装装备就像打游戏代码详解:每行代码都是你的小兵完整代码大放送爬取结果 2025年安居客二手小区数据爬取 这段时间需要爬取安居客二手小区数据,看了一下相关教程基本…...

Java/Kotlin HashMap 等集合引发 ConcurrentModificationException
在对一些非并发集合同时进行读写的时候,会抛出 ConcurrentModificationException 异常产生示例 示例一(单线程): 遍历集合时候去修改 抛出 ConcurrentModificationException 的主要原因是当你在遍历一个集合(如 Map…...

【Day31 LeetCode】动态规划DP Ⅳ
一、动态规划DP Ⅳ 1、最后一块石头的重量II 1049 这题有点像脑筋急转弯,尽量让石头分成重量相同的两堆(尽可能相同),相撞之后剩下的石头就是最小的。明白这一点,就与上一篇博客里的划分等和数组很相似。划分等和数组…...

Unity 2D实战小游戏开发跳跳鸟 - 记录显示最高分
上一篇文章中我们实现了游戏的开始界面,在开始界面中有一个最高分数的UI,本文将接着实现记录最高分数以及在开始界面中显示最高分数的功能。 添加跳跳鸟死亡事件 要记录最高分,则需要在跳跳鸟死亡时去进行判断当前的分数是否是最高分,如果是最高分则进行记录,如果低于之前…...

Ollama AI 开发助手完全指南:从入门到实践
本文将详细介绍如何使用 Ollama AI 开发助手来提升开发效率,包括环境搭建、模型选择、最佳实践等全方位内容。 © ivwdcwso (ID: u012172506) 目录 基础环境配置模型选择与使用开发工具集成实践应用场景性能优化与注意事项最佳实践总结一、基础环境配置 1.1 系统要求 在…...