Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions components/esp_lvgl_port/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## [Unreleased]
### Features
- Added option to place LVGL task stack to external RAM
- Properly swap bytes and draw to display for direct mode in LVGL9

## 2.6.0

Expand Down
43 changes: 33 additions & 10 deletions components/esp_lvgl_port/src/lvgl9/esp_lvgl_port_disp.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ static void lvgl_port_flush_callback(lv_display_t *drv, const lv_area_t *area, u
static void lvgl_port_disp_size_update_callback(lv_event_t *e);
static void lvgl_port_disp_rotation_update(lvgl_port_display_ctx_t *disp_ctx);
static void lvgl_port_display_invalidate_callback(lv_event_t *e);
static void lvgl_port_draw_sw_rgb565_swap_area(void *buf, uint32_t screen_width, uint32_t screen_height, const lv_area_t *area);

/*******************************************************************************
* Public API functions
Expand Down Expand Up @@ -669,29 +670,33 @@ static void lvgl_port_flush_callback(lv_display_t *drv, const lv_area_t *area, u
}

if (disp_ctx->flags.swap_bytes) {
size_t len = lv_area_get_size(area);
lv_draw_sw_rgb565_swap(color_map, len);
if (disp_ctx->flags.direct_mode) {
// in direct mode, color_map is full size but we only need to swap the dirty area
lvgl_port_draw_sw_rgb565_swap_area(color_map, lv_disp_get_hor_res(drv), lv_disp_get_ver_res(drv), area);
} else {
size_t len = lv_area_get_size(area);
lv_draw_sw_rgb565_swap(color_map, len);
}
}
/* Transfer data in buffer for monochromatic screen */
if (disp_ctx->flags.monochrome) {
_lvgl_port_transform_monochrome(drv, area, &color_map);
}

if ((disp_ctx->disp_type == LVGL_PORT_DISP_TYPE_RGB || disp_ctx->disp_type == LVGL_PORT_DISP_TYPE_DSI) && (disp_ctx->flags.direct_mode || disp_ctx->flags.full_refresh)) {
if (disp_ctx->flags.direct_mode || disp_ctx->flags.full_refresh) {
if (lv_disp_flush_is_last(drv)) {
/* If the interface is I80 or SPI, this step cannot be used for drawing. */
esp_lcd_panel_draw_bitmap(disp_ctx->panel_handle, 0, 0, lv_disp_get_hor_res(drv), lv_disp_get_ver_res(drv), color_map);
/* Waiting for the last frame buffer to complete transmission */
xSemaphoreTake(disp_ctx->trans_sem, 0);
xSemaphoreTake(disp_ctx->trans_sem, portMAX_DELAY);
if(disp_ctx->disp_type == LVGL_PORT_DISP_TYPE_RGB || disp_ctx->disp_type == LVGL_PORT_DISP_TYPE_DSI) {
/* Waiting for the last frame buffer to complete transmission */
xSemaphoreTake(disp_ctx->trans_sem, 0);
xSemaphoreTake(disp_ctx->trans_sem, portMAX_DELAY);
}
}
} else {
esp_lcd_panel_draw_bitmap(disp_ctx->panel_handle, offsetx1, offsety1, offsetx2 + 1, offsety2 + 1, color_map);
}

if (disp_ctx->disp_type == LVGL_PORT_DISP_TYPE_RGB || (disp_ctx->disp_type == LVGL_PORT_DISP_TYPE_DSI && (disp_ctx->flags.direct_mode || disp_ctx->flags.full_refresh))) {
lv_disp_flush_ready(drv);
}
lv_disp_flush_ready(drv);
}

static void lvgl_port_disp_rotation_update(lvgl_port_display_ctx_t *disp_ctx)
Expand Down Expand Up @@ -752,3 +757,21 @@ static void lvgl_port_display_invalidate_callback(lv_event_t *e)
/* Wake LVGL task, if needed */
lvgl_port_task_wake(LVGL_PORT_EVENT_DISPLAY, NULL);
}

static void lvgl_port_draw_sw_rgb565_swap_area(void *buf, uint32_t screen_width, uint32_t screen_height, const lv_area_t *area) {
if (!buf || !area)
return;
if (area->x1 > area->x2 || area->y1 > area->y2)
return;
if (area->x2 >= (int32_t)screen_width || area->y2 >= (int32_t)screen_height)
return;

uint16_t *buf16 = (uint16_t *)buf;
for (int32_t y = area->y1; y <= area->y2; ++y) {
uint32_t row_start = y * screen_width + area->x1;
for (int32_t x = area->x1; x <= area->x2; ++x) {
uint32_t idx = row_start + (x - area->x1);
buf16[idx] = ((buf16[idx] & 0xff00) >> 8) | ((buf16[idx] & 0x00ff) << 8);
}
}
}