GPU渲染列表模式示例程序
源码路径:example/rt_device/gpu/render_list_mode
警告
未验证
概述
EPIC(ePicasso),是 SiFli 自研的图形引擎,它是专为 2D/2.5D 图像处理设计的硬件加速模块,主要用于分担 CPU 在图像运算中的负载,提升图像处理效率。
图形渲染驱动层提供了两种不同的实现接口(不能同时使用):
单步渲染模式 —— 每准备一个操作之后,就执行对应处理的api
渲染列表模式 —— 准备一帧所有操作,之后异步批量处理
本示例程序演示的是渲染列表模式:将一系列渲染操作(填充、图片、矩形、多边形、边框、圆弧、线、点阵字等)搜集到一个渲染列表中,然后一起渲染。渲染时利用 2 个 1/16 屏幕大小的 framebuffer(render_buffer)分块渲染,并通过回调将渲染结果送到屏幕显示;一次渲染完成后,继续创建新的渲染操作并送屏,实现循环演示。
功能介绍
该例程是一个基于 RT-Thread 操作系统和 EPIC 渲染列表模式的图形演示示例。程序内置 6 个场景,每 10 秒自动切换一次,循环播放:
场景 |
演示内容 |
|---|---|
场景 0 |
全屏灰色填充 → 嵌套渲染列表生成随机色块测试图( |
场景 1 |
纯色填充 → EZIP 压缩格式的时钟背景图(454x454,带缩放)→ 圆弧动画(6 个同心圆弧,前景红色顺时针扫过) |
场景 2 |
纯色填充 → 圆角矩形(交替纯色 / 四角渐变)→ 圆角边框(红色,线宽 20)→ 点阵字(27x30 字模,A8 半透明,铺满屏幕) |
场景 3 |
纯色填充 → 直线(水平虚线、垂直虚线、斜实线,线宽 20)→ 六边形多边形 → 圆弧动画 → 点阵字 |
场景 4 |
纯色填充 → 图片绕 Y 轴 / X 轴 3D 翻转动画(两幅不同尺寸图片,带透视变换) |
场景 5 |
纯色填充 → JPEG 硬件解码图片(454x454,需 |
支持的开发板
例程可以运行在以下开发板(project/proj.conf 为默认单核配置;sf32lb57x 使用独立的 project/sf32lb57x/proj.conf 双核 HCPU 配置):
sf32lb52-lchspi-ulp
sf32lb52-lcd_n16r8
sf32lb56-lcd_a128r12n1
sf32lb57x(双核 HCPU 模式,渲染列表任务在 ACPU 上执行)
硬件需求
支持该示例的开发板:需选用带 PSRAM 的封装(适用于 52x/56x;sf32lb57x 需配合双核 HCPU 配置使用)
配套 LCD 屏:开发板需带有 LCD 显示接口与屏幕(如 sf32lb52-lcd_n16r8、sf32lb56-lcd_a128r12n1)
一根具备数据传输能力的 USB 数据线(用于串口烧录与日志输出)
例程的使用
下面的小节仅提供本示例必需的信息。有关配置 SiFli-SDK 及使用其构建和运行项目的完整步骤,请参阅 SiFli-SDK 快速入门。
编译和烧录
切换到例程 project 目录,运行 scons 命令执行编译(以 sf32lb52-lchspi-ulp 为例):
scons --board=sf32lb52-lchspi-ulp -j8
编译产物生成在 build_sf32lb52-lchspi-ulp_hcpu/ 目录下,执行烧写命令(Windows):
build_sf32lb52-lchspi-ulp_hcpu\uart_download.bat
macOS/Linux 下执行:
./build_sf32lb52-lchspi-ulp_hcpu/uart_download.sh
按提示选择串口端口即可进行下载:
please input the serial port num:6
例程输出结果展示
在 LCD 屏幕上循环播放 6 个场景,每 10 秒切换一个,演示内容见”功能介绍”表格。如果看到以下串口输出,则示例应已正确运行(以下为节选;日志中的场景编号比表格编号大 1,Showing scene 1~6 对应表格中的场景 0~5,循环播放):
__main start
generate_image start
generate_image done
Showing scene 1
Showing scene 2
Showing scene 3
Showing scene 4
Showing scene 5
Showing scene 6
例程的讲解
程序主要流程包括:
初始化 GPU 和 LCD 设备
└─> drv_gpu_open() 打开 GPU 驱动
└─> open_lcd() 打开 LCD 设备并获取屏幕信息、像素对齐要求
└─> drv_epic_setup_render_buffer() 设置 2 个分块渲染 buffer
└─> 生成测试图片(嵌套渲染列表,EPIC_MSG_RENDER_TO_BUF 渲染到 buffer)
└─> while(1) 循环:
├─> drv_epic_alloc_render_list() 申请新的渲染列表
├─> 按当前场景创建一组渲染操作(drv_epic_alloc_op + drv_epic_commit_op)
├─> 提交 EPIC_MSG_RENDER_DRAW 消息开始渲染
├─> partial_done_cb 回调中分块送屏显示(lcd_flush)
├─> 等待渲染完成信号 render_done_sema
└─> 等待 LCD 异步刷屏完成,进入下一帧
渲染列表模式的两种执行场景
渲染 + 送屏(
EPIC_MSG_RENDER_DRAW) 根据配置的渲染 buffer 大小分块渲染,每完成一小块就执行partial_done_cb回调,在回调中刷屏幕。本例程主循环使用的就是这种方式:virtual_render_buf只是描述渲染输出的颜色格式和区域,EPIC_MSG_RENDER_DRAW并不会直接画到这个 buffer,因此data可以不给真实地址(示例中为0xCCCCCCCC)。渲染到指定 buffer(
EPIC_MSG_RENDER_TO_BUF) 直接将渲染结果写到指定 buffer,整个完成后再调用done_cb。本例程的generate_image()用它生成随机色块测试图:渲染到test_imagebuffer,完成后由fill_done_cb释放信号量。
使用到的关键接口
1. GPU / EPIC 渲染列表接口:
接口名 |
功能描述 |
|---|---|
drv_gpu_open() |
初始化 GPU 资源,包括中断等 |
drv_epic_setup_render_buffer() |
设置分块渲染 buffer(需要 2 个一样大小的 buffer) |
drv_epic_alloc_render_list() |
申请一个渲染列表 |
drv_epic_alloc_op() |
在渲染列表中创建一个渲染操作 |
drv_epic_op_alloc_letter() |
在点阵字(LETTERS)操作中分配一个字模 |
drv_epic_commit_op() |
将渲染操作提交到渲染列表 |
drv_epic_render_msg_commit() |
提交渲染消息,启动渲染 |
drv_epic_render_trav() |
遍历渲染列表(用于渲染完成后释放变换矩阵内存等) |
HAL_EPIC_LayerConfigInit() |
初始化图层 / mask 配置结构体 |
2. 渲染消息类型(EPIC_MsgIdDef):
消息类型 |
功能描述 |
|---|---|
EPIC_MSG_RENDER_TO_BUF |
渲染到指定 buffer,完成后调用 done_cb |
EPIC_MSG_RENDER_DRAW |
渲染 + 分块送屏,每块完成调用 partial_done_cb |
EPIC_MSG_RENDER_DRAW2 |
先渲染到 buffer,再将结果绘制到 LCD |
3. 渲染操作类型(drv_epic_op_type_t):
操作类型 |
功能描述 |
|---|---|
DRV_EPIC_DRAW_FILL |
填充(纯色,含透明度) |
DRV_EPIC_DRAW_RECT |
矩形(圆角、四角渐变色) |
DRV_EPIC_DRAW_IMAGE |
图片(ARGB8565 / EZIP / JPEG,支持旋转缩放、3D 变换) |
DRV_EPIC_DRAW_BORDER |
边框(圆角,可分别控制上/下/左/右边) |
DRV_EPIC_DRAW_ARC |
圆弧(起始/结束角度、粗细、圆头圆尾) |
DRV_EPIC_DRAW_LINE |
直线(线宽、虚线、圆头圆尾、无限长) |
DRV_EPIC_DRAW_LETTERS |
点阵字(A8 字模,颜色 + 透明度) |
DRV_EPIC_DRAW_POLYGON |
多边形(最多 16 个顶点) |
4. LCD 显示接口:
接口名 |
功能描述 |
|---|---|
rt_device_find(“lcd”) |
查找 LCD 设备 |
rt_device_open() |
打开 LCD 设备 |
rt_device_control(…, RTGRAPHIC_CTRL_GET_INFO) |
获取 LCD 屏幕信息(分辨率、像素对齐要求) |
rt_device_control(…, RTGRAPHIC_CTRL_SET_BUF_FORMAT) |
设置显存颜色格式(RGB888) |
rt_device_control(…, SF_GRAPHIC_CTRL_LCDC_FLUSH) |
将渲染完成的 buffer 刷到屏幕(lcd_flush) |
rt_device_control(…, RTGRAPHIC_CTRL_SET_NEXT_TE) |
设置下一帧 TE(撕裂效应)同步 |
异常诊断
编译告警 “EPIC driver requrie RT_USING_MESSAGEQUEUE!”:EPIC 驱动通过消息队列提交渲染消息,请确认已开启
RT_USING_MESSAGEQUEUE(RT-Thread Kernel → IPC → Enable message queue)。渲染列表模式在 SF32LB55x 系列上不可用:确认所用芯片为 SF32LB52x / SF32LB56x / SF32LB57x。
场景 5 未显示 JPEG 图片:确认已开启
EPIC_SUPPORT_JPEGD(未开启时该场景回退为 EZIP 图片)。烧录失败或无法下载:确认串口端口选择正确(参见”编译和烧录”中的
please input the serial port num提示)、开发板已连接且驱动正常。画面花屏 / 撕裂:确认渲染 buffer、图片数据等地址满足 4 字节对齐要求;渲染为异步执行,渲染完成前需保持渲染列表引用的数据有效。
如有任何技术疑问,请在 GitHub 上提出 issue。
参考文档
EPIC 图形引擎驱动说明:
docs/source/zh_CN/drivers/epic.md(SDK 内)