diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bef96710..3490563c9 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. ## [15.6.0.3] ### Added - +- LVGL option to prefer PSRAM for draw buffers using bit 5 (0x20) of `:B` in display.ini ### Breaking Changed diff --git a/lib/lib_display/Display_Renderer-gemu-1.0/src/renderer.h b/lib/lib_display/Display_Renderer-gemu-1.0/src/renderer.h index 812c12bbb..99dc92146 100644 --- a/lib/lib_display/Display_Renderer-gemu-1.0/src/renderer.h +++ b/lib/lib_display/Display_Renderer-gemu-1.0/src/renderer.h @@ -37,7 +37,7 @@ typedef struct LVGL_PARAMS { uint8_t async_dma : 1; // force DMA completion before returning, avoid conflict with other devices on same bus. If set you should make sure the display is the only device on the bus uint8_t busy_invert : 1; uint8_t invert_bw : 1; - uint8_t resvd_3 : 1; + uint8_t use_psram : 1; // bit 5 (0x20): prefer PSRAM for LVGL draw buffers (ex: ESP32-P4 DSI), falls back to internal RAM uint8_t resvd_4 : 1; uint8_t resvd_5 : 1; }; diff --git a/lib/lib_display/UDisplay/include/uDisplay_SPI_panel.h b/lib/lib_display/UDisplay/include/uDisplay_SPI_panel.h index 4981d6b51..13c456dd8 100644 --- a/lib/lib_display/UDisplay/include/uDisplay_SPI_panel.h +++ b/lib/lib_display/UDisplay/include/uDisplay_SPI_panel.h @@ -23,7 +23,7 @@ typedef struct LVGL_PARAMS_t { uint8_t async_dma : 1; // force DMA completion before returning, avoid conflict with other devices on same bus. If set you should make sure the display is the only device on the bus uint8_t busy_invert : 1; uint8_t invert_bw : 1; - uint8_t resvd_3 : 1; + uint8_t use_psram : 1; // bit 5 (0x20): prefer PSRAM for LVGL draw buffers (ex: ESP32-P4 DSI), falls back to internal RAM uint8_t resvd_4 : 1; uint8_t resvd_5 : 1; }; diff --git a/tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino b/tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino index de684aeeb..979e67eec 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_54_lvgl.ino @@ -481,12 +481,19 @@ void start_lvgl(const char * uconfig) { if (0 == flushlines) flushlines = LV_BUFFER_ROWS; lvgl_buffer_size = renderer->width() * flushlines; + // By default allocate preferably in internal memory which is faster than PSRAM. + // If bit 5 (0x20) of `:B` is set in display.ini, prefer PSRAM instead: this saves + // internal memory and can be faster with large flushlines on ESP32-P4 DSI panels. + // In both cases, fall back to the other memory type if allocation fails. + bool prefer_psram = renderer->lvgl_pars()->use_psram; + uint32_t caps_first = MALLOC_CAP_8BIT | (prefer_psram ? MALLOC_CAP_SPIRAM : MALLOC_CAP_INTERNAL); + uint32_t caps_second = MALLOC_CAP_8BIT; + const char * mem_pref = prefer_psram ? "PSRAM" : "main memory"; if (renderer->lvgl_pars()->use_dma) { lvgl_buffer_size /= 2; if (lvgl_buffer_size < 1000000) { - // 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); + AddLog(LOG_LEVEL_DEBUG, "LVG: Allocating buffer2 %i KB preferably in %s (flushlines %i)", (lvgl_buffer_size * (LV_COLOR_DEPTH / 8)) / 1024, mem_pref, flushlines); + lvgl_glue->lv_pixel_buf2 = heap_caps_malloc_prefer(lvgl_buffer_size * (LV_COLOR_DEPTH / 8), 2, caps_first, caps_second); } if (!lvgl_glue->lv_pixel_buf2) { status_ok = false; @@ -494,9 +501,8 @@ void start_lvgl(const char * uconfig) { } } - // 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); + AddLog(LOG_LEVEL_DEBUG, "LVG: Allocating buffer1 %i KB preferably in %s (flushlines %i)", (lvgl_buffer_size * (LV_COLOR_DEPTH / 8)) / 1024, mem_pref, flushlines); + lvgl_glue->lv_pixel_buf = heap_caps_malloc_prefer(lvgl_buffer_size * (LV_COLOR_DEPTH / 8), 2, caps_first, caps_second); if (!lvgl_glue->lv_pixel_buf) { status_ok = false; break;