【EmbeddedGUI】脏矩阵设计说明

脏矩阵设计说明

背景介绍

一般情况下,当屏幕内容绘制完毕后,实际应用通常需要更新屏幕中的一部分内容,而不是单纯显示一个静态图片在那。

如下图所示,屏幕中有一个图片控件(Img2)和一个文本控件(Change Text),图片控件是静态不变的,但是文本控件内容是需要变化的。从左边变到右边,文本从《Change Text》变成《New Text》,但是背景并没有变化,如果屏幕有内容变化就去更新整个屏幕,这个不仅会影响CPU性能,还会影响功耗。

对于下面的场景理论上只需要更新红色区域内容即可。只在需要的时候重绘画面中变化的部分。由于基于光栅的绘图技术在数据结构上总表现为一个矩形区域,且画面中变化的内容往往又被称为“弄脏了”的部分——“脏矩阵”故此得名。

脏矩阵技术的应用非常广泛,例如我们所熟悉的Windows系统,大部分时候就只会更新鼠标指针滑动所经过的那一小片矩形区域而已。

因为脏矩阵在降低传输带宽和CPU占用方面有着不可替代的优势,几乎所有的知名GUI协议栈都在默认情况下悄悄地使用各种各样的脏矩阵算法对系统帧率进行优化。

image-20241114205533910

了解脏矩阵基本背景后,脏矩阵主要要解决的问题是屏幕上有哪些内容需要重绘。引用【玩转Arm-2D】如何使用脏矩阵优化帧率(基础篇)-腾讯云开发者社区-腾讯云的一个极端场景。

如下图显示屏从空白到显示一条直线,大多数GUI框架都会重绘整个屏幕内容。

image-20241114211724243

理想的脏矩阵希望是只绘制线覆盖的这部分区域,但是因为脏矩阵都是矩形的,所以这个奇怪的多边形是无法构建的。

image-20241114211951830

那用一连串宽度(Width)和高度(Height)都为1个像素的脏矩阵来精确逼近整个斜线,也就是下图这种形式,理论上是可行,但如何精准的找到这个这些脏矩阵呢?这个需要一个特别聪明的算法,本项目是做不到的。

image-20241114212557053

所以,通过上面分析可以发现。脏矩阵本身虽然可以有效降低刷新区域面积——提高帧率,但生成脏矩阵的算法本身却可能消耗巨大。这里的矛盾在于:太简陋的算法会因为一条对角线就更新整个屏幕;而“想的太多”的算法也可能会因为时间成本的积累而把脏矩阵的带来的收益抵消了不少——难就难在一个度的把握上。

脏矩阵策略

从上面分析来看,脏矩阵不能太智能(嵌入式小设备带不动),也不能说不要,如何设计一个好的策略至关重要。和ARM-2D的设计理念一致,与其让GUI去智能分析哪些区域需要更新,不如让用户自己去告知GUI那些内容需要更新。

对于GUI而言,只需要将用户告知的脏矩阵合并即可。避免作为用户是知道哪些内容是需要更新的,更新的时机也完全由用户来决定,这样对嵌入式设备来说问题就简化了。

在本项目中,所有的控件都是用户构建的,用户需要更新哪个控件的内容,只需要调用egui_view_invalidate接口,就会通知GUI,当前控件需要更新,之后GUI绘制之前,会去计算所有控件的脏矩阵区域,并将重叠的脏矩阵区域合并在一起,最终构建一个脏矩阵列表,在进行屏幕绘制时,会选择PFB和脏矩阵重叠部分,进行绘制。

下面针对各个场景的脏矩阵合并策略进行说明。

场景1

如下图所示,这些控件之间没有重合,egui_core_update_region_dirty这里判断控件和其他脏矩阵有没有重合,没有重合就从egui_core.region_dirty_arr找一个空的位置记录脏矩阵的坐标信息。

最终egui_core.region_dirty_arr会有4个脏矩阵信息。

image-20241114215148268

场景2

如下图所示,Img0和Img1有重叠区域,并且Img0和Img1都需要更新时,Img0对应的脏矩阵是Dirty0.0,Img1对应的脏矩阵是Dirty0.1egui_core_update_region_dirty这里会判断两个脏矩阵有重绘,会通过egui_region_union将2个矩阵合并为Dirty0,存入egui_core.region_dirty_arr中。

Dirty1Dirty0无重合,所以最终egui_core.region_dirty_arr中会有2个脏矩阵信息。

image-20241114215702160

场景3

如下图所示,Img0和Img1有重叠区域,但是只有Img1需要更新时,虽然2个控件重叠了,但是egui_core_update_region_dirty只会保存Dirty0信息,存入egui_core.region_dirty_arr中。

Dirty1Dirty0无重合,所以最终egui_core.region_dirty_arr中会有2个脏矩阵信息。

image-20241114220221459

场景4

