Performance suffers greatly when rollers have many options

What do you want to achieve?

I am making a GUI on ESP32-S3 that requires multiple rollers containing around 25 options. However, when scrolling said rollers, FPS drops to around 15 from 33. I have another roller with 10 options, and it performs great, maintaining 33 FPS even when scrolling very quickly.

What have you tried so far?

I tried changing roller from infinite to normal mode, no improvement.
I tried reducing the number of infinite pages from 7 to 3 in the conf, no improvement.

Code to reproduce

        red_roller = lv_roller_create(timer_app_screen);
        lv_roller_set_options(red_roller,
        "1m\n1m 30s\n2m\n2m 30s\n3m\n3m 30s\n4m\n4m 30s\n5m\n6m\n7m\n8m\n9m\n10m\n12m\n15m\n20m\n25m\n30m\n40m\n50m\n60m\n10s",
        LV_ROLLER_MODE_INFINITE); //the many options
        lv_obj_add_style(red_roller, &style_rollers, 0);
        lv_obj_add_style(red_roller, &style_roller_select, LV_PART_SELECTED | LV_STATE_DEFAULT);
        lv_obj_set_style_bg_color(red_roller, lv_color_hex(0xE01B1B), LV_PART_SELECTED | LV_STATE_DEFAULT);
        lv_obj_set_style_bg_color(red_roller, lv_color_darken(lv_obj_get_style_bg_color(red_roller, LV_PART_SELECTED | LV_STATE_DEFAULT), 160), 0);
        lv_obj_add_style(red_roller, &style_std_shadow, 0);
        lv_obj_set_align(red_roller, LV_ALIGN_CENTER);
        //lv_roller_set_visible_row_count(red_roller, 5);
        lv_obj_set_pos(red_roller, 240, 0);
        lv_obj_add_event_cb(red_roller, red_roll_event, LV_EVENT_VALUE_CHANGED, NULL);
        preferences.begin("saved_vars", false); //for saving which option was selected
        int red_select = preferences.getInt("red_select", 0);
        preferences.end();
        lv_roller_set_selected(red_roller, red_select, LV_ANIM_OFF);




//this is the event CB for red_roller, although removing it does not affect performance

static void red_roll_event(lv_event_t * e){
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * obj = lv_event_get_target(e);
    if(code == LV_EVENT_VALUE_CHANGED) {
        int selected = lv_roller_get_selected(red_roller);
        switch(selected) {
            case 0:  glb::red_timer_seconds = 60; break;
            case 1:  glb::red_timer_seconds = 90; break;
            case 2:  glb::red_timer_seconds = 120; break;
            case 3:  glb::red_timer_seconds = 150; break;
            case 4:  glb::red_timer_seconds = 180; break;
            case 5:  glb::red_timer_seconds = 210; break;
            case 6:  glb::red_timer_seconds = 240; break;
            case 7:  glb::red_timer_seconds = 270; break;
            case 8:  glb::red_timer_seconds = 300; break;
            case 9:  glb::red_timer_seconds = 360; break;
            case 10: glb::red_timer_seconds = 420; break;
            case 11: glb::red_timer_seconds = 480; break;
            case 12: glb::red_timer_seconds = 540; break;
            case 13: glb::red_timer_seconds = 600; break;
            case 14: glb::red_timer_seconds = 720; break;
            case 15: glb::red_timer_seconds = 900; break;
            case 16: glb::red_timer_seconds = 1200; break;
            case 17: glb::red_timer_seconds = 1500; break;
            case 18: glb::red_timer_seconds = 1800; break;
            case 19: glb::red_timer_seconds = 2400; break;
            case 20: glb::red_timer_seconds = 3000; break;
            case 21: glb::red_timer_seconds = 3600; break;
            case 22: glb::red_timer_seconds = 10; break;
        }
        preferences.begin("saved_vars", false);
        preferences.putInt("red_seconds", glb::red_timer_seconds);
        preferences.putInt("red_select", selected);
        preferences.end();
        Serial.println(glb::red_timer_seconds);
    }
}

The roller with only 10 options has functionally identical code, and performs great.

Environment

  • **MCU/MPU/Board: ESP32-S3-LCD-1.28
  • **LVGL version: 8.3.10

Hi @The_Fudge_Bot ,

When rollers hold larger numbers of options, the cumulative height of all options can stretch internal coordinate boundaries

#define LV_USE_LARGE_COORD 1

Also, larger lists or multiple visible rollers force larger invalidation areas to be redrawn and blended every frame.

Try to reduce the rendering overhead by lowering the number of visible rows on the roller ( lv_roller_set_visible_row_count(roller, 3)) to minimize the area invalidated while rolling.

Thanks, Yes, I believe I did that as part of the solution. The other thing that I think helped was reducing visual overhead, letting the rollers be slightly more isolated from all the other graphics