feat(lcd): animate fortune results with shared GFX layers

This commit is contained in:
chenjintao
2026-10-10 11:36:54 +08:00
parent bf06618848
commit ee32b4d63f
26 changed files with 3063 additions and 11 deletions
+32 -5
View File
@@ -1,6 +1,6 @@
# GFX 表情显示应用与开发指南
本文面向本项目的开发者,说明当前 `esp_emote_gfx` 的具体应用及后续开发方法。正文使用中文,代码、路径和日志字段保留原名以便检索。适用基线为 2026 年 10 月 9 日的工作区实现;资源和性能数字随代码变化而变化。
本文面向本项目的开发者,说明当前 `esp_emote_gfx` 的具体应用及后续开发方法。正文使用中文,代码、路径和日志字段保留原名以便检索。适用基线包含 2026 年 10 月 10 日的抽签分层动画;资源和性能数字随代码变化而变化。
## 一、当前方案与边界
@@ -8,9 +8,9 @@
- 底层为 ESP32-S3、ST7789P3、单线 SPI,当前像素时钟为 40 MHz,逻辑画布为 320×240。
- 当前使用 `esp_emote_gfx` 3.0.5,由 `platform` 私有依赖。没有接入 `esp_emote_expression` 状态管理组件,也没有把当前表情绘制建立在 LVGL 上。依赖目录中存在其他库不等于当前显示链路使用它们。
- 待机基础表情与 listening 采用 GFX;其他表情仍走原 PNG 或步骤序列,不是所有资产都已经迁移。listening 缓存失败时单独回退旧 PNG,不影响待机。
- 待机基础表情、listening 与五种抽签结果采用 GFX 图层;其他表情仍走原 PNG 或步骤序列,不是所有资产都已经迁移。listening 缓存失败时单独回退旧 PNG,不影响待机。抽签只在开始画面前准备失败时回退,播放途中取消/传输失败不从头重播 PNG。
- 屏幕目前未使用 TE 同步。软件预合成和连续传输能改善撕裂观感,但不能保证面板扫描与写入完全同步。
- 用户已确认待机缓存/固定时间轴以及新 listening 版本的观感满意。两者最终版本尚无新的配套量化日志,不能写成“稳定达到 30 FPS”或“全部实机验收完成”。
- 用户已确认待机缓存/固定时间轴以及新 listening 版本的观感满意。2026-10-10 启动样本中的待机眨眼约 410 ms、步骤约 29.26/s、实际眼型更新约 21.95/s;不是 listening/抽签帧率或全负载验证,不能写成“全部实机验收完成”。
已安装组件提供图片、网格图片、运动、动画、标签、二维码和按钮等接口。但本项目仅实际使用图片、网格、显示刷新及相关对象控制;通用中文文本、按钮、触摸和复杂布局不属于当前已实现能力。
@@ -63,6 +63,11 @@ esp_err_t err = domain_runtime_request_expression(&request);
| `components/platform/internal/lcd_emote_listening.h` | 平台私有插值接口,不向领域或控制层泄漏 GFX 类型 |
| `tools/prepare_listening_expression.py` | 拆分旧 listening、编码往返校验、生成四个 C 资产及同算法动画预览 |
| `tools/test_lcd_listening_gfx.py` | 实际资产、全闭合参数、缓存分配失败、GFX 对象失败、静态像素恢复与切换回归 |
| `components/platform/src/lcd_emote_fortune.c` | 抽签 LZ4 有界解码、轻透视纹理光栅、签文展开、放大与星光 |
| `components/platform/internal/lcd_emote_fortune.h` | 抽签私有图层/纹理/固定窗口契约 |
| `components/platform/src/generated/emote_gfx/fortune_assets.c` | 六个共享图层、五种签文 LZ4 压缩载荷 |
| `tools/prepare_fortune_expression.py` / `tools/preview_fortune_expression.py` | 拆分/压缩与实际 C 算法预览;均不进设备固件 |
| `tools/test_lcd_fortune_gfx.py` | 五签、损坏输入、几何边界、时间轴、取消和释放回归 |
`/tmp` 下修改过程中生成的补丁脚本不是工程运行依赖,不应提交或作为正式资源流程使用。
@@ -178,6 +183,7 @@ RLE(游程长度编码)把连续相同像素写成“数量+像素值”
| --- | --- | --- | --- |
| 普通 PNG 与 GFX 失败后备 | `lcd_source/*.png` | `lcd_optimized/*.png` 经素材包链接入应用 | 原 PNG 解码/缓存链路 |
| 新待机/listening GFX | 原 PNG 与拆分图层 PNG | 六个实际参与编译的 RLE C 资产 | 初始化解压,生成 PSRAM 眼型缓存,之后切换缓存 |
| 五种抽签 GFX | 抽签源 PNG 与 `lcd_layers/chouqian` 拆分层 | 十一图层的 LZ4 block C 数组 | 动作开始解压六个共享层及所选签文,实时局部纹理光栅,结束/取消解绑后释放 |
| 离线预览 | 图层与实际插值算法 | 不入固件 | 在电脑上检查造型,不能模拟 LCD 扫描 |
RLE 的编码往返对转换后的 RGB565+A8 数据无损,不等于原 PNG 的所有 RGB888
@@ -195,6 +201,7 @@ components/platform/assets/
lcd_layers/
jichubiaoqing/ 待机可编辑拆分图层、布局及预览
listening/ 聆听可编辑拆分图层、布局及预览
chouqian/ 抽签共享图层、五种原签文及布局
components/platform/src/generated/emote_gfx/
idle_base.c 实际编译的底图压缩数据
idle_eyes_open.c 实际编译的睁眼压缩数据
@@ -202,6 +209,7 @@ components/platform/src/generated/emote_gfx/
listening_eyes_open.c 实际编译的聆听睁眼关键图
listening_eyes_half.c 实际编译的聆听半闭关键图
listening_eyes_closed.c 实际编译的聆听闭眼关键图
fortune_assets.c 实际编译的抽签 LZ4;不是 RLE
```
半闭眼、闭眼源图及对应历史生成文件不代表当前参与编译;以构建列表为准,不把目录里的全部文件自动加入固件,也不擅自删除旧资源。
@@ -290,7 +298,7 @@ PSRAM 外部内存充足当成内部 DMA 安全。当前 listening 的已接受
## 八、性能日志如何读
通过 `menuconfig` 搜索 `TQ_LCD_EMOTE_GFX_TEST` 和 `TQ_LCD_EMOTE_FPS_LOG`。前者控制 GFX 待机及 listening 路径;后者控制性能统计,默认关闭,当前本地测量配置开启。关闭统计不应改变动画节奏。
通过 `menuconfig` 搜索 `TQ_LCD_EMOTE_GFX_TEST` 和 `TQ_LCD_EMOTE_FPS_LOG`。前者控制 GFX 待机、listening 及抽签路径;后者控制性能统计,默认关闭,当前本地测量配置开启。关闭统计不应改变动画节奏。抽签使用 `fortune_fps`,只计算运动段、不含最后停留,详见抽签开发说明。
每轮完整眨眼输出一次 `emote_fps` 和 `emote_cost`,不在逐帧传输中打印:
@@ -366,7 +374,25 @@ python3 tools/test_lcd_listening_gfx.py
固定窗口/锚点变化需同步脚本与测试。需要手工保留眉毛等素材编辑时,不要直接重新
拆分覆盖;当前生成脚本不是所有角色通用的热替换工具。
### 接入更多表情
### 已接入的五种抽签结果(2026-10-10)
统一抽出、轻透视翻面、问号、签文展开、放大/闪光与回待机。领域仍选择旧六步
序列和所选结果,平台只对完整匹配的资产序列优化;其他步骤序列不受影响。
纹理光栅由平台私有 C 完成,GFX 使用普通图片承接局部合成及 HUD,不是完整
三维引擎或 LVGL 动画。六图层共享,一次只载入一份签文,不建立五套缓存。
旧十八张 PNG 完整保留。详见 [抽签开发说明](抽签分层动画开发说明.zh-CN.md)。
新载荷 43,547 B,应用实际净增 51,856 B(本次构建 3,157,728 B);运动期
像素 PSRAM 278,249 B,加场景描述 148 B,正常结束/取消释放;临时图片对象
普通堆请求 96 B(不含分配器开销);静态可写 RAM 增量 4 B,无新 DMA/任务。
动画前分配失败后备 PNG;已开始后不因错误重播 PNG;解绑异常保留绑定资源
直到重启,不能假装完整释放。不是新格式一定最省 Flash,比较详见资产台账。
本次主机测试、ESP-IDF 5.5.4、日志/GFX 关闭编译及应用烧录校验通过。
启动日志确认待机/listening 缓存成功,短时显示日志无传输/锁/崩溃错误;
尚未捕获实机抽签播放日志,不宣称已测得抽签 FPS 或五签观感已验收。
### 接入更多表情(逐个评估)
先逐个迁移,保留未迁移 PNG 路径。每个表情准备静态层、动态图层、锚点、时间线、缓存预算及结束行为。固定短动作适合预生成缓存;大量不同动作或连续交互需要考虑按需生成、共享缓存和生命周期,不应给每个表情无上限常驻一份整屏缓存。
@@ -397,6 +423,7 @@ python3 tools/test_lcd_status_hud.py
python3 tools/test_lcd_emote_transport.py
python3 tools/test_lcd_emote_timeline.py
python3 tools/test_lcd_listening_gfx.py
python3 tools/test_lcd_fortune_gfx.py
```
这些脚本在电脑上从实际源码提取 C 函数,使用 Clang 与内存、未定义行为检查器。需要 Python 和 Clang;不是固件代码,不占设备 Flash 或 RAM。测试使用模拟接口,不能证明屏幕无撕裂、实时帧率或设备像素完全一致。