如下图所示,考虑移动的场景,用户调用egui_view_scroll_by或者egui_view_scroll_to接口来移动控件,当新移动的位置和之前的位置没有重叠,在egui_view_layout中,会先将当前控件的脏矩阵信息调用egui_core_update_region_dirty更新到脏矩阵列表中,新的位置通过egui_view_invalidate更新,在下次layout时更新脏矩阵中。之后egui_core_update_region_dirty发现新的位置Dirty1Dirty0没重叠,两个信息都存入egui_core.region_dirty_arr中。

Dirty1Dirty0无重合,所以最终egui_core.region_dirty_arr中会有2个脏矩阵信息。

image-20241114221017435

场景5

如下图所示,考虑移动的场景,用户调用egui_view_scroll_by或者egui_view_scroll_to接口来移动控件,当新移动的位置和之前的位置有重叠时,在egui_view_layout中,会先将当前控件的脏矩阵信息调用egui_core_update_region_dirty更新到脏矩阵列表中,新的位置通过egui_view_invalidate更新,在下次layout时更新脏矩阵中。之后egui_core_update_region_dirty发现新的位置Dirty1Dirty0有重叠,两个矩阵合并存入egui_core.region_dirty_arr中。

所以最终egui_core.region_dirty_arr中只有1个脏矩阵Dirty0信息。

image-20241114221420787

通过简单的处理,由用户来通知脏矩阵信息,相比于ARM-2D必须用户给出具体坐标信息,本项目用户只需要告知GUI哪些控件的内容有变化即可,GUI通过控件去构建脏矩阵列表。

脏矩阵屏幕绘制

在构建好脏矩阵信息后,就需要完成屏幕绘制。由于项目绘制是按照PFB来进行的,下面给出几个场景来说明脏矩阵如何实现提升刷新率的目的。

假设按行扫描,下面是可能遇到的各个场景。

场景1

当PFB和脏矩阵不重叠时,这个情况下,这个区域无需绘制。这样就少了很多绘制动作。

image-20241114222128351

场景2

当PFB包含脏矩阵时,这个情况下,虚线是原本需要绘制的PFB区域,但是因为脏矩阵不大,只需要绘制实现部分的PFB就行。这样就少了很多绘制动作。

image-20241114222331905

场景3

当PFB部分包含脏矩阵时,这个情况下,虚线是原本需要绘制的PFB区域,但是因为脏矩阵不大,只需要绘制实现部分的PFB就行。这样就少了很多绘制动作。

image-20241114222434353

场景4

当PFB中包含多个脏矩阵时,这个情况下,虚线是原本需要绘制的PFB区域,但是因为两个脏矩阵不重叠,原本一次绘制,需要变成2次绘制,PFB0绘制1次,FPB1绘制1次。这样就少了很多绘制动作。

image-20241114222617197

脏矩阵无法解决的场景

开篇说的画线的极端场景是无法优化的。

此外在支持触控的场景中,显示帧率性能并不能通过脏矩阵方案提升,如下所示场景,有2个图片Img1和Img2,从右滑动到左边时,整个屏幕的内容还是需要重绘。

所以说脏矩阵并不是万能的,部分场景还是得一个个去挖掘CPU性能。

image-20241114211124771

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【stable diffusion模型】Stability AI出官方教程了,带你轻松玩转Stable Diffusion 3.5

前言 提示(prompt)是有效使用生成式 AI 图像模型的关键技巧。提示的结构直接影响生成的图像的质量、创造力和准确性。 今日凌晨,Stability AI 发布了 Stable Diffusion 3.5 的提示指南。该指南提供了 Stable Diffusion 3.5 的实用提示技巧&a…

docker安装到D盘

双击安装docker默认是安装在c盘,并且安装时我们没法选择位置,如果我们要安装在其他盘可以通过命令行安装 1、下载docker https://docs.docker.com/desktop/setup/install/windows-install/ Docker Desktop 可以使用 WSL 和 Hyper-V任意一种架构&#xf…

11.11机器学习_介绍和定义

一、 机器学习介绍与定义 1. 机器学习定义 机器学习(Machine Learning)本质上就是让计算机自己在数据中学习规律,并根据所得到的规律对未来数据进行预测。 机器学习包括如聚类、分类、决策树、贝叶斯、神经网络、深度学习(Deep…

ssm111基于MVC的舞蹈网站的设计与实现+vue(论文+源码)_kaic

摘 要 随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,舞蹈网站当然也不能排除在外。舞蹈网站是以实际运用为开发背景,运用软件工程开发方法,采用Java技…

蓝桥杯c++算法学习【2】之搜索与查找(九宫格、穿越雷区、迷宫与陷阱、扫地机器人:::非常典型的必刷例题!!!)

别忘了请点个赞收藏关注支持一下博主喵!!! 关注博主,更多蓝桥杯nice题目静待更新:) 搜索与查找 一、九宫格 【问题描述】 小明最近在教邻居家的小朋友小学奥数,而最近正好讲述到了三阶幻方这个部分,三 …

【Windows 常用工具系列 20 -- MobaXterm 登录 WSL】

文章目录 MobaXterm 登录 WSL MobaXterm 登录 WSL 在 WSL 启动之后,打开 MobaXterm: 在 Distribution 中选择自己本地安装的 ubuntu 版本,我这里使用的是ubuntu-20.4,然后在 runmethod 中选择 Localhost connection. 连接成功之…

ReactPress 安装指南:从 MySQL 安装到项目启动

ReactPress Github项目地址:https://github.com/fecommunity/reactpress 欢迎Star。 ReactPress 是一个基于 React 的开源发布平台,适用于搭建博客、网站或内容管理系统(CMS)。本文将详细介绍如何安装 ReactPress,包括…

STM32 使用 STM32CubeMX HAL库实现低功耗模式

STM32 使用 HAL 库的低功耗模式测试使用 ...... 矜辰所致前言 上次画了一个 STM32L010F4 最小系统的板子,也做了一些基本测试,但是最重要的低功耗一直拖到现在,以前在使用 STM32L151 的时候用标准库做过低功耗的项目,现在都使…

NVR小程序接入平台/设备EasyNVR多个NVR同时管理设备接入:海康NVR 3.0提示不在线如何处理?

在视频监控领域,设备的兼容性和互操作性一直是用户关注的重点。海康NVR管理平台EasyNVR作为一款轻量级的视频监控平台,凭借其强大的兼容性、可扩展性和丰富的功能,成为了公共安全领域“云平台”解决方案的杰出代表。然而,在实际应…

【C语言】Union

一.Union的用法 1.什么是Union? union 共用体名{ 成员列表 }; union,“联合体、共用体”,在某种程度上类似结构体struct的一种数据结构,共用体(union)和结构体(struct)同样可以包含很多种数据类型和变量。 2.为什么使用union&#xff1…

2023_Spark_实验十五:SparkSQL进阶操作

实验目标 通过实践掌握Spark SQL中复杂查询(包括子查询、窗口函数、联接等)的实现方式。了解如何通过合理的数据分区和缓存策略进行性能优化。实现一个基于Spark SQL的ETL数据处理流程,应用相关优化技巧。 实验背景 在本实验中&#xff0c…

PaoluGPT——窥视未知

上一题已经得到一个flag,还有一个flag 根据题目信息,说明还有一些聊天记录是没有公开的,另一个flag就在这些未公开的聊天记录中 下载题目附件看看,发现里面有个main.py: 可以看到有两条SQL查询语句,猜测应该…

初识C++ (三)

如果很迷茫的话,就学习吧 引用 一. 引用的概念 “引用(Reference)是 C 相对于C语言的又一个扩充。引用可以看做是数据的一个别名,通过这个别名和原来的名字都能够找到这份数据。 具体是什么意思呢? 我们这里来举个例子 比如:李逵&#xff0…

南京观海微电子----驱动电路中误导通及应对方法

驱动电路中的误导通 功率器件如 MOSFET、IGBT 可以看作是一个受门极电压控制的开关。当门极电压大于开通阈值时,功率器件就会 被开通,而当门极电压低于开通阈值时就会被关断。但是在实际的应用中,由于器件及外围线路寄生参数的影响&#xff0…

C++ —— 哈希详解 - 开散列与闭散列

目录 1. 哈希的概念 1.1 直接定址法 1.2 哈希冲突 1.3 负载因子 1.4 哈希函数 1.4.1 除法散列法/除留余数法 1.4.2 乘法散列法 1.4.3 全域散列法 1.5 处理哈希冲突 1.5.1 开放定址法(闭散列) 1. 线性探测(挨着查找) 2.…

NVR批量管理软件EasyNVR大华NVR管理平台如何在Linux环境下部署?

随着视频监控技术的不断进步,NVR(网络视频录像机)批量管理软件在维护公共安全、提升管理效能方面发挥着越来越重要的作用。EasyNVR作为一款功能强大的NVR批量管理软件,凭借其高效的视频处理能力、灵活的设备接入能力和智能分析功能…

js技能提升——手搓图片组展示——基础积累

// 图片组展示[{name:,src:}]showAltPics(picList[], index0) {if (picList.length 0) {layer.msg("图片路径不对,请重试!", { time: 2000 });return false;}//解析展示let inPicListHtml ;let indexPic picList[index];for (let i 0; i &…

<项目代码>YOLOv8 番茄识别<目标检测>

YOLOv8是一种单阶段(one-stage)检测算法,它将目标检测问题转化为一个回归问题,能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法(如Faster R-CNN),YOLOv8具有更高的…

Llama架构及代码详解

Llama的框架图如图: 源码中含有大量分布式训练相关的代码,读起来比较晦涩难懂,所以我们对llama自顶向下进行了解析及复现,我们对其划分成三层,分别是顶层、中层、和底层,如下: Llama的整体组成…

冒泡选择法(c基础)

适合对象c语言初学者。 冒泡选择法 作用对一个数组进行排序。(介绍一下数组(c基础)(详细版)-CSDN博客) 核心要点 1: 数组元素个数 sz 2: 比较后的交换。 核心思路 进行(sz - 1)趟,每一趟把最大数的放到末尾。其…