Skip to content

Commit 61ab9cb

Browse files
authored
Merge pull request #399 from espressif/bsp/lvgl_performance
doc(LVGL port): Updated performance documentation for LVGL9
2 parents d823752 + 239f07c commit 61ab9cb

File tree

7 files changed

+74
-52
lines changed

7 files changed

+74
-52
lines changed

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ If you'd like to propose a change to the existing APIs or a large-scale refactor
1414

1515
## Third-party boards
1616

17-
ESP-BSP project is currently intended only to host BSPs for development boards manufactured by Espressif.
17+
ESP-BSP project is currently intended only to host BSPs for development boards manufactured by Espressif and M5Stack.
1818

1919
If you want to create a BSP for a third-party board, we suggest creating a separate repository for it. You are welcome to use the ESP-BSP project as a template for your own board support package repository.
2020

2121
## Pre-commit hooks
2222

2323
ESP-BSP project uses [pre-commit hooks](https://pre-commit.com/) to perform code formatting and other checks when you run `git commit`.
2424

25-
To install pre-commit hooks, run `pip install pre-commit && pre-commit install`.
25+
To install pre-commit hooks, run `pip install pre-commit && pre-commit install`.
2626

2727
If a pre-commit hook has modified any of the files when you run `git commit`, add these changes using `git add` and run `git commit` again.
2828

components/esp_lvgl_port/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## 2.3.3
4+
5+
### Features
6+
- Updated RGB screen flush handling in LVGL9.
7+
38
## 2.3.2
49

510
### Fixes

components/esp_lvgl_port/docs/performance.md

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# LCD & LVGL Performance
22

3-
This document provides steps, how to set up your LCD and LVGL port for the best performance and comparison of different settings. All settings and measurements are valid for Espressif's chips.
3+
This document provides steps, how to set up your LCD and LVGL port for the best performance and comparison of different settings. All settings and measurements are valid for Espressif's chips. Examples in [ESP-BSP](https://github.com/espressif/esp-bsp) are ready to use with the best performance.
44

55
## Performance metrics
66

@@ -26,7 +26,7 @@ On the other hand, the frame buffer(s) will consume significant portion of your
2626

2727
Main takeaways from the graph are:
2828

29-
* The size of **LVGL buffer** and **double buffering** feature has big impact on performance.
29+
* The size of **LVGL buffer** and **double buffering** feature has big impact on performance.
3030
* Frame buffer size >25% of the screen does not bring relevant performance boost
3131
* Frame buffer size <10% will have severe negative effect on performance
3232

@@ -67,18 +67,53 @@ The main LVGL task can be processed on the second core of the CPU. It can increa
6767

6868
### Using esp-idf `memcpy` and `memset` instead LVGL's configuration
6969

70-
Native esp-idf implementation are a little (~1-3 FPS) faster.
70+
Native esp-idf implementation are a little (~1-3 FPS) faster (only for LVGL8).
7171

7272
* `CONFIG_LV_MEMCPY_MEMSET_STD=y`
7373

7474
### Default LVGL display refresh period
7575

7676
This setting can improve subjective performance during screen transitions (scrolling, etc.).
7777

78+
LVGL8
7879
* `CONFIG_LV_DISP_DEF_REFR_PERIOD=10`
7980

81+
LVGL9
82+
* `CONFIG_LV_DEF_REFR_PERIOD=10`
83+
8084
## Example FPS improvement vs graphical settings
8185

86+
The LVGL9 benchmark demo uses a different algorithm for measuring FPS. In this case, we used the same algorithm for measurement in LVGL8 for comparison.
87+
88+
### RGB LCD, PSRAM (octal) with GDMA - ESP32-S3-LCD-EV-BOARD
89+
90+
<img src="https://github.com/espressif/esp-bsp/blob/master/docu/pics/esp32-s3-lcd-ev-board_800x480.png?raw=true" align="right" width="300px" />
91+
92+
Default settings:
93+
* BSP example `display_lvgl_demos`
94+
* LCD: 4.3" 800x480
95+
* Interface: RGB
96+
* LVGL buffer size: 800 x 480
97+
* LVGL buffer mode: Direct (avoid-tearing)
98+
* LVGL double buffer: NO
99+
* Optimization: Debug
100+
* CPU frequency: 160 MHz
101+
* Flash frequency: 80 MHz
102+
* PSRAM frequency: 80 MHz
103+
* Flash mode: DIO
104+
* LVGL display refresh period: 30 ms
105+
106+
| Average FPS (LVGL8) | Average FPS (LVGL 9.2) | Changed settings |
107+
| :---: | :---: | ---------------- |
108+
| 12 | 9 | Default |
109+
| 13 | 9 | + Optimization: Performance (`CONFIG_COMPILER_OPTIMIZATION_PERF=y`) |
110+
| 14 | 11 | + CPU frequency: 240 MHz (`CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y`) |
111+
| 14 | 11 | + Flash mode: QIO (`CONFIG_ESPTOOLPY_FLASHMODE_QIO=y`) |
112+
| 15 | 11 | + LVGL fast memory enabled (`CONFIG_LV_ATTRIBUTE_FAST_MEM_USE_IRAM=y`) |
113+
| 16 | 11 | + (`CONFIG_LV_DISP_DEF_REFR_PERIOD=10` / `CONFIG_LV_DEF_REFR_PERIOD=10`) |
114+
115+
### Parallel 8080 LCD (only for LVGL8)
116+
82117
<img src="https://github.com/espressif/esp-bsp/blob/master/docu/pics/7inch-Capacitive-Touch-LCD-C_l.jpg?raw=true" align="right" width="300px" />
83118

84119
Default settings:
@@ -94,7 +129,7 @@ Default settings:
94129
* Flash mode: DIO
95130
* LVGL display refresh period: 30 ms
96131

97-
### Internal RAM with DMA
132+
#### Internal RAM with DMA
98133

99134
| Average FPS | Weighted FPS | Changed settings |
100135
| :---: | :---: | ---------------- |
@@ -105,7 +140,7 @@ Default settings:
105140
| 28 | **60** | + LVGL fast memory enabled (`CONFIG_LV_ATTRIBUTE_FAST_MEM_USE_IRAM=y`) |
106141
| 41 | 55 | + (`CONFIG_LV_DISP_DEF_REFR_PERIOD=10`) |
107142

108-
### PSRAM (QUAD) without DMA
143+
#### PSRAM (QUAD) without DMA
109144

110145
Default changes:
111146
* LCD IO clock: 2 MHz
@@ -124,36 +159,10 @@ Default changes:
124159

125160
[^1]: This is not working in default and sometimes in fast changes on screen is not working properly.
126161

127-
### RGB LCD (without `esp_lvgl_port`), PSRAM (octal) with GDMA - ESP32-S3-LCD-EV-BOARD
128-
129-
<img src="https://github.com/espressif/esp-bsp/blob/master/docu/pics/esp32-s3-lcd-ev-board_800x480.png?raw=true" align="right" width="300px" />
130-
131-
Default settings:
132-
* BSP example `display_lvgl_demos`
133-
* LCD: 4.3" 800x480
134-
* Interface: RGB
135-
* LVGL buffer size: 800 x 100
136-
* LVGL double buffer: NO
137-
* Optimization: Debug
138-
* CPU frequency: 160 MHz
139-
* Flash frequency: 80 MHz
140-
* PSRAM frequency: 80 MHz
141-
* Flash mode: DIO
142-
* LVGL display refresh period: 30 ms
143-
144-
| Average FPS | Weighted FPS | Changed settings |
145-
| :---: | :---: | ---------------- |
146-
| 18 | 24 | Default |
147-
| 18 | 26 | + Optimization: Performance (`CONFIG_COMPILER_OPTIMIZATION_PERF=y`) |
148-
| 21 | 32 | + CPU frequency: 240 MHz (`CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y`) |
149-
| 21 | 32 | + Flash mode: QIO (`CONFIG_ESPTOOLPY_FLASHMODE_QIO=y`) |
150-
| 21 | 32 | + LVGL fast memory enabled (`CONFIG_LV_ATTRIBUTE_FAST_MEM_USE_IRAM=y`) |
151-
| 35 | 34 | + (`CONFIG_LV_DISP_DEF_REFR_PERIOD=10`) |
152-
153162
## Conclusion
154163

155164
The graphical performance depends on a lot of things and settings, many of which affect the whole system (Compiler, Flash, CPU, PSRAM configuration...). The user should primarily focus on trade-off between frame-buffer(s) size and RAM consumption of the buffer, before optimizing the design further.
156165

157166
Other configuration options not covered in this document are:
158-
* Hardware interfaces, color depth, screen definition (size), clocks, LCD controller and more.
167+
* Hardware interfaces, color depth, screen definition (size), clocks, LCD controller and more.
159168
* Complexity of the graphical application (number of LVGL objects and their styles).

components/esp_lvgl_port/idf_component.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version: "2.3.2"
1+
version: "2.3.3"
22
description: ESP LVGL port
33
url: https://github.com/espressif/esp-bsp/tree/master/components/esp_lvgl_port
44
dependencies:

components/esp_lvgl_port/src/lvgl8/esp_lvgl_port.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@ esp_err_t lvgl_port_init(const lvgl_port_cfg_t *cfg)
7878

7979
BaseType_t res;
8080
if (cfg->task_affinity < 0) {
81-
res = xTaskCreate(lvgl_port_task, "LVGL task", cfg->task_stack, NULL, cfg->task_priority, &lvgl_port_ctx.lvgl_task);
81+
res = xTaskCreate(lvgl_port_task, "taskLVGL", cfg->task_stack, NULL, cfg->task_priority, &lvgl_port_ctx.lvgl_task);
8282
} else {
83-
res = xTaskCreatePinnedToCore(lvgl_port_task, "LVGL task", cfg->task_stack, NULL, cfg->task_priority, &lvgl_port_ctx.lvgl_task, cfg->task_affinity);
83+
res = xTaskCreatePinnedToCore(lvgl_port_task, "taskLVGL", cfg->task_stack, NULL, cfg->task_priority, &lvgl_port_ctx.lvgl_task, cfg->task_affinity);
8484
}
8585
ESP_GOTO_ON_FALSE(res == pdPASS, ESP_FAIL, err, TAG, "Create LVGL task fail!");
8686

components/esp_lvgl_port/src/lvgl9/esp_lvgl_port.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ esp_err_t lvgl_port_init(const lvgl_port_cfg_t *cfg)
8484

8585
BaseType_t res;
8686
if (cfg->task_affinity < 0) {
87-
res = xTaskCreate(lvgl_port_task, "LVGL task", cfg->task_stack, NULL, cfg->task_priority, &lvgl_port_ctx.lvgl_task);
87+
res = xTaskCreate(lvgl_port_task, "taskLVGL", cfg->task_stack, NULL, cfg->task_priority, &lvgl_port_ctx.lvgl_task);
8888
} else {
89-
res = xTaskCreatePinnedToCore(lvgl_port_task, "LVGL task", cfg->task_stack, NULL, cfg->task_priority, &lvgl_port_ctx.lvgl_task, cfg->task_affinity);
89+
res = xTaskCreatePinnedToCore(lvgl_port_task, "taskLVGL", cfg->task_stack, NULL, cfg->task_priority, &lvgl_port_ctx.lvgl_task, cfg->task_affinity);
9090
}
9191
ESP_GOTO_ON_FALSE(res == pdPASS, ESP_FAIL, err, TAG, "Create LVGL task fail!");
9292

components/esp_lvgl_port/src/lvgl9/esp_lvgl_port_disp.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ static bool lvgl_port_flush_panel_ready_callback(esp_lcd_panel_handle_t panel_io
7070
#endif
7171
#endif
7272
static void lvgl_port_flush_callback(lv_display_t *drv, const lv_area_t *area, uint8_t *color_map);
73+
static void lvgl_port_flush_wait_callback(lv_display_t *drv);
7374
static void lvgl_port_disp_size_update_callback(lv_event_t *e);
7475
static void lvgl_port_disp_rotation_update(lvgl_port_display_ctx_t *disp_ctx);
7576
static void lvgl_port_display_invalidate_callback(lv_event_t *e);
@@ -170,6 +171,11 @@ lv_display_t *lvgl_port_add_disp_rgb(const lvgl_port_display_cfg_t *disp_cfg, co
170171
ESP_RETURN_ON_FALSE(false, NULL, TAG, "RGB is supported only on ESP32S3 and from IDF 5.0!");
171172
#endif
172173

174+
/* Set wait callback */
175+
if (disp_ctx->flags.full_refresh || disp_ctx->flags.direct_mode) {
176+
lv_display_set_flush_wait_cb(disp, lvgl_port_flush_wait_callback);
177+
}
178+
173179
/* Apply rotation from initial display configuration */
174180
lvgl_port_disp_rotation_update(disp_ctx);
175181
}
@@ -466,6 +472,17 @@ void lvgl_port_rotate_area(lv_display_t *disp, lv_area_t *area)
466472
}
467473
}
468474

475+
476+
static void lvgl_port_flush_wait_callback(lv_display_t *drv)
477+
{
478+
assert(drv != NULL);
479+
if (lv_disp_flush_is_last(drv)) {
480+
/* Waiting for the last frame buffer to complete transmission */
481+
ulTaskNotifyValueClear(NULL, ULONG_MAX);
482+
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
483+
}
484+
}
485+
469486
static void lvgl_port_flush_callback(lv_display_t *drv, const lv_area_t *area, uint8_t *color_map)
470487
{
471488
assert(drv != NULL);
@@ -512,20 +529,11 @@ static void lvgl_port_flush_callback(lv_display_t *drv, const lv_area_t *area, u
512529
_lvgl_port_transform_monochrome(drv, area, color_map);
513530
}
514531

515-
/* RGB LCD */
516-
if (disp_ctx->disp_type == LVGL_PORT_DISP_TYPE_RGB && (disp_ctx->flags.full_refresh || disp_ctx->flags.direct_mode)) {
517-
if (lv_disp_flush_is_last(drv)) {
518-
/* If the interface is I80 or SPI, this step cannot be used for drawing. */
519-
esp_lcd_panel_draw_bitmap(disp_ctx->panel_handle, offsetx1, offsety1, offsetx2 + 1, offsety2 + 1, color_map);
520-
/* Waiting for the last frame buffer to complete transmission */
521-
ulTaskNotifyValueClear(NULL, ULONG_MAX);
522-
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
523-
}
524-
} else {
525-
esp_lcd_panel_draw_bitmap(disp_ctx->panel_handle, offsetx1, offsety1, offsetx2 + 1, offsety2 + 1, color_map);
526-
}
532+
/* Draw */
533+
esp_lcd_panel_draw_bitmap(disp_ctx->panel_handle, offsetx1, offsety1, offsetx2 + 1, offsety2 + 1, color_map);
527534

528-
if (disp_ctx->disp_type == LVGL_PORT_DISP_TYPE_RGB) {
535+
/* Call flush ready only in RGB screen when not full refresh or direct mode */
536+
if (disp_ctx->disp_type == LVGL_PORT_DISP_TYPE_RGB && !disp_ctx->flags.full_refresh && !disp_ctx->flags.direct_mode) {
529537
lv_disp_flush_ready(drv);
530538
}
531539
}

0 commit comments

Comments
 (0)