How to get better screen change in esp32 based board

Description

how to get better screen change in esp32 based LCD board (480*854 px). how to implement flush callback in esp32 for better screen refresh?

What MCU/Processor/Board and compiler are you using?

ESP32S3 Module (N16R8)

What LVGL version are you using?

V8.1, Espressif IDE

What do you want to achieve?

how to implement Flush Callback. smoother screen change. screen change happened when all invalidate areas copied into the second buffer. is there other options to improve the screen change speed. how to implement DMA with PSRAM and Use it in Flush Callback

What have you tried so far?

using two screen sized buffer as draw buffer. draw buffers are in the external RAM memory.

Code to reproduce

/*
buf1 = heap_caps_malloc(EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES / 1 * sizeof(lv_color_t), MALLOC_CAP_SPIRAM);
assert(buf1);
buf2 = heap_caps_malloc(EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES / 1 * sizeof(lv_color_t), MALLOC_CAP_SPIRAM);
assert(buf2);
// initialize LVGL draw buffers
lv_disp_draw_buf_init(&disp_buf, buf1, buf2, EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES / 1);
/
/

static void example_lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
{
esp_lcd_panel_handle_t panel_handle = (esp_lcd_panel_handle_t) drv->user_data;
int offsetx1 = area->x1;
int offsetx2 = area->x2;
int offsety1 = area->y1;
int offsety2 = area->y2;
#if CONFIG_EXAMPLE_AVOID_TEAR_EFFECT_WITH_SEM
xSemaphoreGive(sem_gui_ready);
xSemaphoreTake(sem_vsync_end, portMAX_DELAY);
#endif
// pass the draw buffer to the driver
esp_lcd_panel_draw_bitmap(panel_handle, offsetx1, offsety1, offsetx2 + 1, offsety2 + 1, color_map);
lv_disp_flush_ready(drv);
}
*/

Screenshot and/or video

ESP32_LCD

1 Like

Forget to use SPIRAM … And basic shool math
Effective max speed your bus to display ? For example with DMA 8 bit 20MHz max
480x854x2 (16bit) = 819840 … 20M/819840 = 24FPS max
but around half time cost preparing data and real with internal framebuf is 12FPS.

Your showed video is horrible slow, but you dont show used bus to LCD.

Enable custom lvgl config so you can see FPS for both use cases.
Personally, in my sample, I didn’t find much of a difference between internal and PSRAM.
Animations are not preferred with slower displays.

LVGL 9 sample here which uses custom lv_conf.h

LTDC is the Display Interface, it seems the slowed animation was because of the frame buffer managing approach. I got much faster animation with stm32-based boards with the same LCD. In the ST-based board, I used the DMA2D for Flush Callback. but for ESP32S3 Based Board I didn’t find any sample code on how to use DMA in flush Callback with External PSRAM as a framebuffer.

Well seeing how how there is a plethora of things that are not known it is going to be hard to help…

What is the connection type? SPI, RGB, I8080
How many lanes if the connection is RGB or I8080
What is the display resolution?
What is the color depth?

How much SPIRAM (PSRAM) does the MCU have?

Doing double buffering without using DMA memory is a complete waste of memory because LVGL is not able to fill the second buffer while the first one is being sent to the display.

If you are running an RGB connection to your display using frame buffers that are external to the RGB driver is going to make it incredibly slow due to the buffer needing to be copied.

From what I am seeing I think you are using an SPI display. If that is the case then you have the frame buffers set way too large and you are not using partial mode to render. You are also not using DMA memory. When using SPI DMA memory can only be allocated from internal memory not SPIRAM. You also have to call a special set of functions and set the SPI up in a very specific way in order for the DMA memory to get used.

What is the connection type? RGB565 using LTDC Interface
How many lanes if the connection is RGB: 565 = 16 data lanes
What is the display resolution? 480*854, 5inch dispaly
What is the color depth? RGB565
How much SPIRAM (PSRAM) does the MCU have? N16R8: 8MB
frame buffers are in the external PSRAM, cat put them in internal RAM: using two screen size partial buffers, as you said without using DMA, deleted one of the partial buffers
and used partial mode to render similar to the attached code
do not use DMA, my intention is how to use it in esp32s3 with external PSRAM
When using SPI DMA memory can only be allocated from internal memory, not SPIRAM: in the tech ref manual it’s possible but how to do it
You also have to call a special set of functions and set the SPI up in a very specific way for the DMA memory to get used: how to do it for external PSRAM, Are there any sources that I can get ideas from

LTDC is not available on the ESP32. So I am guessing you are using an I8080 interface.

The frame buffer size should be 480*854*2/10, if you are using the ESP32-S3 which is looks like you are based on the amount of SPIRAM that is available you should be able to get both frame buffers into internal memory. each frame buffer is 81,984 bytes in size.

There is no way to be able to use DMA memory from SPIRAM using the esp-lcd component other than with an RGB display. The code has not been updated in the ESP-IDF to be able to do this. It is because the buffers need to be allocated at the same time the DMA descriptior is and the DMA descriptor must reside in internal memory.