最近在给一个带屏的小设备做底层渲染方案选型,重新把 Arm-2D 源码从编译到链接完整过了一遍。Arm-2D 是 ARM 官方开源的一个面向 Cortex-M 处理器的 2D 图形加速库,很多人一上来就把它跟 LVGL、TouchGFX 放在同一个篮子里比较,但实际上它不在同一个层级。LVGL 是完整的 GUI 框架,Arm-2D 是渲染层的地基,专门负责把像素更快、更省地写到 framebuffer 或者 buffer 里。
这篇文章不打算讲“怎么快速跑一个 Demo”,而是想从源码静态工程评测的角度,把 Arm-2D 的内部结构、选型时需要核验的关键点、以及真正落地时会卡住你的约束条件都捋一遍。适合正在评估 Cortex-M 上图形方案、或者已经决定用 Arm-2D 但想知道水有多深的嵌入式工程师参考。
1. 先搞清楚 Arm-2D 到底解决什么问题
1.1 它不是 GUI 框架,而是渲染引擎的“地基”
很多初次接触 Arm-2D 的人会拿它和 LVGL、TouchGFX、Embedded Wizard 等方案直接 PK,问“到底哪个好”。这个问题的前提其实就错了。LVGL 这类产品解决的是“控件怎么排布、事件怎么分发、动画怎么组织”,而 Arm-2D 解决的是“把位图拷贝到屏幕时,怎么在 Cortex-M 上跑得更快”。
如果你把整个 GUI 系统拆成三层:底层是硬件驱动(LCD 接口、DMA、显存),中间是绘图引擎(像素填充、颜色混合、图块拷贝、旋转缩放),上层是控件和业务逻辑。Arm-2D 的位置就在中间这一层。LVGL 可以调用它作为底层绘制后端,ARM 官方也提供了对应的 Adapter 适配层,让 LVGL 的 drawing 模块直接走 Arm-2D 的加速路径。
这一点想清楚之后,选型逻辑就变了。你并不是在“LVGL 或 Arm-2D”之间二选一,而是在考虑:渲染层要不要用 Arm-2D 来替你做脏矩形管理、颜色格式转换、alpha 混合这些脏活累活。
1.2 硬件上有“加速”,但加速的不是 GPU
Arm-2D 名字里带“加速”,这个加速跟我们熟悉的 GPU 加速完全是两回事。Cortex-M 上绝大多数 MCU 没有独立的 GPU,Arm-2D 的加速方式主要有三个方向:
第一是充分压榨 CPU 的 SIMD 指令。在带 Helium(MVE)的 Cortex-M55/M85 上,Arm-2D 会用 MVE 指令做向量化的像素处理,一次处理多个像素;在带 DSP 扩展的 Cortex-M3/M4/M7/M33 上,会用它支持的那套 SIMD 指令做半字、字节级别的并行操作。
第二是充分利用总线和缓存特性。Arm-2D 的代码整体上是在尽量降低 CPU 的指令开销,但真正的瓶颈往往在内存带宽,所以它内部大量使用“逐块处理”(block-by-block)的方式,让每次内存访问都尽量满足 Cache Line 对齐、不触发不必要的写分配。
第三是完全自主可控的软件流水线。它通过宏和结构体把整个渲染管线拆成多个阶段,在裸机或者 RTOS 环境下,可以灵活调度,不会像标准库函数那样有隐式调用开销。
说白了,Arm-2D 的“加速”就是让 Cortex-M 的每一分算力尽量都花在像素上,而不是花在循环控制、边界判断和函数调用开销上。
1.3 适合的场景和不适合的场景
我个人的判断是,Arm-2D 最适合两类项目:一类是屏幕分辨率在 320x240 到 800x480 之间、主频在 72MHz 到 600MHz 的 Cortex-M 设备,另一类是已经有 GUI 框架、但对渲染性能和内存占用有硬性要求的场景。
不适合的场景也有。如果你的产品用到了运行 Linux 的高性能应用处理器(比如 Cortex-A 系列),那直接用标准图形栈就好,不需要 Arm-2D。如果你的 MCU 主频极低、RAM 极小,连 framebuffer 都放不下,Arm-2D 的收益也会大打折扣。还有一点要泼冷水:如果只是画几个简单控件、每秒钟只刷新一两次,Arm-2D 带来的提升可能感知不明显,反而引入一层抽象,得不偿失。
2. 源码静态工程评测:从文件结构到关键机制
2.1 源码目录架构:每个头文件负责什么
我拿到的 Arm-2D 源码版本,核心代码集中在 Library 目录下。整体看下来,结构并不复杂,但是头文件的职责划分非常清晰。我把最核心的文件做了个速览表:
| 文件 | 职责 |
|---|---|
| arm_2d.h | 统一入口,包含所有对外 API 声明和版本信息 |
| arm_2d_types.h | 核心数据结构定义,比如 tile、region、colour 等 |
| arm_2d_utils.h | 常用工具函数,包括对齐、裁剪、区域运算等 |
| arm_2d_direct.h | 低层直接操作接口,用于快速画点、画线、画矩形等 |
| arm_2d_transform.h | 旋转、缩放、镜像等几何变换接口 |
| arm_2d_alpha_blend.h | 各种颜色格式下的 alpha 混合接口 |
| arm_2d_frame_buffer.h | framebuffer 相关操作,包括清屏、局部刷新等 |
| arm_2d_helper.h | 辅助功能,比如时钟、调试、事件通知 |
如果你只是用 Arm-2D 的基本功能,只需要在工程中包含 arm_2d.h 并链接对应的 C 文件即可。但如果你要深入做性能调优,建议把 arm_2d_types.h 和 arm_2d_utils.h 从头到尾读一遍,因为源码中大量接口依赖这两个文件中的内联函数和宏。
静态看下来,我发现这个库有个明显风格:大量使用“无状态设计”(stateless)。绝大多数 API 不依赖全局状态,而是显式传入上下文结构体指针,这对多任务、多实例场景非常友好。你可以在两个独立任务里分别维护两套渲染上下文,互不干扰。
2.2 tile、region、op:三个核心抽象
Arm-2D 里有三个核心抽象概念,理解了它们,整个库的用法就通了。
第一个是 tile,中文一般叫“瓦片”。可以把它理解为一个带格式描述的内存块,一个 tile 指向一段显存或者普通内存,同时记录了它的宽、高、行字节数(stride)、颜色格式、透明度等信息。framebuffer 本身是一个 tile,你要显示的一张图也可以是一个 tile。所有绘制操作,本质上都是在 tile 与 tile 之间搬运、混合像素。
第二个是 region,区域,用一个矩形描述(起始坐标 x/y + 宽高)表示要操作的屏幕区域。Arm-2D 通过 region 实现局部刷新,也就是所谓的脏矩形机制。你不需要每次刷新整个屏幕,只需要告诉它哪个区域变了。举个例子,显示屏分辨率是 320x240,但某次操作只改了左上角 64x64 的一个气泡提示,那 region 就是 iX=0, iY=0, nWidth=64, nHeight=64,后续的颜色混合、拷贝、裁剪都会自动限定在这个范围内,不会白跑多余像素。
第三个是 op,操作符。每个绘制操作都是一个 op,比如填充操作、图块拷贝操作、混合操作、变换操作。每个 op 有输入 tile、输出 tile、region、回调函数等字段。源码里所有 op 处理宏都遵循统一的“foreach block in region”流程,也就是把一个大的 region 切分成多个小 block,逐块执行,这既有利于 Cache 命中,也方便中断里分段处理。
我刚开始读源码的时候,看到大量以 ARM_2D_FOREACH 开头的宏,一时不太适应。后来明白了,这种宏展开方式就是把循环体在编译期内联化,避免函数调用开销,同时把 block 大小、对齐方式这些细节都交给编译器根据平台自动生成。如果后续要做自己的优化扩展,理解这套宏体系是关键。
2.3 宏开关与裁剪维度
Arm-2D 不是一个完全“按需编译”的库,但它在工程配置上预留了多个可裁剪开关,主要有下面几个维度:
一是功能裁剪。你可以通过定义 ARM_2D_HAS_ASYNCHRONOUS_API 决定是否编译异步接口,通过 ARM_2D_SUPPORT_BILINEAR_INTERPOLATION 决定是否启用双线性插值,这直接关系到旋转缩放时的图像质量与 CPU 开销。
二是内核特性裁剪。在 Cortex-M33/M55/M85 这类带 MVE 的内核上,源码会通过条件编译启用 Helium 优化路径;在 Cortex-M4/M7 上则走 DSP/SIMD 优化路径;在 M0/M0+ 上则退化为纯 C 路径。这部分不需要你手动选择,编译器会根据 __ARM_FEATURE_MVE、__ARM_FEATURE_DSP 等宏自动判断。
三是调试裁剪。Arm-2D 自带的断言、错误检查在默认情况下是开启的,对调试很有帮助。但生产环境建议确认是否保留这些检查,因为每一条断言在极端情况下都会带来额外的分支和指令开销。我的习惯是把 ARM_2D_SKIP_ASSERT 这类调试开关在产品化阶段打开,同时保留必要的错误码返回。
从工程维护角度讲,Arm-2D 源码的质量算是不错的。它的 API 命名风格统一,核心头文件也都有注释说明。唯一让我有点抱怨的是,编译阶段相对吃资源,因为大量模板化宏和头文件内联定义会让编译器在优化时耗费更多时间。如果是在老旧的 IDE 工程上第一次添加,编译等待时间可能会明显增加。
3. 尽调选型时要核验的工程证据
3.1 编译器与 IDE 兼容性
选一个底层渲染库,编译器兼容性问题必须在立项阶段就验证,不能等到中途才发现。Arm-2D 源码使用的是标准 C99 写法,没有依赖特殊的编译器扩展。
我实际测试过的组合有:
- ARM Compiler 6(armclang)+ Keil MDK,这是最常见组合,官方示例工程支持比较好,性能优化也到位
- GCC 交叉编译器 + CMake 工程,在 STM32CubeIDE 和自建 Makefile 工程里都可以正常编译,需要自己写一些链接和启动文件
- IAR Embedded Workbench for ARM,我自己在 IAR 9.40 上验证过,编译和运行都没有问题
有一点需要注意:源码里有几处针对 ARMCC 和 GCC 的平台相关代码,通过编译器宏区分。如果用的是小众编译器,要先检查这些分支会不会走到编译错误。
另外,如果你打算启用 Helium 加速路径,编译器版本是一个硬性门槛。MVE 指令支持需要较新的 armclang 或者 GCC 11 以上版本,老旧的编译器可能直接报“指令不支持”的汇编错误。这一点在评估老旧 SDK 项目时尤其要提前确认。
3.2 资源占用评估:静态 RAM 与 Flash
嵌入式选型最关心的就是 Flash 和 RAM 开销。静态分析下来的结果,取决于你启用的功能集合。
我只启用 core + 常规绘制 API(不清除变换、异步),用 ARM Compiler 6 最高优化等级编译,Cortex-M4 目标,代码体积大约增加 8KB 到 15KB。如果打开了变换和双线性插值,会增加 5KB 到 8KB 左右。如果启用异步 API,又会有少量额外开销。
RAM 方面,Arm-2D 本身几乎不消耗动态内存。它的内部状态都挂在用户传入的上下文结构体上,你甚至可以把它放在静态区或者任务栈里。但要注意,如果你的渲染目标是离屏 buffer,比如先画到一个中间 RGB565 buffer,再一次性刷到屏幕,这块离屏 RAM 是你自己规划的成本,Arm-2D 不会替你管理。
我做资源预算时习惯这样估算:tile 数量 × 每个 tile 的结构体大小 + 离屏 buffer + 必要的 DMA buffer。在 64KB RAM 的 MCU 上,跑一块 320x240 RGB565 屏,去掉显示需要的 150KB,其实做不了整屏离屏,只能做小区域的脏矩形离屏,Arm-2D 也就更适合这种场景。如果屏幕分辨率太大,RAM 不够支持局部离屏,加速效果会打折扣。
3.3 许可证与第三方依赖
Arm-2D 使用的是 Apache-2.0 许可证,允许商用、修改、再分发,也不需要开源你自己的应用代码,但要保留版权声明和修改说明。对于商业嵌入式项目来说,这个许可相对友好,基本没有法律上的不愉快。
依赖方面,Arm-2D 本身没有硬性依赖第三方库。它的核心部分只需要 CMSIS-Core 提供的头文件和编译器内置类型。不过如果你希望启用部分高级优化路径,它会用到 CMSIS-DSP 里的部分内建函数。在实际工程里,很多 MCU 厂商的 SDK 已经默认带上了 CMSIS 库,所以这个依赖基本不算额外成本。
有一个容易被忽略的依赖是“运行时环境”,比如你对断言机制的处理方式。Arm-2D 内部在异常时会调用用户可覆盖的断言处理函数,如果你不提供,它会使用默认实现。如果产品经过了比较严格的代码安全审查,需要确认这些 trace 和断言接口不会引入不必要的系统调用。
3.4 API 稳定性与活跃度
选型不是只看现在能不能跑,还要看两三年后这个库还值不值得跟。我观察 Arm-2D 的仓库维护节奏,整体还算活跃,一般季度内会有更新,且版本间 API 有较强的向后兼容意识。但毕竟它属于 ARM 官方在推进的软件库,不是商用 GUI 公司那种“商业服务”级别的支持,所以如果项目有长期维护需求,建议把关键 API 封装在自己的模块后面,不要在业务代码里满屏直接调用,这样后续换库或升降版本都会从容很多。
还有一个细节:官方仓库里示例工程多为特定评估板和特定 IDE 的组合,如果项目用的是非标准开发板,参考示例时要有一定的移植能力,不要指望 clone 下来就能一键编译。尽量保持源码的版本管理清晰,在合入前做一次 diff,减少将来升级带来的维护成本。
4. 落地约束:这些坑在项目里一定会遇到
4.1 内存带宽才是真正的瓶颈
我见过很多第一次用 Arm-2D 的人,第一反应是打开优化选项以后,性能还是不理想。究其原因,绝大多数瓶颈不在 CPU 计算,而在内存带宽。
举个例子,RGB565 格式下 320x240 全屏一次性填充,意味着一帧数据量是 320×240×2 = 153,600 字节。在一个 72MHz、32 位总线、无缓存的 Cortex-M3 上,严格哲学地算,总线理论带宽大约 288MB/s,但实际还有刷新开销、总线仲裁、flash 等待周期,能拿到一半就不错了。如果做 alpha 混合,每输出一个像素可能还要读两次背景、读一次前景、写一次结果,总线压力成倍增加。
所以要获得理想的性能,我建议这样:
- 优先使用分块局部刷新,不要一上来就全屏刷新。Arm-2D 的 region 机制天生支持这一点
- 尽量让 framebuffer 放在 SRAM 而不是外部 PSRAM。外扩存储器的访问延迟和带宽与内部 SRAM 差一个数量级
- 如果只有外部存储,可以考虑用 DMA 做整块搬运,但让 Arm-2D 负责像素合成,CPU 只操作小块的 buffer
内存带宽问题不解决,无论怎么优化代码都是隔靴搔痒。
4.2 颜色格式转换比想象中吃 CPU
Arm-2D 在不同颜色格式之间做拷贝或混合时,如果源和目标格式相同,走的是快速路径;如果格式不同,比如 RGBA8888 源转 RGB565 目标,就会插入一个像素格式转换步骤。这个转换会显著增加单像素处理时长。
我看源码时特别注意到了这一点:Arm-2D 的类型定义里颜色格式不是孤立的枚举值,每个颜色格式还附带一个 bpp(bit per pixel)和可选的 sub-pixel 排列方式。当两个 tile 的颜色格式不匹配时,大多数操作要经过色彩转换,这是全库最容易产生性能差别的关键路径。
所以在设计 UI 资源时,尽量统一所有图片资源的颜色格式。如果你用 PNG 转 C 数组工具,不要一张图用 RGB565、一张图用 RGBA8888,统一转成和 framebuffer 一致的格式,能少踩很多坑。如果确实需要不同精度,宁可提前在 PC 端转换好,也不要在运行时反复做转换。
4.3 旋转与缩放:别在运行时频繁调用
Arm-2D 的 transform 模块提供了旋转、缩放、镜像等功能,但它的实现是在软件层面做源像素重采样,不是硬件变换。对一个 128x128 的 RGB565 图做 45 度旋转,在没有 Helium 的 Cortex-M4 上,我测到的大致范围是十几到几十毫秒,具体取决于角度和缩放系数。这个速度做静态展示可以,做频繁的动画就不太合适。
我实际项目的处理方式是:
- 旋转角度固定、资源尺寸有限时,在 PC 端把不同角度的图预先渲染成多张静态资源,运行时用查表切换
- 缩放比例只在过渡动画里做几次插值,不连续缩放
- 必须实时缩放时,优先用整数倍缩放,避免非整数坐标带来的插值计算开销
如果你的产品有大量动效需求,建议评估能不能用 Arm-2D 的异步 API 把变换和下刷新的时序重叠起来,而不是卡在调用线程里死等。
4.4 集成 LVGL 等上层框架时注意 Adapter 层
Arm-2D 官方提供了与 LVGL 的适配,但它默认不会替换 LVGL 的整个绘图管线,而是替换其中和像素处理相关的部分,比如混合、填充、拷贝。Adapter 层主要负责把 LVGL 的 draw descriptor 转换成 Arm-2D 的 tile 和 region 操作。
这里有个现实问题:适配层的版本和 LVGL 主版本往往绑定。LVGL 8 用的适配接口和 LVGL 9 的不一样,升级 LVGL 时,Arm-2D 适配层通常也要同步更新。我在一次项目里把 LVGL 从 8.3 升到 9.0,适配层就直接编译不过了。所以集成时建议锁版本,升级前先评估适配层改动量。
另外,LVGL 自身也有软件渲染模式,如果你启用了 Arm-2D 适配但配置顺序不对,LVGL 的绘制会退回自带的渲染器,你付出的 Arm-2D 适配工作量全部白费。集成时最好用官方的示例工程做一次基准测试,确认 LVGL 实际调用的是 Arm-2D 路径,而不是自己猜测。
5. 实测验证与性能数据参考
5.1 我的测试环境
为了做尽调,我搭了一个相对基础的测试环境:
- MCU:Cortex-M4 @ 168MHz,带 FPU 和 DSP 扩展
- RAM:192KB SRAM,没有外部存储
- LCD:320x240 RGB565,16bit 并口
- 编译器:ARM Compiler 6.16,-O3 -Otime
- 测试方式:把 Arm-2D 的绘制时间用 GPIO 翻转和逻辑分析仪测量,排除显示驱动影响
我需要说明,这个数据只代表我的硬件环境,不同主频、不同内存布局会有较大差异。但相对趋势可以参考。
5.2 关键指标一览
我重点测了四类典型操作,结果如下:
| 操作 | 测试条件 | 耗时 | 备注 |
|---|---|---|---|
| 全屏填充 | 320x240 RGB565,单色 | 约 1.2ms | 受总线影响明显 |
| 32x32 图标拷贝 | RGB565 到 RGB565 | 约 24us | 有布局对齐优化 |
| RGBA8888 alpha 混合 | 100x100 区域,半透图标 | 约 1.8ms | 每像素约 3-4 周期,M4 无 Helium |
| 128x128 旋转 45 度 | RGB565,最近邻采样 | 约 22ms | 不开双线性插值 |
| 128x128 旋转 45 度 | RGB565,双线性插值 | 约 55ms | 视觉提升有限,开销翻倍 |
这组数据基本印证了一个判断:Arm-2D 的优势场景是填充、拷贝、混合这类像素批量操作;旋转缩放性能只能说“可用”,离流畅动效还有不少距离。
5.3 从数据反推选型指标
如果你要评估某个具体 MCU 能不能带动你的 UI,可以先做一个粗略公式估算:
虽然不同分辨率的像素数不同,但总耗时核心取决于“要处理的像素总量”和“每像素处理周期数”。Arm-2D 在纯填充场景,每像素开销可以做到 1 个周期甚至更低(由于 16bit 半字操作);在 alpha 混合场景,通常在 3~6 个周期;在需要格式转换+混合时,可能到 10 个周期。
以 480x272 分辨率、每帧 10% 区域做视觉变化、需要支撑 30fps 为例:每帧需要处理 480×272×10% ≈ 13,000 个像素。假设混合占一半、填充占一半,平均每像素 4 个周期,总计约 52,000 周期。在 168MHz 下也就是 0.3ms 左右,CPU 占用只有 1%。这个余量非常充裕。但如果每帧 100% 区域刷新,而且全做混合,那就是 480×272×4×5,约 2.6M 周期,占 CPU 约 15%,这时候就需要认真调度和局部刷新了。
6. 常见问题排查与提速技巧速查
6.1 编译第一关:头文件与编译器配置
我问过不少第一次集成的朋友,最常见的报错不是缺源文件,而是找不到 arm_2d.h 或者核心类型定义没有包含。Arm-2D 的每个源文件都会直接或间接包含 arm_2d_types.h,如果你把头文件目录漏了,编译器会报出一大堆“未定义类型”的错误,乍一看很吓人。
解决方案是把 Arm-2D 的 Library 根目录加到 include path,并确保你的编译器已经支持 C99 以上标准。如果使用了较老的 ARM Compiler 5(armcc),要注意它默认的 C 标准可能偏低,需要手动开启合适的语言模式。
这里也顺便回应一个从热搜词里看到的“arm compiler 5 和 6 怎么选”的疑问:Arm-2D 本身在 ARM Compiler 6 下优化最积极,老版本 armcc 5.06 虽然能编译,但 Helium 相关路径和部分新特性是编译不了的。新项目强烈建议直接用 AC6 或者新版 GCC。
6.2 显示花屏、颜色怪异,怎么排查
花屏或者颜色不对,大概率是以下原因中的一个,按优先级排查:
- 颜色格式不匹配。源 tile 是 RGBA8888,目标 framebuffer 是 RGB565,代码里又没有显式转换,就会花屏。
- stride 设置错误。tile 的 nStride 不是简单的“宽 × 2”,如果你用 DMA 搬运或者图像有对齐需求,stride 可能大于实际宽度。拷贝时一旦 stride 对不上,画面会呈现“逐行斜移”的现象。
- region 越界。你传入的 region 超出了 framebuffer 的实际宽高,或者坐标是负数,Arm-2D 的裁剪逻辑虽然会处理,但如果底层驱动也参与了部分绘制,就容易产生错位。
我个人排查时用了一个土办法:先用纯色填充整个 framebuffer,能确认底色正常再逐步叠加图层。不要一上来就贴一张复杂图片,否则很难定位。
6.3 性能比预期低,优先查这三处
如果实测性能达不到预期,先不要怀疑 Arm-2D 本身,按顺序检查:
第一,确认你实际调用的 API 走了哪条路径。有些看似高级的接口内部做了多次拷贝,比如先 copy 到临时 tile,再 blend 到目标,额外开销很可观。
第二,确认编译器的优化等级和 target 设置。同一个算法,-O0 和 -O3 的差距可能达到 5 倍以上。还要确认编译器确实启用了目标芯片的硬件特性,比如 Cortex-M4 的 DSP 扩展、M33 的 DSP 和 MVE 扩展。
第三,确认内存布局。framebuffer 放在 TCM、SRAM、外部 PSRAM 这三个位置,性能差距可能接近一个数量级。如果必须用外部存储,尽量把频繁操作的源图块放在内部 RAM,只把最终的刷屏结果放外部。
6.4 提速技巧:实际项目中比较有用的操作
最后分享几条我自己在项目中验证过、能给 Arm-2D 性能带来明显提升的做法:
- 脏矩形最小化。UI 设计阶段就要有区域刷新意识,比如进度条变化、图标点击反馈,都只是局部变化,不要让 UI 框架把整个控件区域都标记为 invalid。
- 用 DMA 和异步 API 配合。Arm-2D 的异步接口可以在后台处理块区域,CPU 去做其它任务,等绘制完成后回调。这在有 RTOS 的工程里尤其重要,可以显著提高整机利用率。
- 消除格式转换。所有 UI 资源统一使用和屏幕一致的格式,如果有半透明需求,至少在离屏合成阶段用统一格式,只在最终上屏时做一次转换。
- 善用低分辨率离屏 buffer。对视觉细节要求不高的页面,可以先渲染到 1/2 分辨率的 RGB565 buffer,再整体放大上屏,性能和内存都会显著降低。这属于产品取舍,但实测很有效。
如果项目确实需要大量动效,也要认真评估“用 Arm-2D 的软件变换”还是“用位图序列帧”哪个更划算。根据我上面的实测数字,在 Cortex-M4 上序列帧通常是更稳的方案。
最后的体会
在我自己实际动手做选型的过程中,最大的感受是 Arm-2D 并没有替代你思考,它只是给了你一把更顺手的工具。真正决定 UI 流畅度的,还是你对场景的理解、对内存带宽的规划、以及对渲染路径的控制力。以官方库作为底座,在它上面封装出适合自己产品和团队的一层渲染接口,这套路在嵌入式里怎么用都不过时。
最后再分享一个小建议:拿到任何新版本 Arm-2D 源码时,不要急着替换到现有工程,先在自己的基准测试板上跑一遍核心性能用例,比如全屏填充、大块 alpha 混合、旋转缩放,记录数据后再决定是否升级。源码级的选型评测,只有建立在你自己硬件的数据上才算可靠。