Skip to content

trans_size field in lvgl_port_display_cfg_t is unused in LVGL9 — PSRAM framebuffers fail on SPI panels (BSP-783) #726

Description

@orioncode-eu

Board

Waveshare Development Board With 3.49inch IPS

Hardware Description

ESP32-S3 High-Performance Development Board With 3.49inch IPS Capacitive Touch Display, 172 × 640 Resolution, Integrated With ESP32-S3R8 Dual-core Processor
ESP32-S3 with QSPI LCD panel (AXS15231B 172×640), 8MB PSRAM

IDE Name

VSCode, esp_lvgl_port 2.7.1, LVGL 9.4.0, ESP-IDF 5.5.2

Operating System

Windows 10

Description

The lvgl_port_display_cfg_t struct exposes a trans_size field:
uint32_t trans_size; /*!< Allocated buffer will be in SRAM to move framebuf (optional) */
In the LVGL8 version (esp_lvgl_port_disp.c), this field is used to:

  1. Allocate a DMA-capable SRAM buffer (trans_buf) via heap_caps_malloc(..., MALLOC_CAP_DMA)
  2. In the flush callback, copy framebuffer data from PSRAM to trans_buf in chunks, calling draw_bitmap per chunk with semaphore synchronization between transfers

In the LVGL9 version (esp_lvgl_port_disp.c), this field is completely ignored. The lvgl_port_display_ctx_t struct does not contain trans_buf or trans_size. The flush callback passes the entire PSRAM buffer directly to esp_lcd_panel_draw_bitmap() in a single call.

Impact:
For SPI-connected panels with full-screen PSRAM buffers (e.g., 172×640×2 = 220KB for full_refresh mode), the single draw_bitmap call attempts a 220KB SPI DMA transfer from PSRAM, which fails:
panel_io_spi_tx_color(395): spi transmit (queue) color failed

LVGL then hangs in wait_for_flushing and the watchdog triggers every 5 seconds.

Users setting trans_size to enable chunking get no error, no warning — the code compiles and runs, but trans_size has no effect whatsoever.

Workaround:
A panel wrapper that intercepts draw_bitmap, copies chunks from PSRAM to a small DMA-capable SRAM buffer via memcpy, and calls the real panel's draw_bitmap per chunk. The wrapper also manually calls lv_disp_flush_ready() after the last chunk and disables the auto-registered on_color_trans_done callback.

Expected behavior:
Either:

  1. Implement trans_size chunking in the LVGL9 flush callback (port the LVGL8 logic), or
  2. Remove the trans_size field from the config struct and document that PSRAM framebuffers require a custom panel wrapper for SPI panels, or
  3. Emit a warning at runtime when trans_size > 0 and LVGL9 is used, so users know it's not implemented
    Option 1 would be ideal — the LVGL8 implementation already works and the pattern is straightforward.

Sketch

.

Other Steps to Reproduce

No response

I have checked existing issues, README.md and ESP32 Forum

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions