news 2026/5/9 23:03:24

LVGL部分刷新与整屏交换的冲突解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LVGL部分刷新与整屏交换的冲突解析

原因说明

LV_USE_PERF_MONITOR会在lv_layer_sys()上放一个 FPS 标签,并周期性lv_label_set_text_fmt,只让一小块区域变脏。

你的disp_flush是这样工作的:

static void disp_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) { rt_sem_take(_SemaphoreVsync, RT_WAITING_FOREVER); R_GLCDC_BufferChange(&g_display0_ctrl, (uint8_t *) color_p, (display_frame_layer_t) DISPLAY_FRAME_LAYER_1); lv_disp_flush_ready(disp_drv); }

R_GLCDC_BufferChange是把整屏显存基址切到color_p,相当于“整帧缓冲交换”,并没有按area做局部拷贝
在 LVGL 默认的部分刷新 + 双全屏缓冲下,每次只重绘脏区,缓冲区里其它像素可能是旧的或无效的;硬件却整屏显示这块缓冲 → 就容易出现花屏/错位

性能监视器一开,小区域刷新变多,问题就更容易暴露。
关闭监视器时,刷新节奏、lv_timer_pause行为不同,有时看起来“还能用”,但根因仍是:整指针交换 与 部分刷新 不匹配

LVGL 官方对“双满屏缓冲 + 只换地址”的说明就是:要设disp_drv.full_refresh = 1(见lv_port_disp_template.c里 “Example 3”)。

修改

void lv_port_disp_init(void) { _SemaphoreVsync = rt_sem_create("lvgl_sem", 1, RT_IPC_FLAG_PRIO); if (RT_NULL == _SemaphoreVsync) { rt_kprintf("lvgl semaphore create failed\r\n"); RT_ASSERT(0); } #if LVGL_VERSION_MAJOR < 9 /*Initialize `disp_buf` with the buffer(s). With only one buffer use NULL instead buf_2 */ lv_disp_draw_buf_init(&disp_buf, &fb_background[0][0], &fb_background[1][0], sizeof(fb_background[0])); /*Basic initialization*/ lv_disp_drv_init(&disp_drv); /*Set the resolution of the display*/ disp_drv.hor_res = LV_HOR_RES_MAX; disp_drv.ver_res = LV_VER_RES_MAX; /*Set a display buffer*/ disp_drv.draw_buf = &disp_buf; /* * GLCDC flush only switches the layer base address to a full framebuffer; it does not * merge partial areas. Partial refresh leaves non-dirty pixels stale in the back buffer, * which looks like corruption (often triggered by LV_USE_PERF_MONITOR updating a small label). * LVGL doc: two full-screen buffers + address swap => set full_refresh (see lv_port_disp_template). */ disp_drv.full_refresh = 1; /*Used to copy the buffer's content to the display*/ disp_drv.flush_cb = disp_flush; /*Finally register the driver*/ lv_disp_drv_register(&disp_drv); #else /*------------------------------------ * Create a display and set a flush_cb * -----------------------------------*/ lv_display_t *disp = lv_display_create(LV_HOR_RES_MAX, LV_VER_RES_MAX); lv_display_set_flush_cb(disp, disp_flush); lv_display_set_flush_wait_cb(disp, vsync_wait_cb); lv_display_set_buffers(disp, &fb_background[0][0], &fb_background[1][0], sizeof(fb_background[0]), LV_DISPLAY_RENDER_MODE_DIRECT); #endif lvgl_init_flag = 1; }

lv_port_disp.c里为 LVGL 8 路径增加了disp_drv.full_refresh = 1,保证每次刷新都会画满一整帧再交给 GLCDC,与当前的 BufferChange 用法一致。

代价:任意脏区都会触发整屏重绘,CPU 会高一些;调试时开LV_USE_PERF_MONITOR一般可以接受,正式发布可关掉监视器。

若仍要部分刷新以省算力,就需要改驱动:在flush_cb里按area把像素写入“当前显示用”的那块显存(或 DMA 局部更新),而不能只靠切换整帧指针。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/9 22:59:32

Lidar360 9.1&Lidar360MLS9.1雷达点云数据处理软件

LiDAR360 是北京数字绿土科技股份有限公司自主研发的激光雷达&#xff08;LiDAR&#xff09;点云数据后处理及行业应用软件&#xff0c;专为机载、移动和无人机&#xff08;UAV&#xff09;平台采集的海量点云数据而设计。其核心定位是“为机载数据而生”&#xff0c;具备适配所…

作者头像 李华
网站建设 2026/5/9 22:51:19

PTO Tile Intrinsics 编程模型

PTO Tile Intrinsics 编程模型 【免费下载链接】pto-isa Parallel Tile Operation (PTO) is a virtual instruction set architecture designed by Ascend CANN, focusing on tile-level operations. This repository offers high-performance, cross-platform tile operations…

作者头像 李华
网站建设 2026/5/9 22:51:18

数据库性能优化的两大基石

数据库性能优化是一个永恒的话题&#xff0c;DBA们似乎永远在讨论它。究其原因&#xff0c;性能问题是最终用户抱怨最多的一类技术问题——没有之一。如果DBA能迅速解决性能瓶颈&#xff0c;他们就是团队里的英雄&#xff1b;如果迟迟无法定位问题&#xff0c;再好的架构设计也…

作者头像 李华
网站建设 2026/5/9 22:50:46

Python 爬虫高级实战:百亿级数据爬虫架构优化

前言 随着互联网公开数据源体量呈指数级增长&#xff0c;普通分布式爬虫架构在面对百亿级网页、接口、结构化数据采集场景时&#xff0c;暴露出队列阻塞、节点扩容瓶颈、存储写入瓶颈、去重效率低下、资源开销失控、任务调度混乱等一系列问题。常规多线程、多进程单机爬虫仅能…

作者头像 李华
网站建设 2026/5/9 22:49:30

IT66353:3 进 1 出 HDMI2.0 18Gbps 重定时器切换芯片方案

标签&#xff1a;# 嵌入式硬件 #HDMI 切换器 #4K 高清 #音视频方案 #ITE 芯片一、前言多设备共享显示场景中&#xff0c;机顶盒、游戏主机、电脑、笔记本等多信号源切换需求日益普遍&#xff0c;传统 HDMI 切换器存在长线传输信号衰减、4K60Hz 画面抖动、切换黑屏、兼容性差、外…

作者头像 李华