Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature(lvgl_port): RGB888 SIMD fill #480

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

pborcin
Copy link
Collaborator

@pborcin pborcin commented Jan 14, 2025

This MR adds SIMD support for LV_DRAW_SW_COLOR_BLEND_TO_RGB888

ESP-BSP Pull Request checklist

Note: For new BSPs create a PR with this link.

  • Version of modified component bumped
  • CI passing

Change description

  • esp32s3 SIMD assembly implementation of the RGB888 simple fill
  • esp32 assembly implementation of the RGB888 simple fill
  • Functionality and benchmark tests
  • Updated README with achieved benchmark results

Copy link
Collaborator

@peter-marcisovsky peter-marcisovsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pborcin thanks for the changes. Nice work with the switch-case implementation. I have never tried that myself (did not have a proper use case) but this looks like a good one.

Sorry for the review comments regarding your style of commenting, but as you might have seen the assembly is very hard be read and to be navigated through and commenting makes it bit easier for us to know what is going on and which buffer are you aligning and where to are you jumping. Thank you.

I will also try the test app and let you know.

@pborcin pborcin force-pushed the rgb888_accel branch 2 times, most recently from 3da85ab to 234966a Compare January 22, 2025 10:29
@pborcin pborcin force-pushed the rgb888_accel branch 4 times, most recently from e5983dc to 2d7a665 Compare January 28, 2025 10:40
Copy link
Collaborator

@peter-marcisovsky peter-marcisovsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the build errors I have described. Thank you.


// Canary bytes area must stay 0
TEST_ASSERT_EACH_EQUAL_UINT8_MESSAGE(0, (uint8_t *)test_case->buf.p_ansi + test_case->active_buf_len * test_case->data_type_size + CANARY_BYTES * test_case->data_type_size, CANARY_BYTES * test_case->data_type_size, test_msg_buf);
TEST_ASSERT_EACH_EQUAL_UINT8_MESSAGE(0, (uint8_t *)test_case->buf.p_asm + test_case->active_buf_len * test_case->data_type_size + CANARY_BYTES * test_case->data_type_size, CANARY_BYTES * test_case->data_type_size, test_msg_buf);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we simplify this a bit?

To something like this

Suggested change
TEST_ASSERT_EACH_EQUAL_UINT8_MESSAGE(0, (uint8_t *)test_case->buf.p_asm + test_case->active_buf_len * test_case->data_type_size + CANARY_BYTES * test_case->data_type_size, CANARY_BYTES * test_case->data_type_size, test_msg_buf);
TEST_ASSERT_EACH_EQUAL_UINT8_MESSAGE(0, (uint8_t *)test_case->buf.p_asm + (test_case->active_buf_len + CANARY_BYTES) * test_case->data_type_size, CANARY_BYTES * test_case->data_type_size, test_msg_buf);

Or like the other tests_eval_ functions above? Which use (total_buf_len - CANARY_BYTES) approach, they calculate the end Canary bytes area from the end of the total buffer. Whereas you are calculating it from beginning of the buffer.

Just to make it more readable.

#endif

// Canary bytes area must stay 0
TEST_ASSERT_EACH_EQUAL_UINT8_MESSAGE(0, (uint8_t *)test_case->buf.p_ansi, CANARY_BYTES * test_case->data_type_size, test_msg_buf);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just and idea here: you can create something like
static const canary_bytes_area = CANARY_BYTES * test_case->data_type_size and use this variable in tests asserts.

test_case->blend_api_func(&dsc_asm); // Call the LVGL API with Assembly code
test_case->blend_api_func(&dsc_ansi); // Call the LVGL API with ANSI code
} else if (test_case->blend_api_px_func != NULL) {
test_case->blend_api_px_func(&dsc_asm, 3); // Call the LVGL API with Assembly code
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or something similar, just to know why do we have it here like this.

Suggested change
test_case->blend_api_px_func(&dsc_asm, 3); // Call the LVGL API with Assembly code
test_case->blend_api_px_func(&dsc_asm, 3); // Call the LVGL API with Assembly code with set pixel size

@@ -0,0 +1,105 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget to update license years in relevant files.

/*Simple fill*/
if (mask == NULL && opa >= LV_OPA_MAX) {
if (dsc->use_asm && dest_px_size == 3) {
LV_DRAW_SW_COLOR_BLEND_TO_RGB888(dsc);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, I have mentioned problem with this already.

The original, LVGL's LV_DRAW_SW_COLOR_BLEND_TO_RGB888 macro, looks like this

Thus, it takes 2 parameters dsc and dest_px_size. Whereas your macro takes only one parameter, dsc. And you have substituted the original macro with your implementation and changed the ANSI version of the blending funciton, which we are not suppose to do, to be compatible with the LVGL upstream.

Now, it you try to build the the any LVGL code with our assembly rendering enabled, the build will fail. Because of this changed macro.

Please, fix this issue and try to build some lvgl app with rendering enabled. I have prepared sdkconfig.ci.asm_render for this purpose. It is not run in any CI yet, so we shall check it manually for now.

components/lvgl__lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb888.c
/home/peter/proj/esp-bsp/components/esp_lvgl_port/test_apps/lvgl_port/managed_components/lvgl__lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb888.c: In function 'lv_draw_sw_blend_color_to_rgb888':
/home/peter/proj/esp-bsp/components/esp_lvgl_port/test_apps/lvgl_port/managed_components/lvgl__lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb888.c:153:83: error: macro "LV_DRAW_SW_COLOR_BLEND_TO_RGB888" passed 2 arguments, but takes just 1
  153 |         if(LV_RESULT_INVALID == LV_DRAW_SW_COLOR_BLEND_TO_RGB888(dsc, dest_px_size)) {
      |                                                                                   ^
In file included from /home/peter/proj/esp-bsp/components/esp_lvgl_port/test_apps/lvgl_port/managed_components/lvgl__lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb888.c:24:
/home/peter/proj/esp-bsp/components/esp_lvgl_port/include/esp_lvgl_port_lv_blend.h:36:9: note: macro "LV_DRAW_SW_COLOR_BLEND_TO_RGB888" defined here
   36 | #define LV_DRAW_SW_COLOR_BLEND_TO_RGB888(dsc) \
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/peter/proj/esp-bsp/components/esp_lvgl_port/test_apps/lvgl_port/managed_components/lvgl__lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb888.c:153:33: error: 'LV_DRAW_SW_COLOR_BLEND_TO_RGB888' undeclared (first use in this function)
  153 |         if(LV_RESULT_INVALID == LV_DRAW_SW_COLOR_BLEND_TO_RGB888(dsc, dest_px_size)) {
      |                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/peter/proj/esp-bsp/components/esp_lvgl_port/test_apps/lvgl_port/managed_components/lvgl__lvgl/src/draw/sw/blend/lv_draw_sw_blend_to_rgb888.c:153:33: note: each undeclared identifier is reported only once for each function it appears in

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants