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
- LVGL restore `lv_palette` functions
- IPv6 support in safeboot
- LVGL fix memory allocation of flush buffers
### Removed
- LVGL disabled vector graphics

View File

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

View File

@ -142,7 +142,7 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
epc_full_cnt = 0;
lut_num = 0;
lvgl_param.data = 0;
lvgl_param.fluslines = 40;
lvgl_param.flushlines = 40;
rot_t[0] = 0;
rot_t[1] = 1;
rot_t[2] = 2;
@ -590,7 +590,7 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
lut3time = next_val(&lp1);
break;
case 'B':
lvgl_param.fluslines = next_val(&lp1);
lvgl_param.flushlines = next_val(&lp1);
lvgl_param.data = next_val(&lp1);
break;
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() {
lvgl_param.fluslines = 10;
lvgl_param.flushlines = 10;
SPI.beginTransaction(m_spiSettings);

View File

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

View File

@ -33,11 +33,10 @@
struct LVGL_Glue {
lv_display_t *lv_display = nullptr;
lv_indev_t *lv_indev = nullptr;
lv_color_t *lv_pixel_buf = nullptr;
lv_color_t *lv_pixel_buf2 = nullptr;
void *lv_pixel_buf = nullptr;
void *lv_pixel_buf2 = nullptr;
Ticker tick;
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;
@ -70,10 +69,6 @@ void lv_flush_callback(lv_display_t *disp, const lv_area_t *area, uint8_t *color
// save pixels to file
int32_t btw = (width * height * LV_COLOR_DEPTH + 7) / 8;
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
int32_t ret = lvgl_glue->screenshot->write((const uint8_t*) color_p, btw);
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
}
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 chrono_start = millis();
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;
size_t lvgl_buffer_size;
do {
//lvgl_buffer_size = LV_HOR_RES_MAX * LV_BUFFER_ROWS;
uint32_t flushlines = renderer->lvgl_pars()->fluslines;
uint32_t flushlines = renderer->lvgl_pars()->flushlines;
if (0 == flushlines) flushlines = LV_BUFFER_ROWS;
lvgl_buffer_size = renderer->width() * flushlines;
if (renderer->lvgl_pars()->use_dma) {
lvgl_buffer_size /= 2;
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);
lvgl_glue->lv_pixel_buf2 = new lv_color_t[lvgl_buffer_size];
// allocate preferably in internal memory which is faster than PSRAM
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) {
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);
lvgl_glue->lv_pixel_buf = new lv_color_t[lvgl_buffer_size];
// allocate preferably in internal memory which is faster than PSRAM
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) {
status_ok = false;
break;
@ -434,11 +423,11 @@ void start_lvgl(const char * uconfig) {
if (!status_ok) {
if (lvgl_glue->lv_pixel_buf) {
delete[] lvgl_glue->lv_pixel_buf;
free(lvgl_glue->lv_pixel_buf);
lvgl_glue->lv_pixel_buf = NULL;
}
if (lvgl_glue->lv_pixel_buf2) {
delete[] lvgl_glue->lv_pixel_buf2;
free(lvgl_glue->lv_pixel_buf2);
lvgl_glue->lv_pixel_buf2 = NULL;
}
delete lvgl_glue;
@ -450,7 +439,7 @@ void start_lvgl(const char * uconfig) {
// Initialize LvGL display driver
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_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)
lvgl_glue->lv_indev = lv_indev_create();