Skip to content

Draw buf size not aligned correctly for PPA #9868

@clydebarrow

Description

@clydebarrow

LVGL version

9.5.0

Platform

ESP32

What happened?

When filling rectangles e.g. for the indicator part of a slider, using the PPA feature on an ESP32 P4, the draw buf size is not rounded up to a multiple of LV_DRAW_BUF_ALIGN, which in this case is 64. This results in the ESP-IDF code throwing errors since the PPA can only operate on buffers whose start and end are properly aligned.

[11:05:26.616][E][lvgl:000]: [Error] lv_draw_ppa_fill: PPA fill failed: 258
[11:05:26.655]E (24829) cache: esp_cache_msync(122): start address: 0x48096680, or the size: 0x18f0 is(are) not aligned with cache line size (0x40)B
[11:05:26.666]E (24830) cache: esp_cache_msync(122): start address: 0x48096680, or the size: 0x18f0 is(are) not aligned with cache line size (0x40)B
[11:05:26.677][D][esp-idf:000]: E (24830) ppa_fill: ppa_do_fill(97): out.buffer addr or out.buffer_size not aligned to cache line size
[11:05:26.683][E][lvgl:000]: [Error] lv_draw_ppa_fill: PPA fill failed: 258

This is currently an issue for the adoption of LVGL 9.5 into ESPHome. The workaround is to turn off PPA.

The fix appears to be this:

diff --git a/src/draw/lv_draw_buf.c b/src/draw/lv_draw_buf.c
index 293f23d5e..62ba200d8 100644
--- a/src/draw/lv_draw_buf.c
+++ b/src/draw/lv_draw_buf.c
@@ -673,6 +673,7 @@ static uint32_t _calculate_draw_buf_size(uint32_t w, uint32_t h, lv_color_format
         size += LV_COLOR_INDEXED_PALETTE_SIZE(cf) * 4;
     }

+    size = LV_ROUND_UP(size, LV_DRAW_BUF_ALIGN);
     return size;
 }

How to reproduce?

The following ESPHome config is for a Waveshare P4-NANO with the 10.1" screen. Compile and run this:

esphome run p4-10.yaml

and observe the logs.

lvgl:
  byte_order: little_endian
  widgets:
    - slider:
        width: 21
        height: 200
        align: center
        indicator:
          radius: 0
        min_value: 0
        max_value: 255
        radius: 10
        knob:
          pad_top: -5

display:
  - platform: mipi_dsi
    id: main_display
    model: WAVESHARE-P4-NANO-10.1

esphome:
  name: p4-10
  friendly_name: P4 10.1

logger:
  hardware_uart: UART0

esp32:
  variant: esp32p4
  board: esp32-p4-evboard
  flash_size: 16MB
  cpu_frequency: 360MHz
  framework:
    type: esp-idf
    advanced:
      execute_from_psram: true
      enable_idf_experimental_features: true

external_components:
  - source: github://pr#12312
    components: [font, image, lvgl]
    refresh: 1h

psram:
  mode: hex
  speed: 200MHz

esp_ldo:
  - voltage: 2.5V
    channel: 3

# -------------------------------------------
# Touchscreen GT911/GT9271 i2c
# -------------------------------------------
i2c:
  - id: bus_a
    sda: GPIO07
    scl: GPIO08
    frequency: 400kHz
    scan: true

touchscreen:
  - platform: gt911
    id: my_touchscreen
    i2c_id: bus_a
    update_interval: 50ms
    transform:
      swap_xy: true
      mirror_x: false
      mirror_y: true
# -------------------------------------------
# Backlight
# -------------------------------------------
output:
  - platform: ledc
    id: gpio_backlight_pwm
    pin: GPIO26
    inverted: false
    frequency: 1000Hz

light:
  - platform: monochromatic
    output: gpio_backlight_pwm
    name: Display Backlight
    icon: mdi:lightbulb-on
    id: display_backlight
    restore_mode: ALWAYS_ON
    default_transition_length: 250ms

Generated C Code for LVGL widget:

   lv_slider_t_id = lv_slider_create(lvgl_lvglcomponent_id->get_screen_active());
  lv_obj_set_style_align(lv_slider_t_id, LV_ALIGN_CENTER, LV_PART_MAIN);
  lv_obj_set_style_height(lv_slider_t_id, 200, LV_PART_MAIN);
  lv_obj_set_style_radius(lv_slider_t_id, 10, LV_PART_MAIN);
  lv_obj_set_style_width(lv_slider_t_id, 21, LV_PART_MAIN);
  lv_obj_set_style_radius(lv_slider_t_id, 0, LV_PART_INDICATOR);
  lv_obj_set_style_pad_top(lv_slider_t_id, -5, LV_PART_KNOB);
  lv_slider_set_range(lv_slider_t_id, 0, 255);
  lv_slider_set_mode(lv_slider_t_id, LV_SLIDER_MODE_NORMAL);

And lv_conf.h used:

#define LV_ATTRIBUTE_MEM_ALIGN_SIZE 0
#define LV_BUILD_DEMOS 0
#define LV_BUILD_EXAMPLES 0
#define LV_COLOR_16_SWAP 0
#define LV_COLOR_CHROMA_KEY lv_color_make(0, 4, 0)
#define LV_COLOR_DEPTH 16
#define LV_DRAW_BUF_ALIGN 64
#define LV_DRAW_BUF_STRIDE_ALIGN 1
#define LV_DRAW_SW_COMPLEX 1
#define LV_DRAW_SW_DRAW_UNIT_CNT 0
#define LV_DRAW_SW_SUPPORT_A8 0
#define LV_DRAW_SW_SUPPORT_AL88 0
#define LV_DRAW_SW_SUPPORT_ARGB8888 0
#define LV_DRAW_SW_SUPPORT_I1 0
#define LV_DRAW_SW_SUPPORT_L8 0
#define LV_DRAW_SW_SUPPORT_PREMULTIPLIED 0
#define LV_DRAW_SW_SUPPORT_RGB565 1
#define LV_DRAW_SW_SUPPORT_RGB565A8 0
#define LV_DRAW_SW_SUPPORT_RGB888 1
#define LV_DRAW_SW_SUPPORT_SWAPPED 0
#define LV_DRAW_SW_SUPPORT_XRGB8888 0
#define LV_FILE_EXPLORER_QUICK_ACCESS 0
#define LV_FONT_DEFAULT &lv_font_montserrat_14
#define LV_FONT_MONTSERRAT_14 1
#define LV_GRADIENT_MAX_STOPS 2
#define LV_IME_PINYIN_USE_DEFAULT_DICT 0
#define LV_IME_PINYIN_USE_K9_MODE 0
#define LV_LABEL_LONG_TXT_HINT 0
#define LV_LABEL_TEXT_SELECTION 0
#define LV_LINUX_DRM_USE_EGL 0
#define LV_LINUX_FBDEV_MMAP 0
#define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
#define LV_LOG_USE_FILE_LINE 0
#define LV_LOG_USE_TIMESTAMP 0
#define LV_PROFILER_BUILTIN_DEFAULT_ENABLE 0
#define LV_PROFILER_CACHE 0
#define LV_PROFILER_DECODER 0
#define LV_PROFILER_DRAW 0
#define LV_PROFILER_EVENT 0
#define LV_PROFILER_FONT 0
#define LV_PROFILER_FS 0
#define LV_PROFILER_INDEV 0
#define LV_PROFILER_LAYOUT 0
#define LV_PROFILER_REFR 0
#define LV_PROFILER_TIMER 0
#define LV_SDL_USE_EGL 0
#define LV_TEST_SCREENSHOT_CREATE_REFERENCE_IMAGE 0
#define LV_THEME_DEFAULT_GROW 0
#define LV_USE_ANIMIMG 0
#define LV_USE_ARC 0
#define LV_USE_ARCLABEL 0
#define LV_USE_BAR 1
#define LV_USE_BTNMATRIX_BTN 0
#define LV_USE_BUTTON 0
#define LV_USE_BUTTONMATRIX 0
#define LV_USE_CALENDAR 0
#define LV_USE_CALENDAR_HEADER_ARROW 0
#define LV_USE_CALENDAR_HEADER_DROPDOWN 0
#define LV_USE_CANVAS 0
#define LV_USE_CHART 0
#define LV_USE_CHECKBOX 0
#define LV_USE_CONTAINER 0
#define LV_USE_DRAW_G2D 0
#define LV_USE_DRAW_PXP 0
#define LV_USE_DRAW_SW 1
#define LV_USE_DROPDOWN 0
#define LV_USE_DROPDOWN_LIST 0
#define LV_USE_EGL 0
#define LV_USE_FLEX 0
#define LV_USE_FONT_PLACEHOLDER 1
#define LV_USE_FREERTOS_TASK_NOTIFY 0
#define LV_USE_G2D_DRAW_THREAD 0
#define LV_USE_GENERIC_MIPI 0
#define LV_USE_GRID 0
#define LV_USE_IMAGE 0
#define LV_USE_KEYBOARD 0
#define LV_USE_LABEL 1
#define LV_USE_LED 0
#define LV_USE_LINE 0
#define LV_USE_LIST 0
#define LV_USE_LOG 1
#define LV_USE_LV_TILEVIEW_TILE_T 0
#define LV_USE_LZ4 0
#define LV_USE_MENU 0
#define LV_USE_METER 0
#define LV_USE_MSGBOX 0
#define LV_USE_NUTTX_MOUSE_MOVE_STEP 0
#define LV_USE_OBJ 0
#define LV_USE_OBJ_ID_BUILTIN 0
#define LV_USE_OBJ_PROPERTY_NAME 0
#define LV_USE_OBSERVER 0
#define LV_USE_PAGE 0
#define LV_USE_PPA 1
#define LV_USE_PROFILER_BUILTIN 0
#define LV_USE_PXP_DRAW_THREAD 0
#define LV_USE_QRCODE 0
#define LV_USE_ROLLER 0
#define LV_USE_SCALE 0
#define LV_USE_SLIDER 1
#define LV_USE_SPAN 0
#define LV_USE_SPINBOX 0
#define LV_USE_SPINNER 0
#define LV_USE_STDLIB_MALLOC LV_STDLIB_CUSTOM
#define LV_USE_STDLIB_SPRINTF LV_STDLIB_CLIB
#define LV_USE_STDLIB_STRING LV_STDLIB_CLIB
#define LV_USE_STYLE 1
#define LV_USE_SWITCH 0
#define LV_USE_TABLE 0
#define LV_USE_TABVIEW 0
#define LV_USE_TEXTAREA 0
#define LV_USE_THEME_DEFAULT 1
#define LV_USE_THEME_MONO 0
#define LV_USE_THEME_SIMPLE 0
#define LV_USE_THORVG 0
#define LV_USE_TILEVIEW 0
#define LV_USE_USER_DATA 1
#define LV_USE_WIN 0
#define LV_VG_LITE_THORVG_16PIXELS_ALIGN 0
#define LV_VG_LITE_USE_BOX_SHADOW 0
#define LV_WAYLAND_USE_EGL 0
#define LV_WAYLAND_USE_G2D 0
#define LV_WAYLAND_USE_SHM 0
#define LV_WIDGETS_HAS_DEFAULT_VALUE 0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions