Skip to content

Commit

Permalink
feat(lvgl_port_simd): RBG565 image blend to RGB565
Browse files Browse the repository at this point in the history
    - RGB565 blend to RGB565 (optimized memcpy for RGB565 type)
    - esp32s3 assembly implementation using SIMD instructions
    - esp32 assembly fallback
  • Loading branch information
peter-marcisovsky committed Jan 6, 2025
1 parent a9620d5 commit ceb646f
Show file tree
Hide file tree
Showing 17 changed files with 1,657 additions and 11 deletions.
5 changes: 5 additions & 0 deletions components/esp_lvgl_port/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ if((lvgl_ver VERSION_GREATER_EQUAL "9.1.0") AND (lvgl_ver VERSION_LESS "9.2.0"))
else()
file(GLOB_RECURSE ASM_SRCS ${PORT_PATH}/simd/*_esp32.S) # Select only esp32 related files
endif()

# Explicitly add all assembly macro files
file(GLOB_RECURSE ASM_MACROS ${PORT_PATH}/simd/lv_macro_*.S)
list(APPEND ADD_SRCS ${ASM_MACROS})
list(APPEND ADD_SRCS ${ASM_SRCS})

# Include component libraries, so lvgl component would see lvgl_port includes
Expand All @@ -94,6 +98,7 @@ if((lvgl_ver VERSION_GREATER_EQUAL "9.1.0") AND (lvgl_ver VERSION_LESS "9.2.0"))
# Force link .S files
set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "-u lv_color_blend_to_argb8888_esp")
set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "-u lv_color_blend_to_rgb565_esp")
set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "-u lv_rgb565_blend_normal_to_rgb565_esp")
endif()
endif()

Expand Down
20 changes: 20 additions & 0 deletions components/esp_lvgl_port/include/esp_lvgl_port_lv_blend.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ extern "C" {
_lv_color_blend_to_rgb565_esp(dsc)
#endif

#ifndef LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565
#define LV_DRAW_SW_RGB565_BLEND_NORMAL_TO_RGB565(dsc) \
_lv_rgb565_blend_normal_to_rgb565_esp(dsc)
#endif

/**********************
* TYPEDEFS
Expand Down Expand Up @@ -83,6 +87,22 @@ static inline lv_result_t _lv_color_blend_to_rgb565_esp(_lv_draw_sw_blend_fill_d
return lv_color_blend_to_rgb565_esp(&asm_dsc);
}

extern int lv_rgb565_blend_normal_to_rgb565_esp(asm_dsc_t *asm_dsc);

static inline lv_result_t _lv_rgb565_blend_normal_to_rgb565_esp(_lv_draw_sw_blend_image_dsc_t *dsc)
{
asm_dsc_t asm_dsc = {
.dst_buf = dsc->dest_buf,
.dst_w = dsc->dest_w,
.dst_h = dsc->dest_h,
.dst_stride = dsc->dest_stride,
.src_buf = dsc->src_buf,
.src_stride = dsc->src_stride
};

return lv_rgb565_blend_normal_to_rgb565_esp(&asm_dsc);
}

#endif // CONFIG_LV_DRAW_SW_ASM_CUSTOM

#ifdef __cplusplus
Expand Down
60 changes: 60 additions & 0 deletions components/esp_lvgl_port/src/lvgl9/simd/lv_macro_memcpy.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

// Memcpy macros for modulo checking
// After running the main loop, there is need to check remaining bytes to be copied out of the main loop
// Macros work with both, aligned and unaligned (4-byte boundary) memories
// but performance is significantly lower when using unaligned memory, because of the unaligned memory access exception


// Macro for checking modulo 8
.macro macro_memcpy_mod_8 src_buf, dest_buf, condition, x1, x2, JUMP_TAG
// Check modulo 8 of the \condition, if - then copy 8 bytes
bbci \condition, 3, ._mod_8_check_\JUMP_TAG // Branch if 3-rd bit of \condition is clear
l32i.n \x1, \src_buf, 0 // Load 32 bits from \src_buff to \x1, offset 0
l32i.n \x2, \src_buf, 4 // Load 32 bits from \src_buff to \x2, offset 4
s32i.n \x1, \dest_buf, 0 // Save 32 bits from \x1 to \dest_buff, offset 0
s32i.n \x2, \dest_buf, 4 // Save 32 bits from \x2 to \dest_buff, offset 4
addi.n \src_buf, \src_buf, 8 // Increment \src_buff pointer by 8
addi.n \dest_buf, \dest_buf, 8 // Increment \dest_buff pointer 8
._mod_8_check_\JUMP_TAG:
.endm // macro_memcpy_mod_8


// Macro for checking modulo 4
.macro macro_memcpy_mod_4 src_buf, dest_buf, condition, x1, JUMP_TAG
// Check modulo 4 of the \condition, if - then copy 4 bytes
bbci \condition, 2, ._mod_4_check_\JUMP_TAG // Branch if 2-nd bit of \condition is clear
l32i.n \x1, \src_buf, 0 // Load 32 bits from \src_buff to \x1, offset 0
addi.n \src_buf, \src_buf, 4 // Increment \src_buff pointer by 4
s32i.n \x1, \dest_buf, 0 // Save 32 bits from \x1 to \dest_buff, offset 0
addi.n \dest_buf, \dest_buf, 4 // Increment \dest_buff pointer 4
._mod_4_check_\JUMP_TAG:
.endm // macro_memcpy_mod_4


// Macro for checking modulo 2
.macro macro_memcpy_mod_2 src_buf, dest_buf, condition, x1, JUMP_TAG
// Check modulo 2 of the \condition, if - then copy 2 bytes
bbci \condition, 1, ._mod_2_check_\JUMP_TAG // Branch if 1-st bit of \condition is clear
l16ui \x1, \src_buf, 0 // Load 16 bits from \src_buff to \x1, offset 0
addi.n \src_buf, \src_buf, 2 // Increment \src_buff pointer by 2
s16i \x1, \dest_buf, 0 // Save 16 bits from \x1 to \dest_buff, offset 0
addi.n \dest_buf, \dest_buf, 2 // Increment \dest_buff pointer 2
._mod_2_check_\JUMP_TAG:
.endm // macro_memcpy_mod_2


// Macro for checking modulo 1
.macro macro_memcpy_mod_1 src_buf, dest_buf, condition, x1, JUMP_TAG
// Check modulo 1 of the \condition, if - then copy 1 byte
bbci \condition, 0, ._mod_1_check_\JUMP_TAG // Branch if 0-th bit of \condition is clear
l8ui \x1, \src_buf, 0 // Load 8 bits from \src_buff to \x1, offset 0
addi.n \src_buf, \src_buf, 1 // Increment \src_buff pointer by 1
s8i \x1, \dest_buf, 0 // Save 8 bits from \x1 to \dest_buff, offset 0
addi.n \dest_buf, \dest_buf, 1 // Increment \dest_buff pointer 1
._mod_1_check_\JUMP_TAG:
.endm // macro_memcpy_mod_1
Loading

0 comments on commit ceb646f

Please sign in to comment.