mirror of https://github.com/arendst/Tasmota.git
LVGL fix memory allocation of flush buffers (#21256)
This commit is contained in:
parent
157e1afb29
commit
595b7f750d
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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':
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue