硬汉嵌入式论坛

 找回密码
 立即注册
查看: 676|回复: 2
收起左侧

[GUI] LVGL终极优化方案

[复制链接]

4

主题

8

回帖

20

积分

新手上路

积分
20
发表于 2026-6-2 11:31:49 | 显示全部楼层 |阅读模式
通常是使用SDRAM的时候直接绘制显存,然后在垂直消隐区域更换地址,再有其他优化就是使用DMA2D加速

我这里因为板载的SDRAM是16位的,通常频率为120Mhz,带宽为240MB/s,但是实际因为SDRAM内部的一些刷新,打开关闭行的操作,实际是跑不到240MB/s

CPU绘制和LTDC抢总线会很严重

我这里换的方案是在内部AXI RAM给lvgl开辟两个小于屏幕大小的缓存区

然后外部SDRAM开辟一个给LTDC用的显存

显存开辟了3个全屏大小,一个提供给LTDC实时显示,一个提供给DMA搬运,一个防止DMA已经搬运完一帧开始搬运下一帧的时候LTDC还没切换

到这里因为LVGL原生不支持这种模式,需要在lv_refr.c修改lv_inv_area函数

lvgl每次加入新脏区的时候都会判断脏区数量有没有超过限制

如果超过限制就变为全局刷新

在lv_inv_area里手动改为每次都全局刷新

然后还可以在LVGL打开DMA2D给LVGL绘制加速

搬运是异步的,为了不影响CPU绘制和搬运抢DMA2D

我搬运改为使用MDMA

优化完之后帧率:


这个跑分还是不太行,但是查看CPU占用率是满的,且等待flush_cb的回调时间小于1ms

还是CPU绘制时间占了大头

因为每次都是全屏绘制非常慢

LVGL原生不支持这种2+3的局部渲染

脏区是对应当前帧和上一帧

但是切换显存之后当前的缓存区可能是上上帧

于是我这里进行了魔改

同样是在refr文件,自行添加外部缓存的脏区数组

在每次渲染前自己切换

因为这一部分逻辑有些复杂

不同版本的lvgl不一样

源码就暂时先不放出来了

优化完后提升了20帧左右




但是我这里开的是最低编译优化

开到O3之后能有90帧

后面又改了一下refr内部的切换逻辑,因为内部比较脏区逻辑复杂度为o(n2)

同时把刷新时间调到5ms,LTDC时钟为18Mhz

这是优化后的帧率



感觉已经没有其他地方可以改进了

如果还要提升跑分,只能换32位的SDRAM或者是把ARGB888换成RGB565,计算量减半


回复

使用道具 举报

1万

主题

7万

回帖

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
123189
QQ
发表于 2026-6-3 07:50:12 | 显示全部楼层
谢谢楼主分享
回复

使用道具 举报

4

主题

8

回帖

20

积分

新手上路

积分
20
 楼主| 发表于 2026-6-3 21:17:27 | 显示全部楼层
忽然发现没有开启ICache,开完跑分有160帧,提升了50左右
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2026-6-27 23:06 , Processed in 2.094037 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表