LVGL fix memory allocation of flush buffers (#21256)

This commit is contained in:
s-hadinger 2024-04-23 20:11:01 +02:00 committed by GitHub
parent 157e1afb29
commit 595b7f750d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 18 additions and 28 deletions

View File

@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file.
- HASPmota `align` attribute and expand PNG cache - HASPmota `align` attribute and expand PNG cache
- LVGL restore `lv_palette` functions - LVGL restore `lv_palette` functions
- IPv6 support in safeboot - IPv6 support in safeboot
- LVGL fix memory allocation of flush buffers
### Removed ### Removed
- LVGL disabled vector graphics - LVGL disabled vector graphics

View File

@ -28,7 +28,7 @@
// b. textcolor,textbgcolor => public; // b. textcolor,textbgcolor => public;
typedef struct LVGL_PARAMS { typedef struct LVGL_PARAMS {
uint16_t fluslines; uint16_t flushlines;
union { union {
uint8_t data; uint8_t data;
struct { struct {

View File

@ -142,7 +142,7 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
epc_full_cnt = 0; epc_full_cnt = 0;
lut_num = 0; lut_num = 0;
lvgl_param.data = 0; lvgl_param.data = 0;
lvgl_param.fluslines = 40; lvgl_param.flushlines = 40;
rot_t[0] = 0; rot_t[0] = 0;
rot_t[1] = 1; rot_t[1] = 1;
rot_t[2] = 2; rot_t[2] = 2;
@ -590,7 +590,7 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
lut3time = next_val(&lp1); lut3time = next_val(&lp1);
break; break;
case 'B': case 'B':
lvgl_param.fluslines = next_val(&lp1); lvgl_param.flushlines = next_val(&lp1);
lvgl_param.data = next_val(&lp1); lvgl_param.data = next_val(&lp1);
break; break;
case 'M': case 'M':

View File

@ -493,7 +493,7 @@ void RA8876::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font) {
bool RA8876::initDisplay() { bool RA8876::initDisplay() {
lvgl_param.fluslines = 10; lvgl_param.flushlines = 10;
SPI.beginTransaction(m_spiSettings); SPI.beginTransaction(m_spiSettings);

View File

@ -63,7 +63,7 @@ int32_t Epd47::Init(void) {
hl = epd_hl_init(WAVEFORM); hl = epd_hl_init(WAVEFORM);
epd47_buffer = epd_hl_get_framebuffer(&hl); epd47_buffer = epd_hl_get_framebuffer(&hl);
framebuffer = epd47_buffer; framebuffer = epd47_buffer;
lvgl_param.fluslines = 10; lvgl_param.flushlines = 10;
return 0; return 0;
} }

View File

@ -33,11 +33,10 @@
struct LVGL_Glue { struct LVGL_Glue {
lv_display_t *lv_display = nullptr; lv_display_t *lv_display = nullptr;
lv_indev_t *lv_indev = nullptr; lv_indev_t *lv_indev = nullptr;
lv_color_t *lv_pixel_buf = nullptr; void *lv_pixel_buf = nullptr;
lv_color_t *lv_pixel_buf2 = nullptr; void *lv_pixel_buf2 = nullptr;
Ticker tick; Ticker tick;
File * screenshot = nullptr; File * screenshot = nullptr;
bool first_frame = true; // Tracks if a call to `lv_flush_callback` needs to wait for DMA transfer to complete
}; };
LVGL_Glue * lvgl_glue; LVGL_Glue * lvgl_glue;
@ -70,10 +69,6 @@ void lv_flush_callback(lv_display_t *disp, const lv_area_t *area, uint8_t *color
// save pixels to file // save pixels to file
int32_t btw = (width * height * LV_COLOR_DEPTH + 7) / 8; int32_t btw = (width * height * LV_COLOR_DEPTH + 7) / 8;
while (btw > 0) { while (btw > 0) {
#if (LV_COLOR_DEPTH == 16) && (LV_COLOR_16_SWAP == 1)
uint16_t * pix = (uint16_t*) color_p;
for (uint32_t i = 0; i < btw / 2; i++) (pix[i] = pix[i] << 8 | pix[i] >> 8);
#endif
if (btw > 0) { // if we had a previous error (ex disk full) don't try to write anymore if (btw > 0) { // if we had a previous error (ex disk full) don't try to write anymore
int32_t ret = lvgl_glue->screenshot->write((const uint8_t*) color_p, btw); int32_t ret = lvgl_glue->screenshot->write((const uint8_t*) color_p, btw);
if (ret >= 0) { if (ret >= 0) {
@ -87,13 +82,6 @@ void lv_flush_callback(lv_display_t *disp, const lv_area_t *area, uint8_t *color
return; // ok return; // ok
} }
if (!lvgl_glue->first_frame) {
//renderer->dmaWait(); // Wait for prior DMA transfer to complete
//disrendererplay->endWrite(); // End transaction from any prior call
} else {
lvgl_glue->first_frame = false;
}
uint32_t pixels_len = width * height; uint32_t pixels_len = width * height;
uint32_t chrono_start = millis(); uint32_t chrono_start = millis();
renderer->setAddrWindow(area->x1, area->y1, area->x1+width, area->y1+height); renderer->setAddrWindow(area->x1, area->y1, area->x1+width, area->y1+height);
@ -407,16 +395,16 @@ void start_lvgl(const char * uconfig) {
bool status_ok = true; bool status_ok = true;
size_t lvgl_buffer_size; size_t lvgl_buffer_size;
do { do {
//lvgl_buffer_size = LV_HOR_RES_MAX * LV_BUFFER_ROWS; uint32_t flushlines = renderer->lvgl_pars()->flushlines;
uint32_t flushlines = renderer->lvgl_pars()->fluslines;
if (0 == flushlines) flushlines = LV_BUFFER_ROWS; if (0 == flushlines) flushlines = LV_BUFFER_ROWS;
lvgl_buffer_size = renderer->width() * flushlines; lvgl_buffer_size = renderer->width() * flushlines;
if (renderer->lvgl_pars()->use_dma) { if (renderer->lvgl_pars()->use_dma) {
lvgl_buffer_size /= 2; lvgl_buffer_size /= 2;
if (lvgl_buffer_size < 1000000) { if (lvgl_buffer_size < 1000000) {
AddLog(LOG_LEVEL_ERROR, "LVG: Allocating buffer2 %i bytes in main memory (flushlines %i)", lvgl_buffer_size * sizeof(lv_color_t), flushlines); // allocate preferably in internal memory which is faster than PSRAM
lvgl_glue->lv_pixel_buf2 = new lv_color_t[lvgl_buffer_size]; AddLog(LOG_LEVEL_DEBUG, "LVG: Allocating buffer2 %i bytes in main memory (flushlines %i)", (lvgl_buffer_size * (LV_COLOR_DEPTH / 8)) / 1024, flushlines);
lvgl_glue->lv_pixel_buf2 = heap_caps_malloc_prefer(lvgl_buffer_size * (LV_COLOR_DEPTH / 8), 2, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT);
} }
if (!lvgl_glue->lv_pixel_buf2) { if (!lvgl_glue->lv_pixel_buf2) {
status_ok = false; status_ok = false;
@ -424,8 +412,9 @@ void start_lvgl(const char * uconfig) {
} }
} }
AddLog(LOG_LEVEL_ERROR, "LVG: Allocating buffer1 %i KB in main memory (flushlines %i)", (lvgl_buffer_size * sizeof(lv_color_t)) / 1024, flushlines); // allocate preferably in internal memory which is faster than PSRAM
lvgl_glue->lv_pixel_buf = new lv_color_t[lvgl_buffer_size]; AddLog(LOG_LEVEL_DEBUG, "LVG: Allocating buffer1 %i KB in main memory (flushlines %i)", (lvgl_buffer_size * (LV_COLOR_DEPTH / 8)) / 1024, flushlines);
lvgl_glue->lv_pixel_buf = heap_caps_malloc_prefer(lvgl_buffer_size * (LV_COLOR_DEPTH / 8), 2, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT);
if (!lvgl_glue->lv_pixel_buf) { if (!lvgl_glue->lv_pixel_buf) {
status_ok = false; status_ok = false;
break; break;
@ -434,11 +423,11 @@ void start_lvgl(const char * uconfig) {
if (!status_ok) { if (!status_ok) {
if (lvgl_glue->lv_pixel_buf) { if (lvgl_glue->lv_pixel_buf) {
delete[] lvgl_glue->lv_pixel_buf; free(lvgl_glue->lv_pixel_buf);
lvgl_glue->lv_pixel_buf = NULL; lvgl_glue->lv_pixel_buf = NULL;
} }
if (lvgl_glue->lv_pixel_buf2) { if (lvgl_glue->lv_pixel_buf2) {
delete[] lvgl_glue->lv_pixel_buf2; free(lvgl_glue->lv_pixel_buf2);
lvgl_glue->lv_pixel_buf2 = NULL; lvgl_glue->lv_pixel_buf2 = NULL;
} }
delete lvgl_glue; delete lvgl_glue;
@ -450,7 +439,7 @@ void start_lvgl(const char * uconfig) {
// Initialize LvGL display driver // Initialize LvGL display driver
lvgl_glue->lv_display = lv_display_create(renderer->width(), renderer->height()); lvgl_glue->lv_display = lv_display_create(renderer->width(), renderer->height());
lv_display_set_flush_cb(lvgl_glue->lv_display, lv_flush_callback); lv_display_set_flush_cb(lvgl_glue->lv_display, lv_flush_callback);
lv_display_set_buffers(lvgl_glue->lv_display, lvgl_glue->lv_pixel_buf, lvgl_glue->lv_pixel_buf2, lvgl_buffer_size, LV_DISPLAY_RENDER_MODE_PARTIAL); lv_display_set_buffers(lvgl_glue->lv_display, lvgl_glue->lv_pixel_buf, lvgl_glue->lv_pixel_buf2, lvgl_buffer_size * (LV_COLOR_DEPTH / 8), LV_DISPLAY_RENDER_MODE_PARTIAL);
// Initialize LvGL input device (touchscreen already started) // Initialize LvGL input device (touchscreen already started)
lvgl_glue->lv_indev = lv_indev_create(); lvgl_glue->lv_indev = lv_indev_create